From 0ff062f48e1a8eea054b31511004a2c6016fce89 Mon Sep 17 00:00:00 2001 From: pgdalmeida Date: Thu, 7 May 2026 19:23:30 +0200 Subject: [PATCH] repo refactoring --- README.md | 65 + firmware/.gitignore | 5 + firmware/.vscode/extensions.json | 10 + firmware/README.md | 136 ++ firmware/compile_commands.json | 212 +++ firmware/include/README | 37 + firmware/lib/Adafruit_Sensor | 1 + firmware/lib/DHT-sensor-library | 1 + firmware/lib/README | 46 + firmware/lib/tmc/helpers/API_Header.h | 42 + firmware/lib/tmc/helpers/Bits.h | 92 + firmware/lib/tmc/helpers/CRC.c | 214 +++ firmware/lib/tmc/helpers/CRC.h | 25 + firmware/lib/tmc/helpers/Config.h | 41 + firmware/lib/tmc/helpers/Constants.h | 24 + firmware/lib/tmc/helpers/Functions.c | 173 ++ firmware/lib/tmc/helpers/Functions.h | 20 + firmware/lib/tmc/helpers/Macros.h | 59 + firmware/lib/tmc/helpers/RegisterAccess.h | 86 + firmware/lib/tmc/helpers/Types.h | 107 ++ firmware/lib/tmc/ic/MAX22200/MAX22200.c | 62 + firmware/lib/tmc/ic/MAX22200/MAX22200.h | 17 + .../tmc/ic/MAX22200/MAX22200_HW_Abstraction.h | 412 +++++ firmware/lib/tmc/ic/MAX22200/MISO_GND.jpg | Bin 0 -> 145577 bytes firmware/lib/tmc/ic/MAX22200/README.md | 43 + .../registercall_hierarchy_flowchart_SPI.svg | 3 + firmware/lib/tmc/ic/MAX22200/uml-tmc-api.svg | 3 + firmware/lib/tmc/ic/MAX22215/MAX22215.c | 56 + firmware/lib/tmc/ic/MAX22215/MAX22215.h | 74 + .../tmc/ic/MAX22215/MAX22215_HW_Abstraction.h | 178 ++ firmware/lib/tmc/ic/MAX22215/README.md | 42 + .../registercall_hierarchy_flowchart_I2C.svg | 3 + firmware/lib/tmc/ic/MAX22215/uml-tmc-api.svg | 3 + firmware/lib/tmc/ic/MAX22216/MAX22216.c | 110 ++ firmware/lib/tmc/ic/MAX22216/MAX22216.h | 67 + .../tmc/ic/MAX22216/MAX22216_HW_Abstraction.h | 555 ++++++ firmware/lib/tmc/ic/MAX22216/README.md | 43 + .../registercall_hierarchy_flowchart_SPI.svg | 3 + firmware/lib/tmc/ic/MAX22216/uml-tmc-api.svg | 3 + firmware/lib/tmc/ic/TMC2130/README.md | 46 + firmware/lib/tmc/ic/TMC2130/TMC2130.c | 192 ++ firmware/lib/tmc/ic/TMC2130/TMC2130.h | 222 +++ .../tmc/ic/TMC2130/TMC2130_HW_Abstraction.h | 1134 ++++++++++++ .../registercall_hierarchy_flowchart_SPI.svg | 3 + firmware/lib/tmc/ic/TMC2130/uml-tmc-api.svg | 3 + firmware/lib/tmc/ic/TMC2160/README.md | 46 + firmware/lib/tmc/ic/TMC2160/TMC2160.c | 192 ++ firmware/lib/tmc/ic/TMC2160/TMC2160.h | 224 +++ .../tmc/ic/TMC2160/TMC2160_HW_Abstraction.h | 1226 +++++++++++++ .../registercall_hierarchy_flowchart_SPI.svg | 3 + firmware/lib/tmc/ic/TMC2160/uml-tmc-api.svg | 3 + firmware/lib/tmc/ic/TMC2208/README.md | 52 + firmware/lib/tmc/ic/TMC2208/TMC2208.c | 208 +++ firmware/lib/tmc/ic/TMC2208/TMC2208.h | 183 ++ .../tmc/ic/TMC2208/TMC2208_HW_Abstraction.h | 288 +++ .../registercall_hierarchy_flowchart_UART.svg | 3 + firmware/lib/tmc/ic/TMC2208/uml-tmc-api.svg | 3 + .../Examples/TMC2209_Simple_Rotation.c | 22 + .../Examples/TMC2209_Simple_Rotation.h | 14 + firmware/lib/tmc/ic/TMC2209/README.md | 52 + firmware/lib/tmc/ic/TMC2209/TMC2209.c | 209 +++ firmware/lib/tmc/ic/TMC2209/TMC2209.h | 179 ++ .../tmc/ic/TMC2209/TMC2209_HW_Abstraction.h | 307 ++++ .../registercall_hierarchy_flowchart_UART.svg | 3 + firmware/lib/tmc/ic/TMC2209/uml-tmc-api.svg | 3 + firmware/lib/tmc/ic/TMC2224/README.md | 52 + firmware/lib/tmc/ic/TMC2224/TMC2224.c | 210 +++ firmware/lib/tmc/ic/TMC2224/TMC2224.h | 176 ++ .../tmc/ic/TMC2224/TMC2224_HW_Abstraction.h | 289 +++ .../registercall_hierarchy_flowchart_UART.svg | 3 + firmware/lib/tmc/ic/TMC2224/uml-tmc-api.svg | 3 + firmware/lib/tmc/ic/TMC2225/README.md | 52 + firmware/lib/tmc/ic/TMC2225/TMC2225.c | 210 +++ firmware/lib/tmc/ic/TMC2225/TMC2225.h | 182 ++ .../tmc/ic/TMC2225/TMC2225_HW_Abstraction.h | 291 +++ .../registercall_hierarchy_flowchart_UART.svg | 3 + firmware/lib/tmc/ic/TMC2225/uml-tmc-api.svg | 3 + firmware/lib/tmc/ic/TMC2226/README.md | 52 + firmware/lib/tmc/ic/TMC2226/TMC2226.c | 210 +++ firmware/lib/tmc/ic/TMC2226/TMC2226.h | 199 ++ .../tmc/ic/TMC2226/TMC2226_HW_Abstraction.h | 326 ++++ .../registercall_hierarchy_flowchart_UART.svg | 3 + firmware/lib/tmc/ic/TMC2226/uml-tmc-api.svg | 3 + firmware/lib/tmc/ic/TMC2240/README.md | 62 + firmware/lib/tmc/ic/TMC2240/TMC2240.c | 306 ++++ firmware/lib/tmc/ic/TMC2240/TMC2240.h | 224 +++ .../tmc/ic/TMC2240/TMC2240_HW_Abstraction.h | 567 ++++++ .../registercall_hierarchy_flowchart_SPI.svg | 3 + .../registercall_hierarchy_flowchart_UART.svg | 3 + firmware/lib/tmc/ic/TMC2240/uml-tmc-api.svg | 3 + firmware/lib/tmc/ic/TMC2241/README.md | 64 + firmware/lib/tmc/ic/TMC2241/TMC2241.c | 303 +++ firmware/lib/tmc/ic/TMC2241/TMC2241.h | 221 +++ .../tmc/ic/TMC2241/TMC2241_HW_Abstraction.h | 610 +++++++ .../registercall_hierarchy_flowchart_SPI.svg | 3 + .../registercall_hierarchy_flowchart_UART.svg | 3 + firmware/lib/tmc/ic/TMC2241/uml-tmc-api.svg | 3 + firmware/lib/tmc/ic/TMC2262/README.md | 43 + firmware/lib/tmc/ic/TMC2262/TMC2262.c | 55 + firmware/lib/tmc/ic/TMC2262/TMC2262.h | 68 + .../tmc/ic/TMC2262/TMC2262_HW_Abstraction.h | 804 ++++++++ .../registercall_hierarchy_flowchart_SPI.svg | 3 + firmware/lib/tmc/ic/TMC2262/uml-tmc-api.svg | 3 + firmware/lib/tmc/ic/TMC2300/README.md | 51 + firmware/lib/tmc/ic/TMC2300/TMC2300.c | 250 +++ firmware/lib/tmc/ic/TMC2300/TMC2300.h | 209 +++ .../tmc/ic/TMC2300/TMC2300_HW_Abstraction.h | 275 +++ .../registercall_hierarchy_flowchart_UART.svg | 3 + firmware/lib/tmc/ic/TMC2300/uml-tmc-api.svg | 3 + firmware/lib/tmc/ic/TMC262/TMC262.c | 830 +++++++++ firmware/lib/tmc/ic/TMC262/TMC262.h | 94 + firmware/lib/tmc/ic/TMC262/TMC262_Register.h | 152 ++ firmware/lib/tmc/ic/TMC2660/README.md | 53 + firmware/lib/tmc/ic/TMC2660/TMC2660.c | 153 ++ firmware/lib/tmc/ic/TMC2660/TMC2660.h | 168 ++ .../tmc/ic/TMC2660/TMC2660_HW_Abstraction.h | 298 +++ ...ll_hierarchy_flowchart_SPIRead_tmc2660.svg | 3 + ...l_hierarchy_flowchart_SPIWrite_tmc2660.svg | 3 + firmware/lib/tmc/ic/TMC2660/uml-tmc-api.svg | 3 + firmware/lib/tmc/ic/TMC4361A/README.md | 43 + firmware/lib/tmc/ic/TMC4361A/TMC4361A.c | 189 ++ firmware/lib/tmc/ic/TMC4361A/TMC4361A.h | 243 +++ .../tmc/ic/TMC4361A/TMC4361A_HW_Abstraction.h | 1413 ++++++++++++++ .../registercall_hierarchy_flowchart_SPI.svg | 3 + firmware/lib/tmc/ic/TMC4361A/uml-tmc-api.svg | 3 + firmware/lib/tmc/ic/TMC4671/README.md | 42 + firmware/lib/tmc/ic/TMC4671/TMC4671.c | 510 ++++++ firmware/lib/tmc/ic/TMC4671/TMC4671.h | 116 ++ .../tmc/ic/TMC4671/TMC4671_HW_Abstraction.h | 1453 +++++++++++++++ .../registercall_hierarchy_flowchart_SPI.svg | 3 + firmware/lib/tmc/ic/TMC4671/uml-tmc-api.svg | 3 + firmware/lib/tmc/ic/TMC5031/README.md | 47 + firmware/lib/tmc/ic/TMC5031/TMC5031.c | 191 ++ firmware/lib/tmc/ic/TMC5031/TMC5031.h | 226 +++ .../tmc/ic/TMC5031/TMC5031_HW_Abstraction.h | 1167 ++++++++++++ .../registercall_hierarchy_flowchart_SPI.svg | 3 + firmware/lib/tmc/ic/TMC5031/uml-tmc-api.svg | 3 + firmware/lib/tmc/ic/TMC5041/README.md | 46 + firmware/lib/tmc/ic/TMC5041/TMC5041.c | 194 ++ firmware/lib/tmc/ic/TMC5041/TMC5041.h | 218 +++ .../tmc/ic/TMC5041/TMC5041_HW_Abstraction.h | 1199 ++++++++++++ .../registercall_hierarchy_flowchart_SPI.svg | 3 + firmware/lib/tmc/ic/TMC5041/uml-tmc-api.svg | 3 + firmware/lib/tmc/ic/TMC5062/README.md | 69 + firmware/lib/tmc/ic/TMC5062/TMC5062.c | 313 ++++ firmware/lib/tmc/ic/TMC5062/TMC5062.h | 252 +++ .../tmc/ic/TMC5062/TMC5062_HW_Abstraction.h | 1287 +++++++++++++ .../registercall_hierarchy_flowchart_SPI.svg | 3 + .../registercall_hierarchy_flowchart_UART.svg | 3 + firmware/lib/tmc/ic/TMC5062/uml-tmc-api.svg | 3 + firmware/lib/tmc/ic/TMC5072/README.md | 71 + firmware/lib/tmc/ic/TMC5072/TMC5072.c | 304 ++++ firmware/lib/tmc/ic/TMC5072/TMC5072.h | 232 +++ .../tmc/ic/TMC5072/TMC5072_HW_Abstraction.h | 1327 ++++++++++++++ .../registercall_hierarchy_flowchart_SPI.svg | 3 + .../registercall_hierarchy_flowchart_UART.svg | 3 + firmware/lib/tmc/ic/TMC5072/uml-tmc-api.svg | 3 + .../Examples/TMC5130_Simple_Rotation.c | 28 + .../Examples/TMC5130_Simple_Rotation.h | 14 + firmware/lib/tmc/ic/TMC5130/README.md | 69 + firmware/lib/tmc/ic/TMC5130/TMC5130.c | 322 ++++ firmware/lib/tmc/ic/TMC5130/TMC5130.h | 225 +++ .../tmc/ic/TMC5130/TMC5130_HW_Abstraction.h | 1384 ++++++++++++++ .../registercall_hierarchy_flowchart_SPI.svg | 3 + .../registercall_hierarchy_flowchart_UART.svg | 3 + firmware/lib/tmc/ic/TMC5130/uml-tmc-api.svg | 3 + firmware/lib/tmc/ic/TMC5160/README.md | 68 + firmware/lib/tmc/ic/TMC5160/TMC5160.c | 311 ++++ firmware/lib/tmc/ic/TMC5160/TMC5160.h | 229 +++ .../tmc/ic/TMC5160/TMC5160_HW_Abstraction.h | 1619 +++++++++++++++++ .../registercall_hierarchy_flowchart_SPI.svg | 3 + .../registercall_hierarchy_flowchart_UART.svg | 3 + firmware/lib/tmc/ic/TMC5160/uml-tmc-api.svg | 3 + firmware/lib/tmc/ic/TMC5240/README.md | 57 + firmware/lib/tmc/ic/TMC5240/TMC5240.c | 179 ++ firmware/lib/tmc/ic/TMC5240/TMC5240.h | 165 ++ .../tmc/ic/TMC5240/TMC5240_HW_Abstraction.h | 810 +++++++++ .../registercall_hierarchy_flowchart_SPI.svg | 3 + .../registercall_hierarchy_flowchart_UART.svg | 3 + firmware/lib/tmc/ic/TMC5240/uml-tmc-api.svg | 3 + firmware/lib/tmc/ic/TMC5241/README.md | 57 + firmware/lib/tmc/ic/TMC5241/TMC5241.c | 177 ++ firmware/lib/tmc/ic/TMC5241/TMC5241.h | 164 ++ .../tmc/ic/TMC5241/TMC5241_HW_Abstraction.h | 875 +++++++++ .../registercall_hierarchy_flowchart_SPI.svg | 3 + .../registercall_hierarchy_flowchart_UART.svg | 3 + firmware/lib/tmc/ic/TMC5241/uml-tmc-api.svg | 3 + firmware/lib/tmc/ic/TMC5262/README.md | 43 + firmware/lib/tmc/ic/TMC5262/TMC5262.c | 67 + firmware/lib/tmc/ic/TMC5262/TMC5262.h | 74 + .../tmc/ic/TMC5262/TMC5262_HW_Abstraction.h | 1031 +++++++++++ .../registercall_hierarchy_flowchart_SPI.svg | 3 + firmware/lib/tmc/ic/TMC5262/uml-tmc-api.svg | 3 + .../Examples/TMC5271_Simple_Rotation.c | 31 + .../Examples/TMC5271_Simple_Rotation.h | 14 + firmware/lib/tmc/ic/TMC5271/README.md | 63 + firmware/lib/tmc/ic/TMC5271/TMC5271.c | 180 ++ firmware/lib/tmc/ic/TMC5271/TMC5271.h | 120 ++ .../tmc/ic/TMC5271/TMC5271_HW_Abstraction.h | 683 +++++++ .../registercall_hierarchy_flowchart_SPI.svg | 3 + .../registercall_hierarchy_flowchart_UART.svg | 3 + firmware/lib/tmc/ic/TMC5271/uml-tmc-api.svg | 3 + .../Examples/TMC5272_Simple_Rotation.c | 37 + .../Examples/TMC5272_Simple_Rotation.h | 14 + firmware/lib/tmc/ic/TMC5272/README.md | 63 + firmware/lib/tmc/ic/TMC5272/TMC5272.c | 179 ++ firmware/lib/tmc/ic/TMC5272/TMC5272.h | 115 ++ .../tmc/ic/TMC5272/TMC5272_HW_Abstraction.h | 735 ++++++++ .../registercall_hierarchy_flowchart_SPI.svg | 3 + .../registercall_hierarchy_flowchart_UART.svg | 3 + firmware/lib/tmc/ic/TMC5272/uml-tmc-api.svg | 3 + firmware/lib/tmc/ic/TMC6100/README.md | 43 + firmware/lib/tmc/ic/TMC6100/TMC6100.c | 55 + firmware/lib/tmc/ic/TMC6100/TMC6100.h | 69 + .../tmc/ic/TMC6100/TMC6100_HW_Abstraction.h | 182 ++ .../registercall_hierarchy_flowchart_SPI.svg | 3 + firmware/lib/tmc/ic/TMC6100/uml-tmc-api.svg | 3 + firmware/lib/tmc/ic/TMC6200/README.md | 43 + firmware/lib/tmc/ic/TMC6200/TMC6200.c | 55 + firmware/lib/tmc/ic/TMC6200/TMC6200.h | 69 + .../tmc/ic/TMC6200/TMC6200_HW_Abstraction.h | 183 ++ .../registercall_hierarchy_flowchart_SPI.svg | 3 + firmware/lib/tmc/ic/TMC6200/uml-tmc-api.svg | 3 + firmware/lib/tmc/ic/TMC7300/README.md | 51 + firmware/lib/tmc/ic/TMC7300/TMC7300.c | 252 +++ firmware/lib/tmc/ic/TMC7300/TMC7300.h | 203 +++ .../tmc/ic/TMC7300/TMC7300_HW_Abstraction.h | 166 ++ .../registercall_hierarchy_flowchart_UART.svg | 3 + firmware/lib/tmc/ic/TMC7300/uml-tmc-api.svg | 3 + firmware/lib/tmc/ic/TMC9660/README.md | 44 + firmware/lib/tmc/ic/TMC9660/TMC9660.c | 358 ++++ firmware/lib/tmc/ic/TMC9660/TMC9660.h | 196 ++ .../ic/TMC9660/TMC9660_BL_HW_Abstraction.h | 693 +++++++ .../ic/TMC9660/TMC9660_PARAM_HW_Abstraction.h | 297 +++ firmware/lib/tmc/ramp/LinearRamp.c | 163 ++ firmware/lib/tmc/ramp/LinearRamp.h | 34 + firmware/lib/tmc/ramp/LinearRamp1.c | 303 +++ firmware/lib/tmc/ramp/LinearRamp1.h | 89 + firmware/lib/tmc/ramp/Ramp.c | 91 + firmware/lib/tmc/ramp/Ramp.h | 40 + firmware/lib/tmc/src/API_Header.h | 42 + firmware/lib/tmc/src/Bits.h | 92 + firmware/lib/tmc/src/CRC.c | 214 +++ firmware/lib/tmc/src/CRC.h | 25 + firmware/lib/tmc/src/Config.h | 41 + firmware/lib/tmc/src/Constants.h | 24 + firmware/lib/tmc/src/Functions.c | 173 ++ firmware/lib/tmc/src/Functions.h | 20 + firmware/lib/tmc/src/Macros.h | 59 + firmware/lib/tmc/src/README.md | 68 + firmware/lib/tmc/src/RegisterAccess.h | 86 + firmware/lib/tmc/src/TMC5160.c | 554 ++++++ firmware/lib/tmc/src/TMC5160.h | 374 ++++ firmware/lib/tmc/src/TMC5160_HW_Abstraction.h | 1619 +++++++++++++++++ firmware/lib/tmc/src/Types.h | 107 ++ firmware/lib/tmc/src/logger.cpp | 12 + firmware/lib/tmc/src/logger.h | 2 + .../registercall_hierarchy_flowchart_SPI.svg | 3 + .../registercall_hierarchy_flowchart_UART.svg | 3 + firmware/lib/tmc/src/uml-tmc-api.svg | 3 + firmware/platformio.ini | 19 + firmware/src/config/Constants.h | 50 + firmware/src/config/Pins.h | 15 + firmware/src/hal/README.md | 25 + firmware/src/hal/SPI_HAL.cpp | 32 + firmware/src/main.cpp | 38 + firmware/src/motor/Homing.cpp | 133 ++ firmware/src/motor/Homing.h | 10 + firmware/src/motor/MotorAxis.cpp | 68 + firmware/src/motor/MotorAxis.h | 68 + firmware/src/motor/MotorConfig.h | 19 + firmware/src/motor/MotorDriver.cpp | 156 ++ firmware/src/motor/MotorDriver.h | 14 + firmware/src/serial/CommandParser.cpp | 170 ++ firmware/src/serial/CommandParser.h | 8 + firmware/src/thermal/ThermalManager.cpp | 36 + firmware/src/thermal/ThermalManager.h | 12 + firmware/test/README | 11 + host/CMakeLists.txt | 84 + host/Camera.cpp | 343 ++++ host/Camera.h | 100 + host/FWT_host.cpp | 281 +++ host/JPEG_XL.h | 110 ++ host/Log.h | 1 + host/MQTT.cpp | 157 ++ host/MQTT.h | 157 ++ host/Parser.h | 101 + host/README.md | 113 ++ host/Serial.h | 144 ++ host/deploy.sh | 8 + host/timing.h | 116 ++ 291 files changed, 47332 insertions(+) create mode 100644 firmware/.gitignore create mode 100644 firmware/.vscode/extensions.json create mode 100644 firmware/README.md create mode 100644 firmware/compile_commands.json create mode 100755 firmware/include/README create mode 160000 firmware/lib/Adafruit_Sensor create mode 160000 firmware/lib/DHT-sensor-library create mode 100755 firmware/lib/README create mode 100755 firmware/lib/tmc/helpers/API_Header.h create mode 100755 firmware/lib/tmc/helpers/Bits.h create mode 100755 firmware/lib/tmc/helpers/CRC.c create mode 100755 firmware/lib/tmc/helpers/CRC.h create mode 100755 firmware/lib/tmc/helpers/Config.h create mode 100755 firmware/lib/tmc/helpers/Constants.h create mode 100755 firmware/lib/tmc/helpers/Functions.c create mode 100755 firmware/lib/tmc/helpers/Functions.h create mode 100755 firmware/lib/tmc/helpers/Macros.h create mode 100755 firmware/lib/tmc/helpers/RegisterAccess.h create mode 100755 firmware/lib/tmc/helpers/Types.h create mode 100755 firmware/lib/tmc/ic/MAX22200/MAX22200.c create mode 100755 firmware/lib/tmc/ic/MAX22200/MAX22200.h create mode 100755 firmware/lib/tmc/ic/MAX22200/MAX22200_HW_Abstraction.h create mode 100755 firmware/lib/tmc/ic/MAX22200/MISO_GND.jpg create mode 100755 firmware/lib/tmc/ic/MAX22200/README.md create mode 100755 firmware/lib/tmc/ic/MAX22200/registercall_hierarchy_flowchart_SPI.svg create mode 100755 firmware/lib/tmc/ic/MAX22200/uml-tmc-api.svg create mode 100755 firmware/lib/tmc/ic/MAX22215/MAX22215.c create mode 100755 firmware/lib/tmc/ic/MAX22215/MAX22215.h create mode 100755 firmware/lib/tmc/ic/MAX22215/MAX22215_HW_Abstraction.h create mode 100755 firmware/lib/tmc/ic/MAX22215/README.md create mode 100755 firmware/lib/tmc/ic/MAX22215/registercall_hierarchy_flowchart_I2C.svg create mode 100755 firmware/lib/tmc/ic/MAX22215/uml-tmc-api.svg create mode 100755 firmware/lib/tmc/ic/MAX22216/MAX22216.c create mode 100755 firmware/lib/tmc/ic/MAX22216/MAX22216.h create mode 100755 firmware/lib/tmc/ic/MAX22216/MAX22216_HW_Abstraction.h create mode 100755 firmware/lib/tmc/ic/MAX22216/README.md create mode 100755 firmware/lib/tmc/ic/MAX22216/registercall_hierarchy_flowchart_SPI.svg create mode 100755 firmware/lib/tmc/ic/MAX22216/uml-tmc-api.svg create mode 100755 firmware/lib/tmc/ic/TMC2130/README.md create mode 100755 firmware/lib/tmc/ic/TMC2130/TMC2130.c create mode 100755 firmware/lib/tmc/ic/TMC2130/TMC2130.h create mode 100755 firmware/lib/tmc/ic/TMC2130/TMC2130_HW_Abstraction.h create mode 100755 firmware/lib/tmc/ic/TMC2130/registercall_hierarchy_flowchart_SPI.svg create mode 100755 firmware/lib/tmc/ic/TMC2130/uml-tmc-api.svg create mode 100755 firmware/lib/tmc/ic/TMC2160/README.md create mode 100755 firmware/lib/tmc/ic/TMC2160/TMC2160.c create mode 100755 firmware/lib/tmc/ic/TMC2160/TMC2160.h create mode 100755 firmware/lib/tmc/ic/TMC2160/TMC2160_HW_Abstraction.h create mode 100755 firmware/lib/tmc/ic/TMC2160/registercall_hierarchy_flowchart_SPI.svg create mode 100755 firmware/lib/tmc/ic/TMC2160/uml-tmc-api.svg create mode 100755 firmware/lib/tmc/ic/TMC2208/README.md create mode 100755 firmware/lib/tmc/ic/TMC2208/TMC2208.c create mode 100755 firmware/lib/tmc/ic/TMC2208/TMC2208.h create mode 100755 firmware/lib/tmc/ic/TMC2208/TMC2208_HW_Abstraction.h create mode 100755 firmware/lib/tmc/ic/TMC2208/registercall_hierarchy_flowchart_UART.svg create mode 100755 firmware/lib/tmc/ic/TMC2208/uml-tmc-api.svg create mode 100755 firmware/lib/tmc/ic/TMC2209/Examples/TMC2209_Simple_Rotation.c create mode 100755 firmware/lib/tmc/ic/TMC2209/Examples/TMC2209_Simple_Rotation.h create mode 100755 firmware/lib/tmc/ic/TMC2209/README.md create mode 100755 firmware/lib/tmc/ic/TMC2209/TMC2209.c create mode 100755 firmware/lib/tmc/ic/TMC2209/TMC2209.h create mode 100755 firmware/lib/tmc/ic/TMC2209/TMC2209_HW_Abstraction.h create mode 100755 firmware/lib/tmc/ic/TMC2209/registercall_hierarchy_flowchart_UART.svg create mode 100755 firmware/lib/tmc/ic/TMC2209/uml-tmc-api.svg create mode 100755 firmware/lib/tmc/ic/TMC2224/README.md create mode 100755 firmware/lib/tmc/ic/TMC2224/TMC2224.c create mode 100755 firmware/lib/tmc/ic/TMC2224/TMC2224.h create mode 100755 firmware/lib/tmc/ic/TMC2224/TMC2224_HW_Abstraction.h create mode 100755 firmware/lib/tmc/ic/TMC2224/registercall_hierarchy_flowchart_UART.svg create mode 100755 firmware/lib/tmc/ic/TMC2224/uml-tmc-api.svg create mode 100755 firmware/lib/tmc/ic/TMC2225/README.md create mode 100755 firmware/lib/tmc/ic/TMC2225/TMC2225.c create mode 100755 firmware/lib/tmc/ic/TMC2225/TMC2225.h create mode 100755 firmware/lib/tmc/ic/TMC2225/TMC2225_HW_Abstraction.h create mode 100755 firmware/lib/tmc/ic/TMC2225/registercall_hierarchy_flowchart_UART.svg create mode 100755 firmware/lib/tmc/ic/TMC2225/uml-tmc-api.svg create mode 100755 firmware/lib/tmc/ic/TMC2226/README.md create mode 100755 firmware/lib/tmc/ic/TMC2226/TMC2226.c create mode 100755 firmware/lib/tmc/ic/TMC2226/TMC2226.h create mode 100755 firmware/lib/tmc/ic/TMC2226/TMC2226_HW_Abstraction.h create mode 100755 firmware/lib/tmc/ic/TMC2226/registercall_hierarchy_flowchart_UART.svg create mode 100755 firmware/lib/tmc/ic/TMC2226/uml-tmc-api.svg create mode 100755 firmware/lib/tmc/ic/TMC2240/README.md create mode 100755 firmware/lib/tmc/ic/TMC2240/TMC2240.c create mode 100755 firmware/lib/tmc/ic/TMC2240/TMC2240.h create mode 100755 firmware/lib/tmc/ic/TMC2240/TMC2240_HW_Abstraction.h create mode 100755 firmware/lib/tmc/ic/TMC2240/registercall_hierarchy_flowchart_SPI.svg create mode 100755 firmware/lib/tmc/ic/TMC2240/registercall_hierarchy_flowchart_UART.svg create mode 100755 firmware/lib/tmc/ic/TMC2240/uml-tmc-api.svg create mode 100755 firmware/lib/tmc/ic/TMC2241/README.md create mode 100755 firmware/lib/tmc/ic/TMC2241/TMC2241.c create mode 100755 firmware/lib/tmc/ic/TMC2241/TMC2241.h create mode 100755 firmware/lib/tmc/ic/TMC2241/TMC2241_HW_Abstraction.h create mode 100755 firmware/lib/tmc/ic/TMC2241/registercall_hierarchy_flowchart_SPI.svg create mode 100755 firmware/lib/tmc/ic/TMC2241/registercall_hierarchy_flowchart_UART.svg create mode 100755 firmware/lib/tmc/ic/TMC2241/uml-tmc-api.svg create mode 100755 firmware/lib/tmc/ic/TMC2262/README.md create mode 100755 firmware/lib/tmc/ic/TMC2262/TMC2262.c create mode 100755 firmware/lib/tmc/ic/TMC2262/TMC2262.h create mode 100755 firmware/lib/tmc/ic/TMC2262/TMC2262_HW_Abstraction.h create mode 100755 firmware/lib/tmc/ic/TMC2262/registercall_hierarchy_flowchart_SPI.svg create mode 100755 firmware/lib/tmc/ic/TMC2262/uml-tmc-api.svg create mode 100755 firmware/lib/tmc/ic/TMC2300/README.md create mode 100755 firmware/lib/tmc/ic/TMC2300/TMC2300.c create mode 100755 firmware/lib/tmc/ic/TMC2300/TMC2300.h create mode 100755 firmware/lib/tmc/ic/TMC2300/TMC2300_HW_Abstraction.h create mode 100755 firmware/lib/tmc/ic/TMC2300/registercall_hierarchy_flowchart_UART.svg create mode 100755 firmware/lib/tmc/ic/TMC2300/uml-tmc-api.svg create mode 100755 firmware/lib/tmc/ic/TMC262/TMC262.c create mode 100755 firmware/lib/tmc/ic/TMC262/TMC262.h create mode 100755 firmware/lib/tmc/ic/TMC262/TMC262_Register.h create mode 100755 firmware/lib/tmc/ic/TMC2660/README.md create mode 100755 firmware/lib/tmc/ic/TMC2660/TMC2660.c create mode 100755 firmware/lib/tmc/ic/TMC2660/TMC2660.h create mode 100755 firmware/lib/tmc/ic/TMC2660/TMC2660_HW_Abstraction.h create mode 100755 firmware/lib/tmc/ic/TMC2660/registercall_hierarchy_flowchart_SPIRead_tmc2660.svg create mode 100755 firmware/lib/tmc/ic/TMC2660/registercall_hierarchy_flowchart_SPIWrite_tmc2660.svg create mode 100755 firmware/lib/tmc/ic/TMC2660/uml-tmc-api.svg create mode 100755 firmware/lib/tmc/ic/TMC4361A/README.md create mode 100755 firmware/lib/tmc/ic/TMC4361A/TMC4361A.c create mode 100755 firmware/lib/tmc/ic/TMC4361A/TMC4361A.h create mode 100755 firmware/lib/tmc/ic/TMC4361A/TMC4361A_HW_Abstraction.h create mode 100755 firmware/lib/tmc/ic/TMC4361A/registercall_hierarchy_flowchart_SPI.svg create mode 100755 firmware/lib/tmc/ic/TMC4361A/uml-tmc-api.svg create mode 100755 firmware/lib/tmc/ic/TMC4671/README.md create mode 100755 firmware/lib/tmc/ic/TMC4671/TMC4671.c create mode 100755 firmware/lib/tmc/ic/TMC4671/TMC4671.h create mode 100755 firmware/lib/tmc/ic/TMC4671/TMC4671_HW_Abstraction.h create mode 100755 firmware/lib/tmc/ic/TMC4671/registercall_hierarchy_flowchart_SPI.svg create mode 100755 firmware/lib/tmc/ic/TMC4671/uml-tmc-api.svg create mode 100755 firmware/lib/tmc/ic/TMC5031/README.md create mode 100755 firmware/lib/tmc/ic/TMC5031/TMC5031.c create mode 100755 firmware/lib/tmc/ic/TMC5031/TMC5031.h create mode 100755 firmware/lib/tmc/ic/TMC5031/TMC5031_HW_Abstraction.h create mode 100755 firmware/lib/tmc/ic/TMC5031/registercall_hierarchy_flowchart_SPI.svg create mode 100755 firmware/lib/tmc/ic/TMC5031/uml-tmc-api.svg create mode 100755 firmware/lib/tmc/ic/TMC5041/README.md create mode 100755 firmware/lib/tmc/ic/TMC5041/TMC5041.c create mode 100755 firmware/lib/tmc/ic/TMC5041/TMC5041.h create mode 100755 firmware/lib/tmc/ic/TMC5041/TMC5041_HW_Abstraction.h create mode 100755 firmware/lib/tmc/ic/TMC5041/registercall_hierarchy_flowchart_SPI.svg create mode 100755 firmware/lib/tmc/ic/TMC5041/uml-tmc-api.svg create mode 100755 firmware/lib/tmc/ic/TMC5062/README.md create mode 100755 firmware/lib/tmc/ic/TMC5062/TMC5062.c create mode 100755 firmware/lib/tmc/ic/TMC5062/TMC5062.h create mode 100755 firmware/lib/tmc/ic/TMC5062/TMC5062_HW_Abstraction.h create mode 100755 firmware/lib/tmc/ic/TMC5062/registercall_hierarchy_flowchart_SPI.svg create mode 100755 firmware/lib/tmc/ic/TMC5062/registercall_hierarchy_flowchart_UART.svg create mode 100755 firmware/lib/tmc/ic/TMC5062/uml-tmc-api.svg create mode 100755 firmware/lib/tmc/ic/TMC5072/README.md create mode 100755 firmware/lib/tmc/ic/TMC5072/TMC5072.c create mode 100755 firmware/lib/tmc/ic/TMC5072/TMC5072.h create mode 100755 firmware/lib/tmc/ic/TMC5072/TMC5072_HW_Abstraction.h create mode 100755 firmware/lib/tmc/ic/TMC5072/registercall_hierarchy_flowchart_SPI.svg create mode 100755 firmware/lib/tmc/ic/TMC5072/registercall_hierarchy_flowchart_UART.svg create mode 100755 firmware/lib/tmc/ic/TMC5072/uml-tmc-api.svg create mode 100755 firmware/lib/tmc/ic/TMC5130/Examples/TMC5130_Simple_Rotation.c create mode 100755 firmware/lib/tmc/ic/TMC5130/Examples/TMC5130_Simple_Rotation.h create mode 100755 firmware/lib/tmc/ic/TMC5130/README.md create mode 100755 firmware/lib/tmc/ic/TMC5130/TMC5130.c create mode 100755 firmware/lib/tmc/ic/TMC5130/TMC5130.h create mode 100755 firmware/lib/tmc/ic/TMC5130/TMC5130_HW_Abstraction.h create mode 100755 firmware/lib/tmc/ic/TMC5130/registercall_hierarchy_flowchart_SPI.svg create mode 100755 firmware/lib/tmc/ic/TMC5130/registercall_hierarchy_flowchart_UART.svg create mode 100755 firmware/lib/tmc/ic/TMC5130/uml-tmc-api.svg create mode 100755 firmware/lib/tmc/ic/TMC5160/README.md create mode 100755 firmware/lib/tmc/ic/TMC5160/TMC5160.c create mode 100755 firmware/lib/tmc/ic/TMC5160/TMC5160.h create mode 100755 firmware/lib/tmc/ic/TMC5160/TMC5160_HW_Abstraction.h create mode 100755 firmware/lib/tmc/ic/TMC5160/registercall_hierarchy_flowchart_SPI.svg create mode 100755 firmware/lib/tmc/ic/TMC5160/registercall_hierarchy_flowchart_UART.svg create mode 100755 firmware/lib/tmc/ic/TMC5160/uml-tmc-api.svg create mode 100755 firmware/lib/tmc/ic/TMC5240/README.md create mode 100755 firmware/lib/tmc/ic/TMC5240/TMC5240.c create mode 100755 firmware/lib/tmc/ic/TMC5240/TMC5240.h create mode 100755 firmware/lib/tmc/ic/TMC5240/TMC5240_HW_Abstraction.h create mode 100755 firmware/lib/tmc/ic/TMC5240/registercall_hierarchy_flowchart_SPI.svg create mode 100755 firmware/lib/tmc/ic/TMC5240/registercall_hierarchy_flowchart_UART.svg create mode 100755 firmware/lib/tmc/ic/TMC5240/uml-tmc-api.svg create mode 100755 firmware/lib/tmc/ic/TMC5241/README.md create mode 100755 firmware/lib/tmc/ic/TMC5241/TMC5241.c create mode 100755 firmware/lib/tmc/ic/TMC5241/TMC5241.h create mode 100755 firmware/lib/tmc/ic/TMC5241/TMC5241_HW_Abstraction.h create mode 100755 firmware/lib/tmc/ic/TMC5241/registercall_hierarchy_flowchart_SPI.svg create mode 100755 firmware/lib/tmc/ic/TMC5241/registercall_hierarchy_flowchart_UART.svg create mode 100755 firmware/lib/tmc/ic/TMC5241/uml-tmc-api.svg create mode 100755 firmware/lib/tmc/ic/TMC5262/README.md create mode 100755 firmware/lib/tmc/ic/TMC5262/TMC5262.c create mode 100755 firmware/lib/tmc/ic/TMC5262/TMC5262.h create mode 100755 firmware/lib/tmc/ic/TMC5262/TMC5262_HW_Abstraction.h create mode 100755 firmware/lib/tmc/ic/TMC5262/registercall_hierarchy_flowchart_SPI.svg create mode 100755 firmware/lib/tmc/ic/TMC5262/uml-tmc-api.svg create mode 100755 firmware/lib/tmc/ic/TMC5271/Examples/TMC5271_Simple_Rotation.c create mode 100755 firmware/lib/tmc/ic/TMC5271/Examples/TMC5271_Simple_Rotation.h create mode 100755 firmware/lib/tmc/ic/TMC5271/README.md create mode 100755 firmware/lib/tmc/ic/TMC5271/TMC5271.c create mode 100755 firmware/lib/tmc/ic/TMC5271/TMC5271.h create mode 100755 firmware/lib/tmc/ic/TMC5271/TMC5271_HW_Abstraction.h create mode 100755 firmware/lib/tmc/ic/TMC5271/registercall_hierarchy_flowchart_SPI.svg create mode 100755 firmware/lib/tmc/ic/TMC5271/registercall_hierarchy_flowchart_UART.svg create mode 100755 firmware/lib/tmc/ic/TMC5271/uml-tmc-api.svg create mode 100755 firmware/lib/tmc/ic/TMC5272/Examples/TMC5272_Simple_Rotation.c create mode 100755 firmware/lib/tmc/ic/TMC5272/Examples/TMC5272_Simple_Rotation.h create mode 100755 firmware/lib/tmc/ic/TMC5272/README.md create mode 100755 firmware/lib/tmc/ic/TMC5272/TMC5272.c create mode 100755 firmware/lib/tmc/ic/TMC5272/TMC5272.h create mode 100755 firmware/lib/tmc/ic/TMC5272/TMC5272_HW_Abstraction.h create mode 100755 firmware/lib/tmc/ic/TMC5272/registercall_hierarchy_flowchart_SPI.svg create mode 100755 firmware/lib/tmc/ic/TMC5272/registercall_hierarchy_flowchart_UART.svg create mode 100755 firmware/lib/tmc/ic/TMC5272/uml-tmc-api.svg create mode 100755 firmware/lib/tmc/ic/TMC6100/README.md create mode 100755 firmware/lib/tmc/ic/TMC6100/TMC6100.c create mode 100755 firmware/lib/tmc/ic/TMC6100/TMC6100.h create mode 100755 firmware/lib/tmc/ic/TMC6100/TMC6100_HW_Abstraction.h create mode 100755 firmware/lib/tmc/ic/TMC6100/registercall_hierarchy_flowchart_SPI.svg create mode 100755 firmware/lib/tmc/ic/TMC6100/uml-tmc-api.svg create mode 100755 firmware/lib/tmc/ic/TMC6200/README.md create mode 100755 firmware/lib/tmc/ic/TMC6200/TMC6200.c create mode 100755 firmware/lib/tmc/ic/TMC6200/TMC6200.h create mode 100755 firmware/lib/tmc/ic/TMC6200/TMC6200_HW_Abstraction.h create mode 100755 firmware/lib/tmc/ic/TMC6200/registercall_hierarchy_flowchart_SPI.svg create mode 100755 firmware/lib/tmc/ic/TMC6200/uml-tmc-api.svg create mode 100755 firmware/lib/tmc/ic/TMC7300/README.md create mode 100755 firmware/lib/tmc/ic/TMC7300/TMC7300.c create mode 100755 firmware/lib/tmc/ic/TMC7300/TMC7300.h create mode 100755 firmware/lib/tmc/ic/TMC7300/TMC7300_HW_Abstraction.h create mode 100755 firmware/lib/tmc/ic/TMC7300/registercall_hierarchy_flowchart_UART.svg create mode 100755 firmware/lib/tmc/ic/TMC7300/uml-tmc-api.svg create mode 100755 firmware/lib/tmc/ic/TMC9660/README.md create mode 100755 firmware/lib/tmc/ic/TMC9660/TMC9660.c create mode 100755 firmware/lib/tmc/ic/TMC9660/TMC9660.h create mode 100755 firmware/lib/tmc/ic/TMC9660/TMC9660_BL_HW_Abstraction.h create mode 100755 firmware/lib/tmc/ic/TMC9660/TMC9660_PARAM_HW_Abstraction.h create mode 100755 firmware/lib/tmc/ramp/LinearRamp.c create mode 100755 firmware/lib/tmc/ramp/LinearRamp.h create mode 100755 firmware/lib/tmc/ramp/LinearRamp1.c create mode 100755 firmware/lib/tmc/ramp/LinearRamp1.h create mode 100755 firmware/lib/tmc/ramp/Ramp.c create mode 100755 firmware/lib/tmc/ramp/Ramp.h create mode 100755 firmware/lib/tmc/src/API_Header.h create mode 100755 firmware/lib/tmc/src/Bits.h create mode 100755 firmware/lib/tmc/src/CRC.c create mode 100755 firmware/lib/tmc/src/CRC.h create mode 100755 firmware/lib/tmc/src/Config.h create mode 100755 firmware/lib/tmc/src/Constants.h create mode 100755 firmware/lib/tmc/src/Functions.c create mode 100755 firmware/lib/tmc/src/Functions.h create mode 100755 firmware/lib/tmc/src/Macros.h create mode 100755 firmware/lib/tmc/src/README.md create mode 100755 firmware/lib/tmc/src/RegisterAccess.h create mode 100755 firmware/lib/tmc/src/TMC5160.c create mode 100755 firmware/lib/tmc/src/TMC5160.h create mode 100755 firmware/lib/tmc/src/TMC5160_HW_Abstraction.h create mode 100755 firmware/lib/tmc/src/Types.h create mode 100755 firmware/lib/tmc/src/logger.cpp create mode 100755 firmware/lib/tmc/src/logger.h create mode 100755 firmware/lib/tmc/src/registercall_hierarchy_flowchart_SPI.svg create mode 100755 firmware/lib/tmc/src/registercall_hierarchy_flowchart_UART.svg create mode 100755 firmware/lib/tmc/src/uml-tmc-api.svg create mode 100755 firmware/platformio.ini create mode 100644 firmware/src/config/Constants.h create mode 100644 firmware/src/config/Pins.h create mode 100644 firmware/src/hal/README.md create mode 100644 firmware/src/hal/SPI_HAL.cpp create mode 100644 firmware/src/main.cpp create mode 100644 firmware/src/motor/Homing.cpp create mode 100644 firmware/src/motor/Homing.h create mode 100644 firmware/src/motor/MotorAxis.cpp create mode 100644 firmware/src/motor/MotorAxis.h create mode 100644 firmware/src/motor/MotorConfig.h create mode 100644 firmware/src/motor/MotorDriver.cpp create mode 100644 firmware/src/motor/MotorDriver.h create mode 100644 firmware/src/serial/CommandParser.cpp create mode 100644 firmware/src/serial/CommandParser.h create mode 100644 firmware/src/thermal/ThermalManager.cpp create mode 100644 firmware/src/thermal/ThermalManager.h create mode 100755 firmware/test/README create mode 100755 host/CMakeLists.txt create mode 100755 host/Camera.cpp create mode 100755 host/Camera.h create mode 100755 host/FWT_host.cpp create mode 100755 host/JPEG_XL.h create mode 100755 host/Log.h create mode 100755 host/MQTT.cpp create mode 100755 host/MQTT.h create mode 100755 host/Parser.h create mode 100644 host/README.md create mode 100755 host/Serial.h create mode 100644 host/deploy.sh create mode 100755 host/timing.h diff --git a/README.md b/README.md index e69de29..95fc0ca 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,65 @@ +# FireWatchTower 2-Axis + +An automated fire surveillance system built around a LattePanda platform, combining real-time motor control firmware with a host application for camera capture, MQTT telemetry, and remote gimbal control. + +## Overview + +The system mounts a camera on a 2-axis gimbal (yaw + pitch) and continuously scans the surrounding area. When motion or stopping events are detected, the host triggers image capture and publishes telemetry data over MQTT for remote monitoring. + +### Architecture + +``` +┌─────────────────────────────────────────────┐ +│ LattePanda │ +│ │ +│ ┌──────────────────┐ ┌───────────────┐ │ +│ │ Host (Linux) │◄──►│ Arduino MCU │ │ +│ │ │ │ (Firmware) │ │ +│ │ - Camera (Vimba)│ │ - Motor ctrl │ │ +│ │ - MQTT client │ │ - Thermal mg │ │ +│ │ - Serial I/O │ │ - Cmd parser │ │ +│ └──────────────────┘ └───────────────┘ │ +│ │ +│ External: Camera │ TMC5160 Drivers │ Fan│ +└─────────────────────────────────────────────┘ +``` + +### Components + +| Component | Description | +|-----------|-------------| +| **firmware/** | Arduino sketch running on the LattePanda's onboard MCU. Handles TMC5160 stepper motor drivers, endstop homing, thermal management (DHT sensor + PWM fan), and serial command parsing. | +| **host/** | C++ application running on the Linux side. Manages camera acquisition via Vimba SDK, communicates with the firmware over serial, and publishes/subscribes to MQTT topics for remote control and status reporting. | + +## Hardware + +- **Main board:** LattePanda (Intel x86 + Arduino Leonardo ATmega32U4) +- **Motor drivers:** 2× TMC5160 (yaw and pitch axes) +- **Camera:** Area-scan camera via Vimba SDK (Allied Vision / FLIR) +- **Thermal:** DHT22 temperature/humidity sensor + PWM-controlled cooling fan +- **Endstops:** Hardware limit switches on both axes + +## Quick Start + +1. **Flash firmware:** `cd firmware && pio run --environment megaatmega2560 --target upload` +2. **Build host:** `cd host/build && cmake .. && make -j$(nproc)` +3. **Run host:** `./FireWatchTower_2axis --init true --start true` + +See the subdirectory README files for detailed documentation: +- [firmware/README.md](firmware/README.md) — MCU firmware architecture, commands, pinout +- [host/README.md](host/README.md) — Host application build, configuration, MQTT topics + +## MQTT Topics + +The system uses the following topic pattern (`` is the instance name, default `Dev`): + +| Topic | Direction | Description | +|-------|-----------|-------------| +| `GGS/FWT//StatusCode` | Publish | Current control mode (0=free scan, 1=guided) | +| `GGS/FWT//CamEvent/RGB` | Publish | Camera event notifications | +| `GGS/FWT//ControlCode` | Subscribe | Set control mode remotely | +| `GGS/FWT//target_HDG` | Subscribe | Set target heading for guided mode | + +## License + +[Add your license here] diff --git a/firmware/.gitignore b/firmware/.gitignore new file mode 100644 index 0000000..89cc49c --- /dev/null +++ b/firmware/.gitignore @@ -0,0 +1,5 @@ +.pio +.vscode/.browse.c_cpp.db* +.vscode/c_cpp_properties.json +.vscode/launch.json +.vscode/ipch diff --git a/firmware/.vscode/extensions.json b/firmware/.vscode/extensions.json new file mode 100644 index 0000000..080e70d --- /dev/null +++ b/firmware/.vscode/extensions.json @@ -0,0 +1,10 @@ +{ + // See http://go.microsoft.com/fwlink/?LinkId=827846 + // for the documentation about the extensions.json format + "recommendations": [ + "platformio.platformio-ide" + ], + "unwantedRecommendations": [ + "ms-vscode.cpptools-extension-pack" + ] +} diff --git a/firmware/README.md b/firmware/README.md new file mode 100644 index 0000000..f6b2fba --- /dev/null +++ b/firmware/README.md @@ -0,0 +1,136 @@ +# Firmware + +Arduino sketch for the LattePanda's onboard ATmega32U4 (Leonardo). Controls two stepper motor axes via TMC5160 drivers, manages thermal regulation, and communicates with the host over the serial link. + +## PlatformIO Configuration + +Target: `leonardo` (ATmega32U4) at 115200 baud. + +```bash +pio run --environment megaatmega2560 --target upload +``` + +### Dependencies + +| Library | Version | Purpose | +|---------|---------|---------| +| adafruit/DHT sensor library | ^1.4.4 | DHT22 temperature/humidity readings | +| adafruit/Adafruit Unified Sensor | ^1.1.4 | Unified sensor abstraction | +| TMC5160 (bundled) | — | Stepper motor driver via SPI | + +## Architecture + +``` +src/ +├── main.cpp # Entry point, main loop +├── config/ +│ ├── Constants.h # All tunable parameters +│ └── Pins.h # Pin assignments +├── motor/ +│ ├── MotorConfig.h # Axis IDs, status enum +│ ├── MotorDriver.* # TMC5160 initialization, power control +│ ├── MotorAxis.* # Per-axis state, register reads, SGT/encoder handling +│ └── Homing.* # Endstop homing routine +├── serial/ +│ └── CommandParser.* # Serial command dispatch +└── thermal/ + └── ThermalManager.* # DHT sensor + PWM fan control +``` + +## Pinout + +| Pin | Function | +|-----|----------| +| 0 | TMC5160 ENABLE (Pitch) | +| 1 | TMC5160 CS (Pitch) | +| 7 | TMC5160 ENABLE (Yaw) | +| 8 | TMC5160 CS (Yaw) | +| 9 | DHT22 DATA | +| 10 | Fan PWM | +| 11 | Fan sense | + +## Motor Configuration + +Both axes use TMC5160 stepper drivers with closed-loop control. + +| Parameter | Yaw | Pitch | +|-----------|-----|-------| +| Steps/round | 177,000 | 500,000 | +| Gear ratio | 739.556 | 739.556 | +| Global scaler | 80 | 50 | +| Default Vmax | 50,000 | 250,000 | +| Endstop speed | 25,000 | 150,000 | + +Key constants in [config/Constants.h](src/config/Constants.h): +- `ENC_DEVIATION_LIMIT` — Maximum allowed encoder-position deviation (1500 steps) +- `ACCELERATION` — Default acceleration profile (20,000) + +### Gimbal Status States + +```c +typedef enum { + GIMBAL_STATUS_ERROR = -2, + GIMBAL_STATUS_BOOT = -1, + GIMBAL_STATUS_RESET = 0, + GIMBAL_STATUS_ENC_INIT = 1, + GIMBAL_STATUS_INITIALIZED= 2, + GIMBAL_STATUS_AUTO = 3, + GIMBAL_STATUS_MANUAL = 4 +} gimbal_status; +``` + +## Serial Protocol + +Commands are received character-by-character. A leading command character is followed by optional comma-separated numeric arguments (hex by default; append `d` for decimal). + +### Command Reference + +| Command | Args | Description | +|---------|------|-------------| +| `r` | — | Reset motor params, power on both axes | +| `q` | — | Run endstop homing on yaw then pitch | +| `!` | — | Power off both motors | +| `*` | — | Power on both motors | +| `m` | pos, speed | Move yaw to position with given speed | +| `s` | — | Stop both motors | +| `b` | — | Reset encoder deviation warning flags | +| `t` | — | Set Xenc to Xact (sync encoder to actual position) | +| `e` | — | Reset SGT (step goal threshold) on both axes | +| `w` | value | Set SGT value | +| `u` | step_len | Set auto-scan step length (must be > 2) | +| `h` | axis, hdg | Set heading calibration, save to EEPROM | +| `y` | axis | Load heading calibration from EEPROM | +| `d` | — | Set yaw to manual mode | +| `p` | — | Step yaw to next position (used for scan trigger) | +| `v` | speed | Set yaw Vmax | +| `+` | — | Record right encoder position | +| `-` | — | Record left encoder position | +| `/` | right, left | Set right and left encoder positions | +| `?` | — | Print encoder range info | +| `;` | value | Write raw value to Yaw register 0x21 | + +### Telemetry Output + +Every `INFO_PRINT_INTERVAL_MS` (250 ms), both axes print status lines prefixed with `$`: +``` +$Xenc;Xerr;sgt_val;sgt_stat;is_moving;control_status;hdg;deviation_warn;humid;temp;fan_pwm +``` + +## Thermal Management + +DHT22 sensor on pin 9 drives a PWM fan on pin 10. + +| Parameter | Value | Description | +|-----------|-------|-------------| +| `THERMAL_FAN_ON_TEMP` | 25°C | Fan activation threshold | +| `THERMAL_FAN_GAIN` | 20 | PWM gain per degree above threshold | +| `THERMAL_FAN_MAX_PWM` | 255 | Maximum PWM duty cycle | +| `THERMAL_LOOP_INTERVAL` | 250 ms | Sensor read interval | + +Fan PWM = `min(255, (temp - 25) * 20)` + +## EEPROM Storage + +Heading calibration data is stored at EEPROM address 0: +- Offset 0: `float` — current heading (`c_hdg`) +- Offset 4: `int32_t` — encoder distance offset from heading reference diff --git a/firmware/compile_commands.json b/firmware/compile_commands.json new file mode 100644 index 0000000..aed0cb8 --- /dev/null +++ b/firmware/compile_commands.json @@ -0,0 +1,212 @@ +[ + { + "command": "/home/pedro/.platformio/packages/toolchain-atmelavr/bin/avr-g++ -o .pio/build/megaatmega2560/FrameworkArduino/CDC.cpp.o -c -fno-exceptions -fno-threadsafe-statics -fpermissive -std=gnu++11 -mmcu=atmega32u4 -Os -Wall -ffunction-sections -fdata-sections -flto -DPLATFORMIO=60119 -DARDUINO_AVR_LEONARDO -DF_CPU=16000000L -DARDUINO_ARCH_AVR -DARDUINO=10808 -DUSB_VID=0x2341 -DUSB_PID=0x8036 \"-DUSB_PRODUCT=\\\"Arduino Leonardo\\\"\" -DUSB_MANUFACTURER=\\\"Arduino\\\" -I/home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino -I/home/pedro/.platformio/packages/framework-arduino-avr/variants/leonardo /home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino/CDC.cpp", + "directory": "/home/pedro/code/FirwWatchTower_2axis/firmware", + "file": "/home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino/CDC.cpp", + "output": ".pio/build/megaatmega2560/FrameworkArduino/CDC.cpp.o" + }, + { + "command": "/home/pedro/.platformio/packages/toolchain-atmelavr/bin/avr-g++ -o .pio/build/megaatmega2560/FrameworkArduino/HardwareSerial.cpp.o -c -fno-exceptions -fno-threadsafe-statics -fpermissive -std=gnu++11 -mmcu=atmega32u4 -Os -Wall -ffunction-sections -fdata-sections -flto -DPLATFORMIO=60119 -DARDUINO_AVR_LEONARDO -DF_CPU=16000000L -DARDUINO_ARCH_AVR -DARDUINO=10808 -DUSB_VID=0x2341 -DUSB_PID=0x8036 \"-DUSB_PRODUCT=\\\"Arduino Leonardo\\\"\" -DUSB_MANUFACTURER=\\\"Arduino\\\" -I/home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino -I/home/pedro/.platformio/packages/framework-arduino-avr/variants/leonardo /home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino/HardwareSerial.cpp", + "directory": "/home/pedro/code/FirwWatchTower_2axis/firmware", + "file": "/home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino/HardwareSerial.cpp", + "output": ".pio/build/megaatmega2560/FrameworkArduino/HardwareSerial.cpp.o" + }, + { + "command": "/home/pedro/.platformio/packages/toolchain-atmelavr/bin/avr-g++ -o .pio/build/megaatmega2560/FrameworkArduino/HardwareSerial0.cpp.o -c -fno-exceptions -fno-threadsafe-statics -fpermissive -std=gnu++11 -mmcu=atmega32u4 -Os -Wall -ffunction-sections -fdata-sections -flto -DPLATFORMIO=60119 -DARDUINO_AVR_LEONARDO -DF_CPU=16000000L -DARDUINO_ARCH_AVR -DARDUINO=10808 -DUSB_VID=0x2341 -DUSB_PID=0x8036 \"-DUSB_PRODUCT=\\\"Arduino Leonardo\\\"\" -DUSB_MANUFACTURER=\\\"Arduino\\\" -I/home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino -I/home/pedro/.platformio/packages/framework-arduino-avr/variants/leonardo /home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino/HardwareSerial0.cpp", + "directory": "/home/pedro/code/FirwWatchTower_2axis/firmware", + "file": "/home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino/HardwareSerial0.cpp", + "output": ".pio/build/megaatmega2560/FrameworkArduino/HardwareSerial0.cpp.o" + }, + { + "command": "/home/pedro/.platformio/packages/toolchain-atmelavr/bin/avr-g++ -o .pio/build/megaatmega2560/FrameworkArduino/HardwareSerial1.cpp.o -c -fno-exceptions -fno-threadsafe-statics -fpermissive -std=gnu++11 -mmcu=atmega32u4 -Os -Wall -ffunction-sections -fdata-sections -flto -DPLATFORMIO=60119 -DARDUINO_AVR_LEONARDO -DF_CPU=16000000L -DARDUINO_ARCH_AVR -DARDUINO=10808 -DUSB_VID=0x2341 -DUSB_PID=0x8036 \"-DUSB_PRODUCT=\\\"Arduino Leonardo\\\"\" -DUSB_MANUFACTURER=\\\"Arduino\\\" -I/home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino -I/home/pedro/.platformio/packages/framework-arduino-avr/variants/leonardo /home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino/HardwareSerial1.cpp", + "directory": "/home/pedro/code/FirwWatchTower_2axis/firmware", + "file": "/home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino/HardwareSerial1.cpp", + "output": ".pio/build/megaatmega2560/FrameworkArduino/HardwareSerial1.cpp.o" + }, + { + "command": "/home/pedro/.platformio/packages/toolchain-atmelavr/bin/avr-g++ -o .pio/build/megaatmega2560/FrameworkArduino/HardwareSerial2.cpp.o -c -fno-exceptions -fno-threadsafe-statics -fpermissive -std=gnu++11 -mmcu=atmega32u4 -Os -Wall -ffunction-sections -fdata-sections -flto -DPLATFORMIO=60119 -DARDUINO_AVR_LEONARDO -DF_CPU=16000000L -DARDUINO_ARCH_AVR -DARDUINO=10808 -DUSB_VID=0x2341 -DUSB_PID=0x8036 \"-DUSB_PRODUCT=\\\"Arduino Leonardo\\\"\" -DUSB_MANUFACTURER=\\\"Arduino\\\" -I/home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino -I/home/pedro/.platformio/packages/framework-arduino-avr/variants/leonardo /home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino/HardwareSerial2.cpp", + "directory": "/home/pedro/code/FirwWatchTower_2axis/firmware", + "file": "/home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino/HardwareSerial2.cpp", + "output": ".pio/build/megaatmega2560/FrameworkArduino/HardwareSerial2.cpp.o" + }, + { + "command": "/home/pedro/.platformio/packages/toolchain-atmelavr/bin/avr-g++ -o .pio/build/megaatmega2560/FrameworkArduino/HardwareSerial3.cpp.o -c -fno-exceptions -fno-threadsafe-statics -fpermissive -std=gnu++11 -mmcu=atmega32u4 -Os -Wall -ffunction-sections -fdata-sections -flto -DPLATFORMIO=60119 -DARDUINO_AVR_LEONARDO -DF_CPU=16000000L -DARDUINO_ARCH_AVR -DARDUINO=10808 -DUSB_VID=0x2341 -DUSB_PID=0x8036 \"-DUSB_PRODUCT=\\\"Arduino Leonardo\\\"\" -DUSB_MANUFACTURER=\\\"Arduino\\\" -I/home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino -I/home/pedro/.platformio/packages/framework-arduino-avr/variants/leonardo /home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino/HardwareSerial3.cpp", + "directory": "/home/pedro/code/FirwWatchTower_2axis/firmware", + "file": "/home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino/HardwareSerial3.cpp", + "output": ".pio/build/megaatmega2560/FrameworkArduino/HardwareSerial3.cpp.o" + }, + { + "command": "/home/pedro/.platformio/packages/toolchain-atmelavr/bin/avr-g++ -o .pio/build/megaatmega2560/FrameworkArduino/IPAddress.cpp.o -c -fno-exceptions -fno-threadsafe-statics -fpermissive -std=gnu++11 -mmcu=atmega32u4 -Os -Wall -ffunction-sections -fdata-sections -flto -DPLATFORMIO=60119 -DARDUINO_AVR_LEONARDO -DF_CPU=16000000L -DARDUINO_ARCH_AVR -DARDUINO=10808 -DUSB_VID=0x2341 -DUSB_PID=0x8036 \"-DUSB_PRODUCT=\\\"Arduino Leonardo\\\"\" -DUSB_MANUFACTURER=\\\"Arduino\\\" -I/home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino -I/home/pedro/.platformio/packages/framework-arduino-avr/variants/leonardo /home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino/IPAddress.cpp", + "directory": "/home/pedro/code/FirwWatchTower_2axis/firmware", + "file": "/home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino/IPAddress.cpp", + "output": ".pio/build/megaatmega2560/FrameworkArduino/IPAddress.cpp.o" + }, + { + "command": "/home/pedro/.platformio/packages/toolchain-atmelavr/bin/avr-g++ -o .pio/build/megaatmega2560/FrameworkArduino/PluggableUSB.cpp.o -c -fno-exceptions -fno-threadsafe-statics -fpermissive -std=gnu++11 -mmcu=atmega32u4 -Os -Wall -ffunction-sections -fdata-sections -flto -DPLATFORMIO=60119 -DARDUINO_AVR_LEONARDO -DF_CPU=16000000L -DARDUINO_ARCH_AVR -DARDUINO=10808 -DUSB_VID=0x2341 -DUSB_PID=0x8036 \"-DUSB_PRODUCT=\\\"Arduino Leonardo\\\"\" -DUSB_MANUFACTURER=\\\"Arduino\\\" -I/home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino -I/home/pedro/.platformio/packages/framework-arduino-avr/variants/leonardo /home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino/PluggableUSB.cpp", + "directory": "/home/pedro/code/FirwWatchTower_2axis/firmware", + "file": "/home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino/PluggableUSB.cpp", + "output": ".pio/build/megaatmega2560/FrameworkArduino/PluggableUSB.cpp.o" + }, + { + "command": "/home/pedro/.platformio/packages/toolchain-atmelavr/bin/avr-g++ -o .pio/build/megaatmega2560/FrameworkArduino/Print.cpp.o -c -fno-exceptions -fno-threadsafe-statics -fpermissive -std=gnu++11 -mmcu=atmega32u4 -Os -Wall -ffunction-sections -fdata-sections -flto -DPLATFORMIO=60119 -DARDUINO_AVR_LEONARDO -DF_CPU=16000000L -DARDUINO_ARCH_AVR -DARDUINO=10808 -DUSB_VID=0x2341 -DUSB_PID=0x8036 \"-DUSB_PRODUCT=\\\"Arduino Leonardo\\\"\" -DUSB_MANUFACTURER=\\\"Arduino\\\" -I/home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino -I/home/pedro/.platformio/packages/framework-arduino-avr/variants/leonardo /home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino/Print.cpp", + "directory": "/home/pedro/code/FirwWatchTower_2axis/firmware", + "file": "/home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino/Print.cpp", + "output": ".pio/build/megaatmega2560/FrameworkArduino/Print.cpp.o" + }, + { + "command": "/home/pedro/.platformio/packages/toolchain-atmelavr/bin/avr-g++ -o .pio/build/megaatmega2560/FrameworkArduino/Stream.cpp.o -c -fno-exceptions -fno-threadsafe-statics -fpermissive -std=gnu++11 -mmcu=atmega32u4 -Os -Wall -ffunction-sections -fdata-sections -flto -DPLATFORMIO=60119 -DARDUINO_AVR_LEONARDO -DF_CPU=16000000L -DARDUINO_ARCH_AVR -DARDUINO=10808 -DUSB_VID=0x2341 -DUSB_PID=0x8036 \"-DUSB_PRODUCT=\\\"Arduino Leonardo\\\"\" -DUSB_MANUFACTURER=\\\"Arduino\\\" -I/home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino -I/home/pedro/.platformio/packages/framework-arduino-avr/variants/leonardo /home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino/Stream.cpp", + "directory": "/home/pedro/code/FirwWatchTower_2axis/firmware", + "file": "/home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino/Stream.cpp", + "output": ".pio/build/megaatmega2560/FrameworkArduino/Stream.cpp.o" + }, + { + "command": "/home/pedro/.platformio/packages/toolchain-atmelavr/bin/avr-g++ -o .pio/build/megaatmega2560/FrameworkArduino/Tone.cpp.o -c -fno-exceptions -fno-threadsafe-statics -fpermissive -std=gnu++11 -mmcu=atmega32u4 -Os -Wall -ffunction-sections -fdata-sections -flto -DPLATFORMIO=60119 -DARDUINO_AVR_LEONARDO -DF_CPU=16000000L -DARDUINO_ARCH_AVR -DARDUINO=10808 -DUSB_VID=0x2341 -DUSB_PID=0x8036 \"-DUSB_PRODUCT=\\\"Arduino Leonardo\\\"\" -DUSB_MANUFACTURER=\\\"Arduino\\\" -I/home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino -I/home/pedro/.platformio/packages/framework-arduino-avr/variants/leonardo /home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino/Tone.cpp", + "directory": "/home/pedro/code/FirwWatchTower_2axis/firmware", + "file": "/home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino/Tone.cpp", + "output": ".pio/build/megaatmega2560/FrameworkArduino/Tone.cpp.o" + }, + { + "command": "/home/pedro/.platformio/packages/toolchain-atmelavr/bin/avr-g++ -o .pio/build/megaatmega2560/FrameworkArduino/USBCore.cpp.o -c -fno-exceptions -fno-threadsafe-statics -fpermissive -std=gnu++11 -mmcu=atmega32u4 -Os -Wall -ffunction-sections -fdata-sections -flto -DPLATFORMIO=60119 -DARDUINO_AVR_LEONARDO -DF_CPU=16000000L -DARDUINO_ARCH_AVR -DARDUINO=10808 -DUSB_VID=0x2341 -DUSB_PID=0x8036 \"-DUSB_PRODUCT=\\\"Arduino Leonardo\\\"\" -DUSB_MANUFACTURER=\\\"Arduino\\\" -I/home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino -I/home/pedro/.platformio/packages/framework-arduino-avr/variants/leonardo /home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino/USBCore.cpp", + "directory": "/home/pedro/code/FirwWatchTower_2axis/firmware", + "file": "/home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino/USBCore.cpp", + "output": ".pio/build/megaatmega2560/FrameworkArduino/USBCore.cpp.o" + }, + { + "command": "/home/pedro/.platformio/packages/toolchain-atmelavr/bin/avr-gcc -o .pio/build/megaatmega2560/FrameworkArduino/WInterrupts.c.o -c -std=gnu11 -fno-fat-lto-objects -mmcu=atmega32u4 -Os -Wall -ffunction-sections -fdata-sections -flto -DPLATFORMIO=60119 -DARDUINO_AVR_LEONARDO -DF_CPU=16000000L -DARDUINO_ARCH_AVR -DARDUINO=10808 -DUSB_VID=0x2341 -DUSB_PID=0x8036 \"-DUSB_PRODUCT=\\\"Arduino Leonardo\\\"\" -DUSB_MANUFACTURER=\\\"Arduino\\\" -I/home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino -I/home/pedro/.platformio/packages/framework-arduino-avr/variants/leonardo /home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino/WInterrupts.c", + "directory": "/home/pedro/code/FirwWatchTower_2axis/firmware", + "file": "/home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino/WInterrupts.c", + "output": ".pio/build/megaatmega2560/FrameworkArduino/WInterrupts.c.o" + }, + { + "command": "/home/pedro/.platformio/packages/toolchain-atmelavr/bin/avr-g++ -o .pio/build/megaatmega2560/FrameworkArduino/WMath.cpp.o -c -fno-exceptions -fno-threadsafe-statics -fpermissive -std=gnu++11 -mmcu=atmega32u4 -Os -Wall -ffunction-sections -fdata-sections -flto -DPLATFORMIO=60119 -DARDUINO_AVR_LEONARDO -DF_CPU=16000000L -DARDUINO_ARCH_AVR -DARDUINO=10808 -DUSB_VID=0x2341 -DUSB_PID=0x8036 \"-DUSB_PRODUCT=\\\"Arduino Leonardo\\\"\" -DUSB_MANUFACTURER=\\\"Arduino\\\" -I/home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino -I/home/pedro/.platformio/packages/framework-arduino-avr/variants/leonardo /home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino/WMath.cpp", + "directory": "/home/pedro/code/FirwWatchTower_2axis/firmware", + "file": "/home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino/WMath.cpp", + "output": ".pio/build/megaatmega2560/FrameworkArduino/WMath.cpp.o" + }, + { + "command": "/home/pedro/.platformio/packages/toolchain-atmelavr/bin/avr-g++ -o .pio/build/megaatmega2560/FrameworkArduino/WString.cpp.o -c -fno-exceptions -fno-threadsafe-statics -fpermissive -std=gnu++11 -mmcu=atmega32u4 -Os -Wall -ffunction-sections -fdata-sections -flto -DPLATFORMIO=60119 -DARDUINO_AVR_LEONARDO -DF_CPU=16000000L -DARDUINO_ARCH_AVR -DARDUINO=10808 -DUSB_VID=0x2341 -DUSB_PID=0x8036 \"-DUSB_PRODUCT=\\\"Arduino Leonardo\\\"\" -DUSB_MANUFACTURER=\\\"Arduino\\\" -I/home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino -I/home/pedro/.platformio/packages/framework-arduino-avr/variants/leonardo /home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino/WString.cpp", + "directory": "/home/pedro/code/FirwWatchTower_2axis/firmware", + "file": "/home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino/WString.cpp", + "output": ".pio/build/megaatmega2560/FrameworkArduino/WString.cpp.o" + }, + { + "command": "/home/pedro/.platformio/packages/toolchain-atmelavr/bin/avr-g++ -o .pio/build/megaatmega2560/FrameworkArduino/abi.cpp.o -c -fno-exceptions -fno-threadsafe-statics -fpermissive -std=gnu++11 -mmcu=atmega32u4 -Os -Wall -ffunction-sections -fdata-sections -flto -DPLATFORMIO=60119 -DARDUINO_AVR_LEONARDO -DF_CPU=16000000L -DARDUINO_ARCH_AVR -DARDUINO=10808 -DUSB_VID=0x2341 -DUSB_PID=0x8036 \"-DUSB_PRODUCT=\\\"Arduino Leonardo\\\"\" -DUSB_MANUFACTURER=\\\"Arduino\\\" -I/home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino -I/home/pedro/.platformio/packages/framework-arduino-avr/variants/leonardo /home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino/abi.cpp", + "directory": "/home/pedro/code/FirwWatchTower_2axis/firmware", + "file": "/home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino/abi.cpp", + "output": ".pio/build/megaatmega2560/FrameworkArduino/abi.cpp.o" + }, + { + "command": "/home/pedro/.platformio/packages/toolchain-atmelavr/bin/avr-gcc -o .pio/build/megaatmega2560/FrameworkArduino/hooks.c.o -c -std=gnu11 -fno-fat-lto-objects -mmcu=atmega32u4 -Os -Wall -ffunction-sections -fdata-sections -flto -DPLATFORMIO=60119 -DARDUINO_AVR_LEONARDO -DF_CPU=16000000L -DARDUINO_ARCH_AVR -DARDUINO=10808 -DUSB_VID=0x2341 -DUSB_PID=0x8036 \"-DUSB_PRODUCT=\\\"Arduino Leonardo\\\"\" -DUSB_MANUFACTURER=\\\"Arduino\\\" -I/home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino -I/home/pedro/.platformio/packages/framework-arduino-avr/variants/leonardo /home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino/hooks.c", + "directory": "/home/pedro/code/FirwWatchTower_2axis/firmware", + "file": "/home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino/hooks.c", + "output": ".pio/build/megaatmega2560/FrameworkArduino/hooks.c.o" + }, + { + "command": "/home/pedro/.platformio/packages/toolchain-atmelavr/bin/avr-g++ -o .pio/build/megaatmega2560/FrameworkArduino/main.cpp.o -c -fno-exceptions -fno-threadsafe-statics -fpermissive -std=gnu++11 -mmcu=atmega32u4 -Os -Wall -ffunction-sections -fdata-sections -flto -DPLATFORMIO=60119 -DARDUINO_AVR_LEONARDO -DF_CPU=16000000L -DARDUINO_ARCH_AVR -DARDUINO=10808 -DUSB_VID=0x2341 -DUSB_PID=0x8036 \"-DUSB_PRODUCT=\\\"Arduino Leonardo\\\"\" -DUSB_MANUFACTURER=\\\"Arduino\\\" -I/home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino -I/home/pedro/.platformio/packages/framework-arduino-avr/variants/leonardo /home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino/main.cpp", + "directory": "/home/pedro/code/FirwWatchTower_2axis/firmware", + "file": "/home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino/main.cpp", + "output": ".pio/build/megaatmega2560/FrameworkArduino/main.cpp.o" + }, + { + "command": "/home/pedro/.platformio/packages/toolchain-atmelavr/bin/avr-g++ -o .pio/build/megaatmega2560/FrameworkArduino/new.cpp.o -c -fno-exceptions -fno-threadsafe-statics -fpermissive -std=gnu++11 -mmcu=atmega32u4 -Os -Wall -ffunction-sections -fdata-sections -flto -DPLATFORMIO=60119 -DARDUINO_AVR_LEONARDO -DF_CPU=16000000L -DARDUINO_ARCH_AVR -DARDUINO=10808 -DUSB_VID=0x2341 -DUSB_PID=0x8036 \"-DUSB_PRODUCT=\\\"Arduino Leonardo\\\"\" -DUSB_MANUFACTURER=\\\"Arduino\\\" -I/home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino -I/home/pedro/.platformio/packages/framework-arduino-avr/variants/leonardo /home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino/new.cpp", + "directory": "/home/pedro/code/FirwWatchTower_2axis/firmware", + "file": "/home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino/new.cpp", + "output": ".pio/build/megaatmega2560/FrameworkArduino/new.cpp.o" + }, + { + "command": "/home/pedro/.platformio/packages/toolchain-atmelavr/bin/avr-gcc -o .pio/build/megaatmega2560/FrameworkArduino/wiring.c.o -c -std=gnu11 -fno-fat-lto-objects -mmcu=atmega32u4 -Os -Wall -ffunction-sections -fdata-sections -flto -DPLATFORMIO=60119 -DARDUINO_AVR_LEONARDO -DF_CPU=16000000L -DARDUINO_ARCH_AVR -DARDUINO=10808 -DUSB_VID=0x2341 -DUSB_PID=0x8036 \"-DUSB_PRODUCT=\\\"Arduino Leonardo\\\"\" -DUSB_MANUFACTURER=\\\"Arduino\\\" -I/home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino -I/home/pedro/.platformio/packages/framework-arduino-avr/variants/leonardo /home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino/wiring.c", + "directory": "/home/pedro/code/FirwWatchTower_2axis/firmware", + "file": "/home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino/wiring.c", + "output": ".pio/build/megaatmega2560/FrameworkArduino/wiring.c.o" + }, + { + "command": "/home/pedro/.platformio/packages/toolchain-atmelavr/bin/avr-gcc -o .pio/build/megaatmega2560/FrameworkArduino/wiring_analog.c.o -c -std=gnu11 -fno-fat-lto-objects -mmcu=atmega32u4 -Os -Wall -ffunction-sections -fdata-sections -flto -DPLATFORMIO=60119 -DARDUINO_AVR_LEONARDO -DF_CPU=16000000L -DARDUINO_ARCH_AVR -DARDUINO=10808 -DUSB_VID=0x2341 -DUSB_PID=0x8036 \"-DUSB_PRODUCT=\\\"Arduino Leonardo\\\"\" -DUSB_MANUFACTURER=\\\"Arduino\\\" -I/home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino -I/home/pedro/.platformio/packages/framework-arduino-avr/variants/leonardo /home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino/wiring_analog.c", + "directory": "/home/pedro/code/FirwWatchTower_2axis/firmware", + "file": "/home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino/wiring_analog.c", + "output": ".pio/build/megaatmega2560/FrameworkArduino/wiring_analog.c.o" + }, + { + "command": "/home/pedro/.platformio/packages/toolchain-atmelavr/bin/avr-gcc -o .pio/build/megaatmega2560/FrameworkArduino/wiring_digital.c.o -c -std=gnu11 -fno-fat-lto-objects -mmcu=atmega32u4 -Os -Wall -ffunction-sections -fdata-sections -flto -DPLATFORMIO=60119 -DARDUINO_AVR_LEONARDO -DF_CPU=16000000L -DARDUINO_ARCH_AVR -DARDUINO=10808 -DUSB_VID=0x2341 -DUSB_PID=0x8036 \"-DUSB_PRODUCT=\\\"Arduino Leonardo\\\"\" -DUSB_MANUFACTURER=\\\"Arduino\\\" -I/home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino -I/home/pedro/.platformio/packages/framework-arduino-avr/variants/leonardo /home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino/wiring_digital.c", + "directory": "/home/pedro/code/FirwWatchTower_2axis/firmware", + "file": "/home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino/wiring_digital.c", + "output": ".pio/build/megaatmega2560/FrameworkArduino/wiring_digital.c.o" + }, + { + "command": "/home/pedro/.platformio/packages/toolchain-atmelavr/bin/avr-gcc -mmcu=atmega32u4 -x assembler-with-cpp -DPLATFORMIO=60119 -DARDUINO_AVR_LEONARDO -DF_CPU=16000000L -DARDUINO_ARCH_AVR -DARDUINO=10808 -DUSB_VID=0x2341 -DUSB_PID=0x8036 \"-DUSB_PRODUCT=\\\"Arduino Leonardo\\\"\" -DUSB_MANUFACTURER=\\\"Arduino\\\" -I/home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino -I/home/pedro/.platformio/packages/framework-arduino-avr/variants/leonardo -c -o .pio/build/megaatmega2560/FrameworkArduino/wiring_pulse.S.o /home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino/wiring_pulse.S", + "directory": "/home/pedro/code/FirwWatchTower_2axis/firmware", + "file": "/home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino/wiring_pulse.S", + "output": ".pio/build/megaatmega2560/FrameworkArduino/wiring_pulse.S.o" + }, + { + "command": "/home/pedro/.platformio/packages/toolchain-atmelavr/bin/avr-gcc -o .pio/build/megaatmega2560/FrameworkArduino/wiring_pulse.c.o -c -std=gnu11 -fno-fat-lto-objects -mmcu=atmega32u4 -Os -Wall -ffunction-sections -fdata-sections -flto -DPLATFORMIO=60119 -DARDUINO_AVR_LEONARDO -DF_CPU=16000000L -DARDUINO_ARCH_AVR -DARDUINO=10808 -DUSB_VID=0x2341 -DUSB_PID=0x8036 \"-DUSB_PRODUCT=\\\"Arduino Leonardo\\\"\" -DUSB_MANUFACTURER=\\\"Arduino\\\" -I/home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino -I/home/pedro/.platformio/packages/framework-arduino-avr/variants/leonardo /home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino/wiring_pulse.c", + "directory": "/home/pedro/code/FirwWatchTower_2axis/firmware", + "file": "/home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino/wiring_pulse.c", + "output": ".pio/build/megaatmega2560/FrameworkArduino/wiring_pulse.c.o" + }, + { + "command": "/home/pedro/.platformio/packages/toolchain-atmelavr/bin/avr-gcc -o .pio/build/megaatmega2560/FrameworkArduino/wiring_shift.c.o -c -std=gnu11 -fno-fat-lto-objects -mmcu=atmega32u4 -Os -Wall -ffunction-sections -fdata-sections -flto -DPLATFORMIO=60119 -DARDUINO_AVR_LEONARDO -DF_CPU=16000000L -DARDUINO_ARCH_AVR -DARDUINO=10808 -DUSB_VID=0x2341 -DUSB_PID=0x8036 \"-DUSB_PRODUCT=\\\"Arduino Leonardo\\\"\" -DUSB_MANUFACTURER=\\\"Arduino\\\" -I/home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino -I/home/pedro/.platformio/packages/framework-arduino-avr/variants/leonardo /home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino/wiring_shift.c", + "directory": "/home/pedro/code/FirwWatchTower_2axis/firmware", + "file": "/home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino/wiring_shift.c", + "output": ".pio/build/megaatmega2560/FrameworkArduino/wiring_shift.c.o" + }, + { + "command": "/home/pedro/.platformio/packages/toolchain-atmelavr/bin/avr-g++ -o .pio/build/megaatmega2560/lib1f8/Adafruit_Sensor/Adafruit_Sensor.cpp.o -c -fno-exceptions -fno-threadsafe-statics -fpermissive -std=gnu++11 -mmcu=atmega32u4 -Os -Wall -ffunction-sections -fdata-sections -flto -DPLATFORMIO=60119 -DARDUINO_AVR_LEONARDO -DF_CPU=16000000L -DARDUINO_ARCH_AVR -DARDUINO=10808 -DUSB_VID=0x2341 -DUSB_PID=0x8036 \"-DUSB_PRODUCT=\\\"Arduino Leonardo\\\"\" -DUSB_MANUFACTURER=\\\"Arduino\\\" -Ilib/Adafruit_Sensor -I/home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino -I/home/pedro/.platformio/packages/framework-arduino-avr/variants/leonardo lib/Adafruit_Sensor/Adafruit_Sensor.cpp", + "directory": "/home/pedro/code/FirwWatchTower_2axis/firmware", + "file": "lib/Adafruit_Sensor/Adafruit_Sensor.cpp", + "output": ".pio/build/megaatmega2560/lib1f8/Adafruit_Sensor/Adafruit_Sensor.cpp.o" + }, + { + "command": "/home/pedro/.platformio/packages/toolchain-atmelavr/bin/avr-g++ -o .pio/build/megaatmega2560/libee6/DHT-sensor-library/DHT.cpp.o -c -fno-exceptions -fno-threadsafe-statics -fpermissive -std=gnu++11 -mmcu=atmega32u4 -Os -Wall -ffunction-sections -fdata-sections -flto -DPLATFORMIO=60119 -DARDUINO_AVR_LEONARDO -DF_CPU=16000000L -DARDUINO_ARCH_AVR -DARDUINO=10808 -DUSB_VID=0x2341 -DUSB_PID=0x8036 \"-DUSB_PRODUCT=\\\"Arduino Leonardo\\\"\" -DUSB_MANUFACTURER=\\\"Arduino\\\" -Ilib/DHT-sensor-library -Ilib/Adafruit_Sensor -I/home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino -I/home/pedro/.platformio/packages/framework-arduino-avr/variants/leonardo lib/DHT-sensor-library/DHT.cpp", + "directory": "/home/pedro/code/FirwWatchTower_2axis/firmware", + "file": "lib/DHT-sensor-library/DHT.cpp", + "output": ".pio/build/megaatmega2560/libee6/DHT-sensor-library/DHT.cpp.o" + }, + { + "command": "/home/pedro/.platformio/packages/toolchain-atmelavr/bin/avr-g++ -o .pio/build/megaatmega2560/libee6/DHT-sensor-library/DHT_U.cpp.o -c -fno-exceptions -fno-threadsafe-statics -fpermissive -std=gnu++11 -mmcu=atmega32u4 -Os -Wall -ffunction-sections -fdata-sections -flto -DPLATFORMIO=60119 -DARDUINO_AVR_LEONARDO -DF_CPU=16000000L -DARDUINO_ARCH_AVR -DARDUINO=10808 -DUSB_VID=0x2341 -DUSB_PID=0x8036 \"-DUSB_PRODUCT=\\\"Arduino Leonardo\\\"\" -DUSB_MANUFACTURER=\\\"Arduino\\\" -Ilib/DHT-sensor-library -Ilib/Adafruit_Sensor -I/home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino -I/home/pedro/.platformio/packages/framework-arduino-avr/variants/leonardo lib/DHT-sensor-library/DHT_U.cpp", + "directory": "/home/pedro/code/FirwWatchTower_2axis/firmware", + "file": "lib/DHT-sensor-library/DHT_U.cpp", + "output": ".pio/build/megaatmega2560/libee6/DHT-sensor-library/DHT_U.cpp.o" + }, + { + "command": "/home/pedro/.platformio/packages/toolchain-atmelavr/bin/avr-g++ -o .pio/build/megaatmega2560/lib08b/SPI/SPI.cpp.o -c -fno-exceptions -fno-threadsafe-statics -fpermissive -std=gnu++11 -mmcu=atmega32u4 -Os -Wall -ffunction-sections -fdata-sections -flto -DPLATFORMIO=60119 -DARDUINO_AVR_LEONARDO -DF_CPU=16000000L -DARDUINO_ARCH_AVR -DARDUINO=10808 -DUSB_VID=0x2341 -DUSB_PID=0x8036 \"-DUSB_PRODUCT=\\\"Arduino Leonardo\\\"\" -DUSB_MANUFACTURER=\\\"Arduino\\\" -I/home/pedro/.platformio/packages/framework-arduino-avr/libraries/SPI/src -I/home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino -I/home/pedro/.platformio/packages/framework-arduino-avr/variants/leonardo /home/pedro/.platformio/packages/framework-arduino-avr/libraries/SPI/src/SPI.cpp", + "directory": "/home/pedro/code/FirwWatchTower_2axis/firmware", + "file": "/home/pedro/.platformio/packages/framework-arduino-avr/libraries/SPI/src/SPI.cpp", + "output": ".pio/build/megaatmega2560/lib08b/SPI/SPI.cpp.o" + }, + { + "command": "/home/pedro/.platformio/packages/toolchain-atmelavr/bin/avr-gcc -o .pio/build/megaatmega2560/libb53/tmc/CRC.c.o -c -std=gnu11 -fno-fat-lto-objects -mmcu=atmega32u4 -Os -Wall -ffunction-sections -fdata-sections -flto -DPLATFORMIO=60119 -DARDUINO_AVR_LEONARDO -DF_CPU=16000000L -DARDUINO_ARCH_AVR -DARDUINO=10808 -DUSB_VID=0x2341 -DUSB_PID=0x8036 \"-DUSB_PRODUCT=\\\"Arduino Leonardo\\\"\" -DUSB_MANUFACTURER=\\\"Arduino\\\" -Ilib/tmc/src -I/home/pedro/.platformio/packages/framework-arduino-avr/libraries/EEPROM/src -I/home/pedro/.platformio/packages/framework-arduino-avr/libraries/SPI/src -I/home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino -I/home/pedro/.platformio/packages/framework-arduino-avr/variants/leonardo lib/tmc/src/CRC.c", + "directory": "/home/pedro/code/FirwWatchTower_2axis/firmware", + "file": "lib/tmc/src/CRC.c", + "output": ".pio/build/megaatmega2560/libb53/tmc/CRC.c.o" + }, + { + "command": "/home/pedro/.platformio/packages/toolchain-atmelavr/bin/avr-gcc -o .pio/build/megaatmega2560/libb53/tmc/Functions.c.o -c -std=gnu11 -fno-fat-lto-objects -mmcu=atmega32u4 -Os -Wall -ffunction-sections -fdata-sections -flto -DPLATFORMIO=60119 -DARDUINO_AVR_LEONARDO -DF_CPU=16000000L -DARDUINO_ARCH_AVR -DARDUINO=10808 -DUSB_VID=0x2341 -DUSB_PID=0x8036 \"-DUSB_PRODUCT=\\\"Arduino Leonardo\\\"\" -DUSB_MANUFACTURER=\\\"Arduino\\\" -Ilib/tmc/src -I/home/pedro/.platformio/packages/framework-arduino-avr/libraries/EEPROM/src -I/home/pedro/.platformio/packages/framework-arduino-avr/libraries/SPI/src -I/home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino -I/home/pedro/.platformio/packages/framework-arduino-avr/variants/leonardo lib/tmc/src/Functions.c", + "directory": "/home/pedro/code/FirwWatchTower_2axis/firmware", + "file": "lib/tmc/src/Functions.c", + "output": ".pio/build/megaatmega2560/libb53/tmc/Functions.c.o" + }, + { + "command": "/home/pedro/.platformio/packages/toolchain-atmelavr/bin/avr-gcc -o .pio/build/megaatmega2560/libb53/tmc/TMC5160.c.o -c -std=gnu11 -fno-fat-lto-objects -mmcu=atmega32u4 -Os -Wall -ffunction-sections -fdata-sections -flto -DPLATFORMIO=60119 -DARDUINO_AVR_LEONARDO -DF_CPU=16000000L -DARDUINO_ARCH_AVR -DARDUINO=10808 -DUSB_VID=0x2341 -DUSB_PID=0x8036 \"-DUSB_PRODUCT=\\\"Arduino Leonardo\\\"\" -DUSB_MANUFACTURER=\\\"Arduino\\\" -Ilib/tmc/src -I/home/pedro/.platformio/packages/framework-arduino-avr/libraries/EEPROM/src -I/home/pedro/.platformio/packages/framework-arduino-avr/libraries/SPI/src -I/home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino -I/home/pedro/.platformio/packages/framework-arduino-avr/variants/leonardo lib/tmc/src/TMC5160.c", + "directory": "/home/pedro/code/FirwWatchTower_2axis/firmware", + "file": "lib/tmc/src/TMC5160.c", + "output": ".pio/build/megaatmega2560/libb53/tmc/TMC5160.c.o" + }, + { + "command": "/home/pedro/.platformio/packages/toolchain-atmelavr/bin/avr-g++ -o .pio/build/megaatmega2560/libb53/tmc/gimbal.cpp.o -c -fno-exceptions -fno-threadsafe-statics -fpermissive -std=gnu++11 -mmcu=atmega32u4 -Os -Wall -ffunction-sections -fdata-sections -flto -DPLATFORMIO=60119 -DARDUINO_AVR_LEONARDO -DF_CPU=16000000L -DARDUINO_ARCH_AVR -DARDUINO=10808 -DUSB_VID=0x2341 -DUSB_PID=0x8036 \"-DUSB_PRODUCT=\\\"Arduino Leonardo\\\"\" -DUSB_MANUFACTURER=\\\"Arduino\\\" -Ilib/tmc/src -I/home/pedro/.platformio/packages/framework-arduino-avr/libraries/EEPROM/src -I/home/pedro/.platformio/packages/framework-arduino-avr/libraries/SPI/src -I/home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino -I/home/pedro/.platformio/packages/framework-arduino-avr/variants/leonardo lib/tmc/src/gimbal.cpp", + "directory": "/home/pedro/code/FirwWatchTower_2axis/firmware", + "file": "lib/tmc/src/gimbal.cpp", + "output": ".pio/build/megaatmega2560/libb53/tmc/gimbal.cpp.o" + }, + { + "command": "/home/pedro/.platformio/packages/toolchain-atmelavr/bin/avr-g++ -o .pio/build/megaatmega2560/libb53/tmc/logger.cpp.o -c -fno-exceptions -fno-threadsafe-statics -fpermissive -std=gnu++11 -mmcu=atmega32u4 -Os -Wall -ffunction-sections -fdata-sections -flto -DPLATFORMIO=60119 -DARDUINO_AVR_LEONARDO -DF_CPU=16000000L -DARDUINO_ARCH_AVR -DARDUINO=10808 -DUSB_VID=0x2341 -DUSB_PID=0x8036 \"-DUSB_PRODUCT=\\\"Arduino Leonardo\\\"\" -DUSB_MANUFACTURER=\\\"Arduino\\\" -Ilib/tmc/src -I/home/pedro/.platformio/packages/framework-arduino-avr/libraries/EEPROM/src -I/home/pedro/.platformio/packages/framework-arduino-avr/libraries/SPI/src -I/home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino -I/home/pedro/.platformio/packages/framework-arduino-avr/variants/leonardo lib/tmc/src/logger.cpp", + "directory": "/home/pedro/code/FirwWatchTower_2axis/firmware", + "file": "lib/tmc/src/logger.cpp", + "output": ".pio/build/megaatmega2560/libb53/tmc/logger.cpp.o" + }, + { + "command": "/home/pedro/.platformio/packages/toolchain-atmelavr/bin/avr-g++ -o .pio/build/megaatmega2560/src/FWT_firmware.cpp.o -c -fno-exceptions -fno-threadsafe-statics -fpermissive -std=gnu++11 -mmcu=atmega32u4 -Os -Wall -ffunction-sections -fdata-sections -flto -DPLATFORMIO=60119 -DARDUINO_AVR_LEONARDO -DF_CPU=16000000L -DARDUINO_ARCH_AVR -DARDUINO=10808 -DUSB_VID=0x2341 -DUSB_PID=0x8036 \"-DUSB_PRODUCT=\\\"Arduino Leonardo\\\"\" -DUSB_MANUFACTURER=\\\"Arduino\\\" -Iinclude -Isrc -Ilib/tmc/src -I/home/pedro/.platformio/packages/framework-arduino-avr/libraries/EEPROM/src -I/home/pedro/.platformio/packages/framework-arduino-avr/libraries/SPI/src -Ilib/DHT-sensor-library -Ilib/Adafruit_Sensor -I/home/pedro/.platformio/packages/framework-arduino-avr/cores/arduino -I/home/pedro/.platformio/packages/framework-arduino-avr/variants/leonardo src/FWT_firmware.cpp", + "directory": "/home/pedro/code/FirwWatchTower_2axis/firmware", + "file": "src/FWT_firmware.cpp", + "output": ".pio/build/megaatmega2560/src/FWT_firmware.cpp.o" + } +] diff --git a/firmware/include/README b/firmware/include/README new file mode 100755 index 0000000..630164d --- /dev/null +++ b/firmware/include/README @@ -0,0 +1,37 @@ + +This directory is intended for project header files. + +A header file is a file containing C declarations and macro definitions +to be shared between several project source files. You request the use of a +header file in your project source file (C, C++, etc) located in `src` folder +by including it, with the C preprocessing directive `#include'. + +```src/main.c + +#include "header.h" + +int main (void) +{ + ... +} +``` + +Including a header file produces the same results as copying the header file +into each source file that needs it. Such copying would be time-consuming +and error-prone. With a header file, the related declarations appear +in only one place. If they need to be changed, they can be changed in one +place, and programs that include the header file will automatically use the +new version when next recompiled. The header file eliminates the labor of +finding and changing all the copies as well as the risk that a failure to +find one copy will result in inconsistencies within a program. + +In C, the convention is to give header files names that end with `.h'. + +Read more about using header files in official GCC documentation: + +* Include Syntax +* Include Operation +* Once-Only Headers +* Computed Includes + +https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/firmware/lib/Adafruit_Sensor b/firmware/lib/Adafruit_Sensor new file mode 160000 index 0000000..0a9127a --- /dev/null +++ b/firmware/lib/Adafruit_Sensor @@ -0,0 +1 @@ +Subproject commit 0a9127a1e886ff1adb4c1b6f5958b24108d55aa6 diff --git a/firmware/lib/DHT-sensor-library b/firmware/lib/DHT-sensor-library new file mode 160000 index 0000000..2295fe4 --- /dev/null +++ b/firmware/lib/DHT-sensor-library @@ -0,0 +1 @@ +Subproject commit 2295fe471c38d5e649a7b68cecccc42193c8e41c diff --git a/firmware/lib/README b/firmware/lib/README new file mode 100755 index 0000000..8d3ee2a --- /dev/null +++ b/firmware/lib/README @@ -0,0 +1,46 @@ + +This directory is intended for project specific (private) libraries. +PlatformIO will compile them to static libraries and link into the executable file. + +The source code of each library should be placed in a separate directory +("lib/your_library_name/[Code]"). + +For example, see the structure of the following example libraries `Foo` and `Bar`: + +|--lib +| | +| |--Bar +| | |--docs +| | |--examples +| | |--src +| | |- Bar.c +| | |- Bar.h +| | |- library.json (optional. for custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html +| | +| |--Foo +| | |- Foo.c +| | |- Foo.h +| | +| |- README --> THIS FILE +| +|- platformio.ini +|--src + |- main.c + +Example contents of `src/main.c` using Foo and Bar: +``` +#include +#include + +int main (void) +{ + ... +} + +``` + +The PlatformIO Library Dependency Finder will find automatically dependent +libraries by scanning project source files. + +More information about PlatformIO Library Dependency Finder +- https://docs.platformio.org/page/librarymanager/ldf.html diff --git a/firmware/lib/tmc/helpers/API_Header.h b/firmware/lib/tmc/helpers/API_Header.h new file mode 100755 index 0000000..d9d57f1 --- /dev/null +++ b/firmware/lib/tmc/helpers/API_Header.h @@ -0,0 +1,42 @@ +/******************************************************************************* +* Copyright © 2016 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2023 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#ifndef TMC_API_HEADER_H_ +#define TMC_API_HEADER_H_ + +#include "Config.h" +#include "Macros.h" +#include "Constants.h" +#include "Bits.h" +#include "CRC.h" +#include "RegisterAccess.h" +#include +#include "Types.h" + +// TODO: Restructure these. +/* + * Goal: Just give these values here as status back to the IDE when used with EvalSystem. + * Currently, this is obtained by just leaving out implementation specific error bits here. + */ +typedef enum { + TMC_ERROR_NONE = 0x00, + TMC_ERROR_GENERIC = 0x01, + TMC_ERROR_FUNCTION = 0x02, + TMC_ERROR_MOTOR = 0x08, + TMC_ERROR_VALUE = 0x10, + TMC_ERROR_CHIP = 0x40 +} TMCError; + +typedef enum { + TMC_COMM_DEFAULT, + TMC_COMM_SPI, + TMC_COMM_UART +} TMC_Comm_Mode; + +#endif /* TMC_API_HEADER_H_ */ diff --git a/firmware/lib/tmc/helpers/Bits.h b/firmware/lib/tmc/helpers/Bits.h new file mode 100755 index 0000000..2dbf074 --- /dev/null +++ b/firmware/lib/tmc/helpers/Bits.h @@ -0,0 +1,92 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2023 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +// BIT DEFINITION +#ifndef TMC_BITS_H_ +#define TMC_BITS_H_ + +#define BIT0 0x00000001 +#define BIT1 0x00000002 +#define BIT2 0x00000004 +#define BIT3 0x00000008 +#define BIT4 0x00000010 +#define BIT5 0x00000020 +#define BIT6 0x00000040 +#define BIT7 0x00000080 +#define BIT8 0x00000100 +#define BIT9 0x00000200 +#define BIT10 0x00000400 +#define BIT11 0x00000800 +#define BIT12 0x00001000 +#define BIT13 0x00002000 +#define BIT14 0x00004000 +#define BIT15 0x00008000 +#define BIT16 0x00010000 +#define BIT17 0x00020000 +#define BIT18 0x00040000 +#define BIT19 0x00080000 +#define BIT20 0x00100000 +#define BIT21 0x00200000 +#define BIT22 0x00400000 +#define BIT23 0x00800000 +#define BIT24 0x01000000 +#define BIT25 0x02000000 +#define BIT26 0x04000000 +#define BIT27 0x08000000 +#define BIT28 0x10000000 +#define BIT29 0x20000000 +#define BIT30 0x40000000 +#define BIT31 0x80000000 + +#define BYTE0_MASK 0x00000000000000FF +#define BYTE0_SHIFT 0 +#define BYTE1_MASK 0x000000000000FF00 +#define BYTE1_SHIFT 8 +#define BYTE2_MASK 0x0000000000FF0000 +#define BYTE2_SHIFT 16 +#define BYTE3_MASK 0x00000000FF000000 +#define BYTE3_SHIFT 24 +#define BYTE4_MASK 0x000000FF00000000 +#define BYTE4_SHIFT 32 +#define BYTE5_MASK 0x0000FF0000000000 +#define BYTE5_SHIFT 40 +#define BYTE6_MASK 0x00FF000000000000 +#define BYTE6_SHIFT 48 +#define BYTE7_MASK 0xFF00000000000000 +#define BYTE7_SHIFT 56 + +#define SHORT0_MASK (BYTE0_MASK|BYTE1_MASK) +#define SHORT0_SHIFT BYTE0_SHIFT +#define SHORT1_MASK (BYTE2_MASK|BYTE3_MASK) +#define SHORT1_SHIFT BYTE2_SHIFT +#define SHORT2_MASK (BYTE4_MASK|BYTE5_MASK) +#define SHORT2_SHIFT BYTE4_SHIFT +#define SHORT3_MASK (BYTE6_MASK|BYTE7_MASK) +#define SHORT3_SHIFT BYTE6_SHIFT + +#define WORD0_MASK (SHORT0_MASK|SHORT1_MASK) +#define WORD0_SHIFT SHORT0_SHIFT +#define WORD1_MASK (SHORT2_MASK|SHORT3_MASK) +#define WORD1_SHIFT SHORT2_SHIFT + +#define NIBBLE(value, n) (((value) >> ((n) << 2)) & 0x0F) +#define BYTE(value, n) (((value) >> ((n) << 3)) & 0xFF) +#define SHORT(value, n) (((value) >> ((n) << 4)) & 0xFFFF) +#define WORD(value, n) (((value) >> ((n) << 5)) & 0xFFFFFFFF) + +#define _8_16(__1, __0) (((__1) << BYTE1_SHIFT) | ((__0) << BYTE0_SHIFT)) + +#define _8_32(__3, __2, __1, __0) (((__3) << BYTE3_SHIFT) | ((__2) << BYTE2_SHIFT) | ((__1) << BYTE1_SHIFT) | ((__0) << BYTE0_SHIFT)) +#define _16_32(__1, __0) (((__1) << SHORT1_SHIFT) | ((__0) << SHORT0_SHIFT)) + +#define _8_64(__7, __6, __5, __4, __3, __2, __1, __0) (((__7) << BYTE7_SHIFT) | ((__6) << BYTE6_SHIFT) | ((__5) << BYTE5_SHIFT) | ((__4) << BYTE4_SHIFT) | ((__3) << BYTE3_SHIFT) | ((__2) << BYTE2_SHIFT) | ((__1) << BYTE1_SHIFT) | ((__0) << BYTE0_SHIFT)) +#define _16_64(__3, __2, __1, __0) (((__3) << SHORT3_SHIFT) | ((__2) << SHORT2_SHIFT) | ((__1) << SHORT1_SHIFT) | ((__0) << SHORT0_SHIFT)) +#define _32_64(__1, __0) (((__1) << WORD1_SHIFT) | ((__0) << WORD0_SHIFT)) + +#endif /* TMC_BITS_H_ */ diff --git a/firmware/lib/tmc/helpers/CRC.c b/firmware/lib/tmc/helpers/CRC.c new file mode 100755 index 0000000..3ba8ef4 --- /dev/null +++ b/firmware/lib/tmc/helpers/CRC.c @@ -0,0 +1,214 @@ +/******************************************************************************* +* Copyright © 2017 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2023 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + +/* + * This is a generic implementation for a CRC8 generator supporting + * both compile-time (1) and run-time initialized Lookup tables for efficient CRC8 calculation. + * You can store multiple tables for different polynomials and (non-)reflected CRCs. + * The different tables are referenced by an index, with an upper limit set at compile time (CRC_TABLE_COUNT). + * + * To generate CRCs you must first generate the Lookup-table by calling fillCRCTable() + * with any index. CRCs can then be generated from any data buffer by calling CRC() + * with the same index previously given to fillCRCTable(). + * + * The table generation has been optimized for speed so that the runtime + * table generation can even be done during normal operation if required. + * However, as long as the required polynomials are known on initialization, + * the table generation should be done at that time. + * On the Landungsbruecke the initialization of a CRC table takes ~250µs. (2) + * Should your application still have problems with the table calculation time, + * this algorithm could probably be speed up by preparing a 2- or 4-bit lookup table + * to speed up the actual table generation. + * + * (1): For compile-time CRC tables, just fill the table(s) by initializing CRCTables[] to the proper values. + * (2): Tested by toggling a GPIO pin, generating a table in-between and measuring the GPIO pulse width. + */ + +#include "CRC.h" + +typedef struct { + uint8_t table[256]; + uint8_t polynomial; + bool isReflected; +} CRCTypeDef; + +CRCTypeDef CRCTables[CRC_TABLE_COUNT] = { 0 }; + +static uint8_t flipByte(uint8_t value); +static uint32_t flipBitsInBytes(uint32_t value); + +/* This function generates the Lookup table used for CRC calculations. + * + * Arguments: + * uint8_t polynomial: The CRC polynomial for which the table will be generated. + * bool isReflected: Indicator whether the CRC table will be reflected or not. + * uint8_t index: The index of the table to be filled. + * + * How it works: + * A CRC calculation of a byte can be done by taking the byte to be CRC'd, + * shifting it left by one (appending a 0) and - if a 1 has been shifted out - + * XOR-ing in the CRC polynomial. After 8 iterations the result will be the + * CRC of the Byte. + * + * The function below does this in a compact way, by using all 4 bytes of a + * uint32_t to do 4 separate CRC bytes at once. + * For this to work without the Byte shifting interfering with adjacent bytes, + * the polynomial has the 8th bit (0x100) set. That way, if the shifted-out bit + * is 1, the following XOR-ing with the CRC polynomial will set that 1 to a 0, + * resulting in the shifted-in 0 for the adjacent byte. + * This process will go from the the lowest to the highest byte, resulting in + * fully independent byte-wise CRC calculations. For the highest byte, the value + * of the shifted-out byte needs to be stored before shifting the bytes (isMSBSet). + * + * The for-loop that iterates over all uint8_t values starts out with the + * uint8_t values 3 to 0 stored in one uint32_t: 0x03020100 + * for each iteration each uint8_t value will increase by 4.. + * 0 -> 4 -> 8 -> C -> ... + * 1 -> 5 -> 9 -> D -> ... + * 2 -> 6 -> A -> E -> ... + * 3 -> 7 -> B -> F -> ... + * ..resulting in an increase of the uint32_t by 0x04040404: + * 0x03020100 -> 0x07060504 -> 0x0B0A0908 -> 0x0F0E0D0C -> ... + * The loop ends as soon as we have iterated over all uint8_t values. + * We detect that by looking for the byte-wise overflow into the next byte: + * 0xFFFEFDFC <- last uint32_t value to be calculated + * 0xFF, 0xFE, 0xFD, 0xFC <- the corresponding uint8_t values + * 0x103, 0x102, 0x101, 0x100 <- incremented uint8_t values (overflow into the next byte!) + * 0x04030200 <- uint32_t value with the overflowed bytes + * + * We have the lower uint8_t values at the lower bytes of the uint32_t. + * This allows us to simply store the lowest byte of the uint32_t, + * right-shift the uint32_t by 8 and increment the table pointer. + * After 4 iterations of that all 4 bytes of the uint32_t are stored in the table. + */ +uint8_t tmc_fillCRC8Table(uint8_t polynomial, bool isReflected, uint8_t index) +{ + uint32_t CRCdata; + // Helper pointer for traversing the result table + uint8_t *table; + + if(index >= CRC_TABLE_COUNT) + return 0; + + CRCTables[index].polynomial = polynomial; + CRCTables[index].isReflected = isReflected; + table = &CRCTables[index].table[0]; + + // Extend the polynomial to correct byte MSBs shifting into next bytes + uint32_t poly = (uint32_t) polynomial | 0x0100; + + // Iterate over all 256 possible uint8_t values, compressed into a uint32_t (see detailed explanation above) + uint32_t i; + for(i = 0x03020100; i != 0x04030200; i+=0x04040404) + { + // For reflected table: Flip the bits of each input byte + CRCdata = (isReflected)? flipBitsInBytes(i) : i; + + // Iterate over 8 Bits + int j; + for(j = 0; j < 8; j++) + { + // Store value of soon-to-be shifted out byte + uint8_t isMSBSet = (CRCdata & 0x80000000)? 1:0; + + // CRC Shift + CRCdata <<= 1; + + // XOR the bytes when required, lowest to highest + CRCdata ^= (CRCdata & 0x00000100)? (poly ) : 0; + CRCdata ^= (CRCdata & 0x00010000)? (poly << 8 ) : 0; + CRCdata ^= (CRCdata & 0x01000000)? (poly << 16) : 0; + CRCdata ^= (isMSBSet)? (poly << 24) : 0; + } + + // For reflected table: Flip the bits of each output byte + CRCdata = (isReflected)? flipBitsInBytes(CRCdata) : CRCdata; + // Store the CRC result bytes in the table array + *table++ = (uint8_t) CRCdata; + CRCdata >>= 8; + *table++ = (uint8_t) CRCdata; + CRCdata >>= 8; + *table++ = (uint8_t) CRCdata; + CRCdata >>= 8; + *table++ = (uint8_t) CRCdata; + } + + return 1; +} + +/* This function calculates the CRC from a data buffer + * + * Arguments: + * uint8_t *data: A pointer to the data that will be CRC'd. + * uint32_t bytes: The length of the data buffer. + * uint8_t index: The index of the CRC table to be used. + */ +uint8_t tmc_CRC8(uint8_t *data, uint32_t bytes, uint8_t index) +{ + uint8_t result = 0; + uint8_t *table; + + if(index >= CRC_TABLE_COUNT) + return 0; + + table = &CRCTables[index].table[0]; + + while(bytes--) + result = table[result ^ *data++]; + + return (CRCTables[index].isReflected)? flipByte(result) : result; +} + +uint8_t tmc_tableGetPolynomial(uint8_t index) +{ + if(index >= CRC_TABLE_COUNT) + return 0; + + return CRCTables[index].polynomial; +} + +bool tmc_tableIsReflected(uint8_t index) +{ + if(index >= CRC_TABLE_COUNT) + return false; + + return CRCTables[index].isReflected; +} + +// Helper functions +static uint8_t flipByte(uint8_t value) +{ + // swap odd and even bits + value = ((value >> 1) & 0x55) | ((value & 0x55) << 1); + // swap consecutive pairs + value = ((value >> 2) & 0x33) | ((value & 0x33) << 2); + // swap nibbles ... + value = ((value >> 4) & 0x0F) | ((value & 0x0F) << 4); + + return value; +} + +/* This helper function switches all bits within each byte. + * The byte order remains the same: + * [b31 b30 b29 b28 b27 b26 b25 b24 .. b7 b6 b5 b4 b3 b2 b1 b0] + * || + * \||/ + * \/ + * [b24 b25 b26 b27 b28 b29 b30 b31 .. b0 b1 b2 b3 b4 b5 b6 b7] + */ +static uint32_t flipBitsInBytes(uint32_t value) +{ + // swap odd and even bits + value = ((value >> 1) & 0x55555555) | ((value & 0x55555555) << 1); + // swap consecutive pairs + value = ((value >> 2) & 0x33333333) | ((value & 0x33333333) << 2); + // swap nibbles ... + value = ((value >> 4) & 0x0F0F0F0F) | ((value & 0x0F0F0F0F) << 4); + + return value; +} diff --git a/firmware/lib/tmc/helpers/CRC.h b/firmware/lib/tmc/helpers/CRC.h new file mode 100755 index 0000000..dea02fb --- /dev/null +++ b/firmware/lib/tmc/helpers/CRC.h @@ -0,0 +1,25 @@ +/******************************************************************************* +* Copyright © 2017 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2023 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#ifndef TMC_HELPERS_CRC_H_ +#define TMC_HELPERS_CRC_H_ + + #include "Types.h" + + // Amount of CRC tables available + // Each table takes ~260 bytes (257 bytes, one bool and structure padding) + #define CRC_TABLE_COUNT 2 + + uint8_t tmc_fillCRC8Table(uint8_t polynomial, bool isReflected, uint8_t index); + uint8_t tmc_CRC8(uint8_t *data, uint32_t bytes, uint8_t index); + + uint8_t tmc_tableGetPolynomial(uint8_t index); + bool tmc_tableIsReflected(uint8_t index); + +#endif /* TMC_HELPERS_CRC_H_ */ diff --git a/firmware/lib/tmc/helpers/Config.h b/firmware/lib/tmc/helpers/Config.h new file mode 100755 index 0000000..a9ceed3 --- /dev/null +++ b/firmware/lib/tmc/helpers/Config.h @@ -0,0 +1,41 @@ +/******************************************************************************* +* Copyright © 2018 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2023 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#ifndef TMC_HELPERS_CONFIG_H_ +#define TMC_HELPERS_CONFIG_H_ + +#include "Constants.h" +#include "Types.h" + +// Callback functions have IC-dependent parameters +// To store the function pointers we use this dummy type, which is never +// called without casting it to the IC-specific type first. +// (Casting between function pointers is allowed by the C standard) +typedef void (*tmc_callback_config)(void); + +// States of a configuration +typedef enum { + CONFIG_READY, + CONFIG_RESET, + CONFIG_RESTORE +} ConfigState; + +// structure for configuration mechanism +typedef struct +{ + ConfigState state; + uint8_t configIndex; + int32_t shadowRegister[TMC_REGISTER_COUNT]; + uint8_t (*reset) (void); + uint8_t (*restore) (void); + tmc_callback_config callback; + uint8_t channel; +} ConfigurationTypeDef; + +#endif /* TMC_HELPERS_CONFIG_H_ */ diff --git a/firmware/lib/tmc/helpers/Constants.h b/firmware/lib/tmc/helpers/Constants.h new file mode 100755 index 0000000..e5e4216 --- /dev/null +++ b/firmware/lib/tmc/helpers/Constants.h @@ -0,0 +1,24 @@ +/******************************************************************************* +* Copyright © 2018 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2023 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#ifndef TMC_HELPERS_CONSTANTS_H_ +#define TMC_HELPERS_CONSTANTS_H_ + +#define TMC_WRITE_BIT 0x80 + +#define TMC_ADDRESS_MASK 0x7F + +#define TMC_DEFAULT_MOTOR 0 + +//#define TMC_DIRECTION_RIGHT TRUE +//#define TMC_DIRECTION_LEFT FALSE + +#define TMC_REGISTER_COUNT 128 // Default register count + +#endif /* TMC_HELPERS_CONSTANTS_H_ */ diff --git a/firmware/lib/tmc/helpers/Functions.c b/firmware/lib/tmc/helpers/Functions.c new file mode 100755 index 0000000..535fed6 --- /dev/null +++ b/firmware/lib/tmc/helpers/Functions.c @@ -0,0 +1,173 @@ +/******************************************************************************* +* Copyright © 2018 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2023 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#include "Functions.h" + +int32_t tmc_limitInt(int32_t value, int32_t min, int32_t max) +{ + if (value > max) + return max; + else if (value < min) + return min; + else + return value; +} + +int64_t tmc_limitS64(int64_t value, int64_t min, int64_t max) +{ + if (value > max) + return max; + else if (value < min) + return min; + else + return value; +} + +/* lookup table for square root function */ +static const unsigned char sqrttable[256] = +{ + 0, 16, 22, 27, 32, 35, 39, 42, 45, 48, 50, 53, 55, 57, 59, 61, + 64, 65, 67, 69, 71, 73, 75, 76, 78, 80, 81, 83, 84, 86, 87, 89, + 90, 91, 93, 94, 96, 97, 98, 99, 101, 102, 103, 104, 106, 107, 108, 109, + 110, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, + 128, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, + 143, 144, 144, 145, 146, 147, 148, 149, 150, 150, 151, 152, 153, 154, 155, 155, + 156, 157, 158, 159, 160, 160, 161, 162, 163, 163, 164, 165, 166, 167, 167, 168, + 169, 170, 170, 171, 172, 173, 173, 174, 175, 176, 176, 177, 178, 178, 179, 180, + 181, 181, 182, 183, 183, 184, 185, 185, 186, 187, 187, 188, 189, 189, 190, 191, + 192, 192, 193, 193, 194, 195, 195, 196, 197, 197, 198, 199, 199, 200, 201, 201, + 202, 203, 203, 204, 204, 205, 206, 206, 207, 208, 208, 209, 209, 210, 211, 211, + 212, 212, 213, 214, 214, 215, 215, 216, 217, 217, 218, 218, 219, 219, 220, 221, + 221, 222, 222, 223, 224, 224, 225, 225, 226, 226, 227, 227, 228, 229, 229, 230, + 230, 231, 231, 232, 232, 233, 234, 234, 235, 235, 236, 236, 237, 237, 238, 238, + 239, 240, 240, 241, 241, 242, 242, 243, 243, 244, 244, 245, 245, 246, 246, 247, + 247, 248, 248, 249, 249, 250, 250, 251, 251, 252, 252, 253, 253, 254, 254, 255 +}; + +int32_t tmc_sqrti(int32_t x) +{ + int32_t xn; + + // Negative parameter? + if (x < 0) + return -1; + + if (x < 0x0100) + return (int32_t) sqrttable[x] >> 4; + + if (x >= 0x00010000) + { + if (x >= 0x01000000) + { + if (x >= 0x10000000) + { + if (x >= 0x40000000) + { + // 0x40000000 <= x < 0x7FFFFFFF + xn = (int32_t) sqrttable[x >> 24] << 8; + } + else + { + // 0x10000000 <= x < 0x40000000 + xn = (int32_t) sqrttable[x >> 22] << 7; + } + } + else + { + if (x >= 0x04000000) + { + // 0x04000000 <= x < 0x10000000 + xn = (int32_t) sqrttable[x >> 20] << 6; + } + else + { + // 0x01000000 <= x < 0x04000000 + xn = (int32_t) sqrttable[x >> 18] << 5; + } + } + + // Two steps of the babylonian method + xn = (xn + 1 + (x / xn)) >> 1; + xn = (xn + 1 + (x / xn)) >> 1; + } + else + { + if (x >= 0x00100000) + { + if (x >= 0x00400000) + { + // 0x00400000 <= x < 0x01000000 + xn = (int32_t) sqrttable[x >> 16] << 4; + } + else + { + // 0x00100000 <= x < 0x00400000 + xn = (int32_t) sqrttable[x >> 14] << 3; + } + } + else + { + if (x >= 0x00040000) + { + // 0x00040000 <= x < 0x00100000 + xn = (int32_t) sqrttable[x >> 12] << 2; + } + else + { + // 0x00010000 <= x < 0x00040000 + xn = (int32_t) sqrttable[x >> 10] << 1; + } + } + + // One step of the babylonian method + xn = (xn + 1 + (x / xn)) >> 1; + } + } + else + { + if (x >= 0x1000) + { + if (x >= 0x4000) + { + // 0x4000 <= x < 0x00010000 + xn = (int32_t) (sqrttable[x >> 8] ) + 1; + } + else + { + // 0x1000 <= x < 0x4000 + xn = (int32_t) (sqrttable[x >> 6] >> 1) + 1; + } + } + else + { + if (x >= 0x0400) + { + // 0x0400 <= x < 0x1000 + xn = (int32_t) (sqrttable[x >> 4] >> 2) + 1; + } + else + { + // 0x0100 <= x < 0x0400 + xn = (int32_t) (sqrttable[x >> 2] >> 3) + 1; + } + } + } + + // Make sure that our result is floored + if ((xn * xn) > x) + xn--; + + return xn; +} + +int32_t tmc_filterPT1(int64_t *akku, int32_t newValue, int32_t lastValue, uint8_t actualFilter, uint8_t maxFilter) +{ + *akku += (newValue-lastValue) << (maxFilter-actualFilter); + return *akku >> maxFilter; +} diff --git a/firmware/lib/tmc/helpers/Functions.h b/firmware/lib/tmc/helpers/Functions.h new file mode 100755 index 0000000..93dac20 --- /dev/null +++ b/firmware/lib/tmc/helpers/Functions.h @@ -0,0 +1,20 @@ +/******************************************************************************* +* Copyright © 2018 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2023 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#ifndef TMC_FUNCTIONS_H_ +#define TMC_FUNCTIONS_H_ + +#include "API_Header.h" + +int32_t tmc_limitInt(int32_t value, int32_t min, int32_t max); +int64_t tmc_limitS64(int64_t value, int64_t min, int64_t max); +int32_t tmc_sqrti(int32_t x); +int32_t tmc_filterPT1(int64_t *akku, int32_t newValue, int32_t lastValue, uint8_t actualFilter, uint8_t maxFilter); + +#endif /* TMC_FUNCTIONS_H_ */ diff --git a/firmware/lib/tmc/helpers/Macros.h b/firmware/lib/tmc/helpers/Macros.h new file mode 100755 index 0000000..37771cd --- /dev/null +++ b/firmware/lib/tmc/helpers/Macros.h @@ -0,0 +1,59 @@ +/******************************************************************************* +* Copyright © 2018 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2023 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#ifndef TMC_MACROS_H_ +#define TMC_MACROS_H_ + +/* Cast a n bit signed int to a 32 bit signed int + * This is done by checking the MSB of the signed int (Bit n). + * If it is 1, the value is negative and the Bits 32 to n+1 are set to 1 + * If it is 0, the value remains unchanged + */ +#define CAST_Sn_TO_S32(value, n) ((value) | (((value) & ((uint32_t)1<<((n)-1)))? ~(((uint32_t)1<<(n))-1) : 0 )) + +// Min/Max macros +#ifndef MIN + #define MIN(a,b) (((a)<(b)) ? (a) : (b)) +#endif +#ifndef MAX + #define MAX(a,b) (((a)>(b)) ? (a) : (b)) +#endif + +// Static Array length +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) +#endif + +// Generic mask/shift macros +#define FIELD_GET(data, mask, shift) \ + (((data) & (mask)) >> (shift)) +#define FIELD_SET(data, mask, shift, value) \ + (((data) & (~(mask))) | (((value) << (shift)) & (mask))) + +// Register read/write/update macros using Mask/Shift: +#define FIELD_READ(read, motor, address, mask, shift) \ + FIELD_GET(read(motor, address), mask, shift) +#define FIELD_WRITE(write, motor, address, mask, shift, value) \ + (write(motor, address, ((value)<<(shift)) & (mask))) +#define FIELD_UPDATE(read, write, motor, address, mask, shift, value) \ + (write(motor, address, FIELD_SET(read(motor, address), mask, shift, value))) + +// Macro to surpress unused parameter warnings +#ifndef UNUSED + #define UNUSED(x) (void)(x) +#endif + +// Memory access helpers +// Force the compiler to access a location exactly once +#define ACCESS_ONCE(x) *((volatile typeof(x) *) (&x)) + +// Macro to remove write bit for shadow register array access +#define TMC_ADDRESS(x) ((x) & (TMC_ADDRESS_MASK)) + +#endif /* TMC_MACROS_H_ */ diff --git a/firmware/lib/tmc/helpers/RegisterAccess.h b/firmware/lib/tmc/helpers/RegisterAccess.h new file mode 100755 index 0000000..7990589 --- /dev/null +++ b/firmware/lib/tmc/helpers/RegisterAccess.h @@ -0,0 +1,86 @@ +/******************************************************************************* +* Copyright © 2017 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2023 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + +/* + * The permission system aims to allow a general-purpose implementation for + * all common hardware register usages. This includes: + * - Trivial Cases: Read, Write, Read & Write + * + * - Read & Write accesses that route to different values/functions of a chip. + * (e.g. serial communication, where read/write corresponds to RX/TX) + * - Read to clear, write to clear. This does not directly affect the access, + * but can be used to implement a software shadow register for flags + * (ORing the read value into a shadow register instead of overwriting). + * - Registers with default values that are not known (e.g. Factory configuration + * values that should not be overwritten by default). + */ + +#ifndef TMC_HELPERS_REGISTERACCESS_H +#define TMC_HELPERS_REGISTERACCESS_H + +// Register access bits +/* Lower nibble is used for read/write, higher nibble is used for + * special case registers. This makes it easy to identify the read/write + * part of the permissions in a hexadecimal permission number. + * The dirty bit will only ever be set at runtime, so we keep the easily + * readable lower nibble. + */ +#define TMC_ACCESS_NONE 0x00 + +#define TMC_ACCESS_READ 0x01 +#define TMC_ACCESS_WRITE 0x02 + // 0x04 is currently unused +#define TMC_ACCESS_DIRTY 0x08 // Register has been written since reset -> shadow register is valid for restore + +// Special Register bits +#define TMC_ACCESS_RW_SPECIAL 0x10 // Read and write are independent - different values and/or different functions +#define TMC_ACCESS_FLAGS 0x20 // Register has read or write to clear flags. +#define TMC_ACCESS_HW_PRESET 0x40 // Register has hardware presets (e.g. Factory calibrations) - do not write a default value + // 0x80 is currently unused + +// Permission combinations +#define TMC_ACCESS_RW (TMC_ACCESS_READ | TMC_ACCESS_WRITE) // 0x03 - Read and write +#define TMC_ACCESS_RW_SEPARATE (TMC_ACCESS_RW | TMC_ACCESS_RW_SPECIAL) // 0x13 - Read and write, with separate values/functions +#define TMC_ACCESS_R_FLAGS (TMC_ACCESS_READ | TMC_ACCESS_FLAGS) // 0x21 - Read, has flags (read to clear) +#define TMC_ACCESS_RW_FLAGS (TMC_ACCESS_RW | TMC_ACCESS_FLAGS) // 0x23 - Read and write, has flags (read or write to clear) +#define TMC_ACCESS_W_PRESET (TMC_ACCESS_WRITE | TMC_ACCESS_HW_PRESET) // 0x42 - Write, has hardware preset - skipped in reset routine +#define TMC_ACCESS_RW_PRESET (TMC_ACCESS_RW | TMC_ACCESS_HW_PRESET) // 0x43 - Read and write, has hardware presets - skipped in reset routine + +// Helper macros +#define TMC_IS_READABLE(x) ((x) & TMC_ACCESS_READ) +#define TMC_IS_WRITABLE(x) ((x) & TMC_ACCESS_WRITE) +#define TMC_IS_DIRTY(x) ((x) & TMC_ACCESS_DIRTY) +#define TMC_IS_PRESET(x) ((x) & TMC_ACCESS_HW_PRESET) +#define TMC_IS_RESETTABLE(x) (((x) & (TMC_ACCESS_W_PRESET)) == TMC_ACCESS_WRITE) // Write bit set, Hardware preset bit not set +#define TMC_IS_RESTORABLE(x) (((x) & TMC_ACCESS_WRITE) && (!(x & TMC_ACCESS_HW_PRESET) || (x & TMC_ACCESS_DIRTY))) // Write bit set, if it's a hardware preset register, it needs to be dirty + +// Struct for listing registers that have constant contents which we cannot +// obtain by reading them due to the register not being read-back. +typedef struct +{ + uint8_t address; + uint32_t value; +} TMCRegisterConstant; + +// Helper define: +// Most register permission arrays are initialized with 128 values. +// In those fields its quite hard to have an easy overview of available +// registers. For that, ____ is defined to 0, since 4 underscores are +// very easy to distinguish from the 2-digit hexadecimal values. +// This way, the used registers (permission != ACCESS_NONE) are easily spotted +// amongst unused (permission == ACCESS_NONE) registers. +#define ____ 0x00 + +// Helper define: +// Default reset values are not used if the corresponding register has a +// hardware preset. Since this is not directly visible in the default +// register reset values array, N_A is used as an indicator for a preset +// value, where any value will be ignored anyways (N_A: not available). +#define N_A 0 + +#endif /* TMC_HELPERS_REGISTERACCESS_H */ diff --git a/firmware/lib/tmc/helpers/Types.h b/firmware/lib/tmc/helpers/Types.h new file mode 100755 index 0000000..aeedde1 --- /dev/null +++ b/firmware/lib/tmc/helpers/Types.h @@ -0,0 +1,107 @@ +/******************************************************************************* +* Copyright © 2016 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2023 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +// Turn off the integer typedefs by uncommenting the following two defines. +// If your IDE (e.g. Arduino IDE) already defines these types, deactivating +// these typedefs will fix errors and/or warnings. +//#define TMC_SKIP_UINT_TYPEDEFS // Disable u8, u16, u32, uint8, uint16 and uint32 typedefs +//#define TMC_SKIP_INT_TYPEDEFS // Disable s8, s16, s32, int8, int16 and int32 typedefs + +#ifndef TMC_TYPES_H_ +#define TMC_TYPES_H_ + +#include +#include +#include + +#ifndef TMC_TYPES_INTEGERS +#define TMC_TYPES_INTEGERS + +// todo: change to standard ISO C99 types (ED) + +// www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf +// ISO C99: 7.18 Integer types 8, 16, 32, or 64 bits +// intN_t = two’s complement signed integer type with width N, no padding bits. +// uintN_t = an unsigned integer type with width N. +// floatN_t = N bit IEE 754 float. +// INT8_MIN, INT8_MAX, INT16_MIN, INT16_MAX, INT32_MIN, INT32_MAX, .... UINT32_MAX + +typedef float float32_t; +typedef double float64_t; + +#ifndef TMC_TYPES_INTEGERS_UNSIGNED +#define TMC_TYPES_INTEGERS_UNSIGNED + +#ifndef TMC_SKIP_UINT_TYPEDEFS +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; + +typedef uint8_t uint8; +typedef uint16_t uint16; +typedef uint32_t uint32; +#endif /* TMC_SKIP_UINT_TYPEDEFS */ + +#define u8_MAX (uint8_t) 255 +#define u10_MAX (uint16_t) 1023 +#define u12_MAX (uint16_t) 4095 +#define u15_MAX (uint16_t) 32767 +#define u16_MAX (uint16_t) 65535 +#define u18_MAX (uint32_t) 262143uL +#define u20_MAX (uint32_t) 1048575uL +#define u22_MAX (uint32_t) 4194303uL +#define u24_MAX (uint32_t) 16777215uL +#define u32_MAX (uint32_t) 4294967295uL + +#endif /* TMC_TYPES_INTEGERS_UNSIGNED */ + +#ifndef TMC_TYPES_INTEGERS_SIGNED +#define TMC_TYPES_INTEGERS_SIGNED + +#ifndef TMC_SKIP_INT_TYPEDEFS +typedef int8_t s8; +typedef int16_t s16; +typedef int32_t s32; + +typedef int8_t int8; +typedef int16_t int16; +typedef int32_t int32; +#endif /* TMC_SKIP_INT_TYPEDEFS */ + +#define s8_MAX (int8_t) 127 +#define s8_MIN (int8_t) -128 +#define s16_MAX (int16_t) 32767 +#define s16_MIN (int16_t) -32768 +#define s24_MAX (int32_t) 8388607 +#define s24_MIN (int32_t) -8388608 +#define s32_MAX (int32_t) 2147483647 +#define s32_MIN (int32_t) -2147483648 + +#endif /* TMC_TYPES_INTEGERS_SIGNED */ + +#endif /* TMC_TYPES_INTEGERS */ + +#ifndef TMC_TYPES_NULL +#define TMC_TYPES_NULL + +#ifndef NULL +#define NULL ((void *) 0) +#endif /* NULL */ + +#ifndef FALSE +#define FALSE false +#endif + +#ifndef TRUE +#define TRUE true +#endif + +#endif /* TMC_TYPES_NULL */ + +#endif /* TMC_TYPES_H_ */ diff --git a/firmware/lib/tmc/ic/MAX22200/MAX22200.c b/firmware/lib/tmc/ic/MAX22200/MAX22200.c new file mode 100755 index 0000000..bb04561 --- /dev/null +++ b/firmware/lib/tmc/ic/MAX22200/MAX22200.c @@ -0,0 +1,62 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + +#include + +static int32_t readRegisterSPI(uint16_t icID, uint8_t address); +static void writeRegisterSPI(uint16_t icID, uint8_t address, int32_t value); + +int32_t max22200_readRegister(uint16_t icID, uint8_t address) +{ + return readRegisterSPI(icID, address); +} + +void max22200_writeRegister(uint16_t icID, uint8_t address, int32_t value) +{ + writeRegisterSPI(icID, address, value); +} +int32_t readRegisterSPI(uint16_t icID, uint8_t address) +{ + uint8_t cmd = 0; + uint8_t data[4] = {0}; + + // Send the read request + cmd &= ~(1 << 7); // read + cmd &= ~((1 << 5)|(1 << 6)); + cmd |= (address << 1); + cmd &= ~(1 << 0); + + max22200_readWriteSPI(icID, &cmd, sizeof(cmd), true); + + // Send request to read reply + max22200_readWriteSPI(icID, &data[0], sizeof(data), false); + + return ((int32_t)data[0] << 24) | ((int32_t) data[1] << 16) | ((int32_t) data[2] << 8) | ((int32_t) data[3]); +} + +void writeRegisterSPI(uint16_t icID, uint8_t address, int32_t value) +{ + uint8_t cmd = 0; + uint8_t data[4] = {0}; + + // Send the write request + cmd |= (1 << 7); //write + cmd &= ~((1 << 5)|(1 << 6)); + cmd |= ((address << 1)); + cmd &= ~(1 << 0); + + max22200_readWriteSPI(icID, &cmd, sizeof(cmd), true); + + data[0] = 0xFF & (value>>0); + data[1] = 0xFF & (value>>8); + data[2] = 0xFF & (value>>16); + data[3] = 0xFF & (value>>24); + + // Send another request to send data + max22200_readWriteSPI(icID, &data[0], sizeof(data), false); +} diff --git a/firmware/lib/tmc/ic/MAX22200/MAX22200.h b/firmware/lib/tmc/ic/MAX22200/MAX22200.h new file mode 100755 index 0000000..c63ef9b --- /dev/null +++ b/firmware/lib/tmc/ic/MAX22200/MAX22200.h @@ -0,0 +1,17 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + +#include +#include +#include +#include "MAX22200_HW_Abstraction.h" + +int32_t max22200_readRegister(uint16_t icID, uint8_t address); +void max22200_writeRegister(uint16_t icID, uint8_t address, int32_t value); + +extern void max22200_readWriteSPI(uint16_t icID, uint8_t *data, size_t dataLength, bool cmd_mode); diff --git a/firmware/lib/tmc/ic/MAX22200/MAX22200_HW_Abstraction.h b/firmware/lib/tmc/ic/MAX22200/MAX22200_HW_Abstraction.h new file mode 100755 index 0000000..5341ae7 --- /dev/null +++ b/firmware/lib/tmc/ic/MAX22200/MAX22200_HW_Abstraction.h @@ -0,0 +1,412 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + +// Autogenerated C header for register fields in MAX22200 +// Generator version: 1.0 + +#ifndef MAX22200_FIELDS +#define MAX22200_FIELDS + +// Register definitions +#define MAX22200_STATUS 0x00 +#define MAX22200_CFG_CH_0 0x01 +#define MAX22200_CFG_CH_1 0x02 +#define MAX22200_CFG_CH_2 0x03 +#define MAX22200_CFG_CH_3 0x04 +#define MAX22200_CFG_CH_4 0x05 +#define MAX22200_CFG_CH_5 0x06 +#define MAX22200_CFG_CH_6 0x07 +#define MAX22200_CFG_CH_7 0x08 +#define MAX22200_FAULT 0x09 +#define MAX22200_CFG_DPM 0x0A + + +// Field definitions +#define MAX22200_ACTIVE_MASK 0x00000001 +#define MAX22200_ACTIVE_SHIFT 0 +#define MAX22200_ACTIVE_FIELD ((RegisterField) {MAX22200_ACTIVE_MASK, MAX22200_ACTIVE_SHIFT, MAX22200_STATUS, false}) +#define MAX22200_UVM_MASK 0x00000002 +#define MAX22200_UVM_SHIFT 1 +#define MAX22200_UVM_FIELD ((RegisterField) {MAX22200_UVM_MASK, MAX22200_UVM_SHIFT, MAX22200_STATUS, false}) +#define MAX22200_COMER_MASK 0x00000004 +#define MAX22200_COMER_SHIFT 2 +#define MAX22200_COMER_FIELD ((RegisterField) {MAX22200_COMER_MASK, MAX22200_COMER_SHIFT, MAX22200_STATUS, false}) +#define MAX22200_DPM_MASK 0x00000008 +#define MAX22200_DPM_SHIFT 3 +#define MAX22200_DPM_FIELD ((RegisterField) {MAX22200_DPM_MASK, MAX22200_DPM_SHIFT, MAX22200_STATUS, false}) +#define MAX22200_HHF_MASK 0x00000010 +#define MAX22200_HHF_SHIFT 4 +#define MAX22200_HHF_FIELD ((RegisterField) {MAX22200_HHF_MASK, MAX22200_HHF_SHIFT, MAX22200_STATUS, false}) +#define MAX22200_OLF_MASK 0x00000020 +#define MAX22200_OLF_SHIFT 5 +#define MAX22200_OLF_FIELD ((RegisterField) {MAX22200_OLF_MASK, MAX22200_OLF_SHIFT, MAX22200_STATUS, false}) +#define MAX22200_OCP_MASK 0x00000040 +#define MAX22200_OCP_SHIFT 6 +#define MAX22200_OCP_FIELD ((RegisterField) {MAX22200_OCP_MASK, MAX22200_OCP_SHIFT, MAX22200_STATUS, false}) +#define MAX22200_OVT_MASK 0x00000080 +#define MAX22200_OVT_SHIFT 7 +#define MAX22200_OVT_FIELD ((RegisterField) {MAX22200_OVT_MASK, MAX22200_OVT_SHIFT, MAX22200_STATUS, false}) +#define MAX22200_CM10_MASK 0x00000300 +#define MAX22200_CM10_SHIFT 8 +#define MAX22200_CM10_FIELD ((RegisterField) {MAX22200_CM10_MASK, MAX22200_CM10_SHIFT, MAX22200_STATUS, false}) +#define MAX22200_CM32_MASK 0x00000C00 +#define MAX22200_CM32_SHIFT 10 +#define MAX22200_CM32_FIELD ((RegisterField) {MAX22200_CM32_MASK, MAX22200_CM32_SHIFT, MAX22200_STATUS, false}) +#define MAX22200_CM54_MASK 0x00003000 +#define MAX22200_CM54_SHIFT 12 +#define MAX22200_CM54_FIELD ((RegisterField) {MAX22200_CM54_MASK, MAX22200_CM54_SHIFT, MAX22200_STATUS, false}) +#define MAX22200_CM76_MASK 0x0000C000 +#define MAX22200_CM76_SHIFT 14 +#define MAX22200_CM76_FIELD ((RegisterField) {MAX22200_CM76_MASK, MAX22200_CM76_SHIFT, MAX22200_STATUS, false}) +#define MAX22200_FREQM_MASK 0x00010000 +#define MAX22200_FREQM_SHIFT 16 +#define MAX22200_FREQM_FIELD ((RegisterField) {MAX22200_FREQM_MASK, MAX22200_FREQM_SHIFT, MAX22200_STATUS, false}) +#define MAX22200_M_UVM_MASK 0x00020000 +#define MAX22200_M_UVM_SHIFT 17 +#define MAX22200_M_UVM_FIELD ((RegisterField) {MAX22200_M_UVM_MASK, MAX22200_M_UVM_SHIFT, MAX22200_STATUS, false}) +#define MAX22200_M_COMF_MASK 0x00040000 +#define MAX22200_M_COMF_SHIFT 18 +#define MAX22200_M_COMF_FIELD ((RegisterField) {MAX22200_M_COMF_MASK, MAX22200_M_COMF_SHIFT, MAX22200_STATUS, false}) +#define MAX22200_M_DPM_MASK 0x00080000 +#define MAX22200_M_DPM_SHIFT 19 +#define MAX22200_M_DPM_FIELD ((RegisterField) {MAX22200_M_DPM_MASK, MAX22200_M_DPM_SHIFT, MAX22200_STATUS, false}) +#define MAX22200_M_HHF_MASK 0x00100000 +#define MAX22200_M_HHF_SHIFT 20 +#define MAX22200_M_HHF_FIELD ((RegisterField) {MAX22200_M_HHF_MASK, MAX22200_M_HHF_SHIFT, MAX22200_STATUS, false}) +#define MAX22200_M_OLF_MASK 0x00200000 +#define MAX22200_M_OLF_SHIFT 21 +#define MAX22200_M_OLF_FIELD ((RegisterField) {MAX22200_M_OLF_MASK, MAX22200_M_OLF_SHIFT, MAX22200_STATUS, false}) +#define MAX22200_M_OCP_MASK 0x00400000 +#define MAX22200_M_OCP_SHIFT 22 +#define MAX22200_M_OCP_FIELD ((RegisterField) {MAX22200_M_OCP_MASK, MAX22200_M_OCP_SHIFT, MAX22200_STATUS, false}) +#define MAX22200_M_OVT_MASK 0x00800000 +#define MAX22200_M_OVT_SHIFT 23 +#define MAX22200_M_OVT_FIELD ((RegisterField) {MAX22200_M_OVT_MASK, MAX22200_M_OVT_SHIFT, MAX22200_STATUS, false}) +#define MAX22200_ONCH_MASK 0xFF000000 +#define MAX22200_ONCH_SHIFT 24 +#define MAX22200_ONCH_FIELD ((RegisterField) {MAX22200_ONCH_MASK, MAX22200_ONCH_SHIFT, MAX22200_STATUS, false}) +#define MAX22200_HHF_EN0_MASK 0x00000001 +#define MAX22200_HHF_EN0_SHIFT 0 +#define MAX22200_HHF_EN0_FIELD ((RegisterField) {MAX22200_HHF_EN0_MASK, MAX22200_HHF_EN0_SHIFT, MAX22200_CFG_CH_0, false}) +#define MAX22200_DPM_EN0_MASK 0x00000002 +#define MAX22200_DPM_EN0_SHIFT 1 +#define MAX22200_DPM_EN0_FIELD ((RegisterField) {MAX22200_DPM_EN0_MASK, MAX22200_DPM_EN0_SHIFT, MAX22200_CFG_CH_0, false}) +#define MAX22200_OL_EN0_MASK 0x00000004 +#define MAX22200_OL_EN0_SHIFT 2 +#define MAX22200_OL_EN0_FIELD ((RegisterField) {MAX22200_OL_EN0_MASK, MAX22200_OL_EN0_SHIFT, MAX22200_CFG_CH_0, false}) +#define MAX22200_SRC0_MASK 0x00000008 +#define MAX22200_SRC0_SHIFT 3 +#define MAX22200_SRC0_FIELD ((RegisterField) {MAX22200_SRC0_MASK, MAX22200_SRC0_SHIFT, MAX22200_CFG_CH_0, false}) +#define MAX22200_FREQ_CFG0_MASK 0x00000030 +#define MAX22200_FREQ_CFG0_SHIFT 4 +#define MAX22200_FREQ_CFG0_FIELD ((RegisterField) {MAX22200_FREQ_CFG0_MASK, MAX22200_FREQ_CFG0_SHIFT, MAX22200_CFG_CH_0, false}) +#define MAX22200_HSNLS0_MASK 0x00000040 +#define MAX22200_HSNLS0_SHIFT 6 +#define MAX22200_HSNLS0_FIELD ((RegisterField) {MAX22200_HSNLS0_MASK, MAX22200_HSNLS0_SHIFT, MAX22200_CFG_CH_0, false}) +#define MAX22200_VDRNCDR0_MASK 0x00000080 +#define MAX22200_VDRNCDR0_SHIFT 7 +#define MAX22200_VDRNCDR0_FIELD ((RegisterField) {MAX22200_VDRNCDR0_MASK, MAX22200_VDRNCDR0_SHIFT, MAX22200_CFG_CH_0, false}) +#define MAX22200_HIT_T0_MASK 0x0000FF00 +#define MAX22200_HIT_T0_SHIFT 8 +#define MAX22200_HIT_T0_FIELD ((RegisterField) {MAX22200_HIT_T0_MASK, MAX22200_HIT_T0_SHIFT, MAX22200_CFG_CH_0, false}) +#define MAX22200_HIT0_MASK 0x007F0000 +#define MAX22200_HIT0_SHIFT 16 +#define MAX22200_HIT0_FIELD ((RegisterField) {MAX22200_HIT0_MASK, MAX22200_HIT0_SHIFT, MAX22200_CFG_CH_0, false}) +#define MAX22200_TRGNSPI0_MASK 0x00800000 +#define MAX22200_TRGNSPI0_SHIFT 23 +#define MAX22200_TRGNSPI0_FIELD ((RegisterField) {MAX22200_TRGNSPI0_MASK, MAX22200_TRGNSPI0_SHIFT, MAX22200_CFG_CH_0, false}) +#define MAX22200_HOLD0_MASK 0x7F000000 +#define MAX22200_HOLD0_SHIFT 24 +#define MAX22200_HOLD0_FIELD ((RegisterField) {MAX22200_HOLD0_MASK, MAX22200_HOLD0_SHIFT, MAX22200_CFG_CH_0, false}) +#define MAX22200_HFS0_MASK 0x80000000 +#define MAX22200_HFS0_SHIFT 31 +#define MAX22200_HFS0_FIELD ((RegisterField) {MAX22200_HFS0_MASK, MAX22200_HFS0_SHIFT, MAX22200_CFG_CH_0, false}) +#define MAX22200_HHF_EN1_MASK 0x00000001 +#define MAX22200_HHF_EN1_SHIFT 0 +#define MAX22200_HHF_EN1_FIELD ((RegisterField) {MAX22200_HHF_EN1_MASK, MAX22200_HHF_EN1_SHIFT, MAX22200_CFG_CH_1, false}) +#define MAX22200_DPM_EN1_MASK 0x00000002 +#define MAX22200_DPM_EN1_SHIFT 1 +#define MAX22200_DPM_EN1_FIELD ((RegisterField) {MAX22200_DPM_EN1_MASK, MAX22200_DPM_EN1_SHIFT, MAX22200_CFG_CH_1, false}) +#define MAX22200_OL_EN1_MASK 0x00000004 +#define MAX22200_OL_EN1_SHIFT 2 +#define MAX22200_OL_EN1_FIELD ((RegisterField) {MAX22200_OL_EN1_MASK, MAX22200_OL_EN1_SHIFT, MAX22200_CFG_CH_1, false}) +#define MAX22200_SRC1_MASK 0x00000008 +#define MAX22200_SRC1_SHIFT 3 +#define MAX22200_SRC1_FIELD ((RegisterField) {MAX22200_SRC1_MASK, MAX22200_SRC1_SHIFT, MAX22200_CFG_CH_1, false}) +#define MAX22200_FREQ_CFG1_MASK 0x00000030 +#define MAX22200_FREQ_CFG1_SHIFT 4 +#define MAX22200_FREQ_CFG1_FIELD ((RegisterField) {MAX22200_FREQ_CFG1_MASK, MAX22200_FREQ_CFG1_SHIFT, MAX22200_CFG_CH_1, false}) +#define MAX22200_HSNLS1_MASK 0x00000040 +#define MAX22200_HSNLS1_SHIFT 6 +#define MAX22200_HSNLS1_FIELD ((RegisterField) {MAX22200_HSNLS1_MASK, MAX22200_HSNLS1_SHIFT, MAX22200_CFG_CH_1, false}) +#define MAX22200_VDRNCDR1_MASK 0x00000080 +#define MAX22200_VDRNCDR1_SHIFT 7 +#define MAX22200_VDRNCDR1_FIELD ((RegisterField) {MAX22200_VDRNCDR1_MASK, MAX22200_VDRNCDR1_SHIFT, MAX22200_CFG_CH_1, false}) +#define MAX22200_HIT_T1_MASK 0x0000FF00 +#define MAX22200_HIT_T1_SHIFT 8 +#define MAX22200_HIT_T1_FIELD ((RegisterField) {MAX22200_HIT_T1_MASK, MAX22200_HIT_T1_SHIFT, MAX22200_CFG_CH_1, false}) +#define MAX22200_HIT1_MASK 0x007F0000 +#define MAX22200_HIT1_SHIFT 16 +#define MAX22200_HIT1_FIELD ((RegisterField) {MAX22200_HIT1_MASK, MAX22200_HIT1_SHIFT, MAX22200_CFG_CH_1, false}) +#define MAX22200_TRGNSPI1_MASK 0x00800000 +#define MAX22200_TRGNSPI1_SHIFT 23 +#define MAX22200_TRGNSPI1_FIELD ((RegisterField) {MAX22200_TRGNSPI1_MASK, MAX22200_TRGNSPI1_SHIFT, MAX22200_CFG_CH_1, false}) +#define MAX22200_HOLD1_MASK 0x7F000000 +#define MAX22200_HOLD1_SHIFT 24 +#define MAX22200_HOLD1_FIELD ((RegisterField) {MAX22200_HOLD1_MASK, MAX22200_HOLD1_SHIFT, MAX22200_CFG_CH_1, false}) +#define MAX22200_HFS1_MASK 0x80000000 +#define MAX22200_HFS1_SHIFT 31 +#define MAX22200_HFS1_FIELD ((RegisterField) {MAX22200_HFS1_MASK, MAX22200_HFS1_SHIFT, MAX22200_CFG_CH_1, false}) +#define MAX22200_HHF_EN2_MASK 0x00000001 +#define MAX22200_HHF_EN2_SHIFT 0 +#define MAX22200_HHF_EN2_FIELD ((RegisterField) {MAX22200_HHF_EN2_MASK, MAX22200_HHF_EN2_SHIFT, MAX22200_CFG_CH_2, false}) +#define MAX22200_DPM_EN2_MASK 0x00000002 +#define MAX22200_DPM_EN2_SHIFT 1 +#define MAX22200_DPM_EN2_FIELD ((RegisterField) {MAX22200_DPM_EN2_MASK, MAX22200_DPM_EN2_SHIFT, MAX22200_CFG_CH_2, false}) +#define MAX22200_OL_EN2_MASK 0x00000004 +#define MAX22200_OL_EN2_SHIFT 2 +#define MAX22200_OL_EN2_FIELD ((RegisterField) {MAX22200_OL_EN2_MASK, MAX22200_OL_EN2_SHIFT, MAX22200_CFG_CH_2, false}) +#define MAX22200_SRC2_MASK 0x00000008 +#define MAX22200_SRC2_SHIFT 3 +#define MAX22200_SRC2_FIELD ((RegisterField) {MAX22200_SRC2_MASK, MAX22200_SRC2_SHIFT, MAX22200_CFG_CH_2, false}) +#define MAX22200_FREQ_CFG2_MASK 0x00000030 +#define MAX22200_FREQ_CFG2_SHIFT 4 +#define MAX22200_FREQ_CFG2_FIELD ((RegisterField) {MAX22200_FREQ_CFG2_MASK, MAX22200_FREQ_CFG2_SHIFT, MAX22200_CFG_CH_2, false}) +#define MAX22200_HSNLS2_MASK 0x00000040 +#define MAX22200_HSNLS2_SHIFT 6 +#define MAX22200_HSNLS2_FIELD ((RegisterField) {MAX22200_HSNLS2_MASK, MAX22200_HSNLS2_SHIFT, MAX22200_CFG_CH_2, false}) +#define MAX22200_VDRNCDR2_MASK 0x00000080 +#define MAX22200_VDRNCDR2_SHIFT 7 +#define MAX22200_VDRNCDR2_FIELD ((RegisterField) {MAX22200_VDRNCDR2_MASK, MAX22200_VDRNCDR2_SHIFT, MAX22200_CFG_CH_2, false}) +#define MAX22200_HIT_T2_MASK 0x0000FF00 +#define MAX22200_HIT_T2_SHIFT 8 +#define MAX22200_HIT_T2_FIELD ((RegisterField) {MAX22200_HIT_T2_MASK, MAX22200_HIT_T2_SHIFT, MAX22200_CFG_CH_2, false}) +#define MAX22200_HIT2_MASK 0x007F0000 +#define MAX22200_HIT2_SHIFT 16 +#define MAX22200_HIT2_FIELD ((RegisterField) {MAX22200_HIT2_MASK, MAX22200_HIT2_SHIFT, MAX22200_CFG_CH_2, false}) +#define MAX22200_TRGNSPI2_MASK 0x00800000 +#define MAX22200_TRGNSPI2_SHIFT 23 +#define MAX22200_TRGNSPI2_FIELD ((RegisterField) {MAX22200_TRGNSPI2_MASK, MAX22200_TRGNSPI2_SHIFT, MAX22200_CFG_CH_2, false}) +#define MAX22200_HOLD2_MASK 0x7F000000 +#define MAX22200_HOLD2_SHIFT 24 +#define MAX22200_HOLD2_FIELD ((RegisterField) {MAX22200_HOLD2_MASK, MAX22200_HOLD2_SHIFT, MAX22200_CFG_CH_2, false}) +#define MAX22200_HFS2_MASK 0x80000000 +#define MAX22200_HFS2_SHIFT 31 +#define MAX22200_HFS2_FIELD ((RegisterField) {MAX22200_HFS2_MASK, MAX22200_HFS2_SHIFT, MAX22200_CFG_CH_2, false}) +#define MAX22200_HHF_EN3_MASK 0x00000001 +#define MAX22200_HHF_EN3_SHIFT 0 +#define MAX22200_HHF_EN3_FIELD ((RegisterField) {MAX22200_HHF_EN3_MASK, MAX22200_HHF_EN3_SHIFT, MAX22200_CFG_CH_3, false}) +#define MAX22200_DPM_EN3_MASK 0x00000002 +#define MAX22200_DPM_EN3_SHIFT 1 +#define MAX22200_DPM_EN3_FIELD ((RegisterField) {MAX22200_DPM_EN3_MASK, MAX22200_DPM_EN3_SHIFT, MAX22200_CFG_CH_3, false}) +#define MAX22200_OL_EN3_MASK 0x00000004 +#define MAX22200_OL_EN3_SHIFT 2 +#define MAX22200_OL_EN3_FIELD ((RegisterField) {MAX22200_OL_EN3_MASK, MAX22200_OL_EN3_SHIFT, MAX22200_CFG_CH_3, false}) +#define MAX22200_SRC3_MASK 0x00000008 +#define MAX22200_SRC3_SHIFT 3 +#define MAX22200_SRC3_FIELD ((RegisterField) {MAX22200_SRC3_MASK, MAX22200_SRC3_SHIFT, MAX22200_CFG_CH_3, false}) +#define MAX22200_FREQ_CFG3_MASK 0x00000030 +#define MAX22200_FREQ_CFG3_SHIFT 4 +#define MAX22200_FREQ_CFG3_FIELD ((RegisterField) {MAX22200_FREQ_CFG3_MASK, MAX22200_FREQ_CFG3_SHIFT, MAX22200_CFG_CH_3, false}) +#define MAX22200_HSNLS3_MASK 0x00000040 +#define MAX22200_HSNLS3_SHIFT 6 +#define MAX22200_HSNLS3_FIELD ((RegisterField) {MAX22200_HSNLS3_MASK, MAX22200_HSNLS3_SHIFT, MAX22200_CFG_CH_3, false}) +#define MAX22200_VDRNCDR3_MASK 0x00000080 +#define MAX22200_VDRNCDR3_SHIFT 7 +#define MAX22200_VDRNCDR3_FIELD ((RegisterField) {MAX22200_VDRNCDR3_MASK, MAX22200_VDRNCDR3_SHIFT, MAX22200_CFG_CH_3, false}) +#define MAX22200_HIT_T3_MASK 0x0000FF00 +#define MAX22200_HIT_T3_SHIFT 8 +#define MAX22200_HIT_T3_FIELD ((RegisterField) {MAX22200_HIT_T3_MASK, MAX22200_HIT_T3_SHIFT, MAX22200_CFG_CH_3, false}) +#define MAX22200_HIT3_MASK 0x007F0000 +#define MAX22200_HIT3_SHIFT 16 +#define MAX22200_HIT3_FIELD ((RegisterField) {MAX22200_HIT3_MASK, MAX22200_HIT3_SHIFT, MAX22200_CFG_CH_3, false}) +#define MAX22200_TRGNSPI3_MASK 0x00800000 +#define MAX22200_TRGNSPI3_SHIFT 23 +#define MAX22200_TRGNSPI3_FIELD ((RegisterField) {MAX22200_TRGNSPI3_MASK, MAX22200_TRGNSPI3_SHIFT, MAX22200_CFG_CH_3, false}) +#define MAX22200_HOLD3_MASK 0x7F000000 +#define MAX22200_HOLD3_SHIFT 24 +#define MAX22200_HOLD3_FIELD ((RegisterField) {MAX22200_HOLD3_MASK, MAX22200_HOLD3_SHIFT, MAX22200_CFG_CH_3, false}) +#define MAX22200_HFS3_MASK 0x80000000 +#define MAX22200_HFS3_SHIFT 31 +#define MAX22200_HFS3_FIELD ((RegisterField) {MAX22200_HFS3_MASK, MAX22200_HFS3_SHIFT, MAX22200_CFG_CH_3, false}) +#define MAX22200_HHF_EN4_MASK 0x00000001 +#define MAX22200_HHF_EN4_SHIFT 0 +#define MAX22200_HHF_EN4_FIELD ((RegisterField) {MAX22200_HHF_EN4_MASK, MAX22200_HHF_EN4_SHIFT, MAX22200_CFG_CH_4, false}) +#define MAX22200_DPM_EN4_MASK 0x00000002 +#define MAX22200_DPM_EN4_SHIFT 1 +#define MAX22200_DPM_EN4_FIELD ((RegisterField) {MAX22200_DPM_EN4_MASK, MAX22200_DPM_EN4_SHIFT, MAX22200_CFG_CH_4, false}) +#define MAX22200_OL_EN4_MASK 0x00000004 +#define MAX22200_OL_EN4_SHIFT 2 +#define MAX22200_OL_EN4_FIELD ((RegisterField) {MAX22200_OL_EN4_MASK, MAX22200_OL_EN4_SHIFT, MAX22200_CFG_CH_4, false}) +#define MAX22200_SRC4_MASK 0x00000008 +#define MAX22200_SRC4_SHIFT 3 +#define MAX22200_SRC4_FIELD ((RegisterField) {MAX22200_SRC4_MASK, MAX22200_SRC4_SHIFT, MAX22200_CFG_CH_4, false}) +#define MAX22200_FREQ_CFG4_MASK 0x00000030 +#define MAX22200_FREQ_CFG4_SHIFT 4 +#define MAX22200_FREQ_CFG4_FIELD ((RegisterField) {MAX22200_FREQ_CFG4_MASK, MAX22200_FREQ_CFG4_SHIFT, MAX22200_CFG_CH_4, false}) +#define MAX22200_HSNLS4_MASK 0x00000040 +#define MAX22200_HSNLS4_SHIFT 6 +#define MAX22200_HSNLS4_FIELD ((RegisterField) {MAX22200_HSNLS4_MASK, MAX22200_HSNLS4_SHIFT, MAX22200_CFG_CH_4, false}) +#define MAX22200_VDRNCDR4_MASK 0x00000080 +#define MAX22200_VDRNCDR4_SHIFT 7 +#define MAX22200_VDRNCDR4_FIELD ((RegisterField) {MAX22200_VDRNCDR4_MASK, MAX22200_VDRNCDR4_SHIFT, MAX22200_CFG_CH_4, false}) +#define MAX22200_HIT_T4_MASK 0x0000FF00 +#define MAX22200_HIT_T4_SHIFT 8 +#define MAX22200_HIT_T4_FIELD ((RegisterField) {MAX22200_HIT_T4_MASK, MAX22200_HIT_T4_SHIFT, MAX22200_CFG_CH_4, false}) +#define MAX22200_HIT4_MASK 0x007F0000 +#define MAX22200_HIT4_SHIFT 16 +#define MAX22200_HIT4_FIELD ((RegisterField) {MAX22200_HIT4_MASK, MAX22200_HIT4_SHIFT, MAX22200_CFG_CH_4, false}) +#define MAX22200_TRGNSPI4_MASK 0x00800000 +#define MAX22200_TRGNSPI4_SHIFT 23 +#define MAX22200_TRGNSPI4_FIELD ((RegisterField) {MAX22200_TRGNSPI4_MASK, MAX22200_TRGNSPI4_SHIFT, MAX22200_CFG_CH_4, false}) +#define MAX22200_HOLD4_MASK 0x7F000000 +#define MAX22200_HOLD4_SHIFT 24 +#define MAX22200_HOLD4_FIELD ((RegisterField) {MAX22200_HOLD4_MASK, MAX22200_HOLD4_SHIFT, MAX22200_CFG_CH_4, false}) +#define MAX22200_HFS4_MASK 0x80000000 +#define MAX22200_HFS4_SHIFT 31 +#define MAX22200_HFS4_FIELD ((RegisterField) {MAX22200_HFS4_MASK, MAX22200_HFS4_SHIFT, MAX22200_CFG_CH_4, false}) +#define MAX22200_HHF_EN5_MASK 0x00000001 +#define MAX22200_HHF_EN5_SHIFT 0 +#define MAX22200_HHF_EN5_FIELD ((RegisterField) {MAX22200_HHF_EN5_MASK, MAX22200_HHF_EN5_SHIFT, MAX22200_CFG_CH_5, false}) +#define MAX22200_DPM_EN5_MASK 0x00000002 +#define MAX22200_DPM_EN5_SHIFT 1 +#define MAX22200_DPM_EN5_FIELD ((RegisterField) {MAX22200_DPM_EN5_MASK, MAX22200_DPM_EN5_SHIFT, MAX22200_CFG_CH_5, false}) +#define MAX22200_OL_EN5_MASK 0x00000004 +#define MAX22200_OL_EN5_SHIFT 2 +#define MAX22200_OL_EN5_FIELD ((RegisterField) {MAX22200_OL_EN5_MASK, MAX22200_OL_EN5_SHIFT, MAX22200_CFG_CH_5, false}) +#define MAX22200_SRC5_MASK 0x00000008 +#define MAX22200_SRC5_SHIFT 3 +#define MAX22200_SRC5_FIELD ((RegisterField) {MAX22200_SRC5_MASK, MAX22200_SRC5_SHIFT, MAX22200_CFG_CH_5, false}) +#define MAX22200_FREQ_CFG5_MASK 0x00000030 +#define MAX22200_FREQ_CFG5_SHIFT 4 +#define MAX22200_FREQ_CFG5_FIELD ((RegisterField) {MAX22200_FREQ_CFG5_MASK, MAX22200_FREQ_CFG5_SHIFT, MAX22200_CFG_CH_5, false}) +#define MAX22200_HSNLS5_MASK 0x00000040 +#define MAX22200_HSNLS5_SHIFT 6 +#define MAX22200_HSNLS5_FIELD ((RegisterField) {MAX22200_HSNLS5_MASK, MAX22200_HSNLS5_SHIFT, MAX22200_CFG_CH_5, false}) +#define MAX22200_VDRNCDR5_MASK 0x00000080 +#define MAX22200_VDRNCDR5_SHIFT 7 +#define MAX22200_VDRNCDR5_FIELD ((RegisterField) {MAX22200_VDRNCDR5_MASK, MAX22200_VDRNCDR5_SHIFT, MAX22200_CFG_CH_5, false}) +#define MAX22200_HIT_T5_MASK 0x0000FF00 +#define MAX22200_HIT_T5_SHIFT 8 +#define MAX22200_HIT_T5_FIELD ((RegisterField) {MAX22200_HIT_T5_MASK, MAX22200_HIT_T5_SHIFT, MAX22200_CFG_CH_5, false}) +#define MAX22200_HIT5_MASK 0x007F0000 +#define MAX22200_HIT5_SHIFT 16 +#define MAX22200_HIT5_FIELD ((RegisterField) {MAX22200_HIT5_MASK, MAX22200_HIT5_SHIFT, MAX22200_CFG_CH_5, false}) +#define MAX22200_TRGNSPI5_MASK 0x00800000 +#define MAX22200_TRGNSPI5_SHIFT 23 +#define MAX22200_TRGNSPI5_FIELD ((RegisterField) {MAX22200_TRGNSPI5_MASK, MAX22200_TRGNSPI5_SHIFT, MAX22200_CFG_CH_5, false}) +#define MAX22200_HOLD5_MASK 0x7F000000 +#define MAX22200_HOLD5_SHIFT 24 +#define MAX22200_HOLD5_FIELD ((RegisterField) {MAX22200_HOLD5_MASK, MAX22200_HOLD5_SHIFT, MAX22200_CFG_CH_5, false}) +#define MAX22200_HFS5_MASK 0x80000000 +#define MAX22200_HFS5_SHIFT 31 +#define MAX22200_HFS5_FIELD ((RegisterField) {MAX22200_HFS5_MASK, MAX22200_HFS5_SHIFT, MAX22200_CFG_CH_5, false}) +#define MAX22200_HHF_EN6_MASK 0x00000001 +#define MAX22200_HHF_EN6_SHIFT 0 +#define MAX22200_HHF_EN6_FIELD ((RegisterField) {MAX22200_HHF_EN6_MASK, MAX22200_HHF_EN6_SHIFT, MAX22200_CFG_CH_6, false}) +#define MAX22200_DPM_EN6_MASK 0x00000002 +#define MAX22200_DPM_EN6_SHIFT 1 +#define MAX22200_DPM_EN6_FIELD ((RegisterField) {MAX22200_DPM_EN6_MASK, MAX22200_DPM_EN6_SHIFT, MAX22200_CFG_CH_6, false}) +#define MAX22200_OL_EN6_MASK 0x00000004 +#define MAX22200_OL_EN6_SHIFT 2 +#define MAX22200_OL_EN6_FIELD ((RegisterField) {MAX22200_OL_EN6_MASK, MAX22200_OL_EN6_SHIFT, MAX22200_CFG_CH_6, false}) +#define MAX22200_SRC6_MASK 0x00000008 +#define MAX22200_SRC6_SHIFT 3 +#define MAX22200_SRC6_FIELD ((RegisterField) {MAX22200_SRC6_MASK, MAX22200_SRC6_SHIFT, MAX22200_CFG_CH_6, false}) +#define MAX22200_FREQ_CFG6_MASK 0x00000030 +#define MAX22200_FREQ_CFG6_SHIFT 4 +#define MAX22200_FREQ_CFG6_FIELD ((RegisterField) {MAX22200_FREQ_CFG6_MASK, MAX22200_FREQ_CFG6_SHIFT, MAX22200_CFG_CH_6, false}) +#define MAX22200_HSNLS6_MASK 0x00000040 +#define MAX22200_HSNLS6_SHIFT 6 +#define MAX22200_HSNLS6_FIELD ((RegisterField) {MAX22200_HSNLS6_MASK, MAX22200_HSNLS6_SHIFT, MAX22200_CFG_CH_6, false}) +#define MAX22200_VDRNCDR6_MASK 0x00000080 +#define MAX22200_VDRNCDR6_SHIFT 7 +#define MAX22200_VDRNCDR6_FIELD ((RegisterField) {MAX22200_VDRNCDR6_MASK, MAX22200_VDRNCDR6_SHIFT, MAX22200_CFG_CH_6, false}) +#define MAX22200_HIT_T6_MASK 0x0000FF00 +#define MAX22200_HIT_T6_SHIFT 8 +#define MAX22200_HIT_T6_FIELD ((RegisterField) {MAX22200_HIT_T6_MASK, MAX22200_HIT_T6_SHIFT, MAX22200_CFG_CH_6, false}) +#define MAX22200_HIT6_MASK 0x007F0000 +#define MAX22200_HIT6_SHIFT 16 +#define MAX22200_HIT6_FIELD ((RegisterField) {MAX22200_HIT6_MASK, MAX22200_HIT6_SHIFT, MAX22200_CFG_CH_6, false}) +#define MAX22200_TRGNSPI6_MASK 0x00800000 +#define MAX22200_TRGNSPI6_SHIFT 23 +#define MAX22200_TRGNSPI6_FIELD ((RegisterField) {MAX22200_TRGNSPI6_MASK, MAX22200_TRGNSPI6_SHIFT, MAX22200_CFG_CH_6, false}) +#define MAX22200_HOLD6_MASK 0x7F000000 +#define MAX22200_HOLD6_SHIFT 24 +#define MAX22200_HOLD6_FIELD ((RegisterField) {MAX22200_HOLD6_MASK, MAX22200_HOLD6_SHIFT, MAX22200_CFG_CH_6, false}) +#define MAX22200_HFS6_MASK 0x80000000 +#define MAX22200_HFS6_SHIFT 31 +#define MAX22200_HFS6_FIELD ((RegisterField) {MAX22200_HFS6_MASK, MAX22200_HFS6_SHIFT, MAX22200_CFG_CH_6, false}) +#define MAX22200_HHF_EN7_MASK 0x00000001 +#define MAX22200_HHF_EN7_SHIFT 0 +#define MAX22200_HHF_EN7_FIELD ((RegisterField) {MAX22200_HHF_EN7_MASK, MAX22200_HHF_EN7_SHIFT, MAX22200_CFG_CH_7, false}) +#define MAX22200_DPM_EN7_MASK 0x00000002 +#define MAX22200_DPM_EN7_SHIFT 1 +#define MAX22200_DPM_EN7_FIELD ((RegisterField) {MAX22200_DPM_EN7_MASK, MAX22200_DPM_EN7_SHIFT, MAX22200_CFG_CH_7, false}) +#define MAX22200_OL_EN7_MASK 0x00000004 +#define MAX22200_OL_EN7_SHIFT 2 +#define MAX22200_OL_EN7_FIELD ((RegisterField) {MAX22200_OL_EN7_MASK, MAX22200_OL_EN7_SHIFT, MAX22200_CFG_CH_7, false}) +#define MAX22200_SRC7_MASK 0x00000008 +#define MAX22200_SRC7_SHIFT 3 +#define MAX22200_SRC7_FIELD ((RegisterField) {MAX22200_SRC7_MASK, MAX22200_SRC7_SHIFT, MAX22200_CFG_CH_7, false}) +#define MAX22200_FREQ_CFG7_MASK 0x00000030 +#define MAX22200_FREQ_CFG7_SHIFT 4 +#define MAX22200_FREQ_CFG7_FIELD ((RegisterField) {MAX22200_FREQ_CFG7_MASK, MAX22200_FREQ_CFG7_SHIFT, MAX22200_CFG_CH_7, false}) +#define MAX22200_HSNLS7_MASK 0x00000040 +#define MAX22200_HSNLS7_SHIFT 6 +#define MAX22200_HSNLS7_FIELD ((RegisterField) {MAX22200_HSNLS7_MASK, MAX22200_HSNLS7_SHIFT, MAX22200_CFG_CH_7, false}) +#define MAX22200_VDRNCDR7_MASK 0x00000080 +#define MAX22200_VDRNCDR7_SHIFT 7 +#define MAX22200_VDRNCDR7_FIELD ((RegisterField) {MAX22200_VDRNCDR7_MASK, MAX22200_VDRNCDR7_SHIFT, MAX22200_CFG_CH_7, false}) +#define MAX22200_HIT_T7_MASK 0x0000FF00 +#define MAX22200_HIT_T7_SHIFT 8 +#define MAX22200_HIT_T7_FIELD ((RegisterField) {MAX22200_HIT_T7_MASK, MAX22200_HIT_T7_SHIFT, MAX22200_CFG_CH_7, false}) +#define MAX22200_HIT7_MASK 0x007F0000 +#define MAX22200_HIT7_SHIFT 16 +#define MAX22200_HIT7_FIELD ((RegisterField) {MAX22200_HIT7_MASK, MAX22200_HIT7_SHIFT, MAX22200_CFG_CH_7, false}) +#define MAX22200_TRGNSPI7_MASK 0x00800000 +#define MAX22200_TRGNSPI7_SHIFT 23 +#define MAX22200_TRGNSPI7_FIELD ((RegisterField) {MAX22200_TRGNSPI7_MASK, MAX22200_TRGNSPI7_SHIFT, MAX22200_CFG_CH_7, false}) +#define MAX22200_HOLD7_MASK 0x7F000000 +#define MAX22200_HOLD7_SHIFT 24 +#define MAX22200_HOLD7_FIELD ((RegisterField) {MAX22200_HOLD7_MASK, MAX22200_HOLD7_SHIFT, MAX22200_CFG_CH_7, false}) +#define MAX22200_HFS7_MASK 0x80000000 +#define MAX22200_HFS7_SHIFT 31 +#define MAX22200_HFS7_FIELD ((RegisterField) {MAX22200_HFS7_MASK, MAX22200_HFS7_SHIFT, MAX22200_CFG_CH_7, false}) +//#define MAX22200_DPM_MASK 0x000000FF +//#define MAX22200_DPM_SHIFT 0 +//#define MAX22200_DPM_FIELD ((RegisterField) {MAX22200_DPM_MASK, MAX22200_DPM_SHIFT, MAX22200_FAULT, false}) +//#define MAX22200_OLF_MASK 0x0000FF00 +//#define MAX22200_OLF_SHIFT 8 +//#define MAX22200_OLF_FIELD ((RegisterField) {MAX22200_OLF_MASK, MAX22200_OLF_SHIFT, MAX22200_FAULT, false}) +//#define MAX22200_HHF_MASK 0x00FF0000 +//#define MAX22200_HHF_SHIFT 16 +//#define MAX22200_HHF_FIELD ((RegisterField) {MAX22200_HHF_MASK, MAX22200_HHF_SHIFT, MAX22200_FAULT, false}) +//#define MAX22200_OCP_MASK 0xFF000000 +//#define MAX22200_OCP_SHIFT 24 +//#define MAX22200_OCP_FIELD ((RegisterField) {MAX22200_OCP_MASK, MAX22200_OCP_SHIFT, MAX22200_FAULT, false}) +#define MAX22200_DPM_CFG0_IPTH_MASK 0x0000000F +#define MAX22200_DPM_CFG0_IPTH_SHIFT 0 +#define MAX22200_DPM_CFG0_IPTH_FIELD ((RegisterField) {MAX22200_DPM_CFG0_IPTH_MASK, MAX22200_DPM_CFG0_IPTH_SHIFT, MAX22200_CFG_DPM, false}) +#define MAX22200_DPM_CFG0_T_MASK 0x000000F0 +#define MAX22200_DPM_CFG0_T_SHIFT 4 +#define MAX22200_DPM_CFG0_T_FIELD ((RegisterField) {MAX22200_DPM_CFG0_T_MASK, MAX22200_DPM_CFG0_T_SHIFT, MAX22200_CFG_DPM, false}) +#define MAX22200_DPM_CFG1_ISTART_MASK 0x00007F00 +#define MAX22200_DPM_CFG1_ISTART_SHIFT 8 +#define MAX22200_DPM_CFG1_ISTART_FIELD ((RegisterField) {MAX22200_DPM_CFG1_ISTART_MASK, MAX22200_DPM_CFG1_ISTART_SHIFT, MAX22200_CFG_DPM, false}) +//#define MAX22200_8BITN32BITS_MASK 0x00000001 +//#define MAX22200_8BITN32BITS_SHIFT 0 +//#define MAX22200_8BITN32BITS_FIELD ((RegisterField) {MAX22200_8BITN32BITS_MASK, MAX22200_8BITN32BITS_SHIFT, MAX22200_CMDREG, false}) +//#define MAX22200_A_BNK_MASK 0x0000007E +//#define MAX22200_A_BNK_SHIFT 1 +//#define MAX22200_A_BNK_FIELD ((RegisterField) {MAX22200_A_BNK_MASK, MAX22200_A_BNK_SHIFT, MAX22200_CMDREG, false}) +//#define MAX22200_RBW_MASK 0x00000080 +//#define MAX22200_RBW_SHIFT 1 +//#define MAX22200_RBW_FIELD ((RegisterField) {MAX22200_RBW_MASK, MAX22200_RBW_SHIFT, MAX22200_CMDREG, false}) + +#endif diff --git a/firmware/lib/tmc/ic/MAX22200/MISO_GND.jpg b/firmware/lib/tmc/ic/MAX22200/MISO_GND.jpg new file mode 100755 index 0000000000000000000000000000000000000000..8f386c3af4c28fec8eef6f1c960fb2a517495f31 GIT binary patch literal 145577 zcmd@5X;@QP6gG&a%DGS}K|rODDil$sl*&*FgenyW5D^5zAf!rV3?V8qCplH+fPhG$ z280x(R1g_LWJn?e5*2VDVw6z`Ap!yd89_2|l9N7m_x--x{j2--eV+T{2KJL5IXT&D z@3r6cu6M1Y|DgYf_}=^QvBQXOzWD}G2>&7U0>nYYvTwir`VYUB!~ZK*uUN5s`HJsW zty;Ny?RRU}8hmG9ux`E4_v_YgSZ`qPz3KNGj5nH?n5;E4+hn?NlhH<#jbCr_%`*5q z%U7&fv0}}}bq4D;{@;G-pCUG_{&vf<$IHI4LVUa7n`Ilm(RUy$5r}VAz_a~2;s5>h z&A0FzSFT#U<~sxU0><}%$z?=|0S;hRqmqn#Yty%hN*Efh||C?F= z!?ORAT^nG#zFoe2+45Ci?fT~1RCp}guzbZ&yH^_h=D+HX3&vJ^{#w29K*7EGXKS|Y z4Un6hx%mD&)9p@U){3vD{jZk&Uo-6Q|Bo#DABO!;yM_^Kmwf|o-m(n{PlWE&{hXbM z|Gyl!othB-UK{`CIOg-~ijDsNZ{yC_3#<_i8}CH_X`165hS+&O2eGq!#3OdZ!^`eJ z)11V~MaxphvDuwd5l_Q*mUsVbnzQr2Z~xbE{Cx=`Y}ekyvERgg{nGzo+=B1+|GMt~ zH}5N;G$phLzN`4?S<-<5&V zeL+R`ei5A}3sc$P={Q#xMHqI=N_r($3I%*+0jpqY)$o8H@d!+^m^n*O2uoshaPd2_MI)hDOIRPxTBL%mN|ukp0i^YNB;#B zfqyg}H?{LNIg30HbFId2Jo|GXxxHOsYlA5cGD53ej7}-D{>Ki@BHep>(1X);W3~dA-A1QM48T^ z-zT!wS=AUGD_U}(-&#Xj0?bB7slcQj!6Ah$*q*I<1WEJWz8b62RcAHLiki@We!+Gh z=w^IKq$i+>os8Y*#5SHJx zIK^ix4vbXF0+8y$?S9Q1qExYeuO5-A6G{6mTt7}OGNx+MapT!Y_aOpJR(WU!q~Df0 zai7kxrlDyCaaIw3W+B_B#A#wv*_GJe_Yr5PafvI7r;){zlZ0+IbBeQ{dPE^9{ny21 zKmU49&w!z=4U5sBN4#Xk`?LW=g3!Xz4eF~EbA~k^(k{QKB2LzZ*ID&U5h7UY;$`BdA#d_Mf#9^y$a%zG(0=>Aj}LzfyVbG=>Qg`w2UtK!;o# zcPkC=?6t41Vp#Q9VZcc|_Et};nd0#9+i}z80huJxk<`a*{H>y*)pwrQ3F1M|Oc?>3 z@v%H5?%jC)9e4`$_#MYp4Rl8CsPFmW^`u`ycQ92t1owChP|SbP=n+V8w!uks^LruT zDED0*&eXy@-uhcRHS@EMdG_z5|WDTeanNe-k3;XTBqzE1+4|V8e=NbYfkHMACLC}Ns{EXBdiZMh z)A{?S$G0_8!0H;^6g^MUYCX~SM5ufrY9^?TIu@mfCIEO<-}0rwlhiA%2loga-puL| z@qi1a$pO*{Sisuw6g^@+pAxS}FhcbRZ1ic);j zNZJn@BJU;?FcdhLb z*UIKma~SplcVt*lI(O@4)W3&Oizs}-dwbLGE~;X>i0lgr^Y)a+-!_(X7sljG`ibZx znAUzemKG9kp4av!2{%0%uYM4K^Xa(lwQ(skA!i6Tc(UmE@Eeu^D`tuQC9U<^sB8g` ze?paS=7{P-_5e{{nN@NA&NV~Qcg{PhUGP@3MP0aVm5VGI_EL`Qh;rcU=FGmeK%-m~ zU8TIU#3-$FVwZcJs*%I1qUC9 z1kfUPKszsivA_o8O0?vF>5h`A{PFPI(u2qUasuh4{!$MAe0TkO(G-y@)THQyi-4f` z3g?HPk2tgg`~@-1aNH)V_0aI&aZBZU*P-x@Bg~X)m;H%}TZ#hJX1S-Ps`6D~8d=}C)kj8E&$QJENr=Y-D%&KJLTmEo1zN0d)`MA!6s|&{3R_tIl;SPiR^oncaGw#zPH>fTmvL10cQH9GjLUxDrz1`~=iHTA#KOcg^ z=PQ2k%pq;tx?8cxi#PInh&fFCjC1a7qxE#w530Puv&rB=tsWuP!iZV4_sHW=cQ=#C zQEG*#U01n+Oxf{LH^^sq3!o|&T!ah`87$ne2pKw|NBmu8)7;n8eSqKIausZ;Wd+}k z+*a-jwYv(3*wP*S8fv1b@V{QtR`s>%z#_@$*5=17RtxCW;JZ@ud(=?lbcAA$_)rAs zij;dQ(0M^;;(Mm<5GOw5dH<~Xr%;i6`@igYvpc?$9ejAhvp*s{uPm}HhcAy$-YiY6oNcMQokUP(o?&0> z?MenTbB#I%e5%9McKiJV2IFm6SASx~eHlvLF1oZ-G}Jqt;~=;nBxJB$MAXsNmm&R8 z*D`bOI=vE09E;2Nle$@{h^sbM>k(f(n@@8ps`=^hMP-NL;!Jvp^$vsQ{11uT^oY-^ zxo%S2OvIPHYfnSASr*4#wpgBa@Fob zp-_6N7<@%BhQ0}T+^wUSl>2*`m;3MW&Q|r4fKnB4N<)Rz-pXBrbnVL(-htdZsU7(_ zWk0G5#tkJh6QH9j9eu`Ik9Y<>2Sk=5&?>qsmy2nN;7z8xrD!SK+)qb7h^ZMZY+d3S zQ|s6Vhk{23WM;2KTHhoU^=vbF=)b%TDLl7Y%+gko>NW({EhWXc->71=DH3s2%m@iI z)lGINE7v223l%;@=q3+2Qk2;xZ~+WqEL2Y>sZ_gB>i@F+H>V_IbhQFI0x@;~c>#Ut z%v;B^2PM0GFF^@426Zqyz`tS?JBi{V*k^UU_=Rc-g}3)Kjv0Ep3&$QL^$#uR5fhZz z?T;h4EkQ(4+mNmw+W+BAQ9y6-^XEOuaY7pmSLMQbJx|mllyg)rvrxea;rOy$h)c6O z8b#QtI!T@?2rZ?n=1|yZ5G8q|N4Sch#nb0vw%OO3%GiG4Y`2tbD{@qk8zp)O$da-X z^@u<9h>V7*Yk|5Y2_@x2#gX{W(t9HNaB}HpbV}Dx%px)VtfS~l9$f{rkXieFs6;;O zPFg2M?{+V|*tyW5z-vMQwjQyJ{@(MlryQLZ)4tWBv4@a8wua!Fz7}hyWaRZcbNUzH z1p=)i34s9kesC z>EcfC2Tv!?`!JjxfqAR8ni7in1eww~?rZdj6~C(E?tgCa%vzM}?OYblI4Z8ZW&TS= z_7KU72;mjlJU!xD`rCeW=SQ_=s`A#zLm7E=00WM3eEVO_Zrv##t(xEwBa+hwPmDJ3 zwjC0%?h{}d23bl68N6-XQ>ZNUB;8AKWWq4V-46%lMOB|}dThsfThn;P6Z(bxYL=NW zFDY9G-VelBlT@!mE#)ltpOmg-M(3eukQ2yOC4gW`q5$fTNxMA}{dY;x(hu^}0v*hn ztxH`R9`dQlKQwH+3)(18>R9eJpr`tPtbOY~+%c<#u<;?6M{YVe*HjTe_V02+J?)L)nqe3TP|w*h$COeIo2_?a)}gF%Fy?>L5O zz_EU9dihKX`QPxU+>=k{sZ$yiK_o*@Moo9t9BUHfi)I>qSgI;zxrVFIBPhC#I&35t z>KRD13H|+O$<7Vb#BSQ8&8uvk@OAJpuvm{+2gt*x^oU%_827desI252@?=aui=!l9 zj0rA!gj8fr+7KD;wXVIPtM>q}9t9L|1vRE-cDOcjkg!NbH&~oLk8jf{Z zvMWGZ41NNbzzA~yTCMhF0?+*&AHTM_BN__M-!rX~k%2I6G_w(mnvjzJ@D*t1@<5ax z0XnCOl|Of;G;~h89ip#%p)uj=auB+^?*KgiuVHbD#4PVVb5A}y9cv$n1|_Wc!P8s@ z>sirTQFf%c8!)4>lTU5Jl{2zYeeWL1iXrce$U{n%K{J=zW+np^P6l^%e=AmLH~M_! zXDuE}I6(&J;Yf&=^5AYq-X@b<(;ye#J#tMq$CM<{BQ~IRq+w1DI)0IOwkskcy$fA9r|>sd zXf_t&mF?&kdW4Y-5>|)vmPdN0o4dAuoz)-m-i{^1tfo!4?PSh-BjyZ~+s#&^rZq!) z1o8CQt-q6xW$v9@p}UXz(f5&$rSgk_P;p6*@bZGw?VD&ozMyQ#YF8%l6{e6+II@K$ zib~aRCAWwo^*X|{Khht%`*|?BG!4vGEIMdTovu4LUa52%-Tb5}{IfLCMf%rIQRrO! z2%NA)Gw+=3N;+Jw$xl}dYByS8EVSqF%L&c}R`N+k?nnf-F}#7dy_z@QL01IsiTffmEBTmq}EbbN5BuCbbYvsZF(@nDZAdsmT-3a0=@BNRdk_yWcOdQ6I`r0kqP`ilH^Di3 z*)dxCE$1$LhW%@f4Ki-rEV&5o@u<$(`Dp)v|1aq_>&?ei`3@Wl^(u7#RI88OmA?kw zm!=l|TlJxu+u2P@i09b0_Bqm%yMyqpevkIB?i5|rBa8uHT8{{Vxj~X{37k{b$b;y) zob}iMzI);P%x=`ZWrsd!3QqU{PgBv;W|xsN_n2{yy~kr6@lbzqBE={op9S!3i8_Jt z6oe$(O(Z?)FFo2Wrv6qq|H7zvk^Ypvyz`?Tv2qBDcIhhnvHwSO+$q_!WyB6YsrEW` z5?+>O{Epf2^nu~76*0HQ<5KR^6?Zi|*@#f@U*FF=Y!_fF%mqEPBuI=`lYtsp{@WJV~=f1@J>AL00piwh_ zG(ke|he?c$tfSlSrKoYHVZgdl3d(8Bn z2Q#buVcB3&7^(Pz%YEw1t!L*Is4wBEv7Dn7_;D~>x1_S>E&E4&Ysx_+sxy1eaqpGT z@VE-bz|@o6puU2#-UDqh^4^)H-3V;*(|SBT|C9Jl=DtaoD3*7~bd}8Si7<;3#?m!UD(#4FnXG>K^G4 z39CJ0EU#~|yh?9%tHqjax%n@vaU^c3VYqyQbH}5b*9T;rhmtW5v0l@KEm`YNU2;9`kx=4Ni=$GGm#O#j1s<(D? z1f;E*8WqE&on!ak0!xPZNUQ4Fo9}eI+;`elyDE9#j-pf^Ojud|cu_+hXpTFX3&a63 zmZ}=#2CbaaE%A>)@W-NLBpi`HoLupV0>0_vt4&{4gAktGkiU;Q_1{YDs720FhZM>nNPq4mjsZzw4M)6Kk2J= z(j`8R@C>SF_BDZd99+f7F?(3XFngN^2?;Qjrivqs$H&tQo?Cv~`qOv~^Zl9rX^NN` zEZc~QO``%O*J)bIm+a}Pf^xqTS;|87Io4|01Pv*%Od|BO007vZ3T;_6_I6M>Au`lS z^oaQlekH9azjfNfhf{KuQEI}>0#1+kCmv|lCfj{3^YBRx*4=eCXiU|rdLs)6^{DGv zFZUyJTFq&*Th=ph)x%!c^LftYGmav7OWEODFELXTUdnJvX*IiS(^iabg&oXVF6$A7 zgd_5~XO^3sJ(AiB)IrX#>X5igVEQ=OVX%uVH0}agC=dpmR@;5f^N!uxJy~WDbChxp zlQ`6?O8ha{q!=TzCCCCTo z9Iz|sY@Q2?H(#kT$}Xst^lXm?*-A9Zie~S;d7wt#(X-*s^eeNHh4y*rkk+oA`*xP! zqBvan9ZU%Kt&$~>SvFvG)k5&$s;aP9<^ICPn$xt01rNg*{cqT*8vjF-Vs5L*aaP-_ zhBL|)NOf*)TF$uVDs#{8V*U4SH`OD~<;ZZJNWq>)<{xdT_rXcPr<)7l~DK4yHycPjjNal#<{-4C1Td3F$YAxia-CV zXexW|@i;!drn!GmZS93Fx~Q#XbEZU;Ioe7^d28X&ZHWsVtO}Tr?qTW?WB4|mNNuS= zr-a{~3QdgrAs?k`=4>WKssdvtPFx~2UIA^MFTGR}ub3*&V~(m4dNh6)JeMjyP~9qp z&??ANw+xrwiu&pArNJ)ncP1n^Yc2%BsodZr!tal%&&q5STeECmDMBJ# zKlDVyQlQU52Q2?YoQhGAhiR&?2t@I85(;JZ$edLf(#r?~ZFPt7L$;2I#M&-C3t^DxlmToeF z`jQJP3NmV0)1pH<&v0;#$-n05~uCMBh>_5Ur&&DY_1Q@t-MTFBQU z@{uBX@V_U%yS0B^q9CK({{(AKoy-{+hCFWravR?12i-H)EZ|NJj5eSJv%H4|E7nX&V=A~P+BE-f&(6^h;6eGEkvLj3j|72> z4b0!bhku;|xqG=I!i7Pf^mUX@lg2$_Rs_6w`5Iv(p*l>k|ZQ!%zxX# zs&4w;EpD$5lpo{RF?vG*&@`|#n4c(;5oZ_hA8bBO6;#DGAY(1unkIZr^=CV02 z;2=0;H|Cd3m7m)8(_lrt+%iiX(|a$)PqHpfl-#37q;Ci%RKRZ(Xj$YW=mrgLK}uFx z^cN`!C5G2)9a=TwRuO9RnbF*-P9*q-0$bP0&ETLO+T}JZ0ho^Gdn%O=?n#aq7M-yc z?;;#&j3ju-m(iDEF1x$Ts9<7HF5p71BkjOrv845K(KD*iXd3n@wE1xxra{8a^ z($#$rq-9a3S+fn31)oTUxBWni)^%rBb-_A%O6$RKvuj_599#dWt}9NsRm-}iEdY{5 zFsICDdoY%q8;|xUaIF~Wm7SOVHs@~bOn6g}4#)gV-Ai~j`BHkOL&uA{9f9NL&&+f= zJ+R7!P3m)zxVHoXb~ucUuBkShj|kBtcn&KC(V|7S+ud-;Madw~2uF&GF2s3p`gZL5 z6N+us06kD+EOo;HR8SOV2{#DoKmt2{(#ZN6F#m)@q;^SLpet3i<>wRC_^a#B%?8xm+S>5 zmtH|CxmWo2b4L3^_eO*tgcyRiF!a=D%~1daiiGd*nv=7%KZ^0$LPkEF?ifZogNfDiWUiVqGq4ihirrZtuZ~Sf(KT?Qn-V317-N zTJxnSLZK|6ry)C3sP)imh4%fgJ)*e%q{_DG;OyQrnq$Z}bEf@%1^l#E+Ph+G85z%viX7^SPnrid0_ z=seXqbC*Qd!@SCB^I~F@ciuZqE+pql&M3!`wsT?@+RvmsZdoHhI2;rVGG zcIHt|t!g!OTV;tzF^61wM8Uu6W^!&1-acMG;9wuq*k=iz(*49RM2$&4&N~`~6bPn6 zDBVRD>0Pu&ETOt4EalyY&#ve#SDRAzMlk+0J!1ul(V`2;H*j@IQ*DjD zJ?^-B8g*LkDn`q5U+zC0cE@bgrSX{cJULO;G=!OA9eb}woWEJc*%7P}rSesFf2u3N zJz6U{z8%=0zI>3QI9y-#`So(6;RsQ<=A@r}l^NNt7L&0fN@(P&s8q4g@6c2er*+<< zXPhlP&Ji((p3Dnt3B_Wo!kza;@de(j6TBAm2q&P%yOz4=5breig`Ljq1?C$<%nouo zXCUN1Zf5rFuEWts>k3f#@!|Kb+I4oXXvG(Kg*HTY8>jSg!qyU0?xY*BL9>B$=*ZAK zE$(6VSUD?Kw>PjDE|o5o`!cef-ot!zuN82S)}FpV9Qe@9{WKKuL;c+(?-l8sjlgqU za?4AJXH@Pax+q#FvKfJ7qhW#`Zj4=Nz}sCP`xE`GBcQ}S4WQ_fK!&3UPo6|+py=W2 z+*BP`o6^!|98f4~XVxdgWM0)Ha27zuT;!tR6@?vd)SU>ez=Sw=7|>7L(!EacnYZEV z7Hb*_tNLZ*P2sr6NuyvKeJwXLRRsZRL+!V1&jkV5{o--K`VXw?{W8IPkdN*n|58l? zH#OxG96-1?TZj{syYf)Z>a=U~;c3=`^oPmO^CfYq_u+6>2vhm*TswXq)-Z=@!;VwF z*+_CT_oK7)b(J%t#g@0=#D>K*r5<6iW;~gRaV{co09b>z;Xx_>-9JvbTl%W^j=#bi zi--F~CEVm5G}vFCBNdvL+-Fp;@ChR@m_c|J~M8!^N6_AsM0o! zN_=U>H+prW?gpD&SV_MFoTUz1@j6RRZ(Y?dO~D4ozw}E93VQM<@U0%vR7MpFFu_}9 zTy8XH!Ob+L8~wcy|4&C6Qc^X6mivieaN@6>!#R8@2w4-Fx?&VAbV9$-F%-}Bbw&&0 zS%38h)#1!T8p$x+GpoMp){Vf&2cE`1K9)~sX-yJ%j`z|%l{Y@$s`fFmd2Oas!Z%dS z)Qlsq#=cfypZjj~XEW=gT5xPjT|D~DS?liXqsqsllgqwj243+ok4gLl?Vy)>CKwJC z0>j&$74G@mC@laEP5&mM-`(d zT95rRReU0$QC#RQ>b6u{6iYrT0(U!+s$WF- zKhBfkP~w(|QMsaF0qQCDat8jX=vqpd(c{~a1dBR)or@kpFD(e-esl{mgO){T3mb5} z*Nkv=us7l7YT^K#3JhMo(V_4&|K<0Zcgnyeupvi#V)p#gs0+%+RHxiE>-!_PMD$tb z5Z|hWK!1ssSD3MG7Ru^sSW1sJDqK%(-$XUerrUdk1{DoE*+ay7B;Qdo$Nh9zk2tHN zPH5)t^g?E_DD!?~vZdjN*)2h%&HH^Wq*k5)hlW&aO@OA}&Z?C*ZzJDd17nF3XK#Pv zC4qsD#h%rU$sXa|3`XWP!Nvex;cQ?kq~haQYLf0Evp0=1Joj{omj9f(!|oSHS~6~r zNQ_A@6OOm#s@SRfx7Tncq*iyHa>W}D>RW@@uW33vlB^Sb@{R_VS#3NijX|!xgl*1u9U;l zNUNJQvw#-wy3`sx$c=l#@+(587TVw`@je>^wETMDDknJpQ{A1|*B3twdv2K9kGfhO z8%(c=+v0@U$_iRI(`(v|Bb4JPO52Xyg@(i!P?V(0V>r{-sQo$y{i@UQ+k;Dl%2Lx; zjF=u=qGuyznk-5>BnVfrAtFy3j)G)1x_oG(n)Olj+`{uWMPY@7a0ESQrW|lt${#j* zyC&FrzToyGPTato=k#lU?BQ0n@}YW_;_Nv3W&W~R$WXC;OT^WGFN6? zPg?%ACic|U@*LG<>hyfE$^D^7;%D%e7w;z_?w;nTH^gI=qv@iJt%n6qPkUs7ZmRZqVQ{|_|4AKH>JA2zMQ6EpVD&|74xb0R z&k=fr%P=fTZY6jqNcoEA6XP~l+X`F;$gs?;Mbg@5vsiOh!@qjFcANHnP>u^^RrZ=($oWrYL%cHJyFB_%-K$GzH0vI z!wt|=@hPLch}vZFX*7u1A-dX&l97$j8d!HRIb!cKRge#Q%w3$td_&sPw56`1HjOku z3=kb*_YDmPGs1~8TpjIZ9wv08m0b~pzl~S<>k)ZyeH!zN+H)L})0!kVp0L#JaCq2V zn?_tL{pn%PnM*kstHEi2qGJKl!JhN2ma&D$qA=0~nAnK`r6su7L^9q?I84kMj;O%1 z{0thzf!7RD;40W{oCm5$e4}MjIi=Z*;$i1mx}_@oPxU1eDIXxr64n-wAeBbdBNhMJ z*-Iv6ISw#_CKOEu!8cxzX*VWqzJYG_S~%06C^UyMf5W!{iteVD+%o*Gx~K&z)|oB%Fw^?2t5I5WZ}RpJ(BajL+ zh-+rSJ>erx0S~s(Bl>lSmkqH5(C6;GBCyd;k5HIQl{x8(AQQr|0Y?Tg>DiKdOUHa- znJlU=5>PZY{Q92It((@=$f0%glJmFdf4=xV-g{3`=O)q8k=`i``o+cm%3vEfv=~#L zmeeu8BcDfqyf%s#)4nyRsS#Xp3rhV}VPzT7ZCfW&)hx#N4iDejG3iHvyVbC`Gik14 za9IM{nnrRkYtKk2y+1Q6Xsy{g?&g&ZDeqMZ(iEReO7tqEh zU-+!Ey;OBk>n&Q_oO?9^h57rAN2OCa!5_q=WkE=4Hg5CaB)F^=>DDt9`SSo*3 z^Y>J01HLECB6nGWCtz{UQja+Lh^|MR@w-uE2j;JNk>422mtc{Q+o4!*&vVw1o^R4f zHR*%V#+~5`xRoSWZ<6k>R z+JaC^aG@6sykaY9nPO2r@4ahm={Vs6>j41v*DaNrA((d6r_Z$rm)$Vy|*Pd2!$?&!lnHE#0lUe>l#%%XsaN zTUc*sj1B%=Wkzq|q0Cbf`UlggVZld>+awubskB!Hsa|F45eHP&Xv?4MIv>|vZ^8ZAwnh85hACq{u2mPHMaj&FbrPIBRRN!>< zOU(I)#e`e**S1b;DOknLpP!$Znfir5{4Ss*3li8-&))IA^4a^!B<~Gr-Oqv@t2>D> z`Yo6BO5rXu-kLxEnOP#00v^1}^M~@V_TJ%w?m}x=D=Fkq)UY7DTq5V@IrBzD zMLKjqxX!%1YF<2dbe_zS=~VTpaM~4FBezi|^+2nKc$Mn2zxF@4r6AYIWPzW z>kT+;hiB|DGHRuoO!=g#g#a)kr>*G4782blxFxDAx9aqLNnz-{M)Gall_MZy67vJe zLfzOQTB$u!5u(P1HnX1`b!lIBqfWvcw;^UXf;E_J&ozm5hFSTHtWL+XeQz!}RR)}H za8LR;Ij$>1I;XPtNPR^at<;IY0s%%X6YqJYaGo55V@(t6b;@M=@9H=?dwl(!_x7AM zitTOyw|v9~R(_lnm%TZ?$$ncpt7cR#W8TphKn88B`)TS7G}v2iTq zodH=}Pq1h{LC~n)xvYm(C+waNx>8J_u{qxJyBI6wi!=`PVvX)zg>diF8P%2@;7sJ7 zW!wM8+hOq|JR_EhwPR^@!MikP&v9l0Ifc!u?#Q8V=g6c|Oz1OOD6uf5`6!uX7Z%}z zx78z_DE9AxqqE)o#8XSp+%r*nL|9ANqF*!nlP?wScbn;RMTIAZy{&wHh-B5ty3%Cs z#>>51dp3)ISv)Uz{ zel^q>!-G0^%VzHk-q0feDLOZd`_pW1<*s7LrLT2gWwj{nG8%f>6sN?q2PzmWa@>_ZZJ&vlHE!^G20YH{XPLHU+5?Wh%Ru zMT|~@O~s}c1z&(t`4sk1Wo~C!xTG`@K8)ENzS9jO9({gDzSg+0K`hXT*z-NwXgQ9N z{}i)jIL_DN?~(0GcjzqHUY}_geu-KhB<<4d(HOF-A?a;Fo^aEZ4^}narNyU%{cUU8e|aDpZVAk#tG5CTU=gi&9b4LYPUynUzSU zSh~gIx(<5^MJFn0bdK=<1LSchA>HquH_W?reg0xh3;E0W?5S5vmLD&F=vH!zBO|&& zdYjgAXXB@Tl4o ztE6xaq4CW+i7ax_a;$8Jjr!qB!8CZPCgc@J<`UO;)kz2KjGBDDL&~?|g`vTt#BPwU zELtZ10x{()Vj6pa%2oLtp~nnd+hbTU`>1OL;NU8)sD$$TY zuBf`CU$DR>=XXdPSmo%e+m$^J;VOACw9vtHiEpvCI@3QpY0P;Ka9U*F~)Q z>mf$MtD20y>hetM*BGsV``N$!_b{;vw9y7PE3&c{k%kzr28?0r$?z^-V{%QUl=~55 z=a3Q8i8p*UZuo6l&51$>xiGH#d<`pA7Tnsa3|Hfkm%kA4Va*XmTNb-cWV4|VTS7jp z@-i|luZu|eHPsTp?l@e-)*jDSaTOwPmSb#yR0kIQB!x4~)coC=Qy=LTB7%qduZpz4 zhg7_WB8TVYq8*c>g-YGR{NSAIFT&Y}YVdg&`nps0+7{BiZ@Y~jYg!D+++q3)+=1um z^g1i}fr1OD&Z{P+Lp5SgwGH*f%f=@y>eQN%`(C@TZQC-5L%?K{C+MnM)Xjq1-sZOu z7ri!~O!$8)FWCGRX`xt9*2ytXJ@@c}pOmROkT_*7ZpXlmnA=%H&Gn2RrmJoqD|qIB zxoas8Fn}SlX+;y)t|`on|e77l&Bcf#3*x2*$ZO*qmIIi@`bP&hJ0 zaV=aj3IF6DfWPy0s$2r|>>2JVX%OV7_9&a=esWm(0i!DdVULjI%Yu#KYu5eigWGt% zrB2P-L!iNMJouY@Wh`|f^~!&Rg4cz14^w=(!fXg`!@^h-{*93>yix5Vjvl4n&%2P6 zIX;)Sqc@r7QjASDsc0&&=e3NFSp%bR`R7|3kZnu7HdPcLe_Nc^OPe14F_birJMY6* zL*u|_gU~I--xncaW+SPeE~^b4!05U?F^TU}RCxGNklujZTa8I&n6K{GXl)Hdef zdh%uv&OZTJlq$n%U89scQNDt*U1w4REUh2k$C}np( zwEX;FrFa*G3rq?Z-fKObkLwW*yP-+qzR4eoIwCRz?Uo(?o@D z-7YW88-FAbpnDw{+r!;zB4lQ=;9X}5?XDL<^Rgp{H7?RXfRcRXwAS_AAHA0{_a%f) ziF`*2j+ZcIaiRWJ0JR%#+<*e$z_(sjG>LD^JIWJNj@)_ENC{J1YaFZL{qo@PyCxx= z*6AE<7^5{NoO|bFlg=#w5A9drF5)iqS*<*<)Io_Bhp%}~01RWmiSWt&^I43GjB z>`MCy#$%%E+_gYG;Z$5yYDEN+vVY{z=qZw_8!T}0ooDJ`6)}}NijGRm7=ie&hTU6V zAfNJYZgG{Y7~8~ zEUUxU?wP7(s=^@hx0nm*7b<6{u}zFnWs9b+r^Z!UVxzIbvAKDiz(qa+E=-wtBxQX4 zsPo8f>Mr|>fa$CTJ&tL&I5Dj(9whkJ5q{>Vua5b2?-(8Jc5uA!XB%`#^A$VRbLIP& z?rkldB5=k2Z{n)vann~?f7T=Hxeaew(BSQKxV@t7_wF&^8WkVK(G|IqsH2%)ZE)A% z%P0XR?m_?c@Ha!hoqqYYY$aC?b0;xFk%;^TZd{a;sMwW_*yPIDi)@~lI5$Mz&t#N$-w%5Rm`oL4@Tlv25}Js5tps*y2k^Tbw0%I!XyO;l zt!Da_Mki6@ONjwe!DNre=n=2C(@*xf2TfeRkvxz0fBZru9XTuX8 zIFrf`6qt5om#X++Igt|Dn>aE$v;W`0KT)pgqL;hVuzvkvz0X-0h55FADFx|`J|tE! zrX^f>juPn@o{P|9d=ifUhv+N=F+}N=XU1AwH6b^zyF1V$T-%-LJlJty& zZwq%8M3H|ydJ8?o5XH!)kmO>dts*-2qtN(dpZ2%f;j~OYM$m#(Rsk2uM2(*`s=Z>( zsk4bgp-QuV(x!b_15K7&M|b32VoUH%osVNHU{b>iPaPJCiL;}5873C@_Llh9DEYto z;!j>>!J988_T6)CJFpp(Fb7L= z$KitdPWmZ)IvaiLBeCiGQz*8-naO?ZI{#o=Yb>XUHS?aTt?cGANl8Z+JtgdEI7sN0 zyp4mJ0gB4fRrj+WWYyXm)Egrow7e0(4{IcFmEjqjkb+%DKXX37g`69Nr!pT89A_T;V$MO>qtB zQuryA0qi6m{>$9qYI=13K5pCbRE*{mSFKCpI1MbWGxo{JbgmyA97v%luUqscsQlsH zu#`a9So*IP$WlnMHB}yb3PzRv(Cor7Kh>AHEEr#M9?gvNHBr@SqNnJ6A}o;LW0zHk z+G0ge|3%DMMH6+FAzSxQ2D_$_K|bXB2;-}e@mU=tb3d>s(Nlx^)9oBkNS#72)8#9E z5~w0=d-94jy_r`8{$sWk*$hSC8Z`bu83;nZh(7);VU!UHrGa2mjxAdT{?u-y%~+) zucda*5BlrK6CSX@VzT}!{Fs&I^xB=DHQsQa&%#m>x)}Tn%*{&mA+_TKV zY)iP9bd=kS$-7B$7gmdqLcd*5bglK)(9?63j{QyZ7#RNy%>3uMec=QeH^WW_ z^G&#NbVZLiDPW5S1SU#Hcs;cd7cs+O1eeUJd8o|;%GDYd)nUiEsHM-(kthbV=3tg8TXf?Ar6~l_&=xW&H7(b-@#c%y6|D6~y!Xs}Wlm~Z#km;4yeq%uiQiB>ek8v7HCJad z`9YM-wEnG%P}26rhXH%2;1skf;*Rb^8O|@`$b;EPhj$Z0kBB#?yYUmreiT@htuZUx z+bgLnh{?J1Bnn+5b<>LE`xgeeXhwF}3JqzV*nx*(nlBGzzTyN+1eRT+?;ZqeU$|Fd zUGth=28WV*3Vw=PE3dkBERRm-SaRI`Tkh+0@N?ih#6jD(@gb*Pl5fYLrAOZri zOF|Ms0a>z37H)Douis|o!<;!YA3R5i2e|jX_j#Y^x4ov&L0}=Y>h${`diBmDsP)$# zp4b+4*tSS7jvKWvJZoZVOe3yEjKh=W?10hVBN)u&S?q(V%N%(u85%NBE|j#7_PVR% zpaySw1|Yv$t}VLMO%)@W7%xH>#ZlIYV7dij7u$LY(7Zk?^L)c?gYfBHIlb8%z8iM_ z%k=UHQg8aiJgs8}cI1S^&nea?4T0+5BOJl7Ppfr!>cwE(yT>(9 zJ3yR=^Zzw*;{TpN@&Ej9f726Cvi~I0U~38Q7>m@hrT#R0@`0UnJX6J%6 z3>SV>HG^xN>47QAQtcUFEAsw<-hqtO7N5F760*EKX_n^x60;dhRq2!!#}fp*GZMH? zpr!1bD9Q2=N91H_v*T~}$M(Jm&}HY!1hF!B*#QO^6nTsY?M8y#HPUh`p&;Zjcyk3k zXK;ue&`saRJyPTx6gyKdup7j0z;GNcHx+Y^8cl{fDT4VAlD#ZIdszV>dL^7!osq`A zv(!UaG;Hooh{N|cr;`e~3NB<-c&2gzxreP9ZG8>V@Rn27dCsAd?*)bC)e%F20G+1A zJPk4aTk$Im;tfX5vYA&R<wnx<=ycBxKq0zZ*C6F{3G>?XKMVuH{8uK`7 zV`X?>FxakxrPY6tqkZ_*FM*#zVI6MBOhB@#I}x->baou;fUtW%d0>}WNsH-#$GVQ? zHn{hj+_vBOoaR8a&Q+|tMUQ8A6)h9U(+k39??`MN4#t*MuB+Gz%iWP?PbgQ&X!KKRi zYt%{ph8y<{XO}w|cgbk^VI77|C`Rmr-&FNe%hEl%)v~KUnlPi3ILWFvlXa}l`eO+# zsXBR;H<[xFdF93FC!XEP$e+^Nv&fL`dsX3R9XPl=1Z$|&0VlC(3P_~41l$k4ka zf{ur~fl52Wv5$?{=FCD?F_Y_&-_u^pF4`r$zr%2KTfJsfzaiz_0J#k5XVh`KB945k z0^8xiV~u-c<2LTlTQ4dpvXuZTg}}=MW2l zHx2fhTyByB_VrugsqmLkxMOPP-@rT(&*c~FKn_^m7le)DC7$=}c5(Z$Y59}bHPND| z6m8f=42LHaKz_HXCt9C6GWdZc#dEr+f^Kla4?(i@mdwnp-QUwY{9e2#x8E}t{J9Yz zTE;mzb~7^3r)34`=ZG>KFOW3ioVo%uig{;;qy7002F*(l`-Inutu@EfwTb+fO#}Fe zu9nI?rQOTVyM-%Ka>k)uq;n;3)_l%Z3bcSJXw`QvH$5_NpQ^CYF6;#y)>OQFRhV>2 z@UlFm2f=fW4mATpdcGvv;RRI-hNK$!4z$~Zm1vDz(Jbs+-GPe)eW7U;`}QB;e=fXvKIpUv6RO9+zrcDxj2nFTZ2?CeVNbFAJ!mDU-1a6#B*q8{Q!2Kvv8hIE2erT z!=A5bNxPnIXjXHt0AH1T%aKyL0@nZbfQ`t7t@$Ia_JWrtR3=zlE^(#L95S&AvYehJ z@XJ4)X|tEL=gve(vGc`aUkpm` zH$LpK>~P$F&Czu0o|7FKuF)q;a6g>_{jWy}w9>Gle{!S|c#`o`dHj~)rQZk8v4kXh zdVGOB#(hJm(M4}kBbG~|-s`m&QhY+Diat%?dfc3-q?WZ-6(wqljTb)%rnddft|V9=P;rJaY+<+cZ$3jTO3|JFgVuzcyRW-i|G}I5POO< z@$-B)*a-hyVJBxMIkW+9itmosj?$8GIl#uheU%?tvokv!>YPBW5T5E^lQSyX_A1H? z+B^C_e{@oAHym3?l3%lTn8G;3DnrRL+YJXe`DryB8|e5+ahDynn@2Fu zlRM%>LMP8|nndTQU{=xFC|?C1RSmB*tUf3#j0XO^2m9`eT3fhO=Nd>t-|Ypu&U5J! zI#M#nTbO&Uam=pvd*l0gB>yoFzqLn3NwVS{Lsp+Tsbg4ntNqJ^P&93icB>q7%fKDs zp;lrl4K?oB8{hb~v=HP!MI#K$T%#1Bk3Eb7eSUhFjQ3XDW5{iLDzJGx%1AbSdhb|A zMZ!QLtIi|+o!rv5v&+JW+nvm&+>qoflNPX+r@XeXNAG@a`d)ObE6KOD?l9pKK;NbY zD4Q)4tIRSo?JcE5kuu!5SnSqn8FuT~fRgb~)UISc?XVQ*UYVUvG*$#Wq{m|P zeA(ohQNX6e~1*`W6hBtdTpVU(7G?3{EA6LQO{27~HlA2bYLPOLRwr zT}SCbc?8w=>eFC=Tj4TY~EPt_7rx#U2RUqdJttg)y!z`R@f^7D$$U+`kCxpamy z`Ei4UCoh%3YYCwK$wP(()(K%Qt2p;q(;)Ty!{g!!|nKfE0&GF&l#A;=IjNw%?X z=8u@d@L#ez5}Ba)$YsHth@c&}V5IPx#2WrQytFfq?|#?N!d*waZU(J?yJab8KieF$Vy~zLW;cFn`S?ZjJO*=x%8SLl!Zd^I;RQO0NSl z2yAvfOdi7#WBEeEG~oHEs)f$b7GispBh*%&)_JulTjHLwNN|yMk7h2pBt~fz)NLAm ztzq-qd>X(>0fH92G}Zq_|5S~0PGN_!hAo5HnK`qnMKS2e@fxSH z?8%fu8_rm%u<$tCRWKhhU^-kUP})t+JM5=4k$MH)bJQH&E0Cz;Aq(KEI`iCY8~uEB zoT9XIy72E|*>G%TEamlnXdjD26Pu}i1Zv=T+HfP5nTx2&_-_S9O*GkWs-`8u*IQ2Z zB#th8PIcVnpx}>4`@n^wdK-Y*_yDWTbQmnV^#;@=Wph;lS5#cNJ`7DjGGY>$30z9w zJ4nB)x?gW;mW;@y&I7auzy;T1_i7rN0%q zwZ2&t{vrHI@ZG$S<14$WAXJaK5zE!G_6;RF&k!EeIx&RQY4Y?0=sg@vjZt;tbdxY< z!p~WBpMlIHyDQ{{r51f%?@9&a)Ij^Oz~> z=1~U(8o5kI76La4^d7)}^~T?7bidvULam$S2)-Y=AJuOJ-6+-e zqph~XM~)ndBrE}NGGl40O-jO+;c3_CU`_Co(y#7LF)bq!HvF(RGrd>X1rM-|R2;Cm zLRQN^s^Slq_=8X}AzL?xMqDAd*3;xy=&{^lsT8-=fE+n_5Oc?N8eYmOhlsql-W zbD3T_^sJjrzt-w9qX5dNZwYICW!N2{qAbQRk#zi9L1krxBRFW&i5mlsX2uyqh6ODyz2(6j6{2Y6|bV46)>%y zvK{<)T@LQOj&!S3?l%(Ke`peKyhBd}W5x;cb=+fF2kvLm5i^~Sn=D!@UJ%9IZh3b7 z#Q>RyAvD?f3!i{>xd=$+WHGz8!|x)=k9fwZzj}Uym_8#;auS-~*F;-CqHa8U6d`(+ z^Zwwe0y_&o67UdSkfFPp=F_5s|asU$)I;?ni-;@}QF*YX_VCRT~w_TmEqnIybg?2g;6 z(Ds7=8mY&yfredxgXU^&#Q$au41Z-OK%U_cY=$Hhr!qsv5q25 zTpoMPec~Gy@Mw@N$$mCkZZ*h0JcV)GI5?&3#?xEzGROK+81jVNRk@W@t0l+t=nje! zMLXS*k&~OTXS!Ln;Ue#C8mlm67DG)Z(IMYsWNj(4xki_gKZRLs@>OrRSUqmq&lziS zGRziep?x7-s!Mv+TXIiB7*X#rb{{OZF_n*3s(^CU4cZjn^Prw z4LV#YBzt078KLXrUSr2;F04_5a1+%c;i8VCUcP2#?m~7kqXwgVx4@%20WF zuGMn(9IiyD3PKx?8=Z}Tf&YR*!LC+V}yQ>im?$X1A*&eldyT9mCe+7n$^)E$1^P=C-!E@-a$E0V8;_q zFdv|f&;678Cb;RsYVMu1pDN4aPeLfFF1yIdJY$?T!UUlS)iD`V&(LJX{P^WMC?vK$xn_) z&+3cH-sAp2S-_i;fWPTMMorqnPC^B@nLFfGn;&(eB+G|MuvE}bn8cJ<%nEkEk!~s4 z;n7R>ojCPJ6GudJUE1;i%gjJGrX#wQ5jei_M4`e|!<{zL;)9w8*}Ml$h1BvSb|G{a z50ute3uc!P5_WQDp%H54RIRVm;Zm0k&!FgGJ1R-?;}li8O?%=nP9Nx1-wSal>a?I5 zsPE9B>){$L9T{-%9n#8N<%5`FBt?$m*?Ynk10yMMDO{YpjqL5?gus&c(wmL;0s8+| z%rVG*$CEi(cq$EJFFlI3F569@a;o~vK-(NqsxRR0sp3*I5&c$wbAwwVTH6C7+sl*q z^$$STK;pq#a_8Is(k@$7P31R83J z!Z*B`)si-#O9X)zN_TBj@vGwOClxdb<46 zX0=}~(l#S_Z?g(<#YT@F#3xs0AAUb}@KnWqGOb>q>|wo$Jtt~Rq# z6p4$lJMs`@-qJ|5troa4%XC1Zo)CJv+?6F+ro6g2=9YAjvU0%jY*Bm8Bg)edrZ=T) zk9rq{t79O*bdeaZM)C`r`Tv_*ONYywgm3_}tMhWu2*8YmF619owo_Gws%XvNGW67o zdnHF!6nyKk^a$bC&5`?9U1^fizF3sF-Eomp0;HS2PPIEmkvS}wF z+H}hhMTdRJS!Q%Qu@bChi09%>Qk?m-usYN#g9x|LE^*&pK+b=nt-wYmicWN_7QuQw z1EB)&N`xoSs|r1PMyhGLjM9+n8`GJkH$2`;Oxd<4QgDWk#@w#Gz!?tPiFwfOqejYH z@7zm6E^tzTSptU30ExJ~DzsBIltXAWS$%hIH<)4kIgc|cFGfj)+RiraB3&;M4^bvh z%-IqbrQd;VgAnxJinm$w_SNJi$k3A|U7%Y)SYE)h*pNIGILx!_P;(ca&bwJD7Qb z;C?HK+zvbT|5YFSoWVw1Mt-I$$tSr_MrF5oSZ}J3pmebU_Ijr8usYeet}=ZBKtPKa z!>3sbtq0C|^xvVK2-(QqaTnh9fEx71LXf{poS|)JnauzyTcqnobxjDj8EHAmzK z<8DL@^%lHY1h@Rl#@hCG^RgEF03I)*d}Okm#GOa3ENt`gxK)cj{;j6J@eO)7#U>(_ zQW{pWs7{IBpPz2@ubl=Wp{3585qi@>HnhjIJ?d=#uZ?4DtT`arMKH3yHsNzcX;@~u zV1`gK9krmB2=itdARE&O)Fz)#1g?)&qqND^m{4I$qmaDob98pqdArod#xfcl?O|G! zA$1ayyF7L+q9(60_{S_MOVYeeEJsi$)=pUYj~88PU*qSThxTD zMQZ)wk;emwZ6!e*xVNPD!r`aF1YU)rb)aw9w&32TM z|7JcA%>yJ1kMRh1wJWxV=Gc^hfph?PFF#0=XFpw*Q9rAF!&to-7#%5XLM3zk3Np48 z9M#Y%-Sq?8-;%)+WF#y|9me>+l}e2>VH zK!>by^ahlz2sM4HT^xl1)ST}bx|Pjp!m0?b4qH>68;B)YvSR<^JA@SL&KnXk1v`*- z8PT&u)xLTW52P6}BWu(#PrOMo1KJ10f}esB$rP1FaZ;KG0b=WBE(H0$_b`SvD>5n9 z(-4>F7VpJag2jT3^$1>`!cbH|2c~cHB4Q7xlf;5BF~NM#qd4{S_(PT0OX1Wl!HGTrZ0;g#g+ptAz@R*kBD0Ey`+sZZ9(rF(+q_yR z7>XKieYy*j>&6Z(Sw<(XIO~Xx8GIO;X6_W=bvX|@a*Bp}82CE|Gs{=nl?mHDROlZ9s&A5%X}gZdFp$SYEO zji4-ntlJy_GNrhB&D=F76E~D;(L%ll@ycL=lfje1iomTy+GAdqSw3s*x%-3}l|eiZ zm6ndyWmFc%4hhU+9S7P;Y1M;^NlK}_gHrvGkpwwBi^NwK%7s&vFKLI$<299O)M;Tc zwpujL5MXtLogNPtKOlZRbJp_7sKoi5%8EgP!exM8Q@_C>gUTVil51Vf`2Z@~cCOq< z9ZG+_G!oME({{LTAjQ2>TVZtNR~x7Npa#n4fEUq@cx+9^x8h7&MSd@ODBzLQCpdd~7c*LZIsac!zR~ zCR^A<@)Fc0Szlz>E@s7=<#dsFk(udI-}~;yu9R?Ycj3&3RM~Wv_rE#z00*c^O84|~ zxxcgWiPfM)grFs)B}x;O`Qz&Zhkt*J`gcT z0@WxwAg3`3@n7}poZfeK6pwnMR+CP*kgujEoT`qjqyPI+hxX4g35B;<{c2pK#IrVNEqBL}yA zM#4_2RP{e$paMo12)tk@xfs&DYGVP|ASWH3QQndV$&JEhv*>-Vt>1a;>HMUB4*kx- zDJb0NYVMvr@v4o>DMk27S2=GRY)%!e(WXGMj$^&%|5o(sg}GHP)3%At-IL6GeZZ;7 z);FU~W$0-y5Z83*Q`L8Z?$#$4W{G{sjNGSesen5jLjcuR8<a&`)ZT%~7u4Uv*OXNL*do?jv_59@2m@>Klu-->#sS*f#B0>MmD8}cJV?Lot3@|4ih zaGe~a#c;7%G1dNz5qVg1@%EgDpyH9!LU1Jk*a+kw^?8VYoCMNSn-yA71Z^^;D;Sx#+5G`rK_Sl64%Gg7aa5uPjLKM&= zM;*-H9T0!!-1 z`0RM32(Tjw51N7m?db%=5+2f|`)ql5AOh^|cy_6W>Chd>txk1mCGP>!*izu4cyCN;e*@{?@tqo{C;>vqqJ2 zchdZ${QhuBV0>&w zUai2EWy!hTo?Sc=L+dGlYS^CS5$39@U8idn=Q>OMnpgdJX10W9`P^N3S@w0R#N8BF zH@BQyG+7J0>O0(5(oWW?_sgg42opk|fM^$epzc2#V&1ITdRUcHa&NxH zO}|`UMmAS|(vov;!xELa7%O&_ceS)eA_sBnW<#f^^_XL326BU8Y6z`TN`d4#{%(*^`8eOZ5L4QZzd4YnjP8DT5fzsXX~85v0H2 z@o;j3J>cn_>0rn@11o#cYV8#9JiPm`nO9?Lm1yHp`YHE(75=43Kv)ZQbgdiC9=%`+ z0L(f|*q$KRVsckITt>WAZ^%!W`l*^bEI!OSJeZB!Ii~ayj2bH;Fd9=M4sBa}^Xo<3 zpIm^*sr;Vi*bVq>yJyG_6!Nk8DArcYjo98yNr}x2B$s}XvRQE~Kx>cIf<0^G#Asg>8q-)F5??S$ z>{Dt;VoUI%)ubU-_0%OLI9m^h_YWkSUmQ~EWeRT!H_9@BLm!9tMH33A3;VP=WSIny?Un>#sSxj6cVD`o|?mX3>z*@9jR)5AZxlK)mXnbtqw<8q=uwoZzBz9>d2B?LwC zxL!DMFX%C!HM&ulb-j^$TN%kMJ&HMgrX>{mr5=#ET1BnYey}niG8`1s5)hTCrf_JU zlr6`1l>KmHIU7Qngdh8S!~kKv-YD~W_Pew;(^@X%@Pzqshgq`W1xdKnmGrniW^mPx zia-9p{@HADHwFTz?iX-_Cn*Wi{lCi1mkFSj%=F+M0_i&LHi&j>2BMKu*q?-%Y`4`B z>0oba1>I`m;~#}>UZ-X4$iumlaqNkkMsdlEAGGw|Z_)SRgp?Eq?doroByXC$3r5hk z2JoZ~wvxv68($M{0pz_O2MV4yK-CMD_rWWnxFJ&9NDj`RADE^XtVJ$EK={J6_?!G@ zutr7yjg)K%n{Z5Q#gS4zPMDr7q8(U%3j%@Ck`NY2Vb?qPfO&h&yV<{z5tk z&r9`-C8xbBn%4Oox}x@{ls z?3`@8QG`nD-?>HYSUhuneM|X?qqu1k}TW`b;#%g75pfr}wN5YDYR3`Im>bAD=@QbF~At_WF zsPk#?snvG>x55iKf~O6Xyp7J8om93t0GA74eRvz;Of|Z4@9ENOr4>)SWu|-p1!N26 z=ZMNU3d^hmn!I-{vP+f2{7k~sX8hjNVQ6!tbl;b@t$dtx@o)~sDbbB597(~^Pu8|B zT;mwNH`8j+X9Zh%*_mO73b2R&@yic8(!wns0CI-6=*#g$g24c9p(Q<@$xnlA4CnmR zTLf$}oFh(Lqr?+t#-6Wol(*z2I;iV;Q8{dp< zYc6b0FV4E$c3?xZ+QC zr?Pj3B6LxlT9TNUd8Ais5{E?cui_7%g{muai?lX4wO4-x+%@P*LfGcMm+YM-Yz=-~ zfMd_!WOUMWbo4F7KO+ZGpT&3&t#PktO0GaeP1ALHaSC@v1GQoTN6(^iK3ot-C|Fmi#ruKLB}m za8Ce9l;EbpX$q5{vzd!A>?QqJu`qh`9S0ai8L!+sfYz}@*>sp^W(bLIjkVKa`qy*U zS&p*3T1pe$g}etG0pQtzv)}`v#y-IgMD7XJkeo7wyO$Il@~p1Go;jU~YnM@`2_@!- z%U`flI9RYuyDw76l1fXz{@twvJqB{Vpjg zVw$-lxY@{A)7JY*9?Nb{Q!Y5{@X{CTJ+ZOFcI<+0m>U&0qY6I(;0ea|S&tqyUVlxG zf|i~ju80?JfSEi#b{}PCjzc8gRE%4&_&Yb~ql79i4$V@3Rfd9OL=$MWSxc?k2+j&; z(*qyz6@I16y01>ALKRow{&(7|N%bozIIh*30o|$JjM8P*cwSsO3b9^+w+!=vAU}TY zoE4kT>Ty2ZVZma(5Ci&(d0X&Z&am)nl8tl|WOL)SB($fUk_@@B2sJGUKe&b2w&W{g zQ$q=kJBeh;;v83jCwP?kvkXVNg7cL^Ro;9~Fbs=(;ZFh-*FMNHK!JL=gY+X=SIEwf zDGiCu43i&%!=BTnAGAVDhapPh!n-uY$8)8E!kGBFjJwpa!%%1!UOqjN(?f988RNsa zQd!GHFDt#@X(mdRi?q6KYm+h7p+3ba4c;&6EfH6igOMQ(B9xXN4XVD~u-n+k+u8$- zO$b8u{&QC!k}G`w&gmKj$!$8P0z-*tV7qFrm?s&^B8s=BYg|Xl7)nGR- zaEn;s3BM4AL@t!H6yI5+X0CM>O!HyFRYGi)^&jx}$NJS+ z4Ey3S!-YBy;mh=_FEP3+oYwmH7s(^f-rZV+3C{~#D=;l}g0Qi4>r&eI96bj2HS(@Y z*)ws`*AMOXwnRbG`GKfx6BY&50Dio__0V8tuiaeG?YHr!1cN$8_3Y_XU&QZuQI9WR z3*Ac0b}rqT#lz_>p8eB!Tq`###h5e`@VRbA{iW!#P&ZwEz0?PrGvfTCKg$`{$x7uB z0VODt)a!MR`25F1uP?&uT5Tv^og{sKymwU7gF)q~dJp{3fI@&rX`bj2FS>A60r=C) z_>so&HIWDXD2;z~L!qQIj(hJ-2)f+C%z=sK+>!Iz{!AHja#=jI7cUfewbkf`>HKO0YhC_Kkkta zzMka#c~H#T5B(OXhGQfEtvy>I)awy z+109R#K%e@+u1aH(W<%h@{I#iL#eiF8RfLZx<}#So|J~4>lBd1w*4WH(zIDd>67DJ z;a7BPpNI<6>TKcVNb|&_s)kP@%NhUlL*gAijCX~pbdRx;xEaub`IH#o6s2yf+Myk! z|4Gk3ApHzQ_0^=g40H5Z7u{MewWPE|KK1kkEJ=7u)T`Z9-DR>`oX)uFvHhC!0moy1 z%M8}=M`xyX4p;YXYV@siL)$hQajJZ=J=&_Z<(C`S#gOxQaW&L{dLfj+t3U(zB-#o8 zQAS{8Li#>k>ck630x&%(k(fB^CUk<(QBglC+1D%~ucy*p%g|OTJTNmskU2A8evmRk+G z#ul$-_2v75NJO+yA5<;!=oaoK6*cD&VJH~kY$t$6v?eD;uld1%8z9sMNDS-c>O!-V z{#V*MZU>uN5w=pD6wZ01Cg#Ts`|Nvg3ed3EMBH5Y)JVNc&PYuraG*;iQ5)uQh9&dp zGe}LMyQglFawp&N)x*Jtii{K7;l-(86C-^R#bW3VuoOLTK|Q4R!o$9@vkzX-+RHby zfT`RCIr}tcN9o`w&SMAO{XRFH8ntB`b#%#RRC+}$8Ru@FFK)vM1~&heWSfWFK?IP3 zrBLiPmKkxPz~#Rc?n=EK2AXPSZpmodr|Q3y>QsiB+Q!bkBI=;M>Lu2?w71;1#e>kO z<)a!F`lCATW)7u6>sVVGIOh6$-V{z;(qSu#ygbUT_AR=6cN8I?E`A!$H~}5tA3l8p zy&j{>A2-!Z#TJC5M_rr#c-p(j5FV*h8n@dxf#M>M^aJ{@VVSBtiAH%#Gk|jU(FY=| zzQ0P*P4QXAdKb z0kUVoHX_ku;8~x8KaUm)4WW|Blm0O!Hc zbXUpqQs0FZh0L_t8nP-Qx#T8z!MJ^>hxPQ7u$DO2DV!?q5#q|1#@u=|r>i)I54fn5%YAft(G#xxsE4q3i z$9hPfLS?YW1+sYEPAt5RXO^ctn7={d@Ir!n$u+Q;t9Fkw%yvW;U3^~_7Qz~<;&Tgs z9Zj(-opOpuHB?{N8GA^WTApJlb%+Aqn)?r-%8c5We_N!rU$LfEGnW3x`^{x^HR32U1>Hq3?XKx@WcIADVZr~4j)?c{;k3@X@90@` zBpjFSP_kqATEanL`%w@inRZuhOddzQ4zcQQ3s^HYU9cZs+Zy#zfF4e?nN^xb`a>(j z&G)K)%zt*wwBsdZ_7a$#mgbozr!5=$%|Sgtx1Pk{3ysLg*(G@lyw1EiXqZ{-*YxND zHb2Npy7-W$vjeLy>>}1OL~tZ#xcV1|QqxiOW$quMp@S+jU00HywmrNeHzK{`Gv#Bs zSqX+@edmiFjlwwFF7+C#Lp3?4_R#LIvH211TQJ?mS%?NxCJPPeAJ%aCY)8P_c08HA zGlmwz3aHa9LYp#)t?e~%cV^&z9vqu*2SlH~qdt)j8sVj=@!EH)RNp&o*xPTGS}m3} zfPdka=%q&+IXbCae5xd^g7;`G3f?1VG}*@AHI(u9CLpPxe_6RcGM)PKK*|ZY4FD50^K>clN zeyDGq>n!%$f((CdK5V}27PYk##iCqVTFXj)%=g52KdluKMfE6tk;yx0R0-S6O ztIJ19=(0c~x-7ur^;m>$^+H{u;TF8INWJ{bcY|`0bFYReV#LCOgK_E5famh78y=LN z?V%LIW{@(hUXP2&^pP6(ZU_*coM z$f(kK@mx#!g&UZU{U|3{9W(cPpgBqw9VHWMlG7Q=rCq}Az6EI1n4?qPtjvCvckpon ziF>eoTNp%(D6<9=dA+~v>7T)dzG&+UNvNfuoFxi?hcwm&oBGZAUo=kx_1suP+k0}oT^g?Ko1%?DZg;y(olm1Z)HXE_7DRuww%(b-R*OHAH<0SY zIsVh%-$WTty~rW72s@&S7^JPEGkR#928Nzyyn}@mNlDc4~9KpM!ZM*fnVD9LzJ(f*`76kwD#&1ZIk&ok@L8hmE zgd7INMJJX20F-=h6ZFxe7v46Qyz8a5^xoyb0^qU=qa9X@20vuVba~ET#d?x&!rVy}6l%_^z>EiQ# zQzCU0)_ta*e+9_FAy3M`3#&tfEDpK$!Ou|a$+*M807z5yjb=t zXYRG8YQO!qa=|-dD1vGiF<>{bpd}S*t5uY>Dlly(?R)xCCdUGHvcGj2b4MuDJ64NA z-0!4C*i{=7gAn9kN7ozo!x}^ZVg!(WoNAF6}&jHg>#q zvw{O+Bp$-{Le9Vvy7mBBPyB+ZCk@BJuyS&uTjp{?w(x85oXse-9|zE+CYiqDRK`s> z8|t}o=lFgtv9_fGIfH3FHh81yL=KZ=dFzG2`*p6Y74>LQCqQb9E45*1$NZjnXS(F9 zF>F|Q+kW7k$BrKJ=-1!5i$@*q|NjY)a!`%E)tlBEJ#q$$Z_2@%v{)Sirg;6}*uq-y zQIW~YOM@kdkV8E;I!(c&!Zy%yF&@`DhpGDhMm-}H-*V~k`E@W8t-m2Q)JlQOiIGCK zoI3buba&IPrVSey9>cO}OzoT+_2IKHW|^(R2w|sZRj9(AGB-pTi0wA^ql;-cCvqdUWBLG3ZkzMQ zyakl)8Bv82<9>%|0(@$sp-%INSq{GFW)oBKTy}6}Wfnre5@&JlB zI<^c-_+?D|qIu}0&qjP^mEml+X!)~Tg+uZ7^m1%oNm7eFZ<<*r^b!cmG_IVp@W zXo)&0|7`7=ccaUs4QF22W9f^<8h*q67YfA{$P%a~XF5Wlnn;S0ysR9a{szdNyeVl| z08&>)dsUa2C@^@K$M^lW;$aEVq#>9;s+B29=SC<6QFMc;>Hg>ChPI&L?Fsng(4S&) zOThsaXtuCl74`zeG4Y+u`D(<|l5(5j?W6CPpkJbok*RWNZzof~#LOc=|6#~SwrhUeA3 zms+dciuQ@J`3<}InAe20hO)pk-_Ha18ZJp2-mcV|l-fm!UPc5}o=^lXVGU9nUP@W( zJ2o!U3(&@udSMG36ehDgrT&FE)3eEo`{K%Tg^&Wc7}?tB1XW4rGNru`dTcl5#_MDy zrBYqwv4yF1MFM+mx~Hj;TJn}q>>%S5oUQRc*0Abk^$w`BqXB->0^gSgVF?;)PCA5; ze9-SQO`hiSP3F($5%TBt;6O9^DzufLUk4tnmhxsvN7Nntx)C1|P$xsFN3PK}dH`%% zMcI;dqy1=pr{kF$Z6;SkLKVsLMY#9wwVG~aAgzEaRn894+3Bwx62Eo0Dd z-57kkf2E;WH8=x-1Ip6gEF2wDP8B|DNvGB&Wl;pjphR%JByQby3F>GzxfiSW?XiYVfSY@xaFiGzhAG#K}O= z1*#C2OndLmXT>C)?x^hlw4=U!xvo)M`((z5v**D_q5V9{0)TmPfPv#}LiDCFlHaG- zc~uLMm5fV~WmT+rN3_+bku;`_ve+3$ZsRI$5oCln2hhdacNq@pz%dZLXCLseXT9n> z#x)eW9`za%9idM8H*4&gkfli7l8_pJ4Uo9h^?xjw%L$-OhaC)&Sx~YKo8#X4&(HA7 z`+JS|D4w(NlqQr}4KctkvZ5ZGF4RFW?Ay@2G8TkiENx4@fK@ix|Ax=F)k~3(y312$ z_8SHMGc}RH2J|&#aJ$I?+H9b;WpTy-sLR-wxT^-DeSVBOw$&8?10J;>k~Xrgh;65h zR^agnZV$ZAOcj0=nGiN66E!~M(mnqyuJPW@rg&v`ithm5qg%V+N6;seBEy+%F7Lhi@B-(+inu1oNU%%gr>`F6GAePoLH1^wL2 zfhd{E>&>%nzPYwrO3yp9p<|GZbL!?ij;B@>&dOMea3WJmglIYO z5}dsx=ZV0ZGitZLg)1BiO^dse@(D&Syu69hiiH#orVuK z$KWk^nZLP|WnH2`yBFadv@J3R88W}RrVQf#?@ zaPcU$Bu9Tzq75TJYfZLe0&9~)DB#v`8nADq4UUy^D22HdR8)R>bkR*v~(nUyKeG%k&)JWZOZIi}`{$c$yCh*a*0 z@NLu7%&|fy8KpEeMI;v>L7~Z|lFVFC5rMRD2gHR%;GXxI_dj^wANtMw!0mmV*Lfc2 zvG{HKCWPuI93lzzfk&zR>ZtxZtrh8c;L~AE#q-0`Z5|ffyoC9!Yu7I-)T*DdJ2MH4 zG%9WuJQ{)A8T&)VegA^s0k_l-?S26yV~DsWH_0X+^&$H%n;7nI6#~4{#i9CuVN3-Z zeYAp=DUTW27E=*>F%$%D|B6F8z+s3b}5{r|(awFLKke3Y_ z{gN_Uy6AF2q?w<$&S-Ljz}iBxx8Ln}?Bh9tnc=hFX%dXynR2;;zpYbGiAl_3*!Q;g z57RsvClT?fA(Tnm>-{USVMD?C-DmZ?Sbbd73J~PsfCDS!yeMH1Ch3-$yDSpez@`$7 zv|hg~AAmVUgA?a_N6%bf7icZC^N~{{!HB-^!ItKm70r)?q_Mg0_wupOgMzJr*n$+E z-QF(Fv`FI-Q2O-tJ&{zK8#IVn1@vES62{|WPe#L@0YDiE)onRvWND>}!To~Nc}(P> z7o{7&(?4_)=9HotwCW`S(=cm&lAO1fATISF}+J!ZKq;da3h1 z))?=l$Xd@|dU_$LD)+WHIE`MdgzQVt@(e^{&z@%0CUMhzB;bh-dXxTHcaMsJb55@M zHhtIGEJ#yeLI<_nfQ458^UMDT*>%*uny`bd%=_>rANRv$y@OB;leaS5ZepbubQqAu z@QJNW|Ez1w1uK)mcG|kMXB{wAv|WwyDu8ds7_fW1E<3mp{KUfS(|=1lG*nj3j!ZLPlKSsTVBm)0^$?!0=ow7Yy@A^i7# zg%c9|B0^98!3eznKkGdDjGHJ2EYe+*_8sA7wXKGO0OIi<0S^jI(GnlcgODe>Nka54fyjSQo_g#UeZh$EYR{9E*oo48 zV)Lq4q{Qf8mj|;9q9$8;kR&JuZzW^s;qJ`D@}tdy2B&bh&ptd)MO1~?aC19JyHo0T zFO)`N>(lqYt5`Yq1EN#f><`(_{SV73T2wZjr`}2lpOA;1F$&@bCvD`Kn+B)m&a|}j zJMYH6WGYkPL>O^u?)2=op-n)nn16@HIrkG?C=N^hU>v6ICe!$rzg!cKhl)s@F1u`o zi_@Qu<5$aVS!{yKr}UFy{*8nunSqBg5efJ=-p<@FRQpLEO-@7?OiW+@$Z5M~T@t5q zdPQzb%bqVKNlhZ-FcNc_~M5Mxwgbu_#gT4X4E^mrj*Gc)wv4KoVThqVlNJhKtwi=Wn+>vgh z*2dnIO{9%W1pZkdzX1E=JKa-96SuGY4Eidi)d|0EBYB2)nM=x(A*&O^|7q)A5nIBq z{$W!%$e%K|APC>#*Un!Q+QTC1k3A>oz>^%i&qIeWltMMe7H+z!pYi^ zI6Vv;+YrL{vrLbDZG)>{$KyL2aSZ^qq)Z1)(0Nssd-qPuTD{+4ey?a<+7774+~fug z7R1YN(RWoTy||H$Rd4n=EAmO(RX^=`vcy%)$(?S;3L-Eqw7!dcy^v`rgkI?x12Z09 zl)U`g=6>QpGhPkjfnrg%IulGfc(Z7S_VVRP+Fl?H7|Hn$4;o_-n279R#8o-uYIHG{ zgZKEcWQ(eS9AAa=q(GZdW}W=4EYmH<{CTa*0@%Z8Sity20NRg3}3>Zk!`5dy5qM`QJ{91A( z`rYF@Pw?aMgq>W=`HfKFNBYKb0}ZM{-XM%a)8q&b2jf%x<_uWJ0Q2$3!re7$e1ol~ey8H1d$-qcO2g>d5kM)>dJ)n})y% z3AKG;l^e;u@kD3NubC;u1u@#z_TL3$dlZ)xX0;?JX4zRE%kHgz%c-D;sz9mz4(F01 zL2aIQ9t#_zocB4x0WyVcE*LPfDMq@dA9n99gfAGHJe13pqo=p|46VJ}xBSn#?+rin zCndVwY7UR_f;KEl^H85TBFbEPpuda4^I;NNd)E-as$BGQfbtbK7-`x?U!Sq2a_n8- z>Fiok$8S&k9dnOwG?JM~^|0Ok6Z01C$FWYxU#zT$!$9y&LGO5N`xea%AJV)*ec@*w zdeiuECiYjeA~p~{VRMeev-gwZ>M|}MgXaArVi8szrp^3I0}4-oZ1fbgBaAdMK5_;! zH5^qr7tt~z5AMseX^g<>Q(Ljl`#=?XBZKiBWEZ&_@lu_#6Bz?D(ZXLwHr!BIi=v0! zyb_n^nE!nt!Q6m7c(cW@P$&J#L3__$5;`T0fPbc-yM-iREV{s|7`@wO2m)(_Zyn$7 z?Lu>mXg0HJjNgg}eR5Uy51DlaZ}P#DR^PtBk8aZZKf)m&;{b~+!S+weuZqLZ-j6PD-xkkA88)~8V7m36UBVB?3+G<(UyObCf=OyH5dCF2<)~QCln^`?=`6t2#t+Sy_*MP zjefOWed)vn&5w3TL>`BS)qo?bPo*R$b0=&_Y2Y;ihhXW<7yAjWf}Jrs^Xco; zlG6=`r0W5-aa5hfQ@#vCMxp)|{Ym#Q%Q$puUqlRMdmp-zF!*J|K>f`BU#jK5|IduK z7u2=d&^{MAES{An)p}#_b4ICTJZ!!Y?@9RkY#@B1iY8<#u_j~kanMUnK37?FxE?UX zy-Ge^G)kX@I+C`!Y>D$S;_ho-mXPqFwB$}aAI4RG!BliA&7E#=Fncqg+C zJZ{vVlSW}LHrNYDQ=xhHFT7^LRjjunst~e~L}>et=P{_UZHq>k;1+FU%;tGP?-)sO zxBNs+IlwMOX^sd&R&!D}%11@%>ibNK?JCYlj{0|ZD@S@U-76)YMX5Xu$_=1~gr#a} znS}yVCplD#OoBoNY*p62V|N0!y~>Fk!AqNK)}(ORMP3#p2r=0&=n9HfzD&XIC>4SA z+`)Q`eZ8X&L_+OpJbS9*r2owA0!@0&Tb=}^wM-;5MnF4Kd5aBy4)Adhrj*@FP1Jk8 zB{QQiI=n{XF^_u#32rW9$UUTViLf17V`;3Q&kTev4NttnIQj-`b%N7@f36L%fweR5 z;@UD7@wv1)7U{nc#_QiEm7ojt<~>Q&C|vhR^xyeAY#`91aG zo{i0$^dzkM7_hKK*jkM++Gf&9bY!FHW^LNLP^8Q0{ERAYW`*!@V`js>nzu!aG(z%J zDC9b7BpTe$VJ65~mhj-#(vLp*h)|!3B}!tG@v)80a%5V{Ak5!qsj9N*pWNsDC$-H3F?E2Yd0)v;<1;O?j$&LimjJWQwEnQF1$qBpO(Y7s|>8;Mr7e`>QcyEF; z%H`8@BDjyIJh5u@Y!=$xw8NsJ(a-N28Uk0lsdI_klLrwLh6hH!PW44P*s&r`;lu-- zcSR7AtoawMY(7VLVKuFr(`6n?_AJVGYjOa1v5TIURyYT$r<8M!z*q){8?GEaE3qGN ze!?3|D-Q;jPXfUdoQn4YfK|iGGJjW)+Q<_cL2*%SP5!PxUf}p^qi=(Vm(|Ff&jy`9 zSJ*%6f_T856MO#?syz@9?O8G-wNr$g1k4ZsLQDqzx$GepMU0{DXR#!Dptke6JXGAj z17I}Vw>@%}QlW!`E%5&fqyB_@CiZgs-rK1&h}wA{v|46&`JkrhLaFU*inLHHNjvyS z#{?i7;f8)S+PmOWi2n?)g9U-k7@kTPOZY%MQT?M6-7Rx+>vPfiT>EM-$fb=PU~Ibj z{+WvLmJgLxJF$#ev>~28iP-0Uz1PfdTN97J#1j(qC1hi1k)|G`nMr4OMt+pponPO@ zTY60w{U;YMb_soGu7$d1DB9I4&>q!FWY>+^g6f3fO#@))yIA^V1_{);ja+3bBnWG5 z&hJyas5KDg?%9Ix2)!!=fk^=zAj;cso5%G;sqsp~7leOpMsYYs(c#R3DLZ3(dXoM; z`JZ+3eR0qL-BsH=Nm$5+1&Aj{-Tr&84`QQHPBx-uV`6kdQo*#2mkOxMR+B4FxXe~b zU0r!F20*`II<6<-zJ_64poJQarn?rC<#^x0GQ zOir$KBfdcawa`bZha5<}>8*}g2)@bwH>n$E98!-y%0H;Em!mZGwabR3 z9zX&Z?$b{(UiG+1W_M(~)>)|=o(*DJNae6i2|kw^k3@-E%%elvcnRtLban2v-%<&j z<}^7-;-DA*uK(^ZWek&SLRY4{SJaR>J)}4ZWT}ULa9T4}=|3=ARU13ja@D4JiU|%N zN^U1Pe!tJ2Ju#gkZG_9HKVdPwkN}5y1oaVitN=L>;%{SaZ6x+W3+BWE`tYfHm7d@p zb?Cmj+O!7L`rVg?Ydo+w^*r_ZL0R*nX})!~$FwhzMhm1VCd+LB0b8f;QApjh1k=}3 z=!_`8%%>Rzz3~xaJ8;1SGY91d&-{-Gbzz10u4pst*BPkptCnv8Y3h+vJ15GWE|fyi z9+Ox-PYi&j)HcSz<9jG=S-3Lv{Q1%pe_B)~6Lz$tzsgwji__1ot*v)12EO!t!fkd4 ze#_mL(J|5Y($oZrmh4f5<+o7n5LHcaC^NLf()f|gS~JXZU|!K{l!9yRtBbfFhuSu( zPISN~P1Z-NoLQAk%``DD&xw=`2;OmHE&v8Trz9k6?Fx)l@CzC6i$x~!Ygrj3y^{>? z@`8llvz$26BRu3nz6|VG8CC?TKP8pO{gtl%O>0+$?~`r{>$rrzY&>#`lmSqGCnXX_2_kH-1w zm`@o!qBD&AjYZFTC+&S?7pu}wQDp2?on*gW!AVQXrZ%-WNJ2rYPg||(5M-dVcQz`p$mr{eitxIkg2^6m|vEL-$~BqjKuO3Ho(lR94kpB3h)F{ zOtzei4(Qm0q2z#cnmn4>{x&un)l99xLlZJW8+dB&1Ti#OXP~aA+MxdE-A@`e-wOZ0*V@?Qm?*f?`+W{S%1 z@^<4a!~)!gkVDFBYAalX9BB&y0+*M^(P_*P=aTd*LPq_r>s}D)LhtgE+Cyv?sV9a4 z95Ai|Tde%iQ}@QD0hzJ{m#{_99@OO@jLSqRU=m=t!j&)MMCRIyZwsI;n7#hbn#z|V z79i;rW+P(U%dU4y$BWYqPLFZX6<}HDO2D&`0Iy&GLuHwp&xAZ6Xz^2Ib|Istl>L`^ z{j%>&eq(f3YO@0V76P=^t1XID1Rvuo5#rqIPTy;)XQj!p>I@d4{g596K2H6@>LqVG z=&)bkhc?R-Onf5}A!*YNtKNL+r%~mW{WB~DvTk-c`_nk5PC}(I$(PiFb88Qd0PQ^| z)77=7_;AAhf8SZHxYz>p1g@*--RXMhWSW1CfheNnsO%#DU^| z3#=gv&}4YmYcp6Kc#yhHgW1zkjJwry-2WQkRPVFRpxZ(*-0&b!G;>KzJKH%ow_V+|e@LBS3pPm16i} zkf+-Yu7__LTEKn1x0?mAzlatpyz_$);V zdDTV=FP%$2d>gDDo4@F0%3 zk+!;Vn&HorN*eu^v->_&o;mttq#hDt6QyPbAB?*2M@Gu?=Y#e!EeP-%B9)hhcb`2? z>AX9~Z+EFW+om!p(545EH~?~IWyjcsdjYUX|P?}vS*mkm_vS0ps6r=ei^h-<@C zXe1$zYoP^?US7jDl1xCile1dpyrh%|@eiAay(?Vuk{#lkWuh|05iDbuaQUo?)j{8u zv3x?+sc{X|aGiJj9DJy`B@S$!7kVst0J!^&0!9L@Wu>3XWuicp~xV`uwKyr3z*m5uYVXG&d+S{ zAg=EU*y%pj(~r%vbh4Kb@rJ-C!UbJW6DIrh-M1X8baBGKqB;+jXES6y;9-}M4`G~D z^$y&3>=U}M4Y!qBK>Y{Df((odU$W_WhTpNtwO#R>C`qiq?25rq_HyKYZ%+|+>F^dg z3Gyg5h@Z|;fNvw-!eCc0(N4MJXxvk3VecCPy~&wenw+qYL3&68n++prdKKKTK2GCY zN78sJ{$fkDt{sy%X8H}G%WYYytlpN8{`+T0pLB2;KN&}n1LgI;ewmjT4Cmc!Jy-b` z)5=hQ+ISK8b>>$ZX+?!q=F?utv~1+L(r;s)FQ>cBCk^VNgZKZlj#w2s#^+p^ijCA; zcrKPOs%Kr#o0m9C(X8tSs-QknELY|!l_h112prVG{8y9Dq%R)JO|R~V{0Xv&4(2?| z$-+2jHRbvaWzKzYV>@@3@MQ<=nr-IuC$mZ!xiIH!pelaF{O6s!O!O}zY-4A9_aS&fj9r!4$FmXH_oHy zEjHe6d6UL{yrm71UIUJ%eel#0%SEaKMn?|^xP#BMwf565jqtA0oX1r&8dm5P{#OOc z=lWp#m!30ZluT!pOh{L-R3m>tZwXDx+lHO0oea3ytXXfB(_f88fEi>1`CBQ|#a8`Xphj4pD_^sgP#v=2_(TdD7;4of#P zP@4iibZ1*8CDB&onPz8MlpY^^pTPnl|E>=B4zJX*QmJ?Z_AeR&=v-fnwXIopW9MXUCG@A*t5 z(#Cn8dYt>o3)PZ9xzaZG=T*XQ3pJ6bi`qW*Z7sq`!u|2Lg$-MQIoQS{_2|U%U@V^v zqa=WBPDpc-@=z$9ZEM~id0z-K$bOv0A^Va^0KL(c z2rcz=4Ux!fYQpurL0K728OvAg%_hbKalWsQ_DQinnD`r79__a5~5EBe1XYeX1}7t156Wk!N;tx zPZ4YternFo@^nC!-#-kx`T2m3_u2|*?m%J+f}@6Z;&PYB&=^a>Q!?pS9Vat`o+gaz zcuQ}Xt_GEBAZ7v?fFLD^PU*>0V4@O+)n>paOg{0qy=w)=b6`1qzU3@<;@5aU^A3=v zktfwfm};Rs-zH}ps@1b<2kvVRsl@Ho3qms~*CE0om2Y7|S&R9@7RrrQ8OcvF;2moi zX7NO}$CLp3D3pb8ht8hX$C6^e;AF?@1B*_Hp7!P;@!29dh^@^_K`&){B#$hhKX@lEO2#IAmsUv|Hjny~7xAr?mfPAvxl8%M2O z7it?FSYJf7b@H0I5aj zgOOlYG&JJ>{;+bjpzofYFbv(vac)Y|4^RoovIcXoP5hxPR`tahq7x?Q0%O?&aUiTG zkMO}x!~1}s-e)hi&vk5lR=q+5qh&Gxw6Ea=MfEy|S?HwEpv6s=6@dqy_RSRXDyNHn#_Qhh^ z1tBZJPd&xk(Z1%xAKKuHQ6QBI-tewSg8{MyVHQfIa{>2KFgZ^1E!PuTD4amdE z3)Hvt(w965?PF`662+X(t5m1=P-=6~FLKfI_9xB=440qcej92Fh)*V%bls9o z6*z0Ba)q5*%*Mg%im6-5KVvATd|yN)F=(_W)%faI9^^Xg7a^=R+q%Za_8 zBqFBve)=1ZkyqwCn2OLl#slE`Pa@&tM*uZowduqDGQPi=Z!b3l^>9#I*EaTmd$vw` znLK^V{8Pd@X8E3L0&8?En40e?vG>^2T!7#f z;5R@SN@M3$N7P)r@ptn*d5Av?HN$*e5neY$fKf1tW|3y7&X#~~mP0-&;0MS^P z{mZVOu9|n#wYF5l8EqMM@}kqc$o=PY*Ec=^(H3P2H`?ucol8CCp`S#pmiUul!l{O_ zRn!l2OuQ*?$fk9~(cT5Y8ZI9mIis>IEulCONs3}13P=hkO~)>gvbgf1=)I~iwQ&Sz zu4>bsnYosdQ}QmfI3haMXCnXX7_XBPi7!tku4tu4Vuo6cuu@z2Myuz{T~8hT;;QTB#*8OflSR4$ki0A;6?6H_WV+ z{l!hK5)`&~2E$c$)~OuhDOZmv^_+f>>9_SWQYoDbxkLTz zu>UjsRGoqDbiM+=K{S_lNkA88@+wU zUS%Fq5Z2SqKuwC9Pzsx@sNuKsY_NBc68l-%(qbz}t0Rm>jx0PZwx2Q<*f|?{ub@F5 zbWH;;_D(>sqEFCs)-2mK`7n5MOq#N3t$KK8Kw-UvbB znMYFKZj(ubzE%+RqQvY@3Z@FP+Fm_JOPSJKm^`)67STO2kFXFsYEwR>dBtP=+Rn~_xptfOyRpnrT%(k(nDvDTIPIT0o01k1dmv#cg>c+ z&BH<#<{c^t+T<%;xm{k!Zx3;!_l6HN?A|9_&YtoCxAz39xI#~7;6G16O4Ake#r%#HrMb~)1r3$~plv+!0n*Id|0!DoxvRsQ8`U9#7CEP{i2+ovPNIucIdNzw_mc#ntmo ze5Zbn3B~@r^WO!@v@D^B+Szb!6*iHc2No1&8KxaUqJ-@uE@rd+ZnfXl@~%|uRZzeGNt<32*OmJ**RW8?BmpoMmR82oJBwORr?xH1rNM z>rQdn1keUOs$*pSW0~{h*qYu?5Q@4tH_%^^5)wyrK61FpxDo(p)9a&?_EVaQMZeTI z{+ixlwaXE;MSH{ded21w6rqVR$WkYJ0%s9|6JV9Zy;-gngMOJ4ea+>y2!9rW-&X*) zC$Qmq4dCna^8oGr;Ky(54&SP0dWA_4CGOS>X@ylgGL=M4r?OTh6`j9Tpb? z0&*6!jUu=<|3mHW;A)$Fnc5#scS8*)m zoUs#YxXNCyb9Ui3Lt1~{G^A@-|1mB{6#g72p$vOUa~h|N)Rco6Y87UQ1*rQ=+%TOB za5o;r_Hr9t%!ihpA0@9O+W@;6ubO!#xo(JiRy3I*s9*YCQG5;1$h!CpF&;3@=`?n z;R~l|19mlOV`OPeCTd(9?XC}*k4(OJKYUi=#B3}5Mqw}OHw?vvV2;~l5wxoTl(cR= z2>1feqD@+C&1q$IGF_jzM%CM(TB5m~u^IoyZndp4E$r`FyA2eVosO#9yUO`c_BIk= z3Z35$hf5?GhixK?xhGMF!lW8Aj#MuHr9%@soCebmm!KqVr{4CpOO0VbiF^T2f!p?~ zw`EyrL)p^e?EQ^3O`?i%fAa@&h;Jgm_yck;ot?G!;yzZciNV}S(&d5R7ZK<)^Ahe_>F^8 zLPHAftajrE!Vg+sB)l_u{%U=&IJ+(^YiI29=d1vqWAi=Uhl%jvD{D z_Qb?DAO>U>|DRmnYmo=!a<`wT26CBDn*QMJ08?3tl)fOR)z#74OJ4nWXYY6ED*O=l z&EL1zY7V#OzD#u~?P85FI7i)J@wEw8k!7?Fnk3K5H#S#uF#Oaqm&;l)aO2IuC^fSsgK!`^@t8}NFXYq;UT3+VdUIm!2nYZuo_YEr9?U!JZR za~tLM15+q&9}By749NR?801OtDA8S^OCmp55vIQ35gIXXLHK5_JVe03>a0@l%O!V# zU><>(1}~yDhEb*Mc)_-miB~DPZC;zG83S!=xrRNFHDeaZN}WvaFokMmz()fVXRPDx z>oF~s&db4z+wZG|%97zJ3;%nfF)DJOg<&|)C3^)!HU}##pf2EP|K|n++^PY>;@2?9 zy6siCY7;TJGBTdB_=n*XGcQhm!XNvAT9b+B^$8{z{E&F>08$LWs*hcrJDJ9CU}4n$ z(MAJ&J#h-SKYr)LWBC@adV%sZ;E+AgYVfg)bYr(D^eeh)^hI`e)uag=`o8ZQ_pY11 zKwr=@gi$z55-H~cQJqYXI#>_B=Z#)eF@!Bn_o8Q<`@7UFG_2fRoBn~bk=pCMa3;I_ z0NpUWR90*)PPoUnYeR(Y^MCsebo_k4jCkqus7kP)Db4M)&_#|RJ$k1WtMuHmEw0CO zzcMYzQ>;8zR3=UTLd-iCOXqBp-8ZD9Hwdi@ zxNq_Q=hPy-#xrHuJ0Dy{-NKta;}G#^?}5YyH@ezV;H-euy?l4-J?MqyO(cF8K)}K281p_+(xMDI_-XQIiN*drFtvc=94OTTxquOiE+T7z8q!XeQJ^Np_z9mm@m8>Pp^nx0; zcl+B&74{|U7I(*DucA)+ots6nI-9zDkqNY@Ri08i9qOFXGc0JcDf&@v1ou54Gw8}QWfi?{7hlGn&U7bP3TDgYP$vjo} zn%Q`0!3%QNKP;=AJNnPMjF*cIHx{S6!g%pa?Xigft@reMM>)RxVoFwedl}Y67wAM6 zs;T%nq_q7!>b_piVlBqKROXIpZml5E(6+vu#9dJLMrkv^xyM+c2%snL*N zpi&k3xWNmScTcg@ZQ}mef5XQfuRPiL6fv5Uu9QK}k(`Mz=AtzBa0@j)mGioO5|L3o z(V`e9&UR%XwO;sWx;zIlgL!C-QeLd?L~z(#Nsh`hx9UtTdf; zN>6QN+WB3s&j{_Fvm;Y-$FkoQWo8qqg}vuuNV{%oLN7iWKR?#2(W4)m+c1pp*zv{qQD>uY_CEXYX_X|Df*f3PqMkn&8>f6II^y<%Z$+PRk6O|8zb`kVcLxzt(W zlIBvv+Fm%t#uZ&^Jmz%>cjxtOK4TE=(#IOuzlgtaMO5=XrIn&=?v2~>FYAYFnqxK+ zRFb)h;FQJ84G)VOrozo4Vi-iR$HFNdeu70X?OUoC9-QBvCUw*d|3Oz}4p!i#i-!vT z_X+HlHi!~J)mOB;yOc?#DU23YGXt1JcxTHEKibK4NGbMRzCJ=NXt(lQtRK5uQynmo z<@arhD7-;IS!i@a#4h9g=M6qGK=c^Pmd^+Rr6*cPDu$+kSHF{(Qm!VG*_E#BpYk&|MH99HZs1%Yu9j58eTiBIrPJF*njfU zkcY;-mU@bo3C~{N;Sm%gJ&VvAxanc|#r4{U@WM8SCEAK+KHgZLXD$+o2R>po;B#fE zv!z*3WRrm*-<4EU9qxsV$Ee~uTuM}jy0(aQLF3NSV#~6m`^khX8M4@(8BFEewh3?GH4EXFr0~}>4SIxe z&9G>E;IN`SbmsKI*#wqts_n8XP19U63ryXWZ!~e z6@2-Xzf^@VG%R+pgm7Lt7Way`g=+&UuKT0~AI*m?%qF?eNKw1J~8(UPd6 z@oRWu&G_tW8Y|F^o^Gy;Sq_?@sa^DhSWJPbZrHcksrE(=)XOWMF<6W5 zie!iyqMp7&3smE0HzSNIUSdt%!9m%b0^*5BL-iU^)frJqwG*ul>GC}4NKy+?96@s4 zhzKg$bLUBhJ$TadE<{r$fplk_4VVZoChSfZj%C<~y~z`6{0@0i zZ1sInakudf@w;~nry}AFPB={(yDlQZN?7dP*~GVR?_`2N7G>;3``>_CQNB5eK%{n6 zxjw*e5j;2tzpd3zrr&6xY`hryhvf-B)n{lcrUlJesR^UFzcO5H0_;QBo^)I<#J~f0 z$8S|%m;W}x2rK{g@QD0~%l%7lf&59U!3ow{C$Zo1CktT#<>94c2Y*8pl3DJV_{Isu zYvt}^7Tbpy8*4))V-hjbtzNpep+*u1&ADGad)ZBObUygbc|2jp)n?T=U0gFdF70V_ zp22)b2f-EcZ1=@iYK%5-vd~%5#n>3|?M1n(i%?h^5jM4)UWdg_Lgumb`W7qUNWl9P zP8KZ`Nd9+)muFx+PCb0s?~yJ9`}&VMG`B??|0sU`&)+!#8dw8d%hq~We@yi74sx{F zne3+vKz(+fzjJr;1br-S(mbF0owiPN3PXU*vcm!g$ogOPXBezgh-CifiFv^?t${XT<@VV6|y>;FpkpQ1!y3BGY@WRBIT6q>$3?Q{|qlpz`DV_I5e2&aXs zQ#bcWUC6EIX`UtF@BcEe68?vO*6kYm)g>u^Fr1k|fgq5esChXeI4=}@H~4LUxk36i zGox+mGe+!bZNQr_-Oh)A0HemEzHgGKTN~kI=02UrKkM{9kYa6# zz8U`#zSHg4ULDsQ6TMB}98W4fO#_X*80;x5=~)AW^H!Uxb2lP!KMn2YUgVz7DiHkZ zwY4%d7epF!WB*b7s@ItNLv-TqJ?p$?=Gr3x;?Y_4@MW*vBZ$n@lYZ5ZK9gm& z7t9RM{<@HhC*&K58GMGwDDLqlX6s=BAodfI6#aGzJv;8NXyDVG&buIghW-o3=eJQ~OsqQ|O?Zo-lKK2@|mZY&z z`YC&AblKv_q*ea;MPhv)9ocK=cOdS$$c`zDAmr_88*eW7Z$y<(aMjK%-bk|GZAS98 zlEFgXrlPj&kS_boqU+oPCcms5vy66RwLZLgDe7cemmMKFUQY)pCRsRYbg7;E;80=s zvZpTZmooz=o>t@!{T~PgU-$p@AN{qd_E4pZ!D)LrRc7GsZr0C(kdFqtRfui`F9M1qyn5_ej6=5R6 z;;(rn%bn&X7n(Y@MjFWt0LKGcfFwFDm7Z(Q$TT2I;;)KYLD}IRIj; zpYULd7?9FQeO0=Nk@*q!{qaY$k_n6;dD#)+CQP&KX%cnP zIiC`A^RKL$30)uv>RI#fVeIGOj_QF{j-WruzA_}hLrfbBaJqj5{+23pHRu5zu)3R- znK@x+^mr9DLhcxlIMOpOX+lrk6Wi17?L#OkvIh(belvEQ04|-}oWEi|8A~DF139i= z`vljg56A6Pbu-s&^B)aV-m)HuX=)o3Gc&_BDD<1v7;HI`3dwLCrq|les@1F`vwq+C z!-Yz>Sv4WHr^!f(9sXn-=`#Xscw{bzx=834qm@7E{gOmtZQsre9?xu8diTtayDtSZ zuYr~qAQx$HJmE8g6Q&lalV@j|Kj=rg^(KMcjrj6my87l4kH_F~mTWb44PY&`^!igR zEUVNu2j2tVu-f<8yfewQZTD#!I`gpqcTZJ*Tbsrze945IFxGSM_i<5hr!`!v%2d1@ z7^Y~->|4U|02P6vh2OY>g}%f-Obfw&rQQ3hmM|ft*(WKK_A!K(%(0tKp#no1mH!yfVQRTg5K+yn?0aUr^;-QML@z2AbEfye?HtEaA~^63b%~f7M>8F0Knps zeqmJ`la5x;BUQ(lXVaw`^Q1lnCU$gz;@qRHQ9o=hx7t27F3BXh-fR}{W9JHE^ADYDu37g%MX zr_vp|J@Y&ieSlfF?W`w86a#6-pW;gV^;_aJ_m#u{^Kxn$?>cNj(iWFr(Ctik;CfZq z1+^n5^-n1sk!HAs1->Q>($y`4=+y*+H0}C3 zq8<)>xD6F|(IU?1M8r>v={($L&W~#&#-pQ*r5CGEVq`~V`?PU^BZfQy&DFt3aqd$r z(62$?WYRvk$Jmu{pe|A*QEYD!6jp*P#(`)TD?Q5fCmcl)CPkShS>K{_dz0&w55GV<$A`LsXpE^80-Al#(83{hwvlf@EjrO*S`7y5`Y#MDhrCy$B0a=q)B26p zUdwwcu#mk33*hh~;{!3b{g*iX5w2VW-cXHtIJ9xn&+==r5(aZdbTRke3d?GSkL%2* zu+PDE-N;h}RXO;4S=qN``QNR`|E-$1oETn6GVFbd-c@E`n$5nSr6gQL^em^haR501 zE0cg-Of+|OvE)YFlbNf*PNl+ehcYboP?Xnl!w}$wG+L#r{#|(Kpw;t2L)2n<6#`?k{nrxZFXfJqJ8k#~LSK zX;3Jp(SO6(xNk4`lW3?clcJK{r1md1{CTklwK-kw+*;sWc=+VICUAM|YzfFUQjq*#BuP7I2s?VM@-ZhU;lp2Gqk7Od?VrYFs!+Zeu zUIhNt2iW@Tve@%CQb!&vP&HO@qZF*3(f{Xf$*1`yzeM0|M-4>|#Kir(+fPl#CtLlD z7fM@3?&3FT9kwoJxBtQB3Eb#%_};#3*8{XkQV$XJX*o7M4RzlbM97+oo>seSt3I0E zk*=>d_%w7_R?{;y--~+HD6wCoI=eE))xcpnbc&XNFsG5#qJnp%s@&^&Nx*BP-iAn= ze%{jNEoLc_@)7Ivk(8H;JN$MvMzY#iIa69#e&3n0KBw)N6DP9k{Ni{*U*m_fqs5s% zvCIQZ0)L+ustgJ!n-}sgo;&bM+2PZzRaW_^-ld}|r)L9G!~;tY9=ED2-`&qnu11HA zNs3bK+3_Q?S;WlDo@l-W`N1Sl09(5HP09Z=ob4D@X0Wcji zQsrhZC9h5|@^TgqgYlvYjJ$zf27q$cF5f zKm74^Y-V&AFCQgou`si*MKeQ%mzNbwwWYfoY0(*V;>n>^^y>!3F+PH9K4`w+oThSr zxvw!Qn_^6wp+Vk6uHHZqj|x)6s7Q7TDP)m;ODPfXE@^h%X=+2c!r!p@GMxafya~w? zLV*Q?aLc%Q9bfALNwbm>))*&*=yI;Op zb&t$e$`BPt_HE#7*5C>l!M&L=;Z+xuD+CrHc8m~DYf8Wa5b=H|mQM!Au_j$v+r&@I41@2~r|$917j>uv5yL{maly~y zM>!@~U)9OH%J|aQyVP1V_HuSp_HpZH{=e9T=7;Ir#DDy>?t`^j;&~?Z+x_GcRyK2nyf&rK(q#VhUtz zVRNsJiPyyOL4G4l{HXa*AA&v97C%96M)zh`BjZc&G>bYuM^uhSjw8C3EBE%)7aayl z%(NCCNZ_SeF~O z^U)aRc;#$iedO3I32RQ?HWbul{#uW^(zD#wXvY=kCXw}h%Lsy5LcGS!mg-6v$$~+r z>OnO;IKeInS#)?(botQuuQS7_c4FXW%YW7lcwF$W1=aEy@$u%oZlS?<1m>}Aru^{r zZ{UM&U%>Jl%H&l`k9d0bwnl5XcnnJ9*>PN6Q{-Va;~q7pd5JN37~ZoI0jqbpy_01D z1t<>H9U?F|ghjcoabbVHm1)=Gnrlh&mQ(dmClfvs9rU8Mxkor<6jK~}vZt!tja^Tc zwCK(N`-YK%H(VB=USF#aTeA$Ct`}IDxrM;4j>_C1wGMK{zu))xFf zoV|HiQ|J0FY$vT+rGmm1t8}Y~GNo09R*|$7M4?C#nF-ld5g9^?0s#rEU9BP@vK2!r zDWsx+jFBOUBq6IZ3K)hzqjYRzVDphxz0CS=MT6p#$>(gUGMWe z_j5n@9XME5da-PvPByqpOo6W{7o*Ufx4~&Wa;9Bj0(;cn5_BJo4u!~(DCTPKx zmRh&r5`1Y=;tQ@TtbM#Ur%jeTL*4eKK^S>aVKFhoKVi*Gbp&G#8zC1UsamDX?KzM1 z+Ew(j(=lbo5V@XjOlzrq5tcwpEcaAZv|AhoRxA@rhiR%0#gW41>Z`_J7j0qC1&G&& zu!9;>m&5!D&~4P*Oi(eFtO6d0&1m9BSQ)-O4?k5~+wpF`LMo~&ek`d4f)Cl6XK@bg z;f~u4l~KmgQMPYQkJ6T0fAnIijVxl7GIO(H*e#d7dG^YAOG+J^7^|6u%&fa;_Wo%N zjh=k*1YSPLP$%FTdassvX?|npsR}yG(rWFDcjE+(;hr)6hB2R%VP09Z*m1^VQWDSQ zBa1Ipl4|#>VsE!xDy7)|6xZxh3z{ode_pOR;g6{~7>ic~d^K?u`(!Mh8X99qJ~oo3vOYm=skr zSt^tsO*DO`qICuh*czU+)d@>I;K@K-a4Z8^uO1VeeWItFgc{Ds0o1D)th}1FbneBK zuIuDuMi%h1@KE2!j=8Mr;yO##>rTpQj|CB8GcewKb>Y+^I+ikxhp*=u>!q$+H!u+YoRNFp7wr`wHgenfYio2HyPtxxNV zRTD}sAE`D-L6;ZcF2z7|A~^350WYhgoqhrsf&liNzYnvB94@RZqSsIsHb)v=>=bn= z=me@rW*4dx5T^IeUBQ%zQeq3>-JV{R9>4}of4yMujxXXkxL6&=@dM&fWQ0rjgdaE& zo?;pILr<;NlE=|y9pY1V{SZ#rwXwL~$CQ&0G(KDDJ*HJd>&Gp;8&GIF#U77*nrK0 zzSV(s-LnBdWenAZny9SN-40mvm<4^M)x@|tY^X-?KYqm+(P2@K--+{;%b|2c{9S2| z-9r9X9ZOV0_NvmD+W&q{X$gM|gGY`6s7xmJ{hG)_pv7ImxK=IbgnvW&w(DXcQ3V6- zh1C8SfD>-Rpm{khA9di>PIK^zga@F#a3E}y4T0WBCG;*n@a-;j6m;f7u+47=K&zF)tP~p^$)iCfBWH!D5=`I z13W_&K|g~PxaDf(B?iucTLA==e8KLnYXlw2W5M@=s|{a+7jhg!IpF%rHsL0>q1ph0 zjgZMb`xAvynkP0WsSW3X;dByme>WUB@|XD1HG`za!1M30w)Ca|Sy!$Rhc z)E<*fkr82YrvIpMqzRTqiye+B2I)crzy(OrNFY+UmSKG=)GB{0-zg!TvhB0W*6ne7 znMA`$-tv`M6|M;;@X2ql`oF8TOKpUc#N~$Y-YXsKADK3`r2h;E|Poqem z4k{pr6b}WLs7imijy-^<=7F)q^}uLo=c}VOviw|h!$pRQwKRAvIc{4=lj5_i_)~pj zrcL_=?0Cl7u1Rj@>eySGR;wH#rVDeU$mF)0%b?4h+VC`$L#yKMA#J1$ScaXU;R*5{ ztCsI}8n?BRBXzV=!**RFBURLX`Q+x@Qqhh|!`-W)-)^YiHy!A>&{JKAzh4NuS)d!X zBR}cJo*nLLf4^oe*>u2cDk?i|*WyxwV|fSwl_QW*pu!b+ErIf-kOn%_v1^RSOL>Ph zp2mu%eqryFx31TBu;OLKRgJGZ;(HhW&G(0^_#*|e`dlC?lQM!xMr5$cA0up(u@@fN z{Fa=*c2>BnVygCEJ~5Y8%V~+23CGv^ksqrM+9>^Lu?jJg?I$pNX_YV#0rG+@*u4c(QcejgF8xq_B*Ao@hOJYX(T<@405%Yb>*??OVPh+P}+LCI5pT`M`lL zto72$Z|bY)DhC>5sfo?GIC@cxUu;msu0f;R&+}5{K@us@A4^`{0npQ@Ckk34_wz~u zZ`frVw<(N9a_Yk-LDbQ4Q}p zR+Z@bsAvm=T}EKVuNQLWR+p@=zh5J-stI~L3wC{6U*Zvc%g{@BYN`ah+V#Im)?V$? zo}H}yEqG&N4-$YCi(w_SS*ipopMLFl;2-`KVqS5%N|(|)I6{=GlUueq?=Q{0vS)JN ztpC|F>c2;X=6~ZGe{(Z=Y>04oDVf?k;@gAUDwgl9p{qwjC@y-Xwg`s?xM)5qE3UvV2)q4kZW=8#jJYKiy|dCC~p=hX8s_Qh@3rcZi_b35QQz-e}^(Ph`94h0MwoG;tlki#WCbDK_eu1X}Yev^(b@*NO$gl*8V!(`zUlBfFsO#XM6ro%xChMQ4M zg*b*qZ!=a5l{DH4iyn zMrUi2QJ4r>Cg2|5E&E(*=o1x1>odK8ipcvlo$orE^=AVK>T0`%l*hy4j6;UEaApu9 z&6umMSY)xaG+k`R3}t7RBzh87VVeV8JP#!Z8Qd8}n$qy)g^uJDV076BE6)V@)|ZOd zNUrt(pnSS0DW+8sD3T6YExFHaJi6nRV=jD*GYkNl?0BiDK~&e6SP|idSN8&6Flx_o zz-5>AT!9|oRDCq;37#E+yc*u`Rw(S8m8;8q!XH5^3>cz0D)~xuOv@*L4j+PTi+0It zZhE|u%NmmhvXMk7e|0wF#otZBuWd#;KJblF@1+w=m- z2w&->AFp4{Sb~_-bEJE_%z5YanSM%eU)9WM?2e(n#*;$Kwig;s@=!bJL?L&FqmmM6<5T6miVXn%PIY~> zw%An(JH683`lO}%-TvgnlySubpFHYDyA0_8 z0M&B^sHM?#;9WX#f#5!!7S-HT_$lvZWUx=NFuQ(88xA$2Rn~Z!J`Vm0#0dI&@J7)I zOKNsJ8B;a!Fec{Fq-S#tLH6s;e<7Y+>o$Gxrj}v@gHL1mV6@@Hj?A4)?%XM3m_zUn zq-&?yUK39CJt{l$t)5=6x6mv+E>q~fGkL(#*;#ezt&6{3eKM961J6=-ph!bS5i+E( z+V_5q{*5%viqsKyCS`T8mUzC9WO1oS^kt5?R5G{-nC`*#)K0TM(^eP?zfsKi^6BA~ z{Oj)4B{PA9D;oTr&Jra=cq)+SJJsG%+AVitQ_r{3zcU;COnH@o-QD}X#b4lNk zbvd&E3xx{v=l26Ze=iUO8#+3Yv7zX$Vczk<4#70sFOS!gfGeL=ht1c)6A1HJ(Hn-- z!(-HKwqNk1>z%$HXdR(C?|-g?G^0G-14e2PZqHw1?t8-_g_Uc-jm~dFXL1+n)9}%$ z{FMe*8aU&Jf_(vRIkFP56zax))E$m@-`iW|$lZFnH;J7|6e9VHWNMn~C zg~j5?+1JJA+KLkLw@GuIu_mIJC#UXqB+9Jp7J$FzfQuW0iB~d=+B3ZEH6e4H4L(x> z{10e5uHS4nB}N0mEn=5mwo*yd?V8gZT(EyKaNQ(E&^xC1;wjG~al`31a`2}9`cbfJ zdLxqF5-IX4F|K$rnT@KI)`c7sJ3-P@>ZQ!t;+?`^bip6Z_+ateXAa@xjtpnjQL4$+N6s|5V&JHPpxXQCR7&{$xhK(S> z+7rE8c{NAV{P?14VWBW9*Wg+ffpdBOPcBnklA{?JP6BZ0Da9~M z=vEWPfgb^LXW#^N@LhE@^GQ=qcqdFbdnRt?j1+5h&VVufXjgBLeq&1|iC3ykGbA5ATQ=Jpu-7lVrXuMrt5zcY_KHypbB*h9*BO8buV6bE0P zL5|O@ztbbAs&NfweHAfh+163vtrcFsU6HJj=PJw>XA_C0Hg}G+tDC}I*xi_kk<7Wd zxv*jSxC^ypP1Mqch*%g_Cj&!vd;=e-Sn;?r3hE&;J=`&^l=LE_wRTwZTKRPKhr0e& zYC()`|Km2IMgN6r7!qO!;biR&r2@Gp!f%O8EjS6t6{(`uV0tX2R*|4s5Y9<}x#>8U zn0aCRw#d~e9RBt;wavnXRJ7^QDp~95l4sGQl@Nv4Nvc3kDOhZ99}UunT0~vKf5C@7 ziGekTQZEDd!l1y&^SYb87I$7VK0-BV1kfhRNto4obG7a8(m|wK?$eAN2h2Z&BQSG;3*LBT%v@nx>SGIX6!D>6Q$uw)x_g*+`4tipJ(jtT?DkSIQ_yoePWf5? zhev?yyesGpA3F2PeB{@D|A1P*l5YKbN~hIF3;HGS6KjMtxeSd!v5N>D%tu-lM!)6M zvaZQCrF3;lFn6bsld7P?qOJ+&+~54L#yyIL4x(8F#SSVpEbZ<^##xFBb?jG0V@cVA zIg6sqI!rz!94^V5=@dLkWe#05U@9X3R`4u2VFDI zWKC$Y$pRHQ91$;-r@=xlDPGSCl$w#9m!R88=^czO2>s% z2?)+L$Ai0ku%?r<5-jhf!N2MvCK?p+O%5$N<=s(ucEe%rzPDwQ^^Wh*ouL0KcM4V1 zjti2P0&5Is8Rj%uZfafaq9GueNcmpSRG3*`>Rg4`To@XvxTFW0u%?-tp^RW2CJ^1cfRL3O7=A(r?Qr8{#xyTOGf9N zZ(nz4O{=1bUF*uUEV5|--c~=;RD2-d{9$t30w1R)2xY=EgBQTOREf-n6ZMp`Q?a;h zNHMDp*ZbKXayoTuo)aWi1oa6_opS3n29ceBxPsXcgFheFf3xHh7IFqG9&5R2<4qot zhqyfgxfS(=NL$z6!eKoaN8gxXy;Ypyq^z#>CHWZ4kltUcAj+_PBGT(I;6RPqtcemdm?xqlThcW3>zK zo;%joI?+ud;xuY;{8LG8y6v7cMuRjdJf%txf{Q~WXJZTx?^5YVx431%I4d~H!U3lP z4G`$BqHQlX-UIm?tWzujSV1$K<-rmb{Z=CC*V1za5 zaDP689ye!5r5p;Zxial`@)hBSnu`{#ypOxiLo`!0tqpBP|Ntzy4_4RRqI}_c=!sWTNcB)6L!CpW1lOK=fCL$$AW!%n3?`ZEnoKHkg z8*lX=E#DZY;p7kc)mYBN{;+ks5=LtLp zcX@#XZkUql_qxuqxpo8gi&MY9n(LoBB;JOqmE{?Q82uYq+kx%0bi;qn+hJZYl@SS< zU@1p=m2Zg2gxTcq=Oe%MXjX*Ax_S{1ZlK#3|?pTwX zx*w~4wjI>vzm#S@=`gvj&{UPrMx~6y=~@QPIg?;;F_!TUknLfM!=sPge5b~5%;z1P z+Zqf3^05#14bea{78%#8@VQO>yHfE#E^W@m3X?=S-nbPQ4~H}bi(~h*EB5#QF<*uu z-DB4RjhLg*d<%@`d6QJAlQ<4_qoUkr0K^RXZy=`A{{Uh(|9^s*qu=~5K+Na=6~x@k z;PRsWD~S19+>1_Qf%2Q^DX?!6O4<+ypw8+6N~R}g;8hn}B@dvKdrpC$;pPEQ7zOM1 zQ^DiD0em{%5&5f(p|?y1$SZzZ2Ucwl(%u&u6;^$u8nsd%iU;t4T8eTQXcjK3gQ4GW z5x}pIaf9t^&=~(;|3uGYqaIITBx&vi_D$jqAX$0BlH_|&TE}uQ#^n|TH{}hySMsUYp zf^9@slHtbF6}AoXY`urP+w3p0hr%Q`xh$JyQ$oLtKJ`4qn}ueo0S=|f*4eyj+|wic z;$ZKdgf#0yFL3mCJqB>mfmivf7GRl_6+oh}daknT?$_C`dm;wi9hb{M*A3j)jDZ;+ zpz#%sB8(=$YVp?XL9dI52*93nRoMUf<@hyO|6#m-PO25}N`jY1z{D})hi;_jx_0;@ZnxegF1FGma`07 z+d8B>9p2%Ht(^Sd6z{Ai23B?+mf%g_viu_>Y02u}v(LI>ciRK>TYl~G-jmY?sjCoQ z-=N!!ouL0^r|R>mG?=qKaj@p&*qdyAZ@r8$Ixic*OY_bYbUC8+5&=Ok^i|hQ0ajSM1f=LN%gQ*FHD)?mO61AMUpg zoJtkP!&cX!>kp}LsAcAhdfn~Sp@r41TZ|n6`+P3s_+NO~%L?EsAKLPIq~c~n-15B4 zWFdGd|Cnw>hQAJ^^rN%A{+&$R7QQ3n9I`vE+T@>+AvKF-oD)5Y+Z($#Du~p}i~0h& zu}cNC2$i3to;&{1iI&_n_>T5X65^8_e{(8(+ZO1RZRx*V|1Yr-LnBzx7ZafqsRdJo z58e=4IE^qn8sua)+2GONMS+!7;N<&Q3iF0Cx6JvLhi5eYluiCVF^Me*GtNw^&_dVrS z>!%ChEqv!^NFcsFo}r9C%NNargOQ?#y%k4FJ(C(0Vq5P!p6qm2nz{mUUJ>+VKZ@IB z)xhHEGOANWfh|ks>;!lMCGh+`jn$9$v~+ZJn^t)`bc&T+Z5_>pJIc6`d6fL+l52O3@1^^EwuZ<47nJ0sA$WAm^%)u!QM_`!M?Dx50ziKRBA)^K^?V^`YhRuiFV+U!k z_|}fjV-@LRzS@t9S9}=NgM)sUNQv9b$;9iHO{&R2GMc-61~Q;!C+7jTSro6MZA5YETj|3y4;!r-m z#c*-~zwR|5y{%-|(zgCAgXLVKD$8GIZyc_r4mPm5Pn(TXqC-Ak6@A~{1A=Tc}llQX+3Ij%Zu z8G?+)MX60M`+`!UXHLC>Z<$20^J9ud*5&gz>A8cbN3dqiuzuYYpR`2R8K4M zQrAi3wzNw-pNC|yg?BN|AOVS;sPXsI^!ibP`+ZV(x{olW zZzdWMn!C~S(CmqNkDf{n=Kesj1kcB89+>L9I)owlkMyX}f6%E|O*0>}q4plugp zSc#FLlXeFmHLyBJcrFvvzFFvpOzT^)x;)z&$4^k+-;$|BDD)Xy&*ffNw++h;BXtv; zInE9GJ{mh7NB@gvw~J7@>^OY<@$gz=%zf+?7~s{P1k$u3t?N>JwUx?RALlL?#kx#O zjXlmE4Wl14ZFo#4-*^KZbcHo((?ncp(G|1{6R_1`~;0tYBDXPQrvhqLd4@X)&#+%1D=ny@$uf8@$TOkdt|okl+a#>aryQvJ#d z_`}~WX)vG9?K)K=U3#Y_(W8&+QD3Fnab}#t)O_pjVg&Y1``&>>#VRV*OYxOP=uU;~ zQX53x!0mYc`B2@fleh`OBFkr5c|0g%vEF4=ID9(aO}`Fv$p-&Qux?62ukyrX*$gfw zZ%k#k7aq50aH&+K7IIzrJDp`shu0*;PXnU-Nw_n(>0 z_BJ{cll-<4k@DjtupoBv61q+XNw@WdlO0um*blL;RZR3w>woNyPN0P&w-t@ks8&ld z0M||i9UBW}NA6Q~P*=B&)=piIVy1sXaL#op3>weVWT|0De%QX&C{TA8rL-CN6Lc`s zMFrh-z}PHpuC3XPnUFQ{dFi>}G~2V6p=Lu3dkg)s{^)0KHKUnd zEQxRDMt|&50#Pm$E_rSZFB-9W9?}mE{m! zjBJxnVCaH8u7gt;cOzTtsR@VZWISflS8Ai3AE-<6+w9cP>sVbyEDWN?>T--*NKm4i zloB&NaVqrppB@;?f(xj~WQF;T?Ky2hl`F9kQqAlVRgtE$>cVg1**UjeWD9o-=Qcg| zBBqguZzRO4lC_0tg;TPeGwPH&Mb&dKwfzE6gQWG0XSD&Z;Ag>u%!?M0B_U;;sM`+k z#S4?tsN8-JvAGyNq&OY}ID&QBOlNXD5V*#+U78DHab-T0h06;Y&sEH?<_oQHUTDjiWPO-GFZp_M-JS%r-`#WdmVsoRr zIs5|q)+yC+VI5n%?{gb6n*xA87V&bNi z-~8lh!Tx)L8ak4Jj78zxYi$GXM}b|#VZ$BFpQ&GC{;86eO20q)2i%g(29%*Q^>#<} zC+%VP>4`>CpVS4grufUhoSed#L`WjXn|2+|3TNgV2>%hhS;lF}fX}qvubD_L^FrL< zjIl+sh*YlFWH*J$at{BdE_33w5Apt;2Tzw$8qKQhI2@>JOiMw}>%*0H4GXcWm!Da^ zMmAmAnTFvxS4g3Yc#&u9*y!DfqYu;k>^im?0t}KLj&%*E&IUAt6;Ed*O> zY@;Y6*JqUJi$66OPk;vHF;N^3=`Vu{!V>OC{Dg(nw_nX#gu+#R*WcA9zI(i*i&HD+ z`Qz}``L~=&$W9)^c5hAIl{`l+oBAf(npm(%o(+1SvifbGs;`3KSn(ROfUGB)W}sh< zg7c)b*B)dvy<^(aE1zx(Zg>BhrGm0#Lk1I2`o&D9)#H7Lj#LfzQ@&rZY51e;BK(wI zlpyE>!uj(}4D;Erz)t#~9p!N@rXAZ_ctNud#Xehi+;Q16>5*^Itqo-p@XE16&?}RV zXMG<#^tH%fU15_y?r|lLTf&f*bq_$gqvH_S5O0iKw7Wco3-o8pWV&l_hzn#wK2{T3BxXIhT=o{Vq=pTygw!M< zF3VBK&X$7m-h9{C4oxnO8!1g0hLn3SUeKSqD}Bq)3vtPd?g9rTg;*1N7oBsUp$l;O zjBmA;HZz`AKkrU(ZDp}7c4cU|@rBya)%eDUxUkaQ;!}6r{K=rkw-WBgFD_=l>GH?J z5AD9MUvkZIv)05}ZT2o|Uqu^j#R7+F<5kHtDubG!T0Q$wr5Z|C2B%NWAHjZh@rrvE zVW)Ir!CuC^Mh2yrZK*9W$(LJwfAF1jQ!ERLX{6$K*$hYET3a2P&yuZ=$~gl`4BTA@ zg3}GPh9m6SxQj*Z`86>qoa?tZ4~4kz*q^%zi&x!8eY@38T&l6FdT%?e?dv$uX9LpT z&-^Ea5k57&{Fqlc4vj6Xg@Ngro#6*0s!;MvI8XqOLhxa(7G{#B(F(4bZ;nB~qnx5p$$>vt4lxV-{ zGgz@h9xYN6Ab{C(tL9Qg#~P8nmzjcV5q`utQ>jBMmgfF`%>j3!k^{D0%XeP{(ST}) z)!L4VIsO-{tai(?(OUBdmE*Owtzp96WV_5+YltQ|e*8>Q6kZ?4B~mao`^LxQVl|Z6 zoRKc`y1_eoE+TlHn7kvxTwlJ&B zNxpGj11ou0KP36uWT>7cEa9<~k9{f+dgt3KKjQQ@5?~ed*F;Ly0z{0lun5v%g`|`* z3+=&)aAHp2@u%54#akv^8sl^D$do3a$*X?Jx$}Yf9oZ3D*AUVDS(+xr_s*%uw`bvK zsqZW|T1=!W?S8U4ZtX>Fm69nZMeay-5qFp~-K#{U z`hA5qYF4=zjPLrrMn*a(jKgAlVBtXCXHGFgR3|@r=P+JlMfo+y#BG%lu<_Y4zRy6oo$S8ETtK{C)}B;Sh_94j67qt$Fw9 z7Ut1?NggMP!t*rhMQL-fq5O=8Se@X<8L8VBQ9u2e6VRp=X{uGfNe+&>VH{YsgsSn_ zL$meP?OXN+FSo0eC(4#n7^~$#5q+NfMig0ZthX4Km*C%>&kh&(!EypJt2Qd=3ki&T z`y{KY0Nr`;3tQNgUB2YWxOtWxe)C^cqwOrnKYX&ukFwc|dN>yley+4A+Y7ZXXGxrB zTT-Gc-*-Fc1;pjEZ#v{7x_JqtK8P0vVZ7BwnBc{D6p$RhK>~cd@0#UbC$*0VMV*jJJnct4p zFc^-+2g45kQd1lTZL)!^r}lXE7)fAAe%*7c-l~Plx#C~B0+D2Hcv(uBEccEIJrMOP zCR2dv(*h}}G;%F<^V@DvQ*nfE!7y(T5+}{vE{O~wJ2x~heO9GSd2-0l8K&5#`Lqlf zgL|YHtsQ-d`WLiONB0?0FzS*&CD^;V_a67X%f6SB@A!u3d?#2AQmj~q(^%d2WQ)YI zn4;@q<|F?@y_Lr5o~Jng{hhVgFmFD7f6IO98@wh3u$65tzNtpO&+9nnlNO+N3NZR$a{BM*WIy%_8?mmU!1 zSLpR;Dy((iHd+kb=mbg1bH9lGcB>l=I@aor`J;H`fDmIFQr@`i&qup}nj&`^btOKf zr!eBeR#+{nIc>nT%M+0?rzbrYxoA+fNJkngAzvCUOIKk1coagdrGx5-A^Qkf3PyWF z3*ubbQ44QXJ-MMm>Gk`&i_4eOE6Q}(XDXm8T_02JMs=*|cWBGdhte+_=&f)Y;NhGJ zlU{w7tB0YAXD-SXq^eSNVummv4Leo+v3cTb!=%T6eWk&{XuPK!H)7nk zPsV0`H0*p6qj21z;G}dUB}4i+3se9)Jy+flw`I`6n5j+1Q=Lm1gEYF>`tN%o@86nQ z$=e~@WEVL^tYzBeZtS3Bwk4ZE9~tt%K~BHR&syLAjrxVU`ch}afV*lGe%%et^Q=~# zV@Tw3Uij3Q;^Y)Dd)IcRulKaHEpty$c3l#Z4JC1-d=YD4P_0}_(9cg07+>Dm=K0$F73YV#~6&Yie8DHcylQK2~~H^@BNzpbj%okxdtpI3!CQeH7_OPPR$Fv zXMP$X*voQ0b#)u6=w0rOz_j}bxzFe(WUM1YJ{Q)(u~i^@caRRn>#^yLi1Zo0>X+-= zYp9#d;cEJk`+Zj7kJBBtfo57Y^vpN8H~=#2Dfy(S(US;QN{)6absv^0z@DEkqiM#M z7F_CmjCZEs74JpVvr{0|YK@H74BqXvynOSJqF>zG|86V^|8I8u=GvA3jbw?ia(yIk z<@Rrd+Mk?$)VPpLIg0=QyE28n%F9K~x2b)#3z3+q2{R?p0O{nn%q( z+MXUt_8P`ENDcQu>je1(e0q46@!ir-{W;9P8%+BQuDaP;^3k!fVZsg%#AC_1uJ>(4 zQlO+3mO~oo-QfX_@iEV@CYEa9P;pUD;fC15f;+w{R1SKHcG7@yKrz zrvY6ZOrq+5Xq9LOA$?sg>YRF{)AGhmVJ34IXsO}4e_@!5B|-fy>apiT-CyfIduZm( z#H1e^t)%@cvAM*u*0QB*?0;h2M|u}{+K7`g;K^9PN+W9WHwd4tozKm8fy6&>rKtN3 zUGQ|>sf`u>XXiW_4M~YnC)}KmV4ISmLkGJo^@BaVTYX^VA>eMH9m&`@g*WM%s$Dzy zZ0(Qd4ju%U+bz0&n?s_d~{Ry4h;KyUWxw7-*fAl|Ba6ibYRIp$zO85QMvTG%`%WVC`f+vmYXmI`eMHJ zHS<6_Kv4(C+4B#_=kOm*U!D2s>NDk7yX6&ui_X%M8yuE(15N%j|FQ?ZbDbsl24lhjEVxY#FJkW!d=MH@oaA+#To%Jmy0VJ1SS=0BSY-KT1gtXe z9S9F1*iN=>aSskc-{DuC?G6ejp!(9>SdP7q`mlkH>7#>fBM4j1xgh$&Y;rMK?;s;V z)M?bRnsC`lgKHUN^&S^(1=gV5_lvh|v07|A!oeWE>Je}MuiQzxhsZx;thPloi zoobW_!`T`S8&?=UOW5q!jZb|CB3cyHt`tOT9LngINtt{gmo75I;rFLvWfr+iML=8L z<8Utmu_|^{=_ZXrup$dV&g&WIP88v7o^cvAfg=OG@1R@#esBWJ`YA=^S3}81bPBgx z^P$s)b^=w1)Z=c)Vg0FWIHfZPoH;-vnpd}?Uq*iL0vy$K8Pj>2^GS&p8hYRSHE;~8 zj55w8P_$6L!z>d@ng?D$(y}5=_PNS%Js5e+dlSx+?vwQ$2p}2O+r9A<25Si1rL3IW zj48p+8vFvQey@;hUKs-mo+3Z=n!lrF_BS@@ParJL*gi{oL$z|Jv$eoXR!v{;>GD+D zonaZ45PV*55KCA8Hmgfu4|@8Fpq9o(kffXiN!WEr77pyX2Ky^omu&TQ3diTJxC{yq zwAAe!pn-_1Bs0CcTKRicLySA19|luke3yXS>tv?f3^KuzCF0t8J}(n_dhws77NTQL554O%wdn~B>BD|pV|y~FU5)gThZE2FXYs64ISUQl%LKix zMS+esBQ_+AZ0gTSM&f?9J6WE#>r9Y^yvSO#YDD#y@mOV(K;Q3`D) zv}JMSdYPp6U?_lxia%PMrAm=5#YrhNDEvM_j8Qlch!dTwnbZ{CP}FO$1P- zV7?lP;v82;5tMHtJQF}$d!-fbXUioc_z;!!W>Yx_!H?4yR6dS6eg+ySoxqtPf@TuL zJ>~T1i!LVmg1Q8?nw5o#=dRo++ZZ=*d$DjeZ_e|hL#1g9Q&E!-yr>KfMWJT=pG)(; zCV<%ZC9kM2E<6;6j-@5deqtG41UN{U{N2X8ncL=rt2AT6lKP(?j{AHv z{L`al(L)@OltDjC?rxAyGwR7dPvspHO)+jd2^!m?G@(%-%I39k3AxbfDCs=zEghiN z^~+;|=`Agn2ipw){L^r1h#W5Cig)-m$LZtkgJk$diG#AFX13lm&?9hS8F-h1HUR^- z>P?h`-`wp~?=CIYlJA|q_cJ!N(yPR#9r|b`x0ckVn$IPbzkM!5!kH@- zLPtyuc0e}KnB1xS=Y%Lli;QSr2xBLSG11|_v+ZgQG~n%`mkcloT`OW^dn1W|8a_~I zZ#dg!d|v}teRUQoqKvSRvK)*C^+}qPE*u6R29g(9?EIoJ{E_b-Hy>>P^c*;+MIPkE z`H44dmHz|j0%tdCYfoW9jpR$8iOilM{*yt@LH#Mo=|km;dYAtDQuHH(-SWB{b$H~5 zi+_&nslWcG$lb`T@N?OhN|h7oa!~Glz!;%_p*!2v6}AJoxiyhAr&;>bF*pERvbazV zFZX-nolL8XCDu)2_Ca!MHdSzSdxeCq?dw_jrTMz;ndW_oBW>Q7rn8lB<62sIB-vzy z&?JalRS#F7S&N9bIZ`dEA|%>AFIzY~ks&>S$B`bWHf!g-JmR zc>5BPWJEveX)i$KO7v|6~o|7?B#bmi%9_WT9#MZXEtd71orX}`=w@rcc#ER62> z#!dWfRQBmWk;AZ$ZDV^LESStQY-Xsn(njL5Z!*^z+;Hnoac=iTU3-)9{asmT0`0Ps z`jKzF>!ICgC+*@-6liN+2qO9w+mW~s!$y^{Mk6ufF6}hRhgm8h(eF>l*?)i0ZREHf z8r+fsr9&+(dwi?GFf!_j>jruv07W`bJQ7juU9Ptl(54?K4 z0Xjon64^qbVp9P4=fWs zJaMMios{l_4#7BhtoM zbne17gHAW^=j#5cvQewHRgx%pp`e0tB%UI%AtC%Afk5rr1B9meVT(Jw8&ia%FWsfe zcFMc1tCyBzd`xa($j74VLPS1k=b|fmiHYlqXkQk}aEM`81S@_7L^FRslaRJoKz=Wg z_dNj^r=Co~RLcA~VH-%h=~C<)Mq@0O|w zgcsRb68X;^K!Br$yqC?o5>yV4*J6YYH8}oDO+ud%qYTwLol+5Og=cDw%A*Ec!rzDpD#WqhLC_2OTcV`N{yFko>2&-SYhU&ve8Uky0g0Rl0ro6mdxE%)~G8o2w#diV^+HZD#leK`6 z=9Ptgw-SYG4f!7EYVSd$Vg@J=rUV#&73G?ERztN~^4Dd!_I~KvZDgFMVU_uJufFbm zk;4BZ+~ARkiV*2=_nw8ohnna%M)edc-JIw{9Er_fhkq?=?4(&~Dv zC%bDrD`Qix)b(EXTX_;DY`^`sl1-w;-ZjuW8h(Gj<}>onOWbHx$@PO!;=5i@c~98x z)p@?kkg9D`A+QSS_25a69k`VB^=av|qG{UH`lg$X=U7NkJ(QlRp`PvlV?VeET$+DG zy!fL8YMggAH`ZNx;J&3}VPDkC_=TGIcP=*u_wUaBdC2gH%?#ALJ<<=!ed&`m7+pZg zCm^?y-BKw9T38l91fe;|Cfn_UsSI0(14;O-%&jnoNAJnT{F&3e8-GBWxxxmz6^rrZ zUkuzCKUNyMKALpSo|7SXq?UO1Ctg^{o9VUN?G}#C5j}}?pc8+jdRN=ju-5f-d9^J+ zTiwn%g7Zl>!%QrG3G$(IZP1ygf$9P|-cH93E}56AvUL|^cEx^E)EgIu;@=$&591d} z>_~+pO*5WPbHwgFxfp@1Z6gowXnYQL#Dz41Xpsb&_g0eksuqNG*%gkD3J*I4X}9>9 zrE#(84!m%ej1rs_Bc5oy>>^wvX6gKDFFHJM3gczk_#COOjLr(hAF!s>@sRLJ@*|^x zg^09x+s4B_NO^Y3YEh{1{%LEm+CXN`HDFVRg`@w_#Z>67^tW@!reaY{QDd6_?nocZ#974tCo-*A z!|pX$EkKu=?F4pyPnMiqT(O&z;))M~F1Mwqwub#e<)Lg*7#`*9FD{7f(QaCf2(MO% z)nZlGzYSkkM#i!Z_y61NpXI&LtkBHvkAwYf8;+0{MwbXwp!kT+w~Nr&54^pekI|n% zISJU9i@fm5KLg+`U*S4hm%`yhh|~B9!%@hSG*~m@504zmP?iS(0{-oPO3i#qBX=7` zS-hv&a`d$xADsa&5@YqE4lAbXGl!2}|D}}#BlEJhczbwQodpL za8QbXt#mbPwq31Z75`)E;TNv0#+ZWv^NcF`r5)rJ*Ta0ibYx!Q4rE9 z!zmy+R&ju0lqo`h96@AEQe+52!mrkeL8OQwl@wAzWv4CS>PpSMCGM08PEj@+Bs@c}YWSAgRt(~+I(t3Vow<(}PB*xYMtUhPww6wav-3eg|@+pb8%3i+hX(9;L zrl?xygGT$jY@jwPRCCu)3HsZ((=Z9`on$-kD>ySL1W14MqCfG5?~|xvysp1_CbI&P z1kNEf+c*5w1qWIR{zkW43D0^oZTaIf@j@zG$m+e%Tr(_l1JFf{h9sJTe>T;uQD zhzGNdQZu4k7$s91iS^%!j&xB7zDJj+3wJWT?q>J`K~ zT?uWL7uPLWwc0-G$k-~{;jc)k{59?(@rLv>55H=;fBbUFYG5jqfhHSf>8~sm7*ge> zp=@Bh{L4xAp0P#wjiLJZNei%P51`Fpjbik86wZ2}kofR+`>$Utby$OYIfXq3GE%fWf&M>+ zf&bWEsjm&kgvVqm-DdRF{Z`DeF8P-lZ2vP=iNiX-iTA6)HdnlOi6f%Lw`9~;$!E}1 zyabXXLDsjEL!_luUl0=UZXxiEfJEZ$Lrj_0a>Cyr;yDv_I#il#sKS#1+Wr<-)PSTk zB%hXG2eKA}qZl!){cZ&MtdH7$b@jPL&?BddsJM+lepw~9evT{YK%XprzVG!>k7Y0I zJ<8iHHwoX)^qZo4W~|H#w#5{uisM9%6_}_a%`KP!ge!gp7>Gk+-N^F3U4TsuDyXfR z8vz#cdFu{WUw;QLVaG>D|=jiZK&&754qTO2wb(E)`U+vE1{$CFE~FCE93i!rUxJWJhm@@ z$$L)ic!HZ20@4CmMqFH_=WNAc%JnYA@i|U;s3%w2SGg%7v-f};x|$#c!UC%uNu5k+ z{I^LV0-spdBE2tJmb80;+8I3L-9(0Bw0}z86+^I@I`_e@cq=&eH(h-gL+es+VsUX3 zk-3Pf4AOCN4-|w(uy6iFdp}V9)x;m`ww~BXs-{I@|I|(L_wfk%)NFB6RAqRmP>>$N ztdrWimMG= zh{9S-SOkz}i+wz^tFW}%^hbBfC3&N<2k1mB7kWsDMTT~@&+&t(K2&`SW83k42hVb( z{k&O(ycur1#pI?9V7LROTEFEJS9>`QptLxVaWmTR zIr~u8TumTnkg?5W%7)2l9j|Xj0!~$?p`%t^$8mo|vL#itkyvn1S|POdxm7o^WR00E ztjYx#CY0HsYV4=#BuR$F_l)eGo)9xU6xkE4Fe^1$b zy}a$z^^pml0Mg?%(2dy!C_8Ah9Wzh;IH@!7BMe4a-3JpR-ln2EPCP{Wu3lxZnX4FD zqq)J4*bY0)lUEDdJNEy$I;Dudg))4i4i(6Jh*Sx}_?&ZCi~`jx;*)$93Fw1neW>6K zWL=;Xy`v~PSO2YNC2V7hu)#z15ZIBwrT{?cWM#bUaLgJUhx33}Eta9eKtB2tFQxGt zWPLI7=ZR-cC%*o+gv zqzIvV&qMcMA8Y=)5v(zC-z67*qpM)hl6Od1$cWTLwN4Q=Q19Fo4&A7?6V-&m1^lfCX4RjA`G(_ta8{`{6p zw7~!+sR;La!1_bNN>|(8YI}aPNfLKWgK*Q#>aO{`h3A+oSe&`@XB#lmTJsYunwtO; zAL|Sxf->h*fZ-Eb2JKD<1-d&B+b+i-1w_;2VP8ewTNV@~bt%d;rPP3TrCL5n8sSS?jsj*THYOkZ@3U3 zqCKUL(L{YELVv9;AksU0;X$1DMfKfG>W-tX5BjV<=b%!mh6*Y4!gxJq=i8!I1JUQ98`^vbKH>)EJb~eP4$riW%Kz`?o2l=U05EWihuO#Tq=Y*?O zANZad-J`}snq!>;Qun>;x&`J~Y732R^Q@11IOG7yRIX=Fr)br{wPZ`3 z`-nW6ttOhg9pn+lpm}$}$^ZDP;+bMqnmd7SumwH25_cifNCAIaVGUH}S9v zJMBs(<)2Mec5JzJw=qnS4irEZi{!Ar@Y%|=dW7POaN=Fmw9;&fy4=k1VMo8XU(fMl z^@9LZN`42)F4m&ED?=tjU$X~4EeVpe%n6NZ5GjZwtGer|{!jigkb*2XqhjZS=}{x) z!(7ojpAK@Qwg!kPx-a8+s|g5MAk9aG8+8I5XLwDX2j_~ z!s)nwmf3~$pJ8S{1Rk!5~!OutCmRL z?Dvqo_%Gt|to^_AFaj+na#(b2(LNAuY2V*3&#w{SfHx#Js ztwG{*HOKJC^U<}JxXW%rk&kmL-K6)$y=)n;yQ#>i^92vhHOYXbubMAUqlS`2E&@Kh ze2%l?zcE_0xRQ&P8G8xu^`GeIy|~P z7TNlfjEkETvG9NmkC|AN3fB5fJBjI2qVroV*^$BeW~e1)6`G;x;ZkI|{%b>J10lU4)^BOG=WeGRj1sQk9q@b~cEX*1}y4|Ks z5d(QsR$NYQzt@xDKcC!2D$9$(FYZxm7}lC!BM2)IWgTeWk%(d1bn!u)_;1$UompN% zU}=|-YVdVaD&0;qm1K2CHmk5miwxrB`3{yyWer$pU|LD#VLpZH?zhl;uZ%vdfBGoy%mvK(8Sm9rX>kZa;lS~$ zk0BN$ZGVZ5ez7Rr;~~;P5~CEzr;KX32j7o{14#WQ;zAo~9kq@-h;9P#sso8W>8k@J zoG6{XYLEaCo<$`}dY=;>b`!+~^%}K93opQHbtI0dTe_$aPA64DGazCLl&|N6PcvZp8#2sv{3o%rBN&X>VN|^Xpv-pDXfgL?FiS6K zN5~11qiJVe5i<_{YAMIo+5=?FvP9dIwVnlWNXt`yCENZev;D+-{o4x$vVqFTKlWU* zHAVQ|0?`~trbHv2EVcKJ01sCqX#VbYVXdf7WcD9Ufh;ch;OzGki_YPV^DlYJh&CW8 z4UX^I|Danw9&^L}U5d?o_?8Dub)N*^KU8QV1ep@5tZvQHe( zy_z)lnCGbtQ?pxI;ObO6y+Ie6HEQ*xhwIdnWrE4ZRjRxAyi#)Vpq3VqD?Uu9#p~G_c~)+DzNs=6jQ0Gxn6;CmfEUaSt=prUTRNvO%5KyB zk829dD6IK2TIw85=B8gCc>m8Pv(|i9M6O_#6I(awC>_IRZ5zHH`(e@@PP$SL%66NW z_%ZQ^4eDsaY%5#6RJ?%-MxREZG8aa|(VBIiYNab7TWFJN81zw7fT22)9=GqnN+{B; z!OvzHNiO!CKN60UIaaa|uD$p?{)7ou$qf^#fPn<}=F0i4-685*1VnxK#-09cUP$OKPa$D{RSax54r*N%@=TmN;(dobF4x8yzvZ^DR(N+JM#<-HZ$+}&$%ezFHqkk= zpiYSP(po|jHM~}aT;uKBvEOJyJ7>*N90>7heHkCcJD-zGXYokJ0>(oC;B|9|=&`!IN5H}?lj)QJ9@-4yCA`JbrGqlSCwA@Ukg@=zTEDDlQa%%L^i-XBs# zLDT&@@9D*v&YxrHiEe_)0~c+21k6+H0qV7`+*dDjgi2({y1P4-8Qkseft%~1b49E! zi41D_@4LkB^pPuTlGL8=SiKee#(Fa7*Mv0f==R+$gWqIHB=ogtgPF({#ldx ztZ_a0t3M#UgQYoMpRUOR5KgHN7~@~MrRi4qpP@We?F%c&fxnAwA%9B;U8j+%tQUz0<-w}*E|BAwCA9{E$Q`P3pe_EpegjG>q;i=5*6bnu{tUU=G8ImZvXcT>qb#4hdL`AM@=L!shW=7ke8a7)y2uH0qH!`;NkQ!bYcrRu56)?*=ME<>JyN@ptB z_$QgCk8A5^rghNPUVM|e^nw=6$t9jdFc_=VF*Xxe@@GJ;8MutjVkTecEOr#eb6X&0 z$YWh9HcaOlSh%0>P_}i)?l_BSO+nA6>ZK+ce9BT{(%5sh&}w;KTmwpNhZC~rFhWY| zo$FOiD_LZGB(Y9I?^3b8kQ}5Z@iM@dZFHm~U2-ONY3wil#H zIx=%2K=4@fJj4#=P6cl2lasFBtkZir+xIy%q$aX)yKMwXsakck*GlIq5hrR)F|ee(%~_;29opl z`yf8AdeZJ>0UTb%S?XR9NF8ZfqjDKN9kS7GCHQ0xJ$dQx_Yynfx(F`sASo}^JxqYa z<(X?01>}``@+sMkiubM-zb=qN7_VsW(idt492D{@fN6`*=^cK$wcC8|sur3AO^^jJ zFrEdfyl0q{+7Mc^keFXiTyR{&fJi+4&!(%{m$iUZVtoFNUe`N&`ch2awiT*#zN(O} z1B8XLAc>r({|KZUjp)uy>NFw`$;TCopCZ-Ushu!|9C%di9w~>~fyO}hwX!`e@wgmM zXXem zr?c@RzHXE_0+i!(n%1?jq3$n46B3A->+6l80BxB>#_U(evmeaEv5)TmrThI+N}Ze1MVjo7M-xjDhbF(>T_ zlzKkr^5wUDta3@0^b9TFO&npaE+sjz`{D*r-SCYua=+FjjdBgE1Ed>d|7i7|z~dp; z)Clq#(e&B2`n2BulW%5*ut!?A>Vm_kGi&aLHMy~Sxi}d)0vnY|;@!b3U=wBDPY`5{ zeV3lNvNTnFUB7?Y0b$%t<4<=-9bjR$rM9tGXz|JF#XW&QBO;$AJW_>r z6u>C_OZS7cXbtFRSc!0KBYw=xwfLf23<;ZHHg`Az*T&?=DXRazvQTO91(eDe7-|!eJ>*!q}zOdFmQnY70vpe`lM;Uu5U~ zaep*x3bKs{2v(ex=S7)G4y&OHdAkr_x5Ti_5FRx9`l?Y#bkwdMB)FNxbb`y)9iqSt z!y)b^4&rTx6*B(n4FJDymDr%NB+mE*09}1V|6D=6?bHVxKOFKI?|2En+OVDkjPsAw znhThFcEMp0c@NycFEw)o!E!n_6s%@D# zhKnJ9v#ah!wi(C8+o`8CBMl48<^@%TU1k0FLh%OekBk46MBT_VQ29YQr95sPTTU36 zI{elUG*39ogyS{N@o1xam|iR?ejJhX-1D_Zb74W{NmZ19eQ~d$ZhcEzj0#5HDx1s( z9r=C=-~gjl@dYg_R@r!4z0dx%hgr%vz)Ep7!qMm6b3f8FIAIQfqGa=9)aiQ%V?S25 zhY_-0NSR@E)NbWi)K@R2X@{tAx$YzHURnn-qusF!__5J^XWYs0>7&8=arg+aVlGt+ z`dY?a^m0HbwK7Ywuf?LKCO2>;Jmq`3QtHe5FdsYNsus}F;3}jhhaQR&OfD2@GPA}c zE`NZ!>!}*=vw9S(qb_%(=q&D7jm8=(<{&9b8f37&o{AAj^`Ef~1|2EBW|)Jh1O8>w z`ltIlIG`!B`f$KTs5Go=>qk9e-|FQ5)>K?rneER`R5xVx%qQah^L2^kxnJu zs**v;iJI7jp9fq^79I=azQPd|fx^o(P&`aC+Mh#(nO(iEvt@MtZD!m(05B9xdzG#KZHM= zqGSUt3?K{?C|2QJnwgsNGa^%vQHL?H zad46GSx95QW}mvzo2wZ5Nn5W9XwghOHohtODMVVuh^-d;=(Molto{^}_H3DKbfJ^a@lUkXrQ?@g3h`A=2+L&^>qSFDOQOcwQ>-x(L=wis~Vy~AgU`>-KF zcm82)TJEd6a>xE+B*Ik(Cfs@AQ`NSeR@;c>)9HjCs`!aNvjtOQ^Tk2!I)5#1+3?7k zY?z0NbfOTq@(O#L2zcC!<7JIym;Sg<{+>F;`(hz{$Kdo}E9yVXPW9>va`}} z)%C9P(IpqvzO~m@Gkbc`E7Y`qHu-4s6O(jzNDTU6!tV|u!R9AvWwuY091%MU4TwHr z(DVK~Zit+ce>MfTE4IlB=wYD(IvIaeGGT-!guQvG{Q7nnWuD|OKL(_V-@B>*_T4Oe z9%Qs>;f_5T^;myGURGxpdh3ic#-$|KOSS8mse1 z9^2VWy^u18;DzCz8+=}_R5h7~GXC(5d&#wuyS~T);X%SOZV4TGR&Z;d%Zl@JDyCL* zZ$c`?VAKbxrqvYOF5V&)zryAje=v5ZqD?%kw&XU**0iYQQL?YuoR>r$1{We^7~Kfh z`lxDWPVqi;$6TS}L4Oj)Wj59YtII(qXKF8Ve15Mib?N27_1o-+4;mg2e73rK&D4m@ z@h@F+f#xB&YpObRwrTmxs=k@LE0b(^QpGZ4*o%g*ABMhPG(^}Y8nOkrn;2u~oM%(L z7p@W=UkK(H0>W_*%7P3H?1$xA_DZS*3 z1d4}HhWqogOf*H|qn_XURBH-4iv`C!=JFgkOqUJ( z`294_uvP>wkb|*4ORPRYgB5^sCR^^{5s9gqMEAwzS1)EHH{9==&02&xXGKe9iSH0^ zft@ZMqzIpKj=$x5s{@&1kB7^3UpIw?goIQp+}ztSM9EWzKagx`fbO9;r}Xc2d{q11 z?G{Ujtz>$KJv>%kFGBHXbsYvLMSyt2QS2Lqv4 zIo6N<+_+n#KBWl1<=NuEEWlO$%|;_6u#&vQInH_Aketl}?QJFUO*^1_Pg^=p_guJM z)k>9Hdn??5V$gIlPM=j?-FE0EQA52CwVEJybW4di7Xu>;sAZ!M?=kk98Gs`a%Lt+a zm%ENfH;+8TnZ{llPdkm$jph1#v|o>Af$-#$1En+{yvzs-WV#q6-Fjyk{A=Fjt<=3~ zRdUqI^A1cE?O7cZEjeSKFiwGwYUzglHr8y&dtNkk0vDnos$d###t$&F-XPr(7xG|N zAvPNK7Lv@)Yb0!Y)@zsym$BxsGq>;~S-Cyn;g zcb*#H)3bM(WI-eAYIC$jQBMr-%V$108MW`m!4^k|s`C7UZEZSAbp zHUnB0FKYySSYM47t;%&ma0zVzNrSCL^G)sB%&(iMU1_)*|7?ncKG$3wwYPLx?S>+P zLl!X7*}PfOfM+t)!iH@;Hp1U}tL?#qJ*iW*w6*xM3G=~_JYOCh{w-&C&DRCR##qeF zO$FWu{6ekTEkV)}&2LGS@?_99!X4Lqu8VD#u0GcMqOsSo>{I1c9R|ff(dq1+s&w>H z)-;&xGSn^Jjf;@~@akU7ltJu2;dv~JUuLRdJnF{mE@jf$t4MEnI=$B(sa+0+kLsz3JVpOBJ^2j^fOIRh>s$HApT?l6Z;V5XOEkyP z0ALri4635`fYU;TRccQVC}3B|e$h~;=eu`&q7P_&vqsy2)E(g>Nw|8i6o=)dS-Vg- zREsU8X)ugF3w@GuIW8idNc!RT;e7bLi=I+LDFOa}tR6eJ;k?>zAll9{To@#WBW7Z8 zfX<;21S%XvQX}!0x0vnobL6MtmUq-Nmcin)Fp^aq92ij|D25W{jtRHbP==w*MI|5NG+pAp0CuetKoE=V|0aRYgKLA|un3CK+SDiJOGo~zR%@<65Zy*J%e z*`@qTV=>;#I9?j=Kdw()F@GBFG{j*SY>Ul+NOryb(a~{zj>F^J1V3S)Db)O$P1ab= z69vYvRval)(miW=?lCfq1q>**U6W68{k&SP^6S_;&3jJ;qThOJj;Yw1LdBMD@$TGh zTe{qo!CoFLQ^4ZDo-W;EjUtvI`403F@@I2~5%RmMfCiN(LpRxJ)V`XF#7Ko{Aa@A2 z3_f-RxKIl6-BZ;QKPwFrelWW*I^Y3{)PjybHe2VXeEwT?A0ITOzP`jc?tSq=v?td8 zJxqfP*;YoWiB+VX?Bq?5m+2`n#ZBq{QsTl~HHpE5^H)cN?(wDjp4lIFKikA)v9u8^ z7N9L64L2{MA5ZxUaqfXud^wVgmb*OMwOr@FI+KocHSBN#fgTvfjE}< zixp#Ktw0;@wJz>?k{2)cy*GdjD_C{#N}A%4FNog4w(||OZj)#n2^y?KiVI*H@K-PX z+2o>bfO7U7F!CX@abeuH9oddfm#AK?w-*M3v8>7T@BnnTPGXOLxeEHXaUAi1c&b@^ zA`}bGa$SFS>O##j_1&){$&V*^x+Y>%7H;b5Y9Mcx7GIM;!EsT$d=?46u6I!tdL8k> zIn@jt@mo&6XbQS${BUs!|22fZ&G={RAPvERveYqS0hx1Vg(Y9V><#jo#n z5z*JunJ$L_wN(M?!Pvm}VWnAD0<^sAbpcxFHnnB;!=&8FFLl(E`s*673W~Gi*gQxd zPzI>||7^OLX}9+IRMydh;DTCMQp2YouK=ys(&d_unx8y;gf9N-r9v55P78^xa*wEwEk;Clvdufc4^6`kN-n0AWv*w6$^yA-tC9?q zo`S-^Xkb)hYGaXZ>Mon%^}Yu~W1)=PRV*#hd|aBmx? z(^^kS{uSE#ccES1u5<5Dh6xFw*0|hAc?dLH`0dQWtC(EoP_+)S1*%Ztu~iF+X?M;J zB^x~FgG&yU8BvzO>+WM`X#@#ZJ_ourU@=6vNp=?SAyC(x+)-pEdS&!m7K8lb&8fQ% zuFpb(D2<`|Xt;MTA)L3STBjEZ{23p_BU>jk!qNkdv@ry%;*prAKvflO_n3u+lb z%9=hnuMPAh)~dk}eyACF2J^kqPQyBj&UPs&ZgMO&34WhSE|xnqG#!^|{$xp3y|Z%% z}LKsa0J~}+!@i`WFFz&KUcRL#)GcWd+*iNF-E{x(9}|t2(!|8 z;SNsU)LJ%r0IlAQWzw=T(>kZCpZi9t%7>G|t_LcPxF zT0DPSDJDf%hK4#6+O0G`q@~)Au^29XxqFhypk~HZZc~7oZEPELm;M+LIRaY~})H z^PqC+TrM$gbT9iQx;Lh9&um^2j|5m8EVmDC;R^Hk^sB9c6Yiq_{%k0;?rwF8r7V7CG(fk5qizK1!?7{JO!X%~Q@5 zA1Vg{9QsyuphkxW|I9Rg5`L@lSZHkOeJBI=!CEMS+OXfVsK!xBeM0_c(|>CS?nkTd ztf{U>1I^zsKz`ZO=tidA^OvBRK;&8)*(^YM{klfL*^+(*5u(ioB|!MA=DVWMBIUj<7Y!b$3)GHg5L zH(3^<(T>f`f(D7rpwMv7;h#-5oC^Q}LaoANp1^Afq>qhhet#H0CG)=`oVh$L-y8h= z<>t!rxRT_$CZF_eJ%z?!ih5T0 zSUxT+zs}>S@!}Jvw&GPZR)Etx_dM-42}6x9s5aiYHC*)BofkjYr#crECdZO}Rd-e| z+Th4p^1~E0D!xd8m;P(zb$^$+*?{oUB5Nz5oiy?+7DcG9Jj--*7s2_uY!*?{wn`Az z3oFiFP^TYA45-~>s1OmXsuqgkknK^b(vP~|ol>^gxd8>~i5BAo%=m*rpvpH9bbHY9 znz`^5y7b}Ou))5%aj`IrwGt9iq38Wg5u+(a4gJypJQlYlJl-L)da>?)qez0yyW+z( zmUPe2(itmHN(R*tIE&#&rn5NVwf_iJ_Z8N4#&y4uENDZ?z!^%osSmAvb@7YTyOQnm znx>h4GmRu+%;jik_qIO-+lJA{y5m3gt9blAUzv`c1aJ6JxYZ2oi?ppL-ry<<`~ZuC zc~DtAs13B9WaE$2z9WG9K4tx@7;n;{=VyxiF8)z@=#P)xxdXfIzRJ-%lGe}MOj+Xl z|E;o(KRvIM2QAKF?zn8)M%XZ1sIG8HJfOfo1 zhAri*qG0|MijV3gpKL`OM$X>e2mgim<-;;mg5|NF`Rk3Uw|p%p*6_IN=~Xrx+& zUV&-I!Z8uGnb$eaiPqW1gq+g(OG}PZV3dxXB@RC>&O|orh3Kr&3B!hd(a^y_m7-N$ zn#XEeej4L8D@dsSG#h-Zd$g>(`lE`h%9U!>-W6lpqXp$+$g_pwFGHUFmQJ60T>~zA zouoqx36dKv28@x-WcB%Ds&v4C%@phRYrr%4>}q|(OXvJM{qZ|W+tDO-ITpd?*@5-~ z@L-@*u4N*AS)-c~$yA6dOasNi?9BqVqw zB;4BrG;3@ZEzEduRU`1DSvX=k{o9fCh56#uXWun!Zx8i}2Nm|@ zIXqTLo`>E-YUJOZE?IBP1!3!A07ZOi=)V^phVWzP;1jf{OsCu_58A--hB`2O%oIta z200nG-P+mK@sh3@v&a8#`eWj;m7$qW3JQ#`S!IWqluNu}^oyY*5qVcGrlWvk6qxw| zuF#QKVH;|6kbhZMzdDvnu+=as((ZTujj0l$VnfEV@t)OxJ}boib(UtMwG0d-tGP&t zj>guY;&j*C;VaFAS3H;gRpUsCw@0uRi)#EYAYN-Pavc!qXox6Mv&D zXXOt0-v~%<2d#DYazLSj_p9wA--3c|eTPY$0HQ1JJ+d9QJ3*kY!)Y=*BL&<|@X zCt7d{h$dcUyKFqWbOzJ%B8Qrc(t}{2Hvp#AjG^}+MUK&mpzHPp#ou2aQk+%N?}h)6 z_l&!(WHtdSx6wt_cdJs;Q>reNO?3H93$fQ5H$IgP}V@+V2bz0DKJYbp8mEn$*8t;L0q^Zx5vphFXrxtcG+uKar;0H= zPJs#pwCA;Te~-pAg?XvYlr|P+bkxhwMS*rV%`1jG|AH!_V@5qrZqA9Hmz=7d>zn;A zB|;1i2?0uUh5p{hX?aV1YKi{aVzzr&E%@XXsk;G4Ej~NGrQg(BLC|^j??OLSi}rBm z)%M5`P2OAR>)7w1u2COcb9Z8`L(fF85vXiGraSg)<9N~Sh(aLCU{vZkPkOKY5w(7a zGSwE@XHkusD%dljxjl`-efx-%m4Z0za#T=@Vq+*KOZMIKM2h>UK)o7i&-Lj772_Q+v`=2MZqfO`Q zt<&o}E{;W|r(K#R-pyiJr7d^qtYUQqH$5@DqstJ`q2LTXmweSK`4^YHnU1+8-&MbB zTWtErXPbbFoezWbkeeQb2CjqD6}L6XLu)M=R1?>@XABitFB7LRLHvl}DmJTl$J)(k zWjS)fvB&7}TBh?%K~EV!m*xKuKt6K*2k-9-IGN-E&+lSA|1}J->a>HIF=a68X|e26 z(nTi0=x=|FAnViHEB!%BIS5qlokI7~wqG+Tx6m$|Z_j;Neu;Uo=L%-9SuRnV$|}>$ zr4GizMEq4ger`e_toTXlsB!g~(=W@Ut89HE1vxL&?*ei2+MGb}LxMQ$$9ey}pK=eD zT*WIr@sc^Vr+h}61%SLAE63pxeRDZ$XYM-JCM@g6onEd#;fV5Z6{p@WHc*M8tg8VK z<(*LfIVj`Nwz24a+ykA8yr4nhnJ2zxR>u&t|ed;Dl7g?7TK-^XFegPv%g0BILN)@j{Bpr%-6f!gkuSPAnW*V87h*t{gX z8k*9@VriIl_d8yUs56jV*h?G`*fq?d%h=zwf-!l{b7w9r@4>p&XPP_V?V5;lcp`IrRS#UpX;v-t>vugVq3l1T5>b< zgKf@uUCEPfU+4%h)N%hu zhoyQdRP)QwH2>stXft-buZE)gaWy11%;aF+y9sQLlBJ$L6}SGfRq_=-dGKWYLhP1@ zO4$I`L&WQBGmfb1pTnc*CUHhM06EXpxD#7YoHC_NTCgdfyxeq(V)ZUimlN!twq=_9 zS~3w*%~vzyMtPZ#fq-nwd6oE;#jc8z+w7=Q9wC?9{!>D-@uMGJ5{IxCvx*PZw_qYkuHJq7DB_Ef@* zeul_)tGX5GNS_*)?xs&f6#0*q>pbKR9H7M= zNoQ~wCVX&up!9N6X;G4EiL7{8=ov;g(XvT<22?Ix=TO7XBEqtQd#Oi2Hg^5%-|u?F zo(^r9%aI!G#uz)cEx-ll;$tg~H?Bxqq#31ok5Rm~j>aNgL7-DQ2QzKy=5W$m!Mc&+ z;5lOm6jfbMJmROYCXbna^6^JQjIkk+gkf?hVQSmdO8n0r7x?I7B<_b!;4Xb>Kc?B1Zwit-D( zto|(y7xb%wrP4L~obbb0P~kudjKn>og^y?8yAiiHc)8@Rkg|s~G%9Xug*GJc?)SkS z=s0BhMK!{-)pyQ7oj;u?+mD^h?klJ#93LTEp4L@z2C&OcKo!OZVjwT9O2bAE41|x` z*A!*yU#9H(sb)zZBlJ8i_}4(^j;=lA2~+V-}Ln&fC$03uv44h0aEGsrso zXJn5Sg&(2{Kn+2$|)rx|f-xe>T?LH=V;y+a~dx&5yOkoe1^(_6r z7ON)Tw=b{pcMAB%%AsCliWxu16LJE#!oo2?frC{w&_J!Z?@ z>OmOn5gYM^HpB$Qpz~{SPsp>e7X_PF{a$j0W4Kp<*ksP0j5NJf()2debF+;6e16$O zh-PD8C>d-vW=J}HEGDe@(x5mD! zuc;lZT%=CD*E%XkeFU8WwzwC0uvHh+;DC9XA8eiDV&{(2#(eg5`=zvj+2T(WR(A*^ zzB+gl*0qjlpa8{SXdKc_7yOmB#8;Lp&fGS>spmzjJ{X;W>W#My&5(S2TByE?`RwYZ zm32O4F{sH_#h6q$`SqEKj^YeUJ}h+|m|m(^>g!s;)+@15-H6V_q_w|t#ec!_lce2B z*f-TkfhZkPbOPH2CIQfEU@E%!z}MAQG!6C;Aqgu09In09xs5jB;(|xs_xtVPFXT8w zB{LWg?Guf>zc8U$pGIivJluJ>zLx)j6?(U!|69@jH~gz5bZhhkBQ^f`3C35IZBNqG zB4JkzO_fGdYg^ih!^x+Evy29I8MnXSZ>!yoCTRFi+}l$RxyEW!-UsERBWxrD@WBXf z2GcEoYY{4$I?k(meoKADho&622+0$iK&JKe++!k!W!(sjp{S3HI>={_R3 z%E-JtS7+cad|cB2xWO5MKmFZ4dlVg3Z~vo?qy`!fNTSOj6hH8amM1T6j56+uVfz~o z?gQ=4XKW-`u{yfzv-}woGo-X7i<3=5(3Q8gag3rq9{)8+qcT%+mG==^)_#i(Hr<& z_$0J@v4Hi@ri1ne=ikb2H)6~0r#a$O`g}umtys)MJw{drqLz8lu>@50zgkXX%m~3+)VDf_~g=J57U)_w`?Gfxc!GYJhOju!B>CL;va^>-eOX%*%Ki^YhNtbV5vSuMCYw|(g zow@>_st8#TscPdh6U2u`FXt*Zv!Yq3fE1&#N9Q>UIw2hO3@@Lvf68(PVjzX~Eu$^y zY-5Ae1a1E!hB`~mAoPJDyk<`BAJv5P0+`_m&h{KOU)KZU{%j5etjPi6Y65wI= zsp2^$y-MyrPmuh(C$zKA11(HD?sr*#gmf5rU;IX+mfGEFp z=y@hAFb86tFFZ<3mm4CKStCYX2GnmWVqq862i^en!hF9OzufsQq+94`ZZEWYW7zG+I|f1e+XK6XvI(4rwOHQtT1N}jKkTlu72 zoe6luNtw#u`dUdp9h%4sO*w5a$DcI;odDOFwD&)2SZ4j{wsEeE3sYbv5@z>SS7)$(Y6Y}nDW&?iL6`i%QDFIsqL`MX-9(?#ohAVj^E@&;~mn9%f6oK&hp+ zcbBcQZ@bAs?9Xm{+k|#f3)}QB2nbl1p-+ZU%Z$fS!uhO_jz+Lri%`U?K9l=JhLRx> z_i4_cH3wI+_Y^xBM^lij`XG|HdUCQWzv$4%#aYc}A@v+dcKRO!nZ=z$ogT79Qx(2M zs@tUigMyxViT{QWR}gw}CRuzn`bB$VF>?!lp#gI+Gea`}Br7K3`n*0a93|jD5HCh2 z{Lf03>??nJ*H-p-q@;y?9Cjr`brxVQ|By!Y?dehMbaQsgs;S$0D&V94n?EEU-~o4k zP?|GN+a^U_0aB6F1`w-7WUevQU;?z7yF5PawtqA1s3xMrQcyjaJmUF7s+9kZ1=;8$ zwXF9OzctqgICDmhmSKa9VgP?u+5H%`tn!P;K0JQtIN6N(L8Jn*g^Z=7E382r$(3wy2;JeKa z-8}yAFo%Z?kN=PKYT}~_@ni@`VZ{^yKW+T0dJ}@AB4t+@NDhqnSvNcA@L{4S!|#Xe z%lm>fuKVhavNe}1?-P~7+DId$2#z5SHZFyCydXB#q)TxPFw zKE+pe?Wi-_l?bx%98z%xGy;mHe^#4La|=QY_}NVla5aJKp%hxe-xmBDKtYNDcm__e zHjGau@`VLNku?6|Ui+rkLHfSGHf_^8%S8F%L!VIR>a!M`RT3C30L>ZA*v}Ar`CDva z#2x>*l%H!(hUI?uesT&c?r3f9)sfoXRuafUY|dvxeut~gxyYs)5r8B`%YJt+im$o_ zUeLXKtMm^?zna_RWvCj$p>xoDZLcGsG9?pg`FOwzrtE#SUt~Mrk?*Xy8>LJY`gNmsk(qKLa16H=DFvzR^+di zZx-6=`d?I)<8%+IeL?*^$!okXK1Ac9I%{NucD+rX6I#SmoO_knckS>isA`g9lin?} z$glil`f-S1t6N90>|tfd;!B2;AD1J=yn%a_%{i<5QQ)u*B)>Rv(~Rt(hphc?h?iuL z=!j|-qr!C5K*rT)=8w(jX1j{wCMJVdf?2ToTTdq%>*|!v3L@==3W%>86R)0(Ti}cQ zn{r>KQ@k^5_c^t6phJ@XLfz5qTO3+WnCxW>AY~nuP0GGH?3d6$dhuOl@MF}Wi+XD* z3hbF!+Oj64l$%&b+u6E+*sX|6v$)_*sS)WW%qqmq*qiL)s zPeB?4t0{MRr5m5%DT#Fvmz)kH-UH`bKkSAv8sN`!QRCL{8{Bpg@M3f%ZfR@TzR9i_Y?(6BEIC{o_tYdy6u zR0oPu@B8)abRo5`(eaGpBsu(^3n-~P`j+O5`$16(bl2maXWncEERrMbk+iD`DNVuH zZ5?-pyNUw*h29AR)SUAx88w17DWIwa-JS|>RH)i`fUOM5x{EixJSXe_**VA3fyT51 z&LR@_sZm1Z;1ZEkAcF2|{?132asKw#i!ry+ab z*A7Ge3yV|s8b1e@L4KPCm^vc?>`GM0|Z2xv(H9SDOil0mc z-x4TqZ#O0q0=iz8+Rw8k+q4oK)N+`J?;uT1s$${4@!S_I|0tb?*P!B`;D)7>vBtQG253XEAm02BuVw-X-#(%RjF7hSdF<#(dCx$aW{`ZCKy}>uAFkW z!>e~=vZ(VG`DNaA15+)V*{03Bae{Jmgei%#F~h@I#~R&m79!wQm%#OaATXC;Q3)_W zmM|RCJ0l5b9%sV85EJVbEYjLOUTQO&+`(n+jkdFV4Dm$_X9N0ioJ5djz4%k~LReh1 zxlyJFUf0DTNblI-E&wQLHDQV)egf?>Bl#4K##Y?>LB!69ld|)w6SCOmd7P>(&;t9 z$#AZr4T=Sx^4^sNWyo0UgEF0SbvfOS|4in?m^7m8=PhfbEG%FEzARi%_*q?VpdB7H zDIC5jjZSgMU_(ANvaB2u#q^s?F z41xD=4Qr^?qXb7WPgfO~X8y7Yv21=*(Et6vi#~OhVg+^neoKQisnF1xr zK}MBBqro9hhPcNsP)dBtA6~T%cH{VYk8gk`%4Wzrz0Ge^!Q#u>`@3Lv>tIz0@xYI) zk+C@>wA<%SS5v4B-snH5OT9?VHk2-uJbP$qm!^VDMOkbs z`29jX^@4&Uo5N9QbJujMep%a*;?Hxd>D__>2K_}zP_q=F>sJ0v=7p$$vqF)Gs;o1C zO=>^xlg{6#&=L~XP^5HIIX$@;9>vdC5$~p)1)%)fzE`p|q{{q~jUIUC zGc3dM#pVN+oHRa%Z8;3y1yg#Hdk#p3d054I_$V_Y?kSmRmof5Q=&6WVoCaZ+2D0B6 znh&Sy+1+|95At|YJsRzZ*MKorOW1Eeh8^&bT5t9?A7KOeU=G|J03(BqtJPGVZZSax zv}>S`N~CqjkbUP~MOjuaVeD-N)VN$h3qH@o(d;WiVmkn!u+t6{ zz(1|mMGzheR6AQFS$zfb15~78M_ueYSgNEH`UxnF&^{3|Y8qlrqK|2~oA_mMrvC>1 z+}HI))tixoP;+^q;Ru~uOB!b4AMkLcWj%mqg(7*$+GToyLo9!#7Z|SoK3CMY*m99) z-`?8F8%^8&l#BNaS5U0vuFHWL5=))ia(#ydEexM9>nV)0R0o86bfh+_ps!r?%>pelkrTHywM!VYObYC|F)e^0xc5u2BU&BFpe=V-Pv^ zQF-*Nl^BR!Z}@-R`R2~ym*V?ARG&v|E4#JbDBhegoj4ARZjXWx7=2FC`;P&Nq05Tk z;+(uxZ$|0T(fS#yZ8^`%_W?tJwv?tQVVxl|dQ7)4__Ntmuh#{4_&u(Ym`5+N6{jhE zk@$>U-OrkC8Wp>4;6J(`S^IR`*E)s@xDUrvxVQodVydDosYRY%+c zh&4XuDoW_MeT2mN(UU4|>~4(0#FvRoB*j=bXdSyi=r(Y3>^1nRdm;?k4u7oyI)K=A zciz5u;NYABG8_;cG2@QTqdn#{y!mt94LJGu>$!S|Xot_;zq=V16E>IUO63r=Y1$Pn|f%Kj3-TbN(Kae6`lwyc&Du{#l$uBIQEqH{;0| z=L?hV0)5W4$6&{B3j_O*sv$xi`8Z>!I@oIj;P9G7EvdlqUpSsi(pYIj3@4Gj<&Z8t z@P;5i0w{m(Y)8$5g4+Na+S8U~?9|aT>ze?3#kR0=cZ(zuX)C*k{_S0HUn3}mrT`5% zbb5+5#aJI_DvWe#CwQpW)6`2Z7XA{4>K;UZclCg&5az8}wrn$|f7sAMBh*tgl7)Se z^}rs|IA8eyb(sR|Onz)yT%vpYO0-+b9-_+6@tFcJI>83>k0Xr3ZNmutNW{_Vid?EYXKn-Cr zxw)NIS&aci=iw*;eruB_gY4RHVn|VtP%2wwE76kiIrQi|phNk3hK{#xby8cO(Iqw?@)0+m4fYBUIKA5FFdWcm>_#-TVIW5QUqm?d)qH4*zOcrw;9Lus4)V zn?t*H>>S9ekw#6J?_agHd*B5Sh@h>hNnS#!K%0q{y-ut@`;?NLON zG**Fz&Vz-wRu9Gq1DF@-$;+wO-m_XSQA{5o!~kJE*v}6${!sZj)1zNfyi4P?C^PUJ z^b2j`ze$sR72w)B+jnj`>BmP^yS8{e!t4twV9!r5SM{AB+0M@{9$usqlzi(i1H&7D zH*xvujmC8`UWKVwU`nHZjQ*nO3_#Yb5^YO<$BOSIE}UC0Ne4c^TVkZ?1U~ROE3uAk zE_z;2=y9@f&bD+W;v$PgCl!;x`E{2#2k{a5C6~}r)Ps0%jZqndB3QM64z3O?^*P#1 zVgA=LcI*g0TVJfW*X*tLuG&MZTcZ3PCxqXA+oG*Nvx z0-uOXBW{O&NZR7vL%Z26MocBGr8;uN^=)WGn|9>DaYxqu*89x4^4tGEa&rEkY@INN z`>l8MAudlG$qwHF-rCPgJ9_SN0~)=Ul>#%pb~3Ix)>~jlg$1_&_GRT?pugVEJx~*! zSR&57!PwXESN@n)YvStz`%di{34y#x8zbClsDs*-T>h!vH{g5sK z@EC-!w?=C>OPIOaveDh&))e1filQGU!0D60|3a~KEeBsHGJsp6uSf8TleurDBRFhi zNIHg&Q`+Kn`Y~JbY(J;$>Q7BjnqKTS8h<|IzaJeS6oLh$8wNFVLn89k4{ep-m|x!O z42Kdbu$Yf|djkJjWZ;WSc=+GJ8+j#)g_xXxisN$%i{I3LzcSmF#p~5h zto3H!&#`&0f595OSZ?>awc6Y-5a9ZUfdc;Ig{Ndz8J%TpRTs_4MGd%XW4tqFN+TdxYnB3vU*tFsnr!Gt?iqKmZztr# zj`;`5+T?*~B@I4_=f`e6CsZ9-rYjwv0Hb^|T~hVR?)9Xk#jU;K|?s{;t`S+~|uMa2r%rQOZZ?A4D{9;kFE7<*U zDN?jtijg{T!y5&HrcyT!(u@?Ewk>a|Q5HP_2>nyAs{|a=LJzlR*L-7Hub#nlKX(7+ zEah^juIjOdF+EBpZ>u;zp^)RmoI(DbCC9iSu5$vZZYhSIZ>~I9G9Ffb z@$A#5X~vyS#QZ|wqgQ3LfvDwN@M0iuK_Tj~8iyJ`n^=@2aS)v>+Q+}B;xB=7 zh9~g?n{v0sHD@$#hvqY$^Ywu_UvKVE{Ll`2&i7U1==cztFQQ+sM5unnlXpG$UlXy2kHqB z=EEof_D1-HWzb^FA10hibnnnnv+1rYLBC87on48~Q{hZCfS9l632jw0B^wIi@py({ zx*@yE|I^ksb$u)^&rLA?yMCy(nM15Vt9ZzCqb%DUlwqRSv`gAwv#N0?8Q-gJ^FHEg z%3kJWB@oxOwxfb9AzddIU|CH*M41jKOGPBZCPK#>lE`s}l$(|}KW4&U>k<{rcn|?L zn_bs;kJHU_0q4hz#Z0U;Il3^-*N@ha+@lD^EpNPEj+Jz1yj zVf61=lT^eVk`&t+#85x{qV`Ku*g@JehizOn>H2#!ES!7yzaRaS7hjTn8+q2Fxew@M zAZ7bg9R1#I={|c4l$;T2u8K=j$5~Lq+_B>REdTmTgz3*qb(<8(^Gl; zIm^z00zOCyCTCtNf64ehqDFD94{U>b-?6V8e*=ZMgwnz~h9njjK6Z;|M;&u1h+#*y z10*3l@2-%e1a9i#Q7tIyrl8j_@jT5&Dql`otONt5Ye7q|^ey z@z&eT8Da1BQJOvE$}XDt+Rdt43Q5kmD@rLbk-YV;Zr(A&aAgIwQ_gw>EWY*oyC5W_ zq%OU#d2o{adEmcFqmK0vCVP;O`(!XyU5FZCq7UJ97*>_rg)+CS(VGq^y;7a~bEFc1EI5sYd@0 z4v(Zn{s1Bh4nMPj^{?-kVIRe>_Wl!L5sx!aP*`drDdCCjSKB?k=n6bvt4CV~S7E)IsXkB(%91wZQCaWq5 zTKv3S`*P>bcrs{nCIdpL^MT^L*o2pb6O2y&*7s6h$QL=vz~NN>gKn%^KUQ-$Z#M{J zuf@75NUpLgt(#YBWT6jG6Ql&yf7bBNWgq)Ls0wwUUcUU#J?4YbAz6Y@n+55;=E-ay zf&e}V;;wX0WT@7I{2m?u{>tU=Ib3>6jmkICJL$ zmUt?~shtzhyh5lQ9Go%Ybczo{BaXTKoyWx6;bo`m+5H_sr=fAXEqef-L+U$%F!D%!L%oFaztg zBiPtV*2foJhrrp;TjmCj^JXDPlI| zUdOcXMWU*NR6Oij0OuNEQNYY*7{W-OW0Zz}bs`Yv5Aj2W{BCaUvCz*NZ`kD#j^oY) z&PBG$<@oV9u-}Ann~j`?2RSRjmRdWok#pEp)EQgyCLCS?r&u0RLP3X7S845R9;z|z zMdW_N*M6M|62_kC_@)3y^&`tpC1?ddh2P|>L-9bg98qWpeP3hQ84Lm*y)mYw^70>= z(q!@^syFGi>k@E;h|vB4bt0z23>*9-)Csxac=M0{dxbN+?@VxYaHe-?q&od3AorO; zh|~p?d2ED!>O-jBpw!-6w)$?vOno9XsrxZr!k-^*wE2+fh?!kC!@rSSWh_EWfBiaV zt)28LZj5pN)ZCnVj~X_8U$%16^v!~0>LwOkUwHT%L??XOaCI7P+Va24ON0mC2VQR3 zn2%kJV(;&5BDL9!YKsNCC;-~9SC3or^fyWB;19nHE@b23=|0k{U#3YWYw?H0+2mc2 zddEwIcAFtH)L__L=zSQ`X$E9l~jsUp>*V zBST2!2tazWvv0Cxmpj~MAXr25GMiK+hCdjdx44dm=JIxwE_FxttEtcZQz%*6O3Io) z&g0|J5K&e!hDyr0LJoWwNP-;KNwU-MyCr}lvMab>#`@WZjZ6yFUG&75PR zFgJMHhH!EX@`m4rzm}}~-MEp6cxGnR#bQB5eq^3^K+_<*9WD!yv=yN`S`4SubCxOC zAAZ}Xsee>Oq&@KH&p2uUs)VY|b2qZ4&F7ABc_U2cQ71BfPwC6kB@tvV(r3r`P6Yl{ z147o=C_%AG_ne1Lc0&?He5m;z*Z}`H{U*wo? zQlx|an6^2w@kC2sLCe+MP5U_BJ|+QY%tm)beUgfQ8{C+A;~L3cXxG~Ym>HGh!qK~+ zKyWX_nhPj0-@;pKJ=a&4`V07+>6c1VBUL)mnEO5qWecnJ;GGHz;OrnN?kxMUZTIX7V3J|w$<8XdDXw0K%-J-I80 z`i5+et@AP6Dty}^|F%Rg8Y4IhTk)!$TGgFPOHs#wCbUCGY7zHI{4ZehqW#7iC4uTGo@Gxf zXRK;;pDctoMoRN)kR`O|qv&G{c>t`Tt_aXQYunO^LQdROb;fhcKK{_mXqv!3u%o@5 z+0LY#7~ZmlkV~XpWYU%uHcmK<6!EIoqR4igjRm_JUIRgZ_(uQ_(u2`$>O^J4#pE0$Rmsg*o8;yb(j zOFf*QGlthMa+K1QvCen;UcdrHXx=`i9paLVXS5#}k%Z4`Ao7jb{<18O;B>XgW^$5P zOMo(S26)LR$F~VIc|^LXP1k~hYSCYfU6l};yLwLmsZ2Uolzq?FDYHj$d=@5f6^61< zoToUIN4=mI534vpWQQ0fc*qTmSR_cmE9E&Esx+O^Z0?QF*Q*;mE^o@Jo*684Ic^7z zQk4|y#UxpVE!)Pq#}lh3--*LPzG}@Bss#vK!JRobyr^ACdD-CjK<{ z>Gj~H?a7`|c76Axy8Xv3OK=EfSn~kFXcZJq^OyO@F5-JVUJw1K2HH zZdvY?av0zhy1nYSUXIkb)NQ1c}lA#A)nhDQfkFjm_k?-=SBK3h2;NURI z16D{2#eho^;rBml#5r2LJ8iu=$QjSxb$o06KHlkLcRAr1(mW)#g`_#n@La%~b}tW4 zE+Sc1x(d8h-pl-5?YmD7na7Qi1oQr&dFyyCGp{D^0+FA!&GEk>Ezud=RcS4rAOEun1|fR4M1weO#l z&sq9D1xQ(I)d~_mLy=oHOM_5nLAFznu9!k)_kR zRd`cfVG~_VNB;ZKg1xt*K#m5S9l4Rj>BzY@G3K!OG2LfU89}_;gqMKnQ&6{h=Uo3M zE2+H%zommOf@=h>-uI`ls)?nh=nPYTi(I_W%-JMxfI$&vKq1IM(=KCM>>M($6y2ii z1tSgx8uC~|Y%?9G6;9W_mz0Gng0r_(b^jKrx325TlN0MnQV0q^%MfBs<%%_p5x|6Va|m{ug9MgTkE zIBqK2&_K9D)jw(q-WmeQ$i*r%IH%nO?QvfMGcE6K%x2S}#|B|%`R*qg^av|G#;x$z zf466+F;~!y?%n~g?m3e{FEcn{I33soU(-w%obeW&7R5OHnA1@wkn| zfZJExM>}7;twTk%+;2)YvP}~H-Hy8#GaAKD-f_a^c#d8lk;Nu`F4H}(RrUX|%T(n8 z@zdLA)|ux*HJfir%WH5tYH*dvH6?YDuVTDnjtWj!v!?hN=EXO)HqHC}a)Z<-3)EAi z?-^E!!PN`e{<-GEFoXcy&I4(^W;QNU=@(MhqBJs`Nfh&%nLW0w?}IX2^cmxFOqWcA z>~>hExj9N6dszLdVRw7}taUX+^4dKmbLq7(d6>2HiyRAD^fOTu{0BF*(;>VIPcIc< zum=?J&>(V=zs&foR*edZdT>e~i!)|a%UXk0jSG17rY_2kQRZ)U>6B)_<=Y(EoFwCI z0v0ZXnw1uL4vnx`9WVTaXaBA=V1`Y_|I-N8e}{gt1wOsySHoS&1@o#LGH`nQmZ#N*%nzah^kGHmpTTfy1|G(r%1E71n7dOkhIOf*QswCvA03Z~h{QdH z_?k6<7D!_p=6mxZsAoysQELi<8*LqOkVCSA7Hoy)dW^G0yaTtC81wRBP3X)qhP?c_ z?Mzfva0oE1=pA#x7v+#v`B^eKj=B2VfY7Xh)>bt%1##Am<#XfWwL7{>di0`KiiXrP z5~=MHvim|?O!ZoKg-Q=p{Zoy9x@cz3-L`BmgnSn+tc0o0?`SQZ>!?j^pnSfTY|WUE zK|ztSRE6za2nYQ@XQF|n5|>#gPaz;`8&;TQldO#6c4B7`bQ@?K+@dGYc9{xIiTW7c zA#<7O__cBW9eA6#6YQ84=dMUyNpDi&W%DB_Y{9{;LFQ6gj)XR}d8ZUC<8TO;-wzD| zJ4+|~FJt$eLQN)=in^Ll`{?)LNt{<*KR#@`?Yk8{+QnNdRLNNhCVKWu_i0h5o8@; zQ!!xw0=~G2>_@0OMeL&ek2a5zdaOuEl;kK?Quve++n4jHWHQO& z>x*aZ&8)mC@xtwpiXxZZQsyr}^`Oh70acPm;)|$*p{^0mJ9?HKpKp$6ux!g@M{uJq zJY{nM!!$Tuw6%d1snU{Kv`9}7Zic_2FFzgg)u#n3tR*^7lse-qLNTtH0N1Rix%~#T zR8L3btyufK@N3;}++!Nw#%}3~Vv34&i8B1~Mx}6xFd$}wyCOxp0+RKS+d#<_BChk2 z8P-L_?(w4UAf2x7SN@q=KfNoGF?Q}%CfMqJfbf~a&n-KL9;vGu3oFb`0B=7&Vz1b| z>(JKy?R8$Gk-&66v>1#ydMubg^L^kjq1sBwGz2_e6juL_1=h?W&*a(Zy*IDa`Ae5p zQu26cjf+}^hU#ct4AK0HsqbGeH-t~a3sM=)%`9E}P|7_bqr(B?Zx%hUxuTMBunJ<| z?fNOh{ufs3fr2B5WjHf~g@U`!w;!h-7P&4T5y{<#jx;47iOAc6Od|2)2CVNoZQRIh zd(e|tn|q&>W;4ijt`pWKvNs=mrKcu{wvO)zc}aDb=4pL`^}sT%BLuM1pDjz`;u^!%`%R+8CaD~gIL#hw9F6pTfGKwsXgP&zRdmb z%zD(wd%8>4j*dUoelaH;lc3LD`x=+5vzn{H{s!|gfdc%6%}2jJ?Sepq(3QON52=UfV9KsfG9Laz zLGYg0d9|x#jbJ%S-P{m!w>F*#S7r3;PzAT0g3~OYkYIv@bYnU$0w<|hKwDxok}~0$ z_;a6hhB}HQB4rx-KvyKI@zsD*sj{sr$NF*(1VIlT$VgL-H!QY$!0U0O^Q9x)d@#|` zL_>aAwCkxcQ8v}M!Q!-pd4Gb70{8d6&=OjW=(>Z&n~LGKd^39pVf1Hy>&yQxXZ12| zn+|c)?L%m17x*Zkjil2f09IDeNV4h-wFNDVc^4q_FWocL%nHsMB76DM7{k3$KHGy- zp7>t1wjl=Clq{K4dc+%&f8QrxLOo18bpL&tbOrf&`43~X1k+Cr0C3^|?{gceojr&I z#(s#~HfFwm=YK!CSAR0>^MS&Wr+Q6!T|pbcYUUF#q80*H*xR~VkTkj}_NbV@*#wrm z!nlSJfD2&~D&U!&J(MYXriQC~eaKs9l}m~F1&z@+|M#OR!X1ln%?Ee}t}=F7>T8qY zoLH=qP59<1l;pVwi>~vNFx(LLuXxb)1O^8k zS?D=BKuvUezv;}iL6|V*PMZ^s=96N9mvj3SS^+*03y{j;mp@hgNx!`H_2SqDc&Uu2 zZ>(y20NM=jfJmybWq-t|>2U>kZul8#5nPr{cjN0UcTX**@4)NI25M_P15GLj4uUH%SOQ18a48{suf%u1~``FGfCTlE;n|{vsIkaQsbszPJZjjTRy&wsM1PAWBA(i|48Y%(4{0|MYuxsA(EWg_i zvGs}TJAJyWgCYPYCou;<0|9R|?m*@5fsrMLr71_yl`?6-zfTyt=>BZlc*8#(bmYn{r zp%%74+9osqYLTanJ8F!VIhJe8bD371Vq`9N!b9~b`rTf)y2*oGLy~rHp`}(A>zfiH zun3_DdgdJ+#KIeuqsr-BVOxJl>MsqvnMeL1Vy;Sk&)ikL5UGhZbcSBfBex4~C+v~qhmgM*;;(UL!DX3*C$-!ob;dqLDT>dl-i}xnB z`#q*zO&Jxn!;9q?3b05|A{4r~NzFiM{&e^Pq#3`)S24%q9Jh)(e*2WAIa#=E+{8{K z7%HNQNMkCD{;6xY@2*{wdx}^JjDDd!v`o+Mi1VCbh$%s8e76Ae;#x`3KNHu^hR#d7 z>yL=98)NXg0{($ONyC z?LM=fTl!lZFrf|W?{GuTX^Z=e4@BuE1(TeC^o9H^ufHQ)d(Av}D77BvxQw$V7J1q| zeQI7zF)w@Dw>uP&&hW;jBY0Z2tT8-cvQa!IkDJ2iv3XOC z{7FW6SC{IxsKJTL2FVgf8D%CMgb*9pKWXk4b$>h_>;v2h)3fNhs4^Rp+O(>2aMh66 z*HcM~P5oHO-&_OTROUZ`%F9WxygdfeiRBhofM3}XQgM!Gv@7D%C7;RutgYeZd!OV_ zzbPL>)o1;je_HC^eLaGl6B(Ju(@P(BW`ly|Q`al~GyeYuUD^wK*{2KM-uTC%;76$! zp1w|L5J#>cuk8=E)F(B23)tz3dVLIcX5a<9!!nw43)@>``pJ;+C~3#dyZs>f;5kwIq7}5q_GbFApwD2Zl>+ycOh_zrUGPsV=;2vT?e&(2yB} z|2$?Q$?F2f731Zb7oQMrLix!kkZgH;05IT3_Ka5DeF;~5^K$_KX$y_*)jRV9oFe;- zwe$8Ayk7cFtRA~gXI}ZjIZ01P;;N4C$tfqZcgQ=7yu65i)p^m>r2Lj0l zLBjt9j5(xu%3Nh<&ete(5XOJg@q3F_%{=I0m6#3=wSM%H4N=j+i6-UZes<}US&O6+ zkc{)Be;)@h1BGp*2}n|3qn33NBa}Mn!niQC34eWigB(LsndL@)$BK)^H}XJX>6dUu zJS&gg4e#amL1ge4{=tRuXA(N^xY@#b8{zwQK5U{0CL0z93N7Q(NoFV3antH!LNM$5 z(%}I-Gnriu_ky|-TApVdL}W^H?l)H2>{?z<(75RvRA z@c(9k1XqLMW_rj95e$`M!5Ngd95*nO$@EP)oTi=e zEM0-ipu842<3<({WpWuYr<4``&zNU{A~=N8RFd9yl%lYoD@Ue@@6y^W0CM6_2K9~k z9b8Y&!e1HxJ+|s?aGEv_rog-I7Ri%C=pD`$ojer?S)Lxz+NSO- z$w5RGu*pS(;Pr!oTQ{Z!{t;Mw3-JDInU}x;!q?n!eSX$4f6rjrZSJZ1MWj!HE@V!! zGi(i+R|Wa;kiBqC7RL*Cn6kqC?A23Btr%mo$aA;_h-s0o19e-MT-Jy8hOV3rIh_7pGzWk^7;zO3 zd@$47QPf^jnGm}h@qS!!9CUn1HM#VPTT$eaU`k%JEjBMMItNF!q#N1(T~f1xOr8BS zM|Syb%K1E`()px&*l)z)WRG*Zdi@fhqlR-wo@(M~2{XQwQNkE=C>iJ9X9*apI8tH> zKk}-7-#dslXT-dfpxWoVvkPe3GAYNH%C*LNHJG5D zn(6SL6QXYQO@sa5Skq97dqrYGsOJ`Gj#5wLcdj6M&5Igi($&EGs{57wyA*Ad1kH!N z>B3Xt?HG8z-{CVg&!^E>B!`|BoMN_@Dc#C3{?6o`GsgH34nPd1AileKbpp(%I3FV8 zGvNwS1NIv7dDi%kiD&LDt}N>vf=rF&ryKJ?J^xQ`t@QyVhR@CrqCK7a9nSg0y>B~? znT}&NB*lH(Hsra4MX(q9U1OsbztL~DA=XVzJD0$ss8>+ZlwWqrwN?3WS`uLlgcfFl zEBu0vf%a$9J{A#67RR(Z!!nDMjb8ZX%&O~1Ew}#Hqj(ieVXU7)h^(Rvj4D&|uua4; zGsMTYzYvyEm84^MoCH|v##$z!TihTpx&B?|AF~MNy6~;0W5qLR-MP85qwdR!_|y4Q zeXoVO%yL+IV8jMf7?HZJrsl~0m&xV3H+jqQiG_3B7Gb~q09@V5h%3|V>J*nZO=my# zILH^*9_;9@^W$vc)`p>}K#Vq|1mYMo_B77EQ&zWf+c{E>B}@ViN(O@%EmfM(353;uA=+3+9bc z4;YJpiA7j_ANUKs@xrJlu$>E{gyhe_d@~)^PG`5B%?EFx1RM{`GJW^C9ceBONtJWI zIrrPtr9K8+rBN_vR(S$-SvbU>2ZNN#Yk%|8>YR`8&QdfaTFJvyOdGP?aVEmJaF?du zI9KxJ(~jZyZQeCV< z{SZ$^R|kYnv3vD;7fprJ_)ES6_sp#D<3;2(#;@_W=8?E0ROZ*i71;%R7;)IN#H6NA zQ0FJ<&G2G<#J3N<{g2tX7Rmif)!x5wVQ*e?D4mgmFZ7$6Q8(MOa{;R`+xNq`aWKS7 zXMDgO@8$m^tB!-bXs!~`y@Z5)X1&rFfVhYPI+4%6a#vrc6kEQ2k>}*jk!lk zj&iuy)3g=L#K?=FrrLlzj^|l(l<-sg}g8o zXq~`$08;IAOZQ%r60C9^wwLJ8yIu^6%*`T2N)g^!w9iWG!v^7j^B8fku3&`VHWT7y zA98RH``)O#?U2&4;H4mQYf*ofd{bt@bg)$}Y7?_qU8rjtW32vTQ`B>>Dp*$VMg6$m zvHi%D3W9RcvPp}wN2+C}b#BN%ZLEZ+c1nJllNW(S@FI@_h=rdJ5)S?u`5KfWLejoZ zX?~}&B5RuvZ|tqPSj&##ZW&@NooZnxn68aK$r)&;l)XWxtn~qX7Hg?MvlWCH0^--A!34YMPtdU!b~Qv&FAk+rTTI(?=wCB zNP`MCMEGZj=DNX~C&Piaiyvv)o?x5zuzP)Ob>bz_eq)`EGGM_&*}5D(NiS0&Ykqw( z@@RTP@EGkZr1ISyf%f4sYD$UaU^K>Z!InEo_>_@|K+xY7-Ic27@9bo`{uT~#bc zL*W@~WACPtD)ipvNm;DR$rd*X!hG}K9*Fwa1b=n>gHQ8ca=+~k*&6q`P1r)~DR)Lj zLN+0|TY|4E7b05KZMvj4`AR zMVKg$MoW~$GSD4o)aaKUw?&XVEAr5ybOJbT?vglBKJ>DIrj(M5mSn zgJ8SY+>g=Uu+c^25EX50@=B2R>1sGWcfjJt!Id>~o9ffo^WBa5dovR;Ax$p^@+?`@ z^YXh#c^Ny4D+RRur0hv{bEblwY5KZxu1yu%qd_HsL-|EHo&#U`nq)fJF`;?i0)V)4 zfH5)SI%~Cc8!_S6zdrfi89+2=2BEGs7pM%2d3u9s(dlv*n!z>fpBaq{nWj34?1yDT zo1g##K+l{o$bn7zq9cJu>h6*8uo4s$1!@&tEqcEZ)PzOh>Jm$!FbxT}`(P+Jht}JM zX9FWiUNLsPNTL}4^4EZM_81i^EWa1nQX`8R&`Is&`_ms8X_55R1K1IUk0=E+{z&1W z)O^W@^aRL`=7lqqdI(MF>*jB#Z`jD@Z;B;#FNXashfX;<1q|k*VnxId;Ni&YVn5Y% z9HTA%IHvVc`hqiAwOItYrcc#90VP6C^!im_j(9M?9`zimvfik^zw(bLF} z$g|VAC|R_@HnG^ICd#Jev51t44MaP;N=pM%vz>i7?q2lBI}RbHO5*I^^K+7;lDna z7`&)TMc@6A1i81!V(;DuKp*J?uJiQ3(F8fIMDhdgBD$bXmGfpnw>EdbR^(PDFR4ZW z0-(la?PpiQL|y_i?=E-#0l4$`4aUt^Lu2K8+nU(w)k7FeA&+-s&xqqy_FtdWhMgCw zkt6o*N=jE-N0N<}&MGbck%#kY(Y=jx=`aG@j7gZR47?IxXZnpf>zE$^Dd1>hs zo6ikh7J~no81C4ZG!VngM&vGqWyc#I_YptEhmAwq(TkUoGxtuJ%h#p9drCz?pB68) zgOPXlfCA$ROiH8_V|wLT?>aC3!}jZ}qSQv1z~Bm{DrO}*eq*{z1P>sa>XSk+QP=+Z zKza;#X}-#8&A(fREZyX+;R!%|WkVLxVSo2`gK87GsdgEy@I{+KE=9W(`TEV+U5JGt z#$_HJ=ZtTPI9w|}p18k9QshvJ4c zc&6YZv|TxW&G(Sj4*p#1sj|pphS)=r(<+PGc-z{Pjj#u2sLBu@l+Egj=V;?#MvvoPZR)cy3&Jt0Q-F z<*@t@pwVW+6nPF`rALe}uj0NQoUve6PwHY(i`JV?Dw-jGZbGpSX}z3HkdRyJ(368F z-r#LBA1(mc=8M}D%05wCNR?Z0eW-z@I=lyw%z}1Q%7je zp8Emr6M56k#X9f=<&~GU66+2ZMoe~eYG+bSFnj1C)^;czt!VccGNsSGy({_bI#qi? zNi*%_>uAYbg3W-M_Y4jG`2bkDK%Hlg6tK+28Os`?ZYZi9aQxrXEThHjy!4Hk-Q_=) zPcGk&mRB74RxC?Tb8zF zM3!xV(m*msu%*d}yyA4(-xioW+ku)Q83`9?y0kUtE*N8iEd$h!z}?d%$<)I<5)TAY zAHMh;K)-!7xy5x6IGR*JV;t7!V6xoFT{YILUR$*Z1|B=j9&b zo}_00vPee4FzcrfRNw$VWz?F=@xg3Gsv(1!gD50!$2*U%WRs>H#*wJEEz|>Y&%un2 z&ej&qxe!%=`@CReM@7?Pe1YjubO(3-ls@|ctC{p7{9%$h>NRD9T~z@I*9r0{CH_Lb zg!8iCGEbZkfh+C&-Dl5P<;(YUh5512WR+Oy-I)7OoTTzS{qFg%LQ2kwrjDBCM00yJ zaB7;LF4%AglZF<(TI8vF-DvvRPJGWauMqmAgS==AnP@R$PefKQF`QO+|3yv{{`Z2v zKJi0AYm9Sx+{`;)L^`XlhwH%Cxv#b~O1AWwm7~qT)l)i?H2&aqspYNRsz4c++^>?L z)f5H7MuMI;uDgL3Wq*Tk=NBXnnl_*#poyVrg+8W~lU1A==ONq3Jy~>+Kt~#VPJ;Ut zNMDVh9E5OWF7a)P-52wLo#URv-_-_N^9zEw1=v0%iNk?D;XOwquHP^GsXWfnf91|r zdUZxbzU)5E2zMelO}{gxXFiM)B+)Eakt3<}nV-q+F{e>A39%#I3#T)k-x_#&9(7K5 zNZN+(RGSCZDAQ2oA=9BT{%+JVbVg>-aTUO(Ph!g9Qod5WRP7D@kT<-@wbtLjC0vqb z-8*EAd?MN0k3D|}+y^2`rcsg&eEq!or#?dal^VZ74dO~0SJqQBb-}DKgE_AuhI=8*!U1WxUa$x-wV;QG>3}FY_)NUEM=`p)& zTQX1*7lm!u`V4%gK6)Sc<}(@}bdFWQHyHy1HX}=Owg+rJ^^gCrKj?cTWh7j%p(lgr zKgQi0DY13WoqnC_wl1(4Yq~r`F#m zzQ9%nsM^0;^|}*}dmw@NTf%~J-vr~L=g=Et`8P9M;9K%N6_{ZUF|rc zOzers0p2P7s}Bl>aIgW1YpR&)BLi6rRA^>D;C%VySktCSR`{Ra&e2XP$K_?1#Hu7g zvfH01lGnp)1H}}gq__ka{8Q2ipUp@tvM4C!eExE3+Te$vM0HDU(Z1?#ur?rlyo#+v`*r;$qz9}h)K;&~=QcGGgECS2^C zfk{IO8f2)EnlpgnQ+VRi1H}Kh`-nr(UY_!Y=3y*c-awwdKNOT<0_rKW`7`LV81^mG zj)trw$0o3Dof#-Ev#KsNBjIsn&0jfF^Cnqk9qcRltF}j zY*ww~FBR0;W@lEG&l}vpC2QUNt{#*~FJ-250QWv;u^&_(xU%)wAMy5~e~hKLPq&l& zH`08-ns>sGE(rbl022cEOz{!ju;ESbvV0;bFTA}=DR~im^fRGoSh^#)`2)0G49c{t z+By<}xOy3K?NFK7+8ffcKOEYdQ8&iiwmPJDTWsbf<}c9ZP}c+5V(sE!r!ezn{^UT6 z^q5QLm9w9Znj~ET1Kx@mbw^=ABOuvzLI7r2E*`o_DQ%!moBh)3KH^qUxsl{GxhNxG zj}e~pktWInwdG6kkLHKOZ6DV}y=9CA>w}f6<&E^t4lsCwLrkb_zB;x&<-gJfchmYsFxVOZi2B+cUe z$@o4C(GBfW(P`JLccs$$l2ij9xUTqMT9-qMQ!kZ} z{WL~@dE$jPn>XoAL8KP`DyT&%Ksp{60bj0o(iZ%Cc2T-ga?RxO{y?hq&B~z=?^Pau z=o^PaFw*)`iL4e+1;VmZ`r$wAZS)0OI2b_yt5S;1sxpiM9QbNO?8tiMLOq+ZOqzKfIaPV;yN zenE|Ibc$a#fE-j@lD4gA%+LG9@Zqs@V=Km=_Ux%JII`KXw|RYmWg6s`_ZC(l{AlXL z;FT+0oTwfcp#trb!jT3}novXpfI8c2Xs->$+!J}BA9TTU4i+zY`WX{vw-Lfpx7{XY zq(_JsYnQ1tMW!u9yYb!J1Rv56t3+2rzCvi?@1Dr$KZi7oj{!<4uH>RNL1U3=;JvFN zZS=25H?UK&RN}nusrKxvBc77wWMei0fH3GJK3KI-Ait z|3{Wi-SpIf`tpcjEq9ow?+_R#x2uVY{`L-bA8J za%85u<88P>N|BR@RhtRWuf;)^%eNSvy0F=~Rmq#Ok_B5+D^TOqP;@&TX40M@bC4Iz z^-mXhJ6Ju&!4)psvmJiRYvYmAZ>?X?ync-&%SGkmHXkHBC|YKu$-ENqd-cIsr6ef7 zCowT!9IHgVWA@N17{*K44PZ0MIx{WUP*my-aQoHo^^A`=_BQ#%UO0@0Dg1fjjQ%c; zfW5p{?-MZuTiWPRs-w^GhI!}F9wKO6L+JFLeMizUnf}ymN$8ZjsPJP#cg1eh0OUcD z`%D4atZDs9;B4aZMpQ1YU-W%|gyK%Zs`bI!j&?@}v9n?6-xwX`dK5Zgn0pT1h9 zBQGv3|Mkhv8g=Rg3CMa*-T{=_e@SidL>4yuY7Ps7g9Cdo@+(K4WN@_lyPO>z=yl*}u z1gGZ}MMwCg;vKVlF*IO0yd@S1Y>^}vr&PG+tCD21A=VLu&V~%OBMrzL9I2d1>&ld* z<4-?z8PfR{pdqigm2>!&Cy9FC1YbCx52CRxV!$i~M(8KRXI2M;C|qDaN)lLsi|Rjk zx&|-ll1A&gmSkwiQnK-)?%)H#osP8?8=A0mbA&b`LYJ2|61-(pC@=1q#7;=dk-|Nk zieqR|=31}FCyYIoiYL__Nl#}d6UhCeZo^F;UeF-RO`&E`*;nv2ZM9^!^y5LyqK(9A zH5h~T&dn%sOR?MZFeq*sK0BdsL`?yhvf(5X|9B4gB0Asc3*&dh&U}IXGK;jFkpsr2 z-wki!)T@Fo&6$kaWznyVFomJSj&j)$vd0GcX|$o^@HAsflCE&Z;af8>O2}1M{3)m) zR79neS(&$NTv4U%iyT7Lq z``fMxGAehKor;TkzF~oDPae=fyMqh9I!7Zk zbQ{BXOVDwu`HT#B(m_$kvp!vP(vZR5MPCA!4FgWY2iHUsjPxDwI_q)ROnPq*kc^k% z_)6n(b(vfW(z(Z$l|y6^2Mqi?5$1z}@d*7T27Z}m)e+tdb*#{!pX*8A;}2b2VdB2S zNAl_QWFRkIwOGc4CHEJs#b5LF!>(+&od$an$rFDW+;Q^Ie$unN_O_q~JasTPiRhxA*_!G` z)`5_v+MU+R^4q#^1gY=f+;6Gs4|xBj*cEY=&end=79{KWtLmIg*V2}k07OG+WSW-&)H{`!PI=E)%lxw9_R ze{)6vJV$d|_Xjc$U_?H8>eJ+H{9?P;SN+D#^}06;9ytYblS%erjZrC-Tp7E)AQxId zffa9%dNkrao{gu`Zk5|K^K~SQU?GB~6G}Dc;mEsA242COM1%AqO?Ms%;pUHOKyj4k zR*5;F7{72W=&1Tfb;o3;`I;P9%9&Rq!07q2r3wD2spqP|p200I>g#wXM^9^kxpd*# zHq!fa+V0B~PefqgyMCTL)xbiQ;J<61a8K{1bhGvj(Y;Ems_|=nJ=a-R6cR1kJ1Q3E zDB8n`mgoQxRji39q3dy{-kfV8ApU+6_0VMcmK*Fc%wt@6HZd$OblG7)Y5A#4cZQwf zyT0MbC8H$I-kF-I48c4hEwh3`2mCL-aGCd!t$$CmO-9>zq?ymajx%AsS6$lM+mFZb zXLccFCr47JYG9lb^?Am(l*_RFGRBiM8-4#-Owty$egGrcoj^%rfBX9@n#2G;)%rmb zJX6XDRk3?4zS1MRPkmgQ=nXj|3~#2q6l=Y|{qKHUNICAE9a0X)JL=_h5+}AkBiBC) za!r229nT1&9yeqXh7IYAk}OxR1lYLWa6{PdJB*J@^`Dl*p||Zg>xL$B+_4^LtW2T< z+Yg-9SCKIA6nfZ_jgTua*}>~<>|q_P&Fr9zU_YAR{t)mqq5#h=^o-b;iDRTG>8~6v zn)?doC+?=0s%{ASO?*wJfgwFw$iWSoCE85ncGb1sXxg=unYW&UNpl6V(aKrj!cgv> zO@#94yL_j#sbSaWmI?x|lX2mu_1;Iz(>q?09nUa^28fsNw#w@6Dm~L~SX;W7DZ4yj z?XjhgiurX>(w<(R2(VF^UgqEC0b{FGSHA^IoY4sTvjG&VheNLP#0B11!FrFnomA~v z#XUp(s=NCyL3_{K6BKGlbT*mi3}CS1$Iz>_#ftByngv~Zmb8fp;x}>;+nhgaaZCF{ z-vvi@i}VKoGMH~LURwxwU2%u*&$^8^H1Nqj(brDcT}UXt7h&#|8N(}%8vM0y)nzEX z5A>UUtXrcG?$YIyv2H!hx+|L`y-DjW7y|rXT?5T6+ofCa!{P=;aveQuL$K;5m__tF zjrw>gvQkd}{15hgcvFA8pzm@nFvXlNttfFjkv6OmO}lw znb2K;A=L^PJZV_iRH2SF@sVBFL8{g7Kcx&W)&n+3lLxy4HSuhxQTiQP2sE6lbjl@sWx5>qH)n$Td1*^ZCqE|B&B zQz2QMHQ!i2E)BMTMXtu5ae2eGfxC#Sx{LrkJXedcx!2W@wC2TZDax%m?E5Un7bSb2 zpk`$Qk5+PrRzi%QE*@_{bY7 z3^ocMkH!auZ58+u)l6Sc`$R8o)AMyR@1EG)e-ixEz4z>#tRO?dv3W4Ek7J_33$VGz z3NOu8oA0NS^XFx|6SMfh0x*D*n}lfu-o7EPxv4Dhv}fs+)+AzGmU;FwBSV? zyz}1La0v9Kk(rOm$j@E5rbCs-0zSBjT9UbgA9qdFNSa19Fg8c~7oX=PjIJ z>nDI^H{xzM`bz3~k*>G04wY16C64J!x%Zl^#9^txtacNuw*w9aA{&#U$;|YJdc;vM zW6@c+uL@FH%7+>%^3WOG7i~TiM|)5(uHF(V_LP1>75aicUH0j4jB@-n`x5EX#kwa` zC$$XBT=$aZpqVd(xer6V9knYTfN%cY8i%F?;sna(HYj^B{aFY?j#OC zXeR)(10SIB=tV+1TG@A?T@(7^=~!B(G?qh*h|T93pFKV9@s2muNuG!^42hm|$d#mqe` zcU1PaUHPIBOR8FQm2lad!pG@2~QR$atHwFtDGF*YrrDpM+ntS!Y$HtEPNW?&HGGpqz>b4zmC81 zQv*LX)o8ZNtuiE>pAwQdYWR=_xx0Fy6j88R7-5|0TxFXa?+t=Yjf;+a!sht6OC&uu zr9dGfs~1u}&|O0xpV%wiU+sFI(t)SrHV4mv&M~`g0liLqvfN^9hLSqGopgDTmT9hL zl&4xA^7~o0433X@B+hNlK*K3XnRASXMBAYY&=w|{wExOc-a(Ru?!KJV8LRiW{l3@a zM6<$79Q3%ED#v!Truq=d&Xq)og!4w~X)aC&MbCFQB>KIkWoG(@rcBj9Wj4d?3-gF# z_$1Ca*IpQZxOsw(eXsd|Xr8JwwBr}7x_J^K%>%j-9qsFHuYCQ|Q+sdH8cj|_m!XVC zp~I;*mfX5_HWu%#}&%I4Y2y&+#gIIGg zTiYjr?4k=V$>QnIoMkjPAGF+LRgt9|^A+3b&-#x`It}pz4ZIf{|gf2|AR2e=pNSZaqN{a zd#UrOYToqLW+R;qp<$v078&==723BJ(?@7fHapw|6BHUiUy0Z`28LWnO%&xraYyw9 zl3X5foFawRJciIDy)dprsk`2Bxb9tdb8KW11^MjfrA{Zn=NW;k28NW3F4DJI+thMR zz?i^RSUKr8H8yw&=ArW$kP9&tnTET?tdyL^N5{fu2X~Y+FAl^l7&bQGFX;=`_b%Bk z^)t8Ep!WrDnM(+&Vy8`NucsUPn@LJpcto^ugSJ6GGFxc#9`_s06TMG(YNDkEx4MVZ}8lrFEAmvqztp?OWq(4T@^aNnvMu6+=AO$bTNmUC!;uC$Oy%N!F!n~@@9 zOX-r^ao>-a5+D2B>8$el5SKhfdaU@{kLz+|88HE;9hm^X@nUMPKYo=y(2}r=_6NL? z(KBq7-2UR@{g{{ScHQbnMVLLI@CUq=66j7PD5b zSs}R37#O?}xtrWagfEX6ddcesRr)P6rPkh8MYvOBJc^!*dDpGg5-pj=c$7F8=h^7} zL^zUwZc~F})3AgO1Akvl>b01BaSp+i}vW5@V#FxTZ`6vbLR2mF!Q;&;jR``@GmS3|@677n$rej;zqTn4@2 zSS2blvUz`UamKHBxc)fLJUWJ?eCF|RTt4FN>E^8UkeDC8WTTloDpC!U929q+R1z!V zu4ZpxcPX}H-Rdr--PR&V6+P8G37sy%PskDNi2E5jXbXeZlbf1kPj^Thv|1A4es{Pq z-a>aI?90r~=+HQ=)^m`0i4H9z{oiQ-Aq>6s5x)U{;Jjc%@@=)~M4`Eyv4^Kxy40ux zJVaMRo%IA{x6lc{$xTv9{-fZIvyJ|9U9vMhmQy?9A|$f_JpIStiDhm2`?F-KlGIh| z-#l~ReQp-RyXTvJ*kkWLMA;VIzG}0ElaO)NZ_#&bFWo)*k4E3j=WweIa5`={bYcX@ zM171?XF#HN>;?Dx7%6I?NSiIJqX;u<<6+bI`T0&yKYe`%(HOVYuT(|4-}$2a)tJ$ZYEj=;!NKbk4OaEtx%XcJw+5=kB$1R+1-oza({JfD1puZ0|MR*?> z{gtKe@RL06(2M}KR2WlKBwIyUY*@-ED;qrGM!(V1eey2AqZ<#I@=PIUzhs9Nn>;L2 z;W``|iIvk5?|(oIYCXy$dGFDGN)EBjnwWH_LDkU(FwA(W^(@duIhc7f^}$B+&Di=n zjn}!XU=){tIyI*74ad&Z6=ZFhl>L}z>8we$ikCrdcXyD4Xsv5+T@6t;2iXABN0j#C5%evj(L@4q~oN)D-s78oR#-A1y5I>9qB)XfhnCW~eq_xEfmr)FC# zcpJ6D=C5EMdDncr`J|1joS~mHSS_Fo$rDWi(z~TuXCS=;-l-(W%HqaFiP{&li>BS1 zyZ|a|jIid~b7Xb!(tfFq^gm_NOk);M#{K+*Sfw8B#Z4k-iuu%sQSUle>2HTz`@KpB z)06+ZFTiRCf$Tzd4xyW+WM{-IGGZ3`4&s-hm#;la7JmT^()z4=el6UYm#*DaL7CTt z&IRJ+?%p*9B9^YMo)Ej}`;?MDGZyLvi}w3eJ0of*e$kdYz9kOZ6l<0#L#+XSgR~No zx!okz7b-&|RlS{;W-UHNiL%&-C!QGNmcHK>MNf6g6yaPMA}pxLmD@%=KfaMhCT)?q zBImR!c#yx1DQARtvFMh~1hln{f+(w(vftK67-Wk2hONZd`lrGz+ziwWXnrbjs&2VG z1s*>t`!Sq_aNSvu@WehWmMd1ra>Ta2g2aNCW3qc$ zl~>ON3e+9wMXnK`%UXCI3pu7V`HgK4!?7?8AVY?|1db_F2DfPA&@Rm{hF8DDZ@v5{ zk^OD0&T{gd@OU|X>5}zB%COCUfyp?WYCT+Xdehd>xhRyBw3~QAgUECEJUuqItNjMK z@JjXMU@dwnlYQz{12{{fCC_p0GFooJ+aPx-ZZ)V`ju#iW++3;4&7FiM>r$Gh?kV{0 zG(DI^&ogxPO^;N_TRawh?-fA8@O4-;c0(J$HQem@VA6$pRA@=+d zzXN%c$))y0H!%E~CIyJIiAkTkzf{Zf+4A+oKyYrx#UEP*qwUel#v|a(H-j>T99~FF3M8+O zuqE%CE15Dms))t2!|Ohl&J}*%4xgOKw>599B(+3M{p()0mTi0g3Mrjk(VTtSE1hpG zxxmbK#u||q)-l#!PXQwQ5anWl;$+A=XGt z55#rGVP+LyEXC~_!v{S98SyBg{@M%GMN)DpftP?=sVvsI;*HkRTZuSYqSCy$%rGTR z55bK4W#a9l;G;6(vwbp~kpS&*8&r1%(kZH^pf%*b?z}Nio=51M(yBI5w!dBy;)ALd z<9<*xH^61KQOl*qWzOivmkT^ILz~=7yTk~2G8K^hBq?L!I2oi^)eO4s&*n%Cr6T{Z zqXzVx$dsEbuVmR~<2-;?Kp+-7XUBTkUJr<+9WpUu@B+y@)BdNJXlYSlONjr(GGos~ z&Qd#;jNUELA?eI>#!-ckNyL>tY%NmV>JkO_689>(&2}p}n1zFcHJ?H4?dXiwCbG!h z`KadHU!MeAz?GmbH%uHeP+FTyNsT?)r;k~jgb4EY37XR=z1F{bil)B_%fpW%g_`UQ zCI|1ATvBm{$*9^7eQh&cwBB@l+!t1{a0=rR)N1s5U77pToDUumu&C7`I*~ZBfiyYA z^CIk8>!Dqxr+R($Z@xQr&xDNa^PSkY=5y3YtY};8P-CWd_uqyonfq(mKt=8F4mXo{ z!+%GzwiI!T>0$M8`=o z2<AYV7E7+WTP# zJ*KC<>Y>>FEoeU)1YcIPkzA)Ujy5Q)&He1m*Akt?=yeWAX-6Aua3*H*n(xk}(dxnA zY5&Acu1z(@=d{ac#ar{GUj*qYhEy0Wy!zMEwDW(3MgGt~gm|iV0fsdLd)?zl~clftJC9SVe?;KCZ9^^w= zY1o4^vjdu$DO!8MPy+gHaV(^JV8m>gLG}eB)?MUoRJopDOc$b}W8K$K93U#o-+dxuSWG4MMU%MFt!eQ#C0f_{M$JFd*G|1%etzg9`EZRcFnT?)`H2FZcjqm9K%}4U?P;qqGw5Du~!(}#>Ya~zAQq8 zc>>5dTg66jS1{Swtn_Tda?Ufqu4zS=(cvc1rb!84`zvz;!|4R(CP4(EJmMJSP#m6- z3R!4N=}Yz&qYSCYowflC7^TP^$}i@-ui$-{*z8hi2jA${{YoywsIeI&9UBXPY;2C5 zw51u}m}(%k#RUYN+;_+^JF#2#g<$wtxDE~r&r~F&qj%5G%qr|* z8-eS@=k$vsRZ_!fN3@d}%{*(scuf!JzhRQG?6KFQ9+V$uv!q4@)34NO%P;Ub3@?H|0`8;Y~5f~!Qahou4EKCmyK9%@h4)K3@~Wj*x8W!WFYzRAy=Hpn1SB zVT@KrceaEgzOgjj>)DVJ1s9)KYkm)ZPPp;{{henSF1%xu;ijlZE)Sk{pD)4{H|L!u zi4E}9aW#usEn0}a&Y$3q31eWUK~I!DtHy!3W7}opUf1ZhMW#VcIz^JYx zPiXjG)t67kt;-Liq$(5@WZPq_9Cnbp&^3P`?3?lfDzeQE(V4vde+T5&!Hv5 z<=nu(U#A4XRdK^Bi|$MDM9Us#3;9y)b4xRI=z?f73;>)GhrgLzk2)`iBeO>ic{UAM z&!r!QfR@SsuTO@N7YP1a$a93;kQ+MEIulCgb*9wLQ5|OV?yO!eCe1JSOf>Eo$opn2 z*i6NI7Gtg)XEXi)CeSn0N)xCnKCRn!tC%y_&I-zC#-@{~=0fm2WJt6iR-`%3)?s?0 zg$DHcnPooU+Tbqj-8T0+DgzT8H&owH1Hum!cn%uS;bzB+_O_h67?&JTON`3nGXeJsM-qNG^*U!Oeu8~fgc7N4Y` zlYX1~DIt%P2Bm`Sa&|;#UR-;u{l|zqj+BhJf!uGXVIz2*nSY;zLU#&esCUKh^R9Nt zaak5^J{@;>`Tv($Akmrh{JirOV?@&3G7hrKnnOgdWwkPd2Tdoy(|Aehp8(B?k7>}F zw08Q^zZ|@wflxoTY`anr4!IGZ`{T3?n=raE{{Y7G;YmkPD(|A=)?KUw(5>r`X#F=& zf$x(WQ5gv0vv!+~)F=xH&A5DYn{Iqe0T_C)gHq|Sse%4qc{_%_Ik^B(HIf-b;0>_U zc!_*Go2vt6J^!oR&k~6-r1xN5C5AhI!F8591BIPdq*nliM5e~_ZnlZy&CWYD z5rM!ovLBqD4nP-qw7$~)=f{@3Jkaz_qbyix@0X>Eu=K!p)Q*XxffAm%eb(1cHG4#L zE01=3>^I9TTQKtvmk6{!09N57Uov-?xsZ z4S%kWv)EWwnJ&da?@-ri$%neth9-H0LGmGF5E9wIEz*jt7b76ozw-kgWn(P8L{*P3 zVPGhe{5BL?rQpTklnxKxqG(3=|^59OE{;zshd5XZ@{)w8?mIY9w}0 z;t4VufyLILnd$8Gf5R73}8 z+T@jKp*5k)FZ1sf3H%G*kdo0i?JZk5(C}!-;hNy=PkYiY)h1`!aEdeAT@)fNTFf(R zS07bDV}J}GqszVZz%ypX?OxZ101e)#B@8Pne9S7e?Yod^6t0-ZbVewiM1URE6n+cw z)zq@uCL$2 zd#nD7-d+LltH$K^5VWvP6TOJ1caUZVKo)XjzrSr8`Wk?4EGO&Fj}v=GyE#tAL&I&} zI6#`T0LKt=inI|raFOexBvd^dWl~${IBf`H4>wsMzMX$(NQc(LxN(4O@x$Kx56okf zXZl>5|3KTaF3oU6H#ySZ`aGc(0}06B0plK{3mtg{2Hv@1@Xo7?CR+&Vu0CKY{Z z+$$-Sj&+tKTypCQ@E8W)S^-G{ZHBBTW5;>Dv@es<7t4jwiNWdS<)C$4Je3JLQ}rPX za!EtKueSgxO(W=IO>e!veAqT7SX|r%2D&+J-4Qx8!Rg(grhAbl#un&e>jvn%)W%zn zPVSr275#^lwDHV*xc)ZzpZ^+u`mYIV*+p^#%U&9r0@s#!^lyce+ZsLJ)E6N+!oJspq3rh~GCPT6BkC zmUI3n?IBBzZY!_k>K>`{kg-gd2^OgCg?W6Tt528c7erJdHh!d(?;K4()H9BybNkly zbRGFsl6|g#I1IcAYe_c4x(p;=@@Z8hemmgzXp8-CQ*4&bJ|!gz1%sFB@O%bLMn(qw zwiDRQ*=9~bc7tdSlb4dt0?8WRW02&=A#2J7$r2Y)9yV$7TF%Mf_5t~8%A_WB5*=sy zLFHUsiQm!r+d4kB#aQ5HG1Qt>Zxv*~j?IIcE!d-9-A$XyfWB4~?o$6T`k<{StBp6| z$+*5&{^)acWUNpi5d~cOwI9}FZHU{AP6fUS@pvk*|I}EsRWq8f3E=NAwb<@s3S!43 z@hKS@IvY!Qo}FV*loj9uO047t|M@A=>d*M&&Cisv+=rvWBl~(98yuNHoS* z5At$Br>=KUg|$1qE}1pHWM*7L@Yv0Nee&P)>hxsIpLy_@VkHSRz0kA zZ}q`Hszx6?vMSQ2U-6xwut+``R4TW-;`g<6I5kV*2l%v$TO7>>>n zc*48D?DX3K1@TqCwZyB+P@-$ER>46k{0)DF>C;B94PSs4yS9h(yRO{WX1b~z{oYG) zox5vvo3vg$lWUBc6Y>U|q5r0*|UI1cR>ZVE{GVPh>-b zq%UXm8{Qvi;kPy3oLL}8oi!qZ!h4xA1Ex2Pe7I z6lSEt=W9tsI_X7Fm4}=f-l!oJ>A=a=Gk!ZQ_j{u3kFPYO&x1n!T8Ok9-6>@}&a0_8@2Z!5%No&r}owzEu)gju>1>yOzgX+f>PQbT^1hPB*)%G(ZAO1RZF>F&{)mUx{{Bp% z?eVeIg6(^J8UxaSZDq(M4SvuSk$#Y2z8w9LYb#hP|4~2jIBT{$WAx%$Z{u`l=n1Gd zOI!KdJ5l7(CG(sl-R(myxDfV~yDoQJnJHSIbz->3evc~RT1^rj-P%4gh$bts}}`Kb^!>+!q&7A5>n2OOT4R){{)ndP;VyYcW$&^gqhpXl<2 z2JZkE`@sUvT5>;APWupj;0Tqr4BCJfvG#r4OIo|Q-VKAWqFeTMY?^F?uA+F=!wW7V z?ItO%Gm=T7x>SbWGvFIxB2@~S7Lfn!Z1|tx2NvL5x3Y`>oj()l)YO_)DLnXurLMze zhjR(_0}`J{DQW;!-(lqqhUG&qHl6?!{PaY2YhFdMPs&t16*iofIfA!kB(o0==i!|! zZo8LChB=MQf{@mPypb^(s=;;$`?QWD6`Ek0i3%ZF7#ABW4DdG=#Mb!2MN_xIs<`6^ z3UfvH-L01${F2(gy*ll&H3lQL(m$TgO_XFyqmxGh(l=XcdaAlv3({DWsgZP{N}@&M zl&QGm%Dy}J4b$jvKCb-`_tS`TK?pN{{6gzEUDwo2%>;fE+!Jzcn2~-AbZ4Yj<3Cgm zFnqeRJ@UCfUd)-l?U~yNpP^h`Ua5nNStWQ?Y<9E4;55ZPO&FdI`Mq|SGnWwCSr4}( z+Q~!2KPd;W&|D)9oDUPhJaer>s-mQn@!!5ump^&dybD0dq?yeq_PE&*KTW{>!b@N$ z#1h4BBLS9fbPkH4$gFVeG1700G|Hj3Q75)c0Z!*i9rm0}rzy z1SRuT4d7gwYuCJ1VHnilai`*Ys2coJf24sL&jyW1x&x%IlkD#VGn#)JVLvOggLETovkp=~@R*5i*ddw2j7wf> zwaRVkAc0@z_MknXik?;;2m+AGb?1)*&y05ijb42sgAQL$P0$@+Slh;qn0s*Kj>MQZ zsjCXxMd16mI(*H(9~lss5fBnReovhFPQhexPN?=hZju)m$HRB`Ss=(In-@CoN`74u;p_}*$aO=_a_VIG`wMIhzB(eUn0h{>?VcNl8<7CsU}*2Q z`Uvqq+b2A6+r$eSz8H9c|L&>S z;60i9L@w4+x z+EOL{xKhi`)?yAVm=s*z#m06v!YGfti}@LoM|}OeFcWk`WVbdraHD7F-GM&!N>^UJ z5EU17RCdW1zIZ>m8)OR@fM?H|8TO3t#$c=r`M=)i-u26!o(9iB+uW`EX)K5b%V;G7 z&%MiL8JHMi-QyiHsSh+BMKpT__uH&%&!fX>Hy^7uO7arQ#eAE$X9mrVF6^Tr%Ty$Z zsuQ<~TzXC|0RJcRHuSCLkJ{z-swZ_%(J|50w|#G_8>*ucj{fFksF->QYK$fmHMvi= zb$0kxxjhKf4*cB&pBYMB#l!vNGRrkor2lhR3MY>x78*Dmm0~JN8dj@ZLVxKS^~iK` z0^XSJ%x-SNbY2)6YDF-k#YfqBmvEMYET{IcJf8Hv_pn&jkaTqU_dAJ4RAuZg(wEUo zfOzo1!^-+meOH%2UR0|m zA+g&%!L(^o%FR|dvWt16j_u}UMCwSYSmOBD!zf4$QD!hz@yO9?J>hbD1N~{Tz`X(- zs^-ydEm=L7t4*h*1pA(OZhRYnYirYaT|RM3a4>#H$uoUTg=xRiop$zNR?@m|Y|T{6 zN7+-6$2)6*12Yzv`#)>6kFJL4TN$AtY9*ze2r$k~wzo&?1HE9>4XpC@!37T6bw`Jp z65Z3qf&3x&w}K&dGV=;=v%kIGp^FtAaqG%70o8r5yqT2lR#rvBgEv(s5J7Kcm)u_L zhy7U|x`Q`lten(ktol}=-lEWu~HGCoW!EF5?@p9XZC&5|M?ss3q=sNz)a0lgSarRS? z?()^tmKw9~SWUNnWdEHUEw$a7y89(7AuqXlI~en}@-0}jb@2Oy^*czo+RpgI^GlU=g=s~BLF;g-7> zlV?z`t#k&PZ78~?IW_5j$CkW4cS}=R}%m%E6AK1`f$( z6SisZWtj%}`4C6N?zx~>f)>9=@vfo5G-tEK-bP2>q#sdi?Ta_1a$W7@CaS8T|9}Jc zWW{_#vd{Pkos{)KNloIY*J^5oPE}HbFZ_33xh?+J>EENUqN9yw=_03hfvz2lkWI!P zMh04>00PYNuO^?+HMRaMmw7*!>f9Clw)v;M%e#!4PkRd0B>&~2Sw!3wvi>j49g6<4 zHLXtg!{RbnKo(eJf-WGE!ye%lM7v1(ZjrDR)^@y3 z{Q!!z!f$et*eT{wOHD>9O>be?OXIgv+J*zUqhZTmpH=!JujbX%S%sZwOoWM7I0tj& z+BJ(0eG3UWEs~sROg|tH-2mhX9DSH-4km^sytEm`hO~Igz9pI6*M!Iz9GB^qH*O)G zc562L3Q9w0R*tfQ_7&My@mzWMv-_spjMDL-CQbU4an?26uu!{A38j=RpdI7cRG|Rr zI}mUQY#)cZ&Vtit%-bzV$GsIGh6!Yv-0DN)u=1fHoYA%!<&pF6U!&_u{~G7m z$XGq-jIJhlaQpF`W8?0l3>&G%G8{)==7?!hAA3V)4ygfuY1P@ER0zlB6jg?t46hz@ zDmwATnG>8j9fOxis)EWp{S;Nyg{c`){YyHUFzj{X8o{9{->>Ovb2_dkF!!I&zN=!t zN005+`SG&7%+S@!xN)x-yO8s0i&jN4R^^5?>fF0^hT%68bi=*P4_V;mtDdeuq4tcO zJ_EOra;bxi7U+Gk>!A{C7PJ*^A{Acsv{GJRCXWXW=u#fz*EZM6bQ_3dmj<`kbu3^; zpNYU-x*i0JZel;Gg%$LP58I+yhjAz4A@hbWmtCF|gySDlDS+4f7+nYdt}6#*NUrnE zj01nI``^Cc9q{}5-OxmJ9Dp>9qCqr4d>3_WcoL&EI)z@~VL_X685FYawg*5Y(q;C3 zSXbe)e%JnG)}l4^dcXWie=y>XzgF^%LT_Yu&n=lleB#1eM$@xi-Zmz;yU3cnBz9a|to-WQ zL!aNV8#L;PV0?GUSL~)bo29d*>>Y)WGU@>;#dlz_I*dJHs%!vUCESLBEAY^$u|n`RNe*++uidTeyO+j zl}Yr~K|g#hSByMmN%Al)wDHsEZ0}TWVcxlyXX%Q5HP%5xt#BH`S+5QU6M2n?smq;r22c zeoj}@YXf!tlX>ct7O=FCv+^EhIIanybb#DSz>#oES{|5AFUC+S?6ZD{qIqTuEqZAm zYqr0H_74Q&vYMiiCHgeE2v|ZYwR}Zd@g8R<`-nGU+Zlwv!jK5Bz61AX`x`hFtY?IT z-;1{gLr#*CifzPE7j;io7k=rRenRvPQG`nJe{143cEh@b{I}@AA~lv%IkMn$(p<_) zEn+-0XXUxNt$yVTi|9d{JG0oY!rcUtSzDe1{GjCr-Y-ps!Ku%WQ{ije>y=RCn48TQ zw{2RGF9V~+5YBy#*F<2n>uwD`sIEC8MiSoAl5a-4QpK}6PKF(2#o)5VEDehPlVd9M zfaLu>f{m7ixciqUMF)Il$3(u2SLtBf!g}GVKd5zjzuWUj{KaRP+=M$u2)kGumXduh z+@sLTCH-OnbNXHeeuK;ZOlGCA)CmJT)2g+`Z6pF|E5mjsfHu1fPgj)zG;CcPa8b++ zc}E-$;`3!xesa7`S9$fhdv6L%qmsQ>VXJ-hpj^G4s9x+O<0`Q~Pu3inQ6lGEdkyws zBa>AWuJsc@l9Q23ydkkzWzA>aw-P8{0K%wM9XqMO@0kbwqpZHyj%VGu+*98PnDvm% z890D(uC+Fo^}1WK-2sd5F`1#rdVW+xn!4yu-Sv0QOhDtN_`u7J(8qMOvk)GGROp8g z|6cg&O98)kv0!mZ?=#JYB>~_jcu9hZg%nv>jtibR{Gt#jVLIVlgX3(JJkEf{*cFxpj&+k6&pGmfy$ogFS zW4}FjXh#$-XGkOtP?A?hZM*%&2Fdv2 zR(}iBh>JmSNx4#U@SEb6E09eA_=d4zXal-Vpox+mkdocXU&J43N;lBfH`ce1&Io`F zBY18NM#r=lng9jXLbxGs`e>KqUp#B=(;`<2=ul;xh1bo6!pXC@fLP;gfK7E{^JE?# zs~hMUsx8=Fgi?B!0V|KvmfW})0zEsv;G+q(rQ`Q!2y>vU<&|hK(0Xbd1ud;gyD;MF{laFCpQBAyRixot7=jFVG z8>{$G6L_kapLlm{EtIOErj1mp33CzM`IZF-ub)e|DMMw5STb}|b7#%O(K_r#yq$H_ z(Xk7NwjAuB&ZIE_QGgL{{CR+QIvtSS2oEJd-H zB7V=TQqv5zC&GV@O?FZLBKWRaV&AuSKOakzff<`c>!1TZP2l_X(V+q-=t%N_9nXr+ z=?0VI1V55QZ{j|-3*Hc)X<~HDHU_{E)}car`o9ymHi zVXiW~AVH><*0LZdFdkn<0E7QU$N)ye(KX%DkHXG_WJ=TIDV)57MsV`+k7OE+z)UlHqqQYkj;L zOf6sU>422HvtJ#f@HQbwuTm)Ua>7}d8BX;LkdbV>6y`D`r7k^U%P z0ZaH?)#otg<Px{kBMQCk*vX5E|6vxVb7oeqSWIf4F(+V$}veCpwm zx%_%j)GkvtF@~;m*5v_KgxF~(Z)?)gb8>2KP4 z#NRWOWd3$syL0MJLA{z|zUgwPgd+ZRb|p)gJ8|Kz%;-_&f?vO6>^I$QpdC|sK^+NN zvjjI(H0VkcE4M=vpewMRW!wjBGVMO2%9?;tQCs_^7dut?^tQrnGC2J8GV?kS(H|)$ zbgQxe7gsj!g1g={lwHlMO zocliBwJ&cN+FSB=AOBJ2)wz8BblfWSqNvV3#D^ncuw(cPW5x9BohO5}g6=aVvp8Jk zz=y#wR>8Fv+mEOjE!9a)5V;WF_u@4XL{s0$iPRb^+^;NFUEWey#E!3(iI%;eSI&Uw zAWY93+#)uTIVol`r%XaS`{$LKNT|NFI9Fm2DUQfUg27bV1S$#zPYuQ?qr&HpHL}II zW!nCvU!x4j=T4>!l&vP+m+ti?H7lVi5Js&4$u2>O2alhYTOTd$s^hH1fcOIGV?{|8 zR7&=78=Or2R(mJOM%{ZicNXE0xGb4p)|$f`7ByyY+_<-nB_-y~|ESp>)u4U=K9ZbT zq<5dXv$^i(%(99vEwPTvOyyY#dmAp35t!Ye%g`NdMTcAXhnQynnh&~D^fdUSOP!m8 zvUlgEnXZ|NyqT8Hw+Qqea9*UtGo&T{wm0HEF8^*J*NuvpgOvtcyWcZJK2@YJgx&(5 zwx=A7c8UC@p)2(I`eOf#R8e$2|fg- zdK;3e#-mpjxww!_RR5|1vvxg5rVImsN+zW@ruuIWX5wj@^0n)9^6+!$SIqVrVb{MR zO)V7tfk~O|vh|k;1D(H(NA@CFjkum{sJA5=SeaDA*9rc^`SL3FA{fTIYEo5^ebn6= zgU%L*k_KWpc<`*AR8;m7^j!?PVBI&xG~Fr5YK{1sPBq3ZinY2rxcH||z0@Ypyd>x3 zmEj1v7UH{hwziF2+}ZpCt*VQDd3(?84RBmy;tRsH^(eY9SJP;AyJfi3afnz`G0b4X z+eZQ~c%+ zXqnyz$1@AA!0LXBc+=hTG1Gs)i>omjc!L-f6Ai2Nj*=*K`v=A7aBuLbQ%Wxtq#}Iv zaY8w+l!&Xrd*jev-?Z-$o0haZFO zDM}AB>K9NNe#bH~_-zIapih8%Gby_VuBi2*;H+x5+&tu=Lz0|c7=6X?K1QCj{NVTCWdN|S}$OiC-R ze5}3;zD@$YW(zy0b@4g0)8*v*{DH}vvy!#2d*G|w`eE=Zk?3H;@iM^I#;;V1&4I=- zF{#KCf6r_qzud1Mo-iNyy5*nGN;s#ER6nJ?V22KOhPY_3lbAc|jV*6!=v{7I{1$A< zc##hL8p!=+&d{oLw4afWdfF`Ro=uYSS~JoG{xjpaEYpa?C(Uj|$5A{<`4h}n6#zw9 zH3_y5>Nk)`Mc3O>U7&g$6K$)Q51Of~SX~SyJq_yp-~wBFG+gB(RMK8N%$^Qf^$%%y zFuA;QwRLn@T?4XDm~)t&91Fsxysz>I%f?BcLU#9<+aD`eFh)dM1%mCef za$VM;uzwdXtIG}EVIp}u=LCBS3vMovF=0=5q|bM(CS)^4eL>KY??_Rw8Un-S-NS|C zotp9qS=wqk}O{IY66mRHA-p=4r!hkPgLD*DC+ieyuA|m z6D#mzZ$N7|1%4KJS*RqA(ZQLdaF~KdJ&AT)1JE~}t*7@I|9JOp-t^`$=a+RH4x4tt zkJYHe^`sX_8FEVzNw>M}%PCw$^aQEyIoSPwX1YD}wn6eO{5=s@zj3x~*epDBbAwg) z2PyFl|8it$Yet~&mDIbrGf?hTF`p5su_}1IvO5Q}e;~{tqRiiHa^rz>)ZMfr1C;|qBtkW4q3E+`f zX8r-RDS1CN=jTj?suy(uni9)?boJT)_A4oANB#j! zJjhD=6?$<E7T|jRL zG+TA{#GqXSjP3y7TxMu%0q61w`U<0uT9SbT4SV~eFTd5PT$8fV)<_hG_{~i}{IeRL zoaa0AU)NLMy@|Hqes+W6WChfrKrd5ktty$GY+&ZkB!}KPkXN4XPfXWmDB7rpp%>py zkTe9l&15*<&dD5@ZdWtcoDpx$G>0EH;T#!g!>95obsQzsyARTBK{e>~FQJF)dgt6* z??3&yJcF?-R?n2m-+>D`LAxENVW_~7lYZyP+d4>Gz6!s`4eNR)b5$&b_ocnO#}T=w z>$M{Ho+5Z`b#YpDkM`9P`jxQsOeLjiY`^CHA=nZjfo|`g&)x;K;?C;m@ekv#08zS5unwuw>o0cu~LRinpSq$cB4| zFG$y7S+ilQ;QR-$8+_tZdco~owYT0o-~T@KTaiUXcCEf%6Z@#EY^6r&riET;QxgI3 z<}@d*BdT6C4IjH+Y6T@Pj@P8!D}S5Z2oiOtF*{3^U%nm2W(1#j@+>2GxvcZ<{bc~^ zIEk@v$T0HF$cTvi-EwXCK-^%-bg+S6Kh&6GagidMj`3Us+WSd_*2!PI*_ z^UK%=HNZWz=h+Zt@n?JfayB%Itfan1GFj5$w=`2Yg0?4V!<13_d%g7<@9xgwwI^A+ za{V`N>!sq@Hvd^)Bp+GWcgY>!#CmZ8+l_uvuh^cKybfx&Hk{`3%e!CC2tq(U5E>Ki0>pVgblSGtJ3T~)szuY{x>|p_^T!3iimBI4%(z@ z_$A!VA4I!d*UOD1mU{PgU(!&@M?4<2(egmR)&jmwN$rEFi=g-~Iq%i`27h=NX#vkc z!H2L>HP!tx4qIto7x=>B1INds-cZc+H360S`02AG%@-7(%1Btx9=;QDLg9knTAet5 zL?D_wZ!`Upd-hyQ8)DP;lIN5#6HyLLAoIarbTK*>PdIrGe#Cq>uf~MEvmyO7AU$M? zgC$={Yi+!HE|LKABpt7-ND+J+Luw4Q(!y6dHO}&~PFMY58ym|(n@4iA;3+SKl^}QT z=ec%zrY{rS#`Wn(S-naYS524~Z}l{sZl&utbzSvDsA~1%YpwOv7IrUKEAt+YUi_@9 z41fBhjI?l10)lf8S=ev z#>I@u$pcM9p@D4GWcXSIKz@zcNY%yF%So4*QT&0hztAKo5svK7+d*@j6+W8*d3z%ebYDBJT`K=tq%RC zmRns9Rxt*32Fz6e?UzWyiYA`icE;}SQeGAzj!<{U(kMF2`$VR#(sWEbNSk_n8Rg$R zn{Tn49}!djDYWx>u#+!#o7VnThY{-5s4Q>MjfD79VD&&-*v%Idzlz2gYeW3vj_K*+ zSh7Y}O1%$#O z6ai5cJWiI@MvcbRW-VRQ&eb`X{Zyd23`|oPV}CGjOy-*&mD_bNHVd47U6R=PcsCG) z-x8&{+!kQ!_UvrI>}qLxUz4*|oIsxs*)6y0zJKaRg`U=YKv(9`iu*EkuAG_ghf4yK zlXICL#v8cHAdh$fW{31T-6lR^X1t|XjY@1L5tkpi>!N+HjLdNVmAz(ndlYFe^|mFs z`VUB0QLI?ot~=e~zr#!5{wsFV?=|Vlh~D!?cs(qUq`gpZS4u}`I>A}8*wLCiwaxB% zN{VO7J(Q5_)uktnG?3+?W|Meio&c2U&P6rfo7*QQ7$KYl|MSDBMnGFLBx|o<;_X0s zLYA;0fg$S(*qFOIL%BNLK5KV?%Nk|2n583@X|q6BIqJv8tdFclt?C2JmF1ECpMKYV z&I!3IGq$|g30I$U_^4IyZd}vcLr7B$T+9>5dJ4-st>-5t=1aS7XD$ehCOr?^dP%=t z9gtOsz_ggiDC<4StNA{zO6%paC&6dQa#P2IE7#-;8w;D{?#Da5+&=sNU#~IzLdrLD z5$i!gm*4>wRq!;pW)T3{_h^5Tt8WzIB4-J@3l^Zi^S}Zqg#u`n|9tj+ZISA~L(`hj z_rkl9QUWp5JOAPhl_aSE4e9}odssx4C?9S&wNad4+=)9DZxS|6*4VLl#r!wnki zPNPCeF{ioo!aFx$yv1+w+*u_SeG*7bTKAU!8TyNIh9NsGrRPpmb*Mv@vf!%?{s9S{ zwTcV%^%#YfY!#ze(;uy=@!o&+A>V7))lm*!B_>|c9@A7#@C-Cg*w!HjijyZ$4^D}a zVr+9PBmHG9F{5gA8JU(y6-Ymhe5^?k^9F2*42e2gSz~eDClOi1hwX{CdN-TCeC;{E z-1fXFW~$gB9&h#KjVIViPv%SzV~J^bH(p{E1ni3Yae?7VZzNP2m=NuGeTz5{-;g1tSB<;O5w|isa3j8&2R)`k1?|^M zO#g2FTmFRh1p7s!9U-b|(Xfm<@9T4UFNOEseKm3N?2F_W)FN_M*qEPP#ez@Qhak^N zW?Oe5C#pwry1sLOkryY-GXu6|?uhwPta%Iwxg~J-Yu5i&TWrW|s;F(x_Na1iIH49; zj8kAp7Irplx#$YLu0UP4uV#kDy<}L~eyM`G>+!t%87R{M*ZYBZ3Y#9|9k2B5L(lso zi!4n7MWBFokfR5+hZ%06whz(YdN*XNvYM47rI%QPyX?k7H>m0JS(;OaqCYy@9K|+1 z5cIq~Q1hMz&S?+hSKw%WU~x4H-fW-suil+4oQI)Q1-VLX^i&F~`LTl??$Fi;Yw;jT z(6T$^f8=j(DT*fDUS?Hmj(*qA3^*jMwH%zt)DgPcrh#8_IVi|LvGg;tM{`mVmfnbv ztS0;urLIr`av#117OC|R;I+Hz_cKHRE)Es#3ss=NT;4H#RkQ@CO3*rHe1mJ3fL>=v zX!$kF-O}Ownd+=Pa>f$;p7!}-LJ)^mVHK4?Y}u4en+9pZZR=lf{@vfYVS;Y6!Rd zb;0d#vy48B0&lP5X(xw(KN`kZD5ezhI=7Ji5+aYUlAT&wgVJS{1gy=b6GUGm)`B+-^NZR zgUA0w+n`x^UcNv~t|KotpspAJX$oEW*%sdzH!y=(0^~4<@};tK7o;-zT_CNSyiy;$ zTk@dr%GMUQR>WwkXRPy%swmaT~cD#CK4Tw8~rZl#m;l} ztxxYttj3e+T8!K*zpb}BWWOA~y+Zm@W9<_hw%f0ur=b8_g8vxIxwwN;8c?qE{i-6v z0xG(W;kqA5zcw@Di0ZHI&|1s!qva(t1IYI7p2Ep}8G-(HAzmp zgC0*h`y*r=Fw#XK#!lFT*nGL%y;M~cgnP_PpIlX~hQ!EJ1q3ae82?x^JyFTTo6h&? zYG&l|MIoZ-0JuL7_<@J7qQv_KokEqCPn~yNoxA>h19d*{s%H;k64fg3z0VzV$`PJ* z7{euuC7++E9Yrxl;VIyR?o=_XN?2uEg>;TO7*U8@)S@$iM=A zKk&_88~QcW8JntNTwls4bvehvOqT7ficb0bCBiS9)^P-8`! zzyZ4z`2RE8*ptkw<5xg6_Q(xnr2>6B!)y?98M7xTf93@Pp;?6+l3i94{Yi&N}m8KjWYh^Bn)*!r}H;q-aLXW0ZGO_^N?ja8;#S>{ae{ zhEf>h?=`?)`R;E^!;M{qiv%k%4qceEdyfFNfw>f~vYx~J^O+;zQ;Gsv?C?urej)Fd z?C+|VS+6RCN0LvCBFD6r#dq)HBLPjsY=?%e`d+cUDE1KguRQYk81}$uHdY_QBJLyZ%NUlF4di!E^8Xj zCrw?gHSWeYTHZj-7I~oz!aH2l4ky{qjTyMKTN+pBpd%f0R*8ti^1uHK#*mP^NJZa7 znfFCF)ho`gvHt8kZ^gzS2balk zkS}Fq_t`>k%=Zzc8OywL2TC(O``^9}x~|yl{GZj8DeP!M$9u74{ypQa>FzoY%+{nD zJMU$Y=tP}BT=TeA2#w}BVUV7cH)vmW56zJL-5a>WXc+ABKa?{1f>Yg?!;M4CX3u$b zUPBM-D&sdel6ObB;8!`hJ7Qm<>IJozve^y*+MvzC08aX4PO3`>cE`* z7nh=~>KH07G2HHTvt%0GK%}!}F(b5b zze_mYra5tF{!3m*-+a@(s`}MK8B6d-KHten_mQbgirIU6kA38~NZ*O7hxkVNL8U24 zZhUUA(eCqdruucuj9S<7vX4AoP*`V3r zrSM}${x$cD4Y!kye(`H_XLh3*e8Q66k~pW;a%#g8yO!*xfy=aK z1I&Qcj>P8778 znI&1H22O+Ugf)&bEFLxWA0^iSK(tq~4VD2=B{FsF#hdFQ7rEUFo#}$Oy+LEyS@NaA zq^q{5+%^r&3Bt-nl{;BYfJTrf<|Y+|b>-0Am+52~ER)v0RZiglyCO~>l1<__5L|Z+ zY6(wuZH=kT#IOO`>_E+Ufn?MA9vCCACCxMgJ5V&8W6=W2^C86aNIbUv==4#iuY(gp$qg07mmR#-+r=13X2;XPMIKX zK^#SPj+U%EQ?W#^x#VDsv5Wz9)k7r;a-Yla`BqJ0XmW)nt=&vsnB?ID6H@OVJ=q@} zCl)u=)af6{xtM<-Z{QqqMjh|#57A}?E$1iN0Q(>iyWRGd!rT`f;yfE-Vm4kn`J{^! z9~-4YiJhF7u88vdfO0S=F6gVi>(&L%e-yVX?yg9%9n^jKL)P>pdv0h46b1Z+@nBc0!aF5= zM4Yu!3Cctl22&@bdt_SkloR56Fc_|4%xrVZHHB|gvlkkJj|XEs2FvqB%AUB@isjZ} z@QudxIg*-XDc(-k7K7S!)h4-P?ug}ol>Y@ho$pVCwT!Y;qLt*VDR2O$v}J;p_w$u) z{x5f3eWapoA8{ijhsPVWg+8HV`ZNUWa1wN}rX$RH1e_QN-FEzb-LAF_W5k_JB((vl z?qllNO9VV~J8jGP6Wv`&KlwD57a<;D*RmAsDS~u-D$9fn#2fn)Y1&|F$D-hO)vkgx zNoiI}ls}gMh>{C*LaZG)3)ZJw>zkz~4CiPbY#|!^H$Qtfong1%tR5D+2-8^DgJ>V? zL%!vB8^0hN#0EB|{!5iMH9gzS$jG!SxUSgJRSAYxTU+?U0FXK#tDtuq8(pjB*eg!6 zJogfdkSO8}DrKQpH?>R_!naYCtUzTXoP3gfJ-k*ND2(ziyn4UFu{@r#^&Ds>Ocj?X zv`|dZ%&Pwmr!k>YB4$t1n@Wx}4&{IKO&zCsAdJ&85YCRz?710WTQWTBiExrHhk4!= zONeD7^(P)_Dx5lb#=-Pt^uW*zX=40o4=|Jo_ng$l%qR3#FlqXG{Qvi-6 zH^fdanDekQ>TslraYRsR@7BkCWqRg}C5Lz?SKnpBDRB2Po$flm=)dxds(Xqgv_wSF zH1)Wp&=NFg3{ZdgFEK%VfVpLqV#1+6)flv^c9Cn=?Hk@@C2UEqO*fj3JA*CeQz5oC zzL&8C$)l8=M)@>(&99DXKfP2{dad2%5#evi&Q21))rU>abTVzP6Sr}#@s{wk_BZ6> z2(QRe_mLpmokV>x!T1~(RH~z)J1Djnu@mDqRYzf+E}1am;*9Lq>MJhP#gc%6bHSNl zc4T?C^X(zVn|@~T3nm-jZ**gsyJS@e+Pp;RQ1?sTt>2QuJ4(!2<@};k6?6H$Pa18U zJyc1CAXyJ7x*qK*r8z^_TJH%r_$5VN)8+Q}*8S%`l%&<_p4!MJ6n8R)W20|;EKfZT z)UK3L${Vp9;{d%koEjS9L?qa-qNI!_*RPWdeo*jl-=Ud*UvJ(}({ZLh4_$Lo9MRH5 ze&`}arzPD4`|h}-b@Elk=jHk1{yRoq3O{&qmF$KiU0^8Yq+Kub&%VPw;L~yD=$NeX zX65nLK3gj9IB`;IQ{U3Ex)=A5%2i5M6Cp+F;=J968XEx-3CGAa8R#Zuq6Dmeg#$Q8 zM-xDAOGxW;aS_~pNh^y;AxF+s2?Zm-G8!+1o*R7P2w`;#$SqZZuDCI4qh<|bn54pCx>Hm#u z+t7|-8UD$_8#dAoKeQS6!Ov5CJweTQ3kiXSt^1@rs=kY9=dd$xK(@-Zq2kq!(V$RT z#~8v0dSCdX_6>nG#Nrj3qw1zeeVVv)%$+8qyaaShBICZ){{G&zEfS}|cSP;kQjycz zRa$JD%Q#!r!vOlsM9vTvoO!Ge-vBV6na%G%9@*m%xqMpt`p5GBxL%D~n|hDA6Qe!) zSRf4Um~H$!x!w)L_&j7a@zhPw6u$}+j^8quGS2Ky>k{XTn-8iy4qX6e=?NczIZ&}6 z@^$6T@2@}9FzZ)Y`nt}{)CQ7x8Dh3A?i!&*>;BwUwz1ts=}OeqKFWXLV%pohgTq(5 z&T8u!e-DscyP8C#FbZ~J4|zq%`XMEuVd>a@8;4u=V$3(;q8*+Nkmiw}4qHdrI zI2yKtxqjkI4F^;Ze{?VYjru4`gk8W_i0a!^mbe*;w+ySz>VOPe36IBva6w6Ma6=jw zKaN|t)=4|66~`~C)=f=>zevR}Jt%Tug=N(AH`axfDB77J8u!*)VYHPB(P6|x2{5v% zd$jH7CN~2fSmDDR&ZVu$`XIN710@sT2u9G#I7n2-AQ;eUj*=TGzW;o77`l|UObbo& z?`XL~HSQl?%7)kW;9bg6buYA@LHbE&&lSl6-B$hYfHecqHm6^qQ~UkRg#LhQd{7_Z zj0Qik%2}a9&x5KkV5+1Aj#CaU4$aCnh#*Qxw5#WorAgc(yyLZ9>r?F(V^ae z3RZ&OYF}TN+c$crW`EwMV-bmE}*@x}S4(&^jr) zfp5Sm$?>r!S3hK~cJJ9SX}0@=*T@L1ry#nr85a(O5jE%+Xuk@xrBR#~6#urMJSpmh zWjfrjvNK%@JYn**!-x<{S!7KI!xX}W^WWp&VC|Ek-UYWtXHZ@nd&Iq2~7R3z>2eX?diRrBf%MMoHC>8WyzIiH^oxs z%xh{g4&>Z13H5Tl8)UCC&46z|leaO-xMWxB;L6$j)z(Xr3f>oQSlg8I@B-%pJ3#`z z*)!0%R=hlt1f8kl$2-96fmZ*=odpTYk3;-!h3>3#n}*`y6mHX>p?ljZ)S3P?<6UO| z@|dz_m}!haY-I4CO z9q(xjImiMgf=D9&E2*t5hadCXULK&j^)~xlTg5rq<5OxhQxn6TW`^Yd$(-P6ziuH5 z?qm@STZ34tdpOJGVnb69Mlo)DJ(=UL&@Bi+%V61gyo>X@AnTS(B+<4Y{?Ol1?=&Lo z`!U?-Qon;g>5zCdKGr zHImIqgeCyit+5W&nyqIQHM53Ga0C&i&t*%Q=CXjYB|t-0kyzt`D62jklTo+`t2ffy zoKC|OC`$$z8-^nnlX#wkcH|Rutqpsy_2gsF{YC7*6|cHmI#$HeK1Hb536Z#4ClENS zZa?8RAuyfU$M1m@{{%kVfT zn^h~BpLP=AX^CpWfYw@(_?&vAg)fPN^+(3W=H5AUO_F;u^>wRW!s#%qY`;vK9HDA` zvDECzCOScDf`?kCP(V;mdPhnspngDBy1;W@&N0#YDQ*wni96wUdT??~1ru&a`gQ)Y zMjS`QlagxyT%6a07>^h&bN?dc9K1Xt7Oz&7%f7$#n0!Q?wN6oR|FWEswo()FQgHU! zKqEqbnkzfr(U#Mh)&EPJV%wSP_+SraXMlP{Z>f z^?%^kGo7!Q1J|@dP_SI%*eKGL%o0m`)FJvnoAzsto%M9%pyj#pbWkc7;R`hI2m;3w zrv6?jOPih1WTos}ec+)Ah56*K=t)*gl<=2Fs)zmR=_7*Ez|BUDCISlhQR3(_(8a<2Nq#R# z4zG%4mTUaUwUSHEu#pllO=$IV8trjOdk)FHur{b8HWZm7XKwr&Uy$MfUx%Liqid`5 zX}v8P>_x@!-Ref0E$2b6nfh}1FJ}F%>+WJ#;A*3X-opEn*@R^Al zHd6tUz7H&dt1{q(ipP`BEROxKVs5wtpk_Jk|63X4|MzzsimtLX9+G1_MR-CzShw_h>x^vO-R`>|0b9W^A-6=x$MdBk8 z2DM(4x%-!q*jA8*qBF=H~m~th6IodCfSR-|u|sQumbFmUQ&F zsj2*nTcdN1hesd7i+EYD9U@Z~vJz~?1@VxxfM3FzptuJ+Uu;bmW6DZt`Nlc zz^S?gG>J2g8CQZV?=r~%1Be@tg$lujdQ9oI>}Z5<0H~KKa0w(isD>B?=o2> z0iY)qiG-D@->J@i-0diqK~qexKBx^3N- zqXj`Nl^m=X0e$2;xQW4$32UkNW@M-gN&OL9BpG&w7ukH|)BAIU*4mm=?SI#f1J;){ z{zlEDr$2f#5mM`_xE1%9i%!bD!wws=`l3Ap zAtIb(eV*xCJI%^yLk~i;$L}T6mVAX6z4=1o&A^cn0WK&Rj=-fR?btgGbH#PkU=fLn zs=4^vki5?2BCI^TAhy$CJiyiXGBiOYhtmjdlQl7BYKN~NO$!`-wmut)oq*RzqPqt| zURvP(D1;jAia$S>f#~lW$=++VblMHcOLUj39+r(=x-`E=X)211d!uY?-I!%Nn~$fF z5O2^FfSy-N#NV}1q;`8ag5Bl^<_g%=1lP2%X2nu#i#L(3wuUo6Gx8QfZL>(acPf1} zRHbmSetarv*elX69fVE55y%k|0O@Fut`&S;2#?6Ht?%NH*DrzD-DM8Ue7OX^|AA4Bn4>XWpoicUiKxY+~kd7TW%6amP) zfHvs*DZj#h=vtZwh|FL|9N`ZmLh94PgFhF|p7BFI@|Mn-&P#ELg}u{I4b&or!hyVA z4qb!w3snEr6q&xn-wio{MebdK6mhWp9b}-^(>$XdSjC~YjLo#cW`XEjTbepch{Naw z&a?atUYO;mx3%EaunJ#14vP{=Q#A*x^`{e#)V@T7!!rK~nbzLF3%hpE6l}aN#=8OP zbXIE*b)8vMm~}y#r+F~OxRRJ zUu{}E?h*UB7l6l|NWJ=i{;DqIaNorRd~`P3f4EsV1149keC;bRSqI!OB z9>4r@hbpeD*Ptl>(%3+OeO6t>M^dCrW7;i8c2RpWP@Q&ZZOoQrX z(s@>-qC)-Y?6r?zi1h`xtKCjj%=(=TQ$Bn;flX4({_DCW()7!G>zCt|QL#{OXJ7O= zcnmuM4~C<@4(4)~dqw*yiv0Mu*Cz@)KUBkVNO90k8?X3c@_ zZQoz&dwgxMBAsp;co9P+Uzb;$Q~dK;Mx!S-D4leuQMj9q|C_sEP3(#bOq8Kgpzi$kzgLbGtlaVI`5YN*>{;^OV$Y zp?0n2K5#D`2CGYVdKRps`PT|$@_UNdR8#cNXI~C{+Oxzfu=LOD=Wj6)y1(SS4j_Ra zS)`W}?h`2ttO{9#>sI0UB@oJFyu;jCA}aFrQXdNOCf92h1Pw`;rPrnNYt#`k=4Vb| zbYf2qFBVR5sh3?18*eUxxYlG)TqNVbdAe);B#x!cLiYo*1iF71tT<QdS1LB#C|CGqWz;xib|nr)$28J$&wd(F88tlNX3#|FerWOv zcEZg!T)Q`Dx|six{$)k<+Mg}mD!TPZJr10~Hv=W3aH6~#h7#pkw%TrTlKM`()5%hM z>HoBMtx-)}TNr#4@o}v@#78wMDhNWntwI%L+WJ61jEE2kLh1t)Vo0mJDoKWFEe6CC zQD{Ml#)3cysX&MlU=#!&h=33LT~T{qKzukmkR7-1nvoTkMp!NHzvPR>cGMK~2`Pje-I9u}k?byJ#Sw$~?)y36ZdO zjQ!*n%#uF3Rp)zxwVJfTaAgb4qg!KeAoT|Bn!ebnyPHXK-Cl%}T#4EEEDEFLir7`q zK50JJ+8D7aU)M^&S|v_t!!JcOIWN-=2}Po$n!@zaF%|~Qy?2VDOWtq1j(!t!wb7o# z@^*~y$G0qN_<@O0qu1X<_aEtX+>F@CRVZ-ww)ku|AC5yxTBq2ZZp4R_V)|E=l4YSb z?WGZ}t?PdXlyWBy$|13cI?&;XMg+mlE+;S0ar|gf){sbXG!Hbq&i_RL+JbMOQuD)e zmU}RVh{-_VW9m9{cdsnbbC54=)r1z)t2WV()Bqifus<71{Huig8c+0Ciw#%JS(5OD zt7$w2B-Pb&r2Tr;gYZ0h96)>lH6h?CI>d-w zf2Q8g=iSebQN+!I5-DgsY0iUU@yhfjj`1+y{+iPM zb-if1cjwSm??00vRS4;%^t!`fq~MpMW)^%}QQZe+!ZMmecrXuoov3e!R)sRxPB|+W zd5t155i|OEi!7#pXY-YN3lBwRdjhW(Gu( zR08XE(0ot}>{XrLM$XFRW`XfW4CLn1r6Nn#2583`nD}v@rW4~g>TEd=pSJl^O88BM zIld*--7F6$Q+dyLtit3^`p&d;9AgQL4TSdi9n1H(n*xfP;j;pFL#HZ@Je9Z$MVwxg z$gttjaDLD!P+CCXWT^1KE%ta3tEfnVL(Tn<94zG`|33UJ{<7QhjX*|!uqxf;wOLID zTU=dQTkA+ZerN)*rf==QzhB^gAl&LeXWdHU@_p4Ear`f6WAU!6Kuq!-0`cGQEuF+bmCoVD{Ho{84IOJLfDZzESoU(@==kNCS#vx&6YS{Z2Bq?b%;Z1vX0 zJ9ngwRGbE{nw5qZe@60dBpBdVu7VEu7-AbLXWYiNC$%?wOwsSV1?G)AcP5|Pso%1d zkYBecT&-Bh^gcYCZ!3wCn7&pvFDXTo79#D4XiilrOBdGbqPZ{-kLFc@g&}T?AC>a2 zh1B)029vjLTz{Vx&Ug2qrJGY_hv%WIhUaa_!5m;ZLbXFxxJ=7DKJJ_8J*H-o7)nOrsHGj>u&AEDU+^;XCvDcx=Ss`U}+Z%#& zJU0kk;?+LaCIGx7?-l=cyn=wZzIaw%p%OhX78JDHO0pS#+O{qsHF%sve@*C5>&DJK zRV2c4g6WJH`jq*CId}X-P$SP*2`{v1vl^Zwd;R=O?M^GDpdPS>rZw8$Z3{0>{#q%v^SZ$u{egq( zwoctddSXV3H^l6J$W3$pj|PGNBUah&@R7dcv-J`%ybzj(_ao?oFW{eChQQ zP}Jwsn?V4wrf6rX=2Yi)G!R#Qirk;7lPHHpETZ`}jt=0erQh^)nuRIzV^o|KI6gbC z6-x15bvPz))GTLTawEyXs=7~!c%CLp$^ZiV1?bGjR?K~Tl}z`p=_=*+YwB>3$R2~# zVa&>8O_{dgra;*l{`79Q_+#jspO_~eM zTb)sOe{Vxk6czb`N=Apcz;_VUIaiQ3ENq>q4*#b05-D7h<$FE-h%meFaF*F9N`BL8%5FdS&II0vk;uopdTRw{`-dJ<<^ z^yE#9+3ep~&KdK#;{ZDC7Y4vTE@&J8Y?Bi}fLTx5KiQS2Y|%LkV`x(&%r3 zw%DTzz>im$bD?*f)(;jJWFIUrh*-%nt|yGh?>yH%(GGfLG#lK7VNwu6R_2~3JPaR7 zlLj-I!3VhZ`TXTPYG3gLH3nmCgpcB-fMc%IxnVX&ssv6`b-#pBjbTd|$XCW0tv*=n z%Bn|15SEgQ=TmVo-zD@gP4QN_Dk{cHYHoq>Uswwks zi6(404V|o7aS>HSb~u4Tg6G7^ z-s*s~s(}g-Zf|y3`wOcHP~ z8oCK4u0S1|wlxK#fv9i-y5iZPNmp8BSfGm9wlXdmR7FKJ=pBq`(f(qGdbZ7;7qZ~8 zjiv$s*@mY#a<4>LO^hPi0Hnu{)(6-BA)Z2p904u<%)V9$8=VXqpEm-#=<2trrg=r` za|JhwK~?Ixf~(sP3Q!TQPtaH5Joqi$Rf*u3azmHLy#TH3p$GLd7xvkb2)a&W&^Las zV|a9x8}syISwK7ZC!%sbxi=(xI1#%>?74Qxa(r)|enK)YYz}jg+Oj$VC-hL57lN)o zg}7Om+z_;<+_cLWdUWCVj)EIHky)n~>RaqAK`EFELB>?6*X8uX=SNhybFSfwKT41= zdL%_an-A%!N8=0%;aZOzyy14G_9m|$88x?>KdEcwrg*#M=}G3IGDmB?Cj3jnbfnTh zj)tluc%l*C@rK95O>7&cq;4a+rB0LiE&)E4AU6;C!jo;!a5arvMtLxZh}l9Qv_eKz5&K)Jx9RZP2~p7TT7 zx-;t5P;%MLgDvqTGB4l@X8=y#_@11K%>i!i9}W{slDOboQ9^hy*sm*%)O(_!j~b!5}gz5Ztu^@bHf| z!BNd#mkJ4~VSSDdLc))kJFr>EsVN>G97euX0NdGjy@0JGq~`AlzuWp_At+3=Oo%Z| zI}gr$3@Ou?GdxYNAZz$dxl5bKoXNB%)o0$VUpVt=+O`1Ya44XxP6)`{lkM J12aEJ{{<5S<`e(` literal 0 HcmV?d00001 diff --git a/firmware/lib/tmc/ic/MAX22200/README.md b/firmware/lib/tmc/ic/MAX22200/README.md new file mode 100755 index 0000000..dc3e75c --- /dev/null +++ b/firmware/lib/tmc/ic/MAX22200/README.md @@ -0,0 +1,43 @@ +# MAX22200 + +## How to use + +To access the MAX22200's registers, the TMC-API offers two functions: **max22200_readRegister** and **max22200_writeRegister**. +Each of these functions takes in an **icID**, which is used to identify the IC when multiple ICs are connected. This identifier is passed down to the callback functions (see How to Integrate). + +## How to integrate: overview + +1. Include all the files of the TMC-API/ic/max22200/MAX22200 folder into the custom project. +2. Include the MAX22200.h file in the custom source code. +3. Implement the necessary callback functions (see below). + +## Accessing the MAX22200 via SPI +One important thing to make sure is that the MISO pin of SPI is connected externally to the 3.3V via a 330 ohms resistor as show in the picture below. + +![screenshot](MISO_GND.jpg) + +The following diagram depicts how to access the MAX22200 via SPI using the TMC-API. + +![screenshot](registercall_hierarchy_flowchart_SPI.svg) + +The description of the functions, in the above flowchart, are as follows: +- The functions max22200_readRegister and max22200_writeRegister are used to read and write the registers respectively. These functions check the current active bus and call the bus-specific function i.e readRegisterSPI or writeRegisterSPI. +- These bus specific functions construct the datagram and further call the bus specific callback 'max22200_readWriteSPI'. +- This callback function further calls the hardware specific read/write function for SPI and needs to be implemented externally. + +### How to integrate: Callback functions +Implement the following callback functions to access the chip via SPI: +1. **max22200_readWriteSPI()**, which is a HAL wrapper function that provides the necessary hardware access. This function should also set the CMD pin to high for writing a register and set it low for reading a register. Please refer to the datasheet of the IC for further details. + + +## Further info +### Dependency graph for the ICs with new register R/W mechanism +This graph illustrates the relationships between files within the TMC-API library, highlighting dependencies and identifying the files that are essential for integrating the library into custom projects. + +![screenshot](uml-tmc-api.svg) + +### Example usage: TMC-Evalsystem +**For a reference usage of the TMC-API**, visit the [TMC-Evalsystem](https://github.com/analogdevicesinc/TMC-EvalSystem) + +## Migration status +The MAX22200 has been reworked to the access system described above. For more infos on the status of this and other ICs, check out the [migration page](https://github.com/analogdevicesinc/TMC-API/issues/53). \ No newline at end of file diff --git a/firmware/lib/tmc/ic/MAX22200/registercall_hierarchy_flowchart_SPI.svg b/firmware/lib/tmc/ic/MAX22200/registercall_hierarchy_flowchart_SPI.svg new file mode 100755 index 0000000..cbad58f --- /dev/null +++ b/firmware/lib/tmc/ic/MAX22200/registercall_hierarchy_flowchart_SPI.svg @@ -0,0 +1,3 @@ + + +

HAL

HAL

APP (Eval)

APP (Eval)

API

API
Read a register
  •  Call tmcXXXX_readRegister function
Read a register...
Returns the register read value
Returns the register read value
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
tmcXXXX.c
tmcXXXX.c
SPI.c
SPI.c
tmcXXXX_eval.c
tmcXXXX_eval.c

 Implementation of SPI_readWrite
  • Sends and receives bytes on the SPI bus
Implementation of SPI_readWrite...
Returns the raw reply data
Returns the raw reply data

Implementation of tmcXXXX_readWriteSPI
  • Sets the CSN pin to LOW
  • Takes the array of data to write
  • Calls hardware function SPI_readWrite
  • Upon completion of data transfer,
    sets CSN to 
    HIGH
Implementation of tmcXXXX_readWriteSPI...
Passes on the raw reply data to the API
Passes on the raw reply data to the API
Implementation of readRegisterSPI
  • Constructs the datagram
  • Calls HAL wrapper function 
Implementation of readRegisterSPI...
tmcXXXX_readWriteSPI
tmcXXXX_readWriteSPI
Parses the reply and returns the register value
Parses the reply and returns the register value
Implementation of tmcXXXX_readRegister 
  • Check which bus is active SPI/UART. (e.g. SPI)
  • Calls bus-specific function (e.g. readRegisterSPI)
 
Implementation of tmcXXXX_readRegister...
Returns the register read value
Returns the register read value
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/MAX22200/uml-tmc-api.svg b/firmware/lib/tmc/ic/MAX22200/uml-tmc-api.svg new file mode 100755 index 0000000..5a5f8dd --- /dev/null +++ b/firmware/lib/tmc/ic/MAX22200/uml-tmc-api.svg @@ -0,0 +1,3 @@ + + +

TMCXXXX_HW_Abstraction.h



TMCXXXX_HW_Abstraction.h...
// Constants
#define TMCXXXX_MOTORS              
                          
// Register definitions
#define TMCXXXX_GCONF        
                          ⋮
// Register fields definitions
#define TMCXXXX_GCONF_OTPW_FIELD
                     
// Constants...

TMCXXXX.h



TMCXXXX.h...
extern void tmcXXXX_readWriteSPI();
extern void tmcXXXX_readWriteUART();
extern TMCXXXXBusType tmcXXXX_getBusType();
extern uint8_t tmcXXXX_getNodeAddress();
                                  ⋮
tmcXXXX_readRegister();
tmcXXXX_writeRegister();
                                  ⋮
extern void tmcXXXX_readWriteSPI();...

TMCXXXX.c



TMCXXXX.c...
const uint8_t tmcCRCTable_Poly7Reflected[256] = {...};
int32_t tmcXXXX_readRegister(){
/* Call tmcXXXX_getBusType();
 * Based on bus type, call readRegisterSPI/UART() that
 * further calls tmcXXXX_readWriteSPI/UART();
 * For UART it also calls tmcXXXX_getNodeAddress();
                                           ⋮
}
                                           ⋮
const uint8_t tmcCRCTable_Poly7Reflected[256] = {.....
TMC-API
TMC-API

TMCXXXX_Simple_Rotation.h


TMCXXXX_Simple_Rotation.h...
void initAllMotors();
             ⋮
  
void initAllMotors()...

TMCXXXX_Simple_Rotation.c


TMCXXXX_Simple_Rotation.c...
void initAllMotors(){

// Configuring registers to enable motor drivers etc..
tmcXXXX_writeRegister();
                    ⋮
}
                    ⋮
void initAllMotors(){...
Examples
Examples
User Project
User Project

User_Project.h


User_Project.h

User_Project.c








User_Project.c...

void tmcXXXX_readWriteSPI(){
                           ⋮
}
void tmcXXXX_readWriteUART(){
                           ⋮
}
TMCXXXXBusType tmcXXXX_getBusType(){
                           ⋮
}
uint8_t tmcXXXX_getNodeAddress(){
                           ⋮
}

// User Code
                           ⋮
void tmcXXXX_readWriteSPI(){...
#include "TMCXXXX_HW_Abstraction.h"
#include "TMCXXXX.h"
#include "TMCXXXX_Simple_Rotation.h"
                                ⋮
TMCXXXXBusType bus = IC_BUS_SPI/UART;
uint8_t nodeAddress = <nodeAddress>;
                                ⋮
#include "TMCXXXX_HW_Abstraction.h"...
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/MAX22215/MAX22215.c b/firmware/lib/tmc/ic/MAX22215/MAX22215.c new file mode 100755 index 0000000..1f0bac9 --- /dev/null +++ b/firmware/lib/tmc/ic/MAX22215/MAX22215.c @@ -0,0 +1,56 @@ +/******************************************************************************* +* Copyright © 2025 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#include "MAX22215.h" + +static int32_t readRegisterI2C(uint16_t icID, uint8_t address); +static void writeRegisterI2C(uint16_t icID, uint8_t address, int32_t value); + +int32_t max22215_readRegister(uint16_t icID, uint8_t address) +{ + MAX22215BusType bus = max22215_getBusType(icID); + + if(bus == IC_BUS_I2C) + { + return readRegisterI2C(icID, address); + } + //ToDo: Error handling + return -1; +} + +void max22215_writeRegister(uint16_t icID, uint8_t address, int32_t value) +{ + MAX22215BusType bus = max22215_getBusType(icID); + + if(bus == IC_BUS_I2C) + { + return writeRegisterI2C(icID, address, value); + } +} + +int32_t readRegisterI2C(uint16_t icID, uint8_t address) +{ + uint8_t data[3] = { 0 }; + + data[0] = max22215_getDeviceAddress(icID); + data[1] = address; //register address + + if(!max22215_readWriteI2C(icID, &data[0], 1,1)) + return 0; + + return (int32_t)data[2]; +} + +void writeRegisterI2C(uint16_t icID, uint8_t address, int32_t value) +{ + uint8_t data[3] = { 0 }; + + data[0] = max22215_getDeviceAddress(icID); + data[1] = address; //register address + data[2] = 0xFF & value; + + max22215_readWriteI2C(icID, &data[0], 2,0); +} diff --git a/firmware/lib/tmc/ic/MAX22215/MAX22215.h b/firmware/lib/tmc/ic/MAX22215/MAX22215.h new file mode 100755 index 0000000..8fbee6f --- /dev/null +++ b/firmware/lib/tmc/ic/MAX22215/MAX22215.h @@ -0,0 +1,74 @@ +/******************************************************************************* +* Copyright © 2025 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#ifndef API_IC_MAX22215_H +#define API_IC_MAX22215_H + +#include +#include +#include +#include "MAX22215_HW_Abstraction.h" + +typedef enum { + IC_BUS_SPI, + IC_BUS_I2C, +} MAX22215BusType; + +typedef struct +{ + uint32_t mask; + uint8_t shift; + uint8_t address; + bool isSigned; +} RegisterField; + +// => TMC-API wrapper +extern bool max22215_readWriteI2C(uint16_t icID, uint8_t *data, size_t writeLength, size_t readLength); +extern MAX22215BusType max22215_getBusType(uint16_t icID); +extern uint8_t max22215_getDeviceAddress(uint16_t icID); +// => TMC-API wrapper + +int32_t max22215_readRegister(uint16_t icID, uint8_t address); +void max22215_writeRegister(uint16_t icID, uint8_t address, int32_t value); + +static inline uint32_t max22215_fieldExtract(uint32_t data, RegisterField field) +{ + uint32_t value = (data & field.mask) >> field.shift; + + if (field.isSigned) + { + // Apply signedness conversion + uint32_t baseMask = field.mask >> field.shift; + uint32_t signMask = baseMask & (~baseMask >> 1); + value = (value ^ signMask) - signMask; + } + + return value; +} + +static inline uint32_t max22215_fieldRead(uint16_t icID, RegisterField field) +{ + uint32_t value = max22215_readRegister(icID, field.address); + + return max22215_fieldExtract(value, field); +} + +static inline uint32_t field_update(uint32_t data, RegisterField field, uint32_t value) +{ + return (data & (~field.mask)) | ((value << field.shift) & field.mask); +} + +static inline void max22215_fieldWrite(uint16_t icID, RegisterField field, uint32_t value) +{ + uint32_t regValue = max22215_readRegister(icID, field.address); + + regValue = field_update(regValue, field, value); + + max22215_writeRegister(icID, field.address, regValue); +} + + +#endif /* API_IC_MAX22215_H */ diff --git a/firmware/lib/tmc/ic/MAX22215/MAX22215_HW_Abstraction.h b/firmware/lib/tmc/ic/MAX22215/MAX22215_HW_Abstraction.h new file mode 100755 index 0000000..47b5a30 --- /dev/null +++ b/firmware/lib/tmc/ic/MAX22215/MAX22215_HW_Abstraction.h @@ -0,0 +1,178 @@ +/******************************************************************************* +* Copyright © 2025 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + +#ifndef max22215_HW_ABSTRACTION +#define max22215_HW_ABSTRACTION + +// Registers in MAX22215 +#define MAX22215_CHIP_REV 0x00 +#define MAX22215_CFG_1 0x01 +#define MAX22215_CFG_2 0x02 +#define MAX22215_FAULT1 0x03 +#define MAX22215_FAULT2 0x04 +#define MAX22215_FAULT_MASK1 0x05 +#define MAX22215_FAULT_MASK2 0x06 +#define MAX22215_ACTION_ENABLE 0x07 +#define MAX22215_CONTROL_STS 0x08 + +// Fields in MAX22215 +#define MAX22215_CHIP_REV_MASK 0x0000000F +#define MAX22215_CHIP_REV_SHIFT 0 +#define MAX22215_CHIP_REV_FIELD ((RegisterField) {MAX22215_CHIP_REV_MASK, MAX22215_CHIP_REV_SHIFT, MAX22215_CHIP_REV, false}) +#define MAX22215_SR_MASK 0x03 +#define MAX22215_SR_SHIFT 0 +#define MAX22215_SR_FIELD ((RegisterField) {MAX22215_SR_MASK, MAX22215_SR_SHIFT, MAX22215_CFG_1, false}) +#define MAX22215_GAIN_MASK 0x0C +#define MAX22215_GAIN_SHIFT 2 +#define MAX22215_GAIN_FIELD ((RegisterField) {MAX22215_GAIN_MASK, MAX22215_GAIN_SHIFT, MAX22215_CFG_1, false}) +#define MAX22215_SW_HW_MASK 0x10 +#define MAX22215_SW_HW_SHIFT 4 +#define MAX22215_SW_HW_FIELD ((RegisterField) {MAX22215_SW_HW_MASK, MAX22215_SW_HW_SHIFT, MAX22215_CFG_1, false}) +#define MAX22215_ODM_MASK 0x60 +#define MAX22215_ODM_SHIFT 5 +#define MAX22215_ODM_FIELD ((RegisterField) {MAX22215_ODM_MASK, MAX22215_ODM_SHIFT, MAX22215_CFG_1, false}) +#define MAX22215_RESET_MASK 0x02 +#define MAX22215_RESET_SHIFT 1 +#define MAX22215_RESET_FIELD ((RegisterField) {MAX22215_RESET_MASK, MAX22215_RESET_SHIFT, MAX22215_CFG_2, false}) +#define MAX22215_DEMAG_MASK 0x1C +#define MAX22215_DEMAG_SHIFT 2 +#define MAX22215_DEMAG_FIELD ((RegisterField) {MAX22215_DEMAG_MASK, MAX22215_DEMAG_SHIFT, MAX22215_CFG_2, false}) +#define MAX22215_NSLEEP_MASK 0x20 +#define MAX22215_NSLEEP_SHIFT 5 +#define MAX22215_NSLEEP_FIELD ((RegisterField) {MAX22215_NSLEEP_MASK, MAX22215_NSLEEP_SHIFT, MAX22215_CFG_2, false}) +#define MAX22215_DIAG_MASK 0x40 +#define MAX22215_DIAG_SHIFT 6 +#define MAX22215_DIAG_FIELD ((RegisterField) {MAX22215_DIAG_MASK, MAX22215_DIAG_SHIFT, MAX22215_CFG_2, false}) +#define MAX22215_RLS_BRK_MASK 0x80 +#define MAX22215_RLS_BRK_SHIFT 7 +#define MAX22215_RLS_BRK_FIELD ((RegisterField) {MAX22215_RLS_BRK_MASK, MAX22215_RLS_BRK_SHIFT, MAX22215_CFG_2, false}) +#define MAX22215_OCP0_MASK 0x01 +#define MAX22215_OCP0_SHIFT 0 +#define MAX22215_OCP0_FIELD ((RegisterField) {MAX22215_OCP0_MASK, MAX22215_OCP0_SHIFT, MAX22215_FAULT1, false}) +#define MAX22215_OCP1_MASK 0x02 +#define MAX22215_OCP1_SHIFT 1 +#define MAX22215_OCP1_FIELD ((RegisterField) {MAX22215_OCP1_MASK, MAX22215_OCP1_SHIFT, MAX22215_FAULT1, false}) +//#define MAX22215_OCP0_MASK 0x04 +//#define MAX22215_OCP0_SHIFT 2 +//#define MAX22215_OCP0_FIELD ((RegisterField) {MAX22215_OCP0_MASK, MAX22215_OCP0_SHIFT, MAX22215_FAULT1, false}) +#define MAX22215_TWARN_UL_MASK 0x08 +#define MAX22215_TWARN_UL_SHIFT 3 +#define MAX22215_TWARN_UL_FIELD ((RegisterField) {MAX22215_TWARN_UL_MASK, MAX22215_TWARN_UL_SHIFT, MAX22215_FAULT1, false}) +#define MAX22215_TSD_MASK 0x10 +#define MAX22215_TSD_SHIFT 4 +#define MAX22215_TSD_FIELD ((RegisterField) {MAX22215_TSD_MASK, MAX22215_TSD_SHIFT, MAX22215_FAULT1, false}) +#define MAX22215_UVLO_MASK 0x20 +#define MAX22215_UVLO_SHIFT 5 +#define MAX22215_UVLO_FIELD ((RegisterField) {MAX22215_UVLO_MASK, MAX22215_UVLO_SHIFT, MAX22215_FAULT1, false}) +#define MAX22215_UVLO5V_MASK 0x40 +#define MAX22215_UVLO5V_SHIFT 6 +#define MAX22215_UVLO5V_FIELD ((RegisterField) {MAX22215_UVLO5V_MASK, MAX22215_UVLO5V_SHIFT, MAX22215_FAULT1, false}) +#define MAX22215_UVLOCP_MASK 0x80 +#define MAX22215_UVLOCP_SHIFT 7 +#define MAX22215_UVLOCP_FIELD ((RegisterField) {MAX22215_UVLOCP_MASK, MAX22215_UVLOCP_SHIFT, MAX22215_FAULT1, false}) +#define MAX22215_LFD1_MASK 0x01 +#define MAX22215_LFD1_SHIFT 0 +#define MAX22215_LFD1_FIELD ((RegisterField) {MAX22215_LFD1_MASK, MAX22215_LFD1_SHIFT, MAX22215_FAULT2, false}) +#define MAX22215_LFD2_MASK 0x02 +#define MAX22215_LFD2_SHIFT 1 +#define MAX22215_LFD2_FIELD ((RegisterField) {MAX22215_LFD2_MASK, MAX22215_LFD2_SHIFT, MAX22215_FAULT2, false}) +#define MAX22215_SAFEDEM_MASK 0x04 +#define MAX22215_SAFEDEM_SHIFT 2 +#define MAX22215_SAFEDEM_FIELD ((RegisterField) {MAX22215_SAFEDEM_MASK, MAX22215_SAFEDEM_SHIFT, MAX22215_FAULT2, false}) +#define MAX22215_ISM_MASK 0x08 +#define MAX22215_ISM_SHIFT 3 +#define MAX22215_ISM_FIELD ((RegisterField) {MAX22215_ISM_MASK, MAX22215_ISM_SHIFT, MAX22215_FAULT2, false}) +#define MAX22215_ODVM_MASK 0x10 +#define MAX22215_ODVM_SHIFT 4 +#define MAX22215_ODVM_FIELD ((RegisterField) {MAX22215_ODVM_MASK, MAX22215_ODVM_SHIFT, MAX22215_FAULT2, false}) +#define MAX22215_DVD_MASK 0x20 +#define MAX22215_DVD_SHIFT 5 +#define MAX22215_DVD_FIELD ((RegisterField) {MAX22215_DVD_MASK, MAX22215_DVD_SHIFT, MAX22215_FAULT2, false}) +#define MAX22215_TWARN_MASK 0x40 +#define MAX22215_TWARN_SHIFT 6 +#define MAX22215_TWARN_FIELD ((RegisterField) {MAX22215_TWARN_MASK, MAX22215_TWARN_SHIFT, MAX22215_FAULT2, false}) +#define MAX22215_LFD3_MASK 0x80 +#define MAX22215_LFD3_SHIFT 7 +#define MAX22215_LFD3_FIELD ((RegisterField) {MAX22215_LFD3_MASK, MAX22215_LFD3_SHIFT, MAX22215_FAULT2, false}) +#define MAX22215_OCP0_MSK_MASK 0x01 +#define MAX22215_OCP0_MASK_SHIFT 0 +#define MAX22215_OCP0_MASK_FIELD ((RegisterField) {MAX22215_OCP0_MSK_MASK, MAX22215_OCP0_MASK_SHIFT, MAX22215_FAULT_MASK1, false}) +#define MAX22215_OCP1_MSK_MASK 0x02 +#define MAX22215_OCP1_MASK_SHIFT 1 +#define MAX22215_OCP1_MASK_FIELD ((RegisterField) {MAX22215_OCP1_MSK_MASK, MAX22215_OCP1_MASK_SHIFT, MAX22215_FAULT_MASK1, false}) +#define MAX22215_OCP2_MSK_MASK 0x04 +#define MAX22215_OCP2_MASK_SHIFT 2 +#define MAX22215_OCP2_MASK_FIELD ((RegisterField) {MAX22215_OCP2_MSK_MASK, MAX22215_OCP2_MASK_SHIFT, MAX22215_FAULT_MASK1, false}) +#define MAX22215_TWARN_MSK_MASK 0x08 +#define MAX22215_TWARN_MASK_SHIFT 3 +#define MAX22215_TWARN_MASK_FIELD ((RegisterField) {MAX22215_TWARN_MSK_MASK, MAX22215_TWARN_MASK_SHIFT, MAX22215_FAULT_MASK1, false}) +#define MAX22215_TSDN_MSK_MASK 0x10 +#define MAX22215_TSDN_MASK_SHIFT 4 +#define MAX22215_TSDN_MASK_FIELD ((RegisterField) {MAX22215_TSDN_MSK_MASK, MAX22215_TSDN_MASK_SHIFT, MAX22215_FAULT_MASK1, false}) +#define MAX22215_UVLO_MSK_MASK 0x20 +#define MAX22215_UVLO_MASK_SHIFT 5 +#define MAX22215_UVLO_MASK_FIELD ((RegisterField) {MAX22215_UVLO_MSK_MASK, MAX22215_UVLO_MASK_SHIFT, MAX22215_FAULT_MASK1, false}) +#define MAX22215_UVLO_5V_MSK_MASK 0x40 +#define MAX22215_UVLO_5V_MASK_SHIFT 6 +#define MAX22215_UVLO_5V_MASK_FIELD ((RegisterField) {MAX22215_UVLO_5V_MSK_MASK, MAX22215_UVLO_5V_MASK_SHIFT, MAX22215_FAULT_MASK1, false}) +#define MAX22215_UVLO_CP_MSK_MASK 0x80 +#define MAX22215_UVLO_CP_MASK_SHIFT 7 +#define MAX22215_UVLO_CP_MASK_FIELD ((RegisterField) {MAX22215_UVLO_CP_MSK_MASK, MAX22215_UVLO_CP_MASK_SHIFT, MAX22215_FAULT_MASK1, false}) +#define MAX22215_LFD1_MSK_MASK 0x01 +#define MAX22215_LFD1_MASK_SHIFT 0 +#define MAX22215_LFD1_MASK_FIELD ((RegisterField) {MAX22215_LFD1_MSK_MASK, MAX22215_LFD1_MASK_SHIFT, MAX22215_FAULT_MASK2, false}) +#define MAX22215_LFD2_MSK_MASK 0x02 +#define MAX22215_LFD2_MASK_SHIFT 1 +#define MAX22215_LFD2_MASK_FIELD ((RegisterField) {MAX22215_LFD2_MSK_MASK, MAX22215_LFD2_MASK_SHIFT, MAX22215_FAULT_MASK2, false}) +#define MAX22215_SAFEDEM_MSK_MASK 0x04 +#define MAX22215_SAFEDEM_MASK_SHIFT 2 +#define MAX22215_SAFEDEM_MASK_FIELD ((RegisterField) {MAX22215_SAFEDEM_MSK_MASK, MAX22215_SAFEDEM_MASK_SHIFT, MAX22215_FAULT_MASK2, false}) +#define MAX22215_ISM_MSK_MASK 0x08 +#define MAX22215_ISM_MASK_SHIFT 3 +#define MAX22215_ISM_MASK_FIELD ((RegisterField) {MAX22215_ISM_MSK_MASK, MAX22215_ISM_MASK_SHIFT, MAX22215_FAULT_MASK2, false}) +#define MAX22215_ODVM_MSK_MASK 0x10 +#define MAX22215_ODVM_MASK_SHIFT 4 +#define MAX22215_ODVM_MASK_FIELD ((RegisterField) {MAX22215_ODVM_MSK_MASK, MAX22215_ODVM_MASK_SHIFT, MAX22215_FAULT_MASK2, false}) +#define MAX22215_DVD_MSK_MASK 0x20 +#define MAX22215_DVD_MASK_SHIFT 5 +#define MAX22215_DVD_MASK_FIELD ((RegisterField) {MAX22215_DVD_MSK_MASK, MAX22215_DVD_MASK_SHIFT, MAX22215_FAULT_MASK2, false}) +//#define MAX22215_LFD1_MSK_MASK 0x80 +//#define MAX22215_LFD1_MASK_SHIFT 7 +//#define MAX22215_LFD1_MASK_FIELD ((RegisterField) {MAX22215_LFD1_MSK_MASK, MAX22215_LFD1_MASK_SHIFT, MAX22215_FAULT_MASK2, false}) +#define MAX22215_ENABLE1_MASK 0x01 +#define MAX22215_ENABLE1_SHIFT 0 +#define MAX22215_ENABLE1_FIELD ((RegisterField) {MAX22215_ENABLE1_MASK, MAX22215_ENABLE1_SHIFT, MAX22215_ACTION_ENABLE, false}) +#define MAX22215_ENABLE2_MASK 0x02 +#define MAX22215_ENABLE2_SHIFT 1 +#define MAX22215_ENABLE2_FIELD ((RegisterField) {MAX22215_ENABLE2_MASK, MAX22215_ENABLE2_SHIFT, MAX22215_ACTION_ENABLE, false}) +#define MAX22215_ENABLE3_MASK 0x04 +#define MAX22215_ENABLE3_SHIFT 2 +#define MAX22215_ENABLE3_FIELD ((RegisterField) {MAX22215_ENABLE3_MASK, MAX22215_ENABLE3_SHIFT, MAX22215_ACTION_ENABLE, false}) +#define MAX22215_ODVM_TIME_MASK 0x18 +#define MAX22215_ODVM_TIME_SHIFT 3 +#define MAX22215_ODVM_TIME_FIELD ((RegisterField) {MAX22215_ODVM_TIME_MASK, MAX22215_ODVM_TIME_SHIFT, MAX22215_ACTION_ENABLE, false}) +#define MAX22215_STATUS_SLEEP_MASK 0x01 +#define MAX22215_STATUS_SLEEP_SHIFT 0 +#define MAX22215_STATUS_SLEEP_FIELD ((RegisterField) {MAX22215_STATUS_SLEEP_MASK, MAX22215_STATUS_SLEEP_SHIFT, MAX22215_CONTROL_STS, false}) +#define MAX22215_STATUS_BRK_MASK 0x02 +#define MAX22215_STATUS_BRK_SHIFT 1 +#define MAX22215_STATUS_BRK_FIELD ((RegisterField) {MAX22215_STATUS_BRK_MASK, MAX22215_STATUS_BRK_SHIFT, MAX22215_CONTROL_STS, false}) +#define MAX22215_STATUS_RLS_MASK 0x04 +#define MAX22215_STATUS_RLS_SHIFT 2 +#define MAX22215_STATUS_RLS_FIELD ((RegisterField) {MAX22215_STATUS_RLS_MASK, MAX22215_STATUS_RLS_SHIFT, MAX22215_CONTROL_STS, false}) +#define MAX22215_STATUS_DIAG_MASK 0x08 +#define MAX22215_STATUS_DIAG_SHIFT 3 +#define MAX22215_STATUS_DIAG_FIELD ((RegisterField) {MAX22215_STATUS_DIAG_MASK, MAX22215_STATUS_DIAG_SHIFT, MAX22215_CONTROL_STS, false}) +#define MAX22215_STATUS_ENF_DMG_MASK 0x10 +#define MAX22215_STATUS_ENF_DMG_SHIFT 4 +#define MAX22215_STATUS_ENF_DMG_FIELD ((RegisterField) {MAX22215_STATUS_ENF_DMG_MASK, MAX22215_STATUS_ENF_DMG_SHIFT, MAX22215_CONTROL_STS, false}) +#define MAX22215_STATUS_SAFE_DMG_MASK 0x20 +#define MAX22215_STATUS_SAFE_DMG_SHIFT 5 +#define MAX22215_STATUS_SAFE_DMG_FIELD ((RegisterField) {MAX22215_STATUS_SAFE_DMG_MASK, MAX22215_STATUS_SAFE_DMG_SHIFT, MAX22215_CONTROL_STS, false}) +#define MAX22215_STATUS_FLT_PWP_MASK 0x80 +#define MAX22215_STATUS_FLT_PWP_SHIFT 7 +#define MAX22215_STATUS_FLT_PWP_FIELD ((RegisterField) {MAX22215_STATUS_FLT_PWP_MASK, MAX22215_STATUS_FLT_PWP_SHIFT, MAX22215_CONTROL_STS, false}) + +#endif diff --git a/firmware/lib/tmc/ic/MAX22215/README.md b/firmware/lib/tmc/ic/MAX22215/README.md new file mode 100755 index 0000000..aeb82f8 --- /dev/null +++ b/firmware/lib/tmc/ic/MAX22215/README.md @@ -0,0 +1,42 @@ +# max22215 + + +## How to use + +To access the max22215's registers, the TMC-API offers two functions: **max22215_readRegister** and **max22215_writeRegister**. +Each of these functions takes in an **icID**, which is used to identify the IC when multiple ICs are connected. This identifier is passed down to the callback functions (see How to Integrate). + +## How to integrate: overview + +1. Include all the files of the TMC-API/ic/tmc/max22215 folder into the custom project. +2. Include the max22215.h file in the custom source code. +3. Implement the necessary callback functions (see below). +4. (optional): Take a look at the Examples subfolder for ready-made examples of the TMC-API usage. + +## Accessing the max22215 via I2C +The following diagram depicts how to access the MAX22200 via I2C using the TMC-API. + +![screenshot](registercall_hierarchy_flowchart_I2C.svg) + +The description of the functions, in the above flowchart, are as follows: +- The functions max22215_readRegister and max22215_writeRegister are used to read and write the registers respectively. These functions check the current active bus and call the bus-specific function i.e readRegisterI2C or writeRegisterI2C. +- These bus specific functions construct the datagram and further call the bus specific callback 'max22215_readWriteI2C'. +- This callback function further calls the hardware specific read/write function for I2C and needs to be implemented externally. + +### How to integrate: Callback functions +Implement the following callback functions to access the chip via I2C: +1. **max22215_readWriteI2C()**, which is a HAL wrapper function that provides the necessary hardware access. + +## Further info +### Dependency graph for the ICs with new register R/W mechanism +This graph illustrates the relationships between files within the TMC-API library, highlighting dependencies and identifying the files that are essential for integrating the library into the custom projects. + +![screenshot](uml-tmc-api.svg) + +### Example usage: TMC-Evalsystem +**For a reference usage of the TMC-API**, visit the [TMC-Evalsystem](https://github.com/analogdevicesinc/TMC-EvalSystem) + +## Migration status +The max22215 has been reworked to the access system described above. For more infos on the status of this and other ICs, check out the [migration page](https://github.com/analogdevicesinc/TMC-API/issues/53). + + diff --git a/firmware/lib/tmc/ic/MAX22215/registercall_hierarchy_flowchart_I2C.svg b/firmware/lib/tmc/ic/MAX22215/registercall_hierarchy_flowchart_I2C.svg new file mode 100755 index 0000000..721fdf6 --- /dev/null +++ b/firmware/lib/tmc/ic/MAX22215/registercall_hierarchy_flowchart_I2C.svg @@ -0,0 +1,3 @@ + + +

HAL

HAL

APP (Eval)

APP (Eval)

API

API
Read a register
  •  Call tmcXXXX_readRegister function
Read a register...
Returns the register read value
Returns the register read value
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
tmcXXXX.c
tmcXXXX.c
I2C.c
I2C.c
tmcXXXX_eval.c
tmcXXXX_eval.c

 Implementation of I2CMasterWriteRead
  • Sends and receives bytes on the I2C bus
Implementation of I2CMasterWriteRead...
Returns the raw reply data
Returns the raw reply data

Implementation of tmcXXXX_readWriteI2C
  • Calls hardware function I2CMasterWriteRead
Implementation of tmcXXXX_readWriteI2C...
Passes on the raw reply data to the API
Passes on the raw reply data to the API
Implementation of readRegisterI2C
  • Constructs the datagram
  • Calls HAL wrapper function 
Implementation of readRegisterI2C...
tmcXXXX_readWriteI2C
tmcXXXX_readWriteI2C
Parses the reply and returns the register value
Parses the reply and returns the register value
Implementation of tmcXXXX_readRegister 
  • Check which bus is active SPI/UART/I2C. (e.g. I2C)
  • Calls bus-specific function (e.g. readRegisterI2C)
 
Implementation of tmcXXXX_readRegister...
Returns the register read value
Returns the register read value
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/MAX22215/uml-tmc-api.svg b/firmware/lib/tmc/ic/MAX22215/uml-tmc-api.svg new file mode 100755 index 0000000..5a5f8dd --- /dev/null +++ b/firmware/lib/tmc/ic/MAX22215/uml-tmc-api.svg @@ -0,0 +1,3 @@ + + +

TMCXXXX_HW_Abstraction.h



TMCXXXX_HW_Abstraction.h...
// Constants
#define TMCXXXX_MOTORS              
                          
// Register definitions
#define TMCXXXX_GCONF        
                          ⋮
// Register fields definitions
#define TMCXXXX_GCONF_OTPW_FIELD
                     
// Constants...

TMCXXXX.h



TMCXXXX.h...
extern void tmcXXXX_readWriteSPI();
extern void tmcXXXX_readWriteUART();
extern TMCXXXXBusType tmcXXXX_getBusType();
extern uint8_t tmcXXXX_getNodeAddress();
                                  ⋮
tmcXXXX_readRegister();
tmcXXXX_writeRegister();
                                  ⋮
extern void tmcXXXX_readWriteSPI();...

TMCXXXX.c



TMCXXXX.c...
const uint8_t tmcCRCTable_Poly7Reflected[256] = {...};
int32_t tmcXXXX_readRegister(){
/* Call tmcXXXX_getBusType();
 * Based on bus type, call readRegisterSPI/UART() that
 * further calls tmcXXXX_readWriteSPI/UART();
 * For UART it also calls tmcXXXX_getNodeAddress();
                                           ⋮
}
                                           ⋮
const uint8_t tmcCRCTable_Poly7Reflected[256] = {.....
TMC-API
TMC-API

TMCXXXX_Simple_Rotation.h


TMCXXXX_Simple_Rotation.h...
void initAllMotors();
             ⋮
  
void initAllMotors()...

TMCXXXX_Simple_Rotation.c


TMCXXXX_Simple_Rotation.c...
void initAllMotors(){

// Configuring registers to enable motor drivers etc..
tmcXXXX_writeRegister();
                    ⋮
}
                    ⋮
void initAllMotors(){...
Examples
Examples
User Project
User Project

User_Project.h


User_Project.h

User_Project.c








User_Project.c...

void tmcXXXX_readWriteSPI(){
                           ⋮
}
void tmcXXXX_readWriteUART(){
                           ⋮
}
TMCXXXXBusType tmcXXXX_getBusType(){
                           ⋮
}
uint8_t tmcXXXX_getNodeAddress(){
                           ⋮
}

// User Code
                           ⋮
void tmcXXXX_readWriteSPI(){...
#include "TMCXXXX_HW_Abstraction.h"
#include "TMCXXXX.h"
#include "TMCXXXX_Simple_Rotation.h"
                                ⋮
TMCXXXXBusType bus = IC_BUS_SPI/UART;
uint8_t nodeAddress = <nodeAddress>;
                                ⋮
#include "TMCXXXX_HW_Abstraction.h"...
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/MAX22216/MAX22216.c b/firmware/lib/tmc/ic/MAX22216/MAX22216.c new file mode 100755 index 0000000..ccc5b08 --- /dev/null +++ b/firmware/lib/tmc/ic/MAX22216/MAX22216.c @@ -0,0 +1,110 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + +#include "MAX22216.h" + +#ifdef TMC_API_EXTERNAL_CRC_TABLE +extern const uint8_t tmcCRCTable_Poly110101[256]; +#else +const uint8_t tmcCRCTable_Poly110101[256] = { + 0x00, 0x16, 0x19, 0x0F, 0x07, 0x11, 0x1E, 0x08, 0x0E, 0x18, 0x17, 0x01, 0x09, 0x1F, 0x10, 0x06, + 0x1C, 0x0A, 0x05, 0x13, 0x1B, 0x0D, 0x02, 0x14, 0x12, 0x04, 0x0B, 0x1D, 0x15, 0x03, 0x0C, 0x1A, + 0x0D, 0x1B, 0x14, 0x02, 0x0A, 0x1C, 0x13, 0x05, 0x03, 0x15, 0x1A, 0x0C, 0x04, 0x12, 0x1D, 0x0B, + 0x11, 0x07, 0x08, 0x1E, 0x16, 0x00, 0x0F, 0x19, 0x1F, 0x09, 0x06, 0x10, 0x18, 0x0E, 0x01, 0x17, + 0x1A, 0x0C, 0x03, 0x15, 0x1D, 0x0B, 0x04, 0x12, 0x14, 0x02, 0x0D, 0x1B, 0x13, 0x05, 0x0A, 0x1C, + 0x06, 0x10, 0x1F, 0x09, 0x01, 0x17, 0x18, 0x0E, 0x08, 0x1E, 0x11, 0x07, 0x0F, 0x19, 0x16, 0x00, + 0x17, 0x01, 0x0E, 0x18, 0x10, 0x06, 0x09, 0x1F, 0x19, 0x0F, 0x00, 0x16, 0x1E, 0x08, 0x07, 0x11, + 0x0B, 0x1D, 0x12, 0x04, 0x0C, 0x1A, 0x15, 0x03, 0x05, 0x13, 0x1C, 0x0A, 0x02, 0x14, 0x1B, 0x0D, + 0x01, 0x17, 0x18, 0x0E, 0x06, 0x10, 0x1F, 0x09, 0x0F, 0x19, 0x16, 0x00, 0x08, 0x1E, 0x11, 0x07, + 0x1D, 0x0B, 0x04, 0x12, 0x1A, 0x0C, 0x03, 0x15, 0x13, 0x05, 0x0A, 0x1C, 0x14, 0x02, 0x0D, 0x1B, + 0x0C, 0x1A, 0x15, 0x03, 0x0B, 0x1D, 0x12, 0x04, 0x02, 0x14, 0x1B, 0x0D, 0x05, 0x13, 0x1C, 0x0A, + 0x10, 0x06, 0x09, 0x1F, 0x17, 0x01, 0x0E, 0x18, 0x1E, 0x08, 0x07, 0x11, 0x19, 0x0F, 0x00, 0x16, + 0x1B, 0x0D, 0x02, 0x14, 0x1C, 0x0A, 0x05, 0x13, 0x15, 0x03, 0x0C, 0x1A, 0x12, 0x04, 0x0B, 0x1D, + 0x07, 0x11, 0x1E, 0x08, 0x00, 0x16, 0x19, 0x0F, 0x09, 0x1F, 0x10, 0x06, 0x0E, 0x18, 0x17, 0x01, + 0x16, 0x00, 0x0F, 0x19, 0x11, 0x07, 0x08, 0x1E, 0x18, 0x0E, 0x01, 0x17, 0x1F, 0x09, 0x06, 0x10, + 0x0A, 0x1C, 0x13, 0x05, 0x0D, 0x1B, 0x14, 0x02, 0x04, 0x12, 0x1D, 0x0B, 0x03, 0x15, 0x1A, 0x0C, +}; +#endif + +static uint16_t readRegisterSPI(uint16_t icID, uint8_t address); +static void writeRegisterSPI(uint16_t icID, uint8_t address, uint16_t value); + +uint16_t max22216_readRegister(uint16_t icID, uint8_t address) +{ + return readRegisterSPI(icID, address); +} + +void max22216_writeRegister(uint16_t icID, uint8_t address, uint16_t value) +{ + writeRegisterSPI(icID, address, value); +} + +uint16_t readRegisterSPI(uint16_t icID, uint8_t address) +{ + uint8_t data[4] = {0}; + + // clear write bit + data[0] = address & MAX22216_ADDRESS_MASK; + + bool useCRC = max22216_getCRCEnState(); + + if (useCRC) + { + // Generate the CRC value for comparison + data[3] = max22216_CRC(&data[0], 3); + } + + // Send the read request + max22216_readWriteSPI(icID, &data[0], useCRC? 4:3); + + // Rewrite address and clear write bit + data[0] = address & MAX22216_ADDRESS_MASK; + + if (useCRC) + { + // Generate the CRC value for comparison + data[3] = max22216_CRC(&data[0], 3); + } + + // Send another request to receive the read reply + max22216_readWriteSPI(icID, &data[0], useCRC? 4:3); + + return ((uint16_t) data[1] << 8) | ((uint16_t) data[2]); +} + +void writeRegisterSPI(uint16_t icID, uint8_t address, uint16_t value) +{ + uint8_t data[4] = {0}; + + bool useCRC = max22216_getCRCEnState(); + + data[0] = address | MAX22216_WRITE_BIT; + data[1] = ((value >> 8) & 0xFF); + data[2] = value & 0xFF; + + if (useCRC) + { + // Generate the CRC value for comparison + data[3] = max22216_CRC(&data[0], 3); + } + + // Send the write request + max22216_readWriteSPI(icID, &data[0], useCRC? 4:3); +} + +// length in bytes +uint8_t max22216_CRC(uint8_t *data, size_t length) +{ + uint8_t crc = 0b11111000; + + for (size_t i = 0; i < length; i++) + { + crc = tmcCRCTable_Poly110101[crc ^ data[i]]; + } + return crc; +} diff --git a/firmware/lib/tmc/ic/MAX22216/MAX22216.h b/firmware/lib/tmc/ic/MAX22216/MAX22216.h new file mode 100755 index 0000000..f3dcfdd --- /dev/null +++ b/firmware/lib/tmc/ic/MAX22216/MAX22216.h @@ -0,0 +1,67 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + +#ifndef API_IC_MAX22216_H +#define API_IC_MAX22216_H + +#include +#include +#include +#include "MAX22216_HW_Abstraction.h" + +extern void max22216_readWriteSPI(uint16_t icID, uint8_t *data, size_t dataLength); +extern uint8_t max22216_getCRCEnState(void); +uint16_t max22216_readRegister(uint16_t icID, uint8_t address); +void max22216_writeRegister(uint16_t icID, uint8_t address, uint16_t value); +uint8_t max22216_CRC(uint8_t *data, size_t length); + +typedef struct +{ + uint32_t mask; + uint8_t shift; + uint8_t address; + bool isSigned; +} RegisterField; + +static inline uint16_t max22216_fieldExtract(uint16_t data, RegisterField field) +{ + uint16_t value = (data & field.mask) >> field.shift; + + if (field.isSigned) + { + // Apply signedness conversion + uint16_t baseMask = field.mask >> field.shift; + uint16_t signMask = baseMask & (~baseMask >> 1); + value = (value ^ signMask) - signMask; + } + + return value; +} + +static inline uint16_t max22216_fieldRead(uint16_t icID, RegisterField field) +{ + uint16_t value = max22216_readRegister(icID, field.address); + + return max22216_fieldExtract(value, field); +} + +static inline uint16_t max22216_fieldUpdate(uint16_t data, RegisterField field, uint16_t value) +{ + return (data & (~field.mask)) | ((value << field.shift) & field.mask); +} + +static inline void max22216_fieldWrite(uint16_t icID, RegisterField field, uint16_t value) +{ + uint16_t regValue = max22216_readRegister(icID, field.address); + + regValue = max22216_fieldUpdate(regValue, field, value); + + max22216_writeRegister(icID, field.address, regValue); +} + +#endif /* API_IC_MAX22216_H */ diff --git a/firmware/lib/tmc/ic/MAX22216/MAX22216_HW_Abstraction.h b/firmware/lib/tmc/ic/MAX22216/MAX22216_HW_Abstraction.h new file mode 100755 index 0000000..2655587 --- /dev/null +++ b/firmware/lib/tmc/ic/MAX22216/MAX22216_HW_Abstraction.h @@ -0,0 +1,555 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + +#ifndef max22216_HW_ABSTRACTION +#define max22216_HW_ABSTRACTION + + +// Constants +#define MAX22216_SYNC_BYTE 0x55 +#define MAX22216_MASTER_ADDRESS 0xFF + +// motion modes +#define MAX22216_MOTION_MODE_STOPPED 0 +#define MAX22216_MOTION_MODE_TORQUE 1 +#define MAX22216_MOTION_MODE_VELOCITY 2 +#define MAX22216_MOTION_MODE_POSITION 3 +#define MAX22216_MOTION_MODE_UQ_UD_EXT 8 + +// PHI_E selections +#define MAX22216_PHI_E_EXTERNAL 1 +#define MAX22216_PHI_E_OPEN_LOOP 2 +#define MAX22216_PHI_E_ABN 3 +#define MAX22216_PHI_E_HALL 5 +#define MAX22216_PHI_E_AENC 6 +#define MAX22216_PHI_A_AENC 7 + +#define MAX22216_STATE_NOTHING_TO_DO 0 +#define MAX22216_STATE_START_INIT 1 +#define MAX22216_STATE_WAIT_INIT_TIME 2 +#define MAX22216_STATE_ESTIMATE_OFFSET 3 + +#define MAX22216_CHIPINFO_ADDR_SI_TYPE 0 +#define MAX22216_CHIPINFO_ADDR_SI_VERSION 1 +#define MAX22216_CHIPINFO_ADDR_SI_DATE 2 +#define MAX22216_CHIPINFO_ADDR_SI_TIME 3 +#define MAX22216_CHIPINFO_ADDR_SI_VARIANT 4 +#define MAX22216_CHIPINFO_ADDR_SI_BUILD 5 + +#define MAX22216_WRITE_BIT 0x80 +#define MAX22216_ADDRESS_MASK 0x7F + + +// Registers in max22216 +#define MAX22216_GLOBAL_CTRL 0x00 +#define MAX22216_GLOBAL_CFG 0x01 +#define MAX22216_STATUS 0x02 +#define MAX22216_STATUS_CFG 0x03 +#define MAX22216_DC_H2L 0x04 +#define MAX22216_VM_MONITOR 0x05 +#define MAX22216_VM_THRESHOLD 0x06 +#define MAX22216_F_AC 0x07 +#define MAX22216_U_AC_SCAN 0x08 +#define MAX22216_CFG_DC_L2H_0 0x09 +#define MAX22216_CFG_DC_H_0 0x0A +#define MAX22216_CFG_DC_L_0 0x0B +#define MAX22216_CFG_L2H_TIME_0 0x0C +#define MAX22216_CFG_CTRL0_0 0x0D +#define MAX22216_CFG_CTRL1_0 0x0E +#define MAX22216_CFG_DPM0_0 0x0F +#define MAX22216_CFG_DPM1_0 0x10 +#define MAX22216_CFG_IDC_THLD_0 0x11 +#define MAX22216_CFG_R_THLD_0 0x12 +#define MAX22216_CFG_IND_0_0 0x13 +#define MAX22216_CFG_IND_1_0 0x14 +#define MAX22216_CFG_P_0 0x15 +#define MAX22216_CFG_I_0 0x16 +#define MAX22216_CFG_DC_L2H_1 0x17 +#define MAX22216_CFG_DC_H_1 0x18 +#define MAX22216_CFG_DC_L_1 0x19 +#define MAX22216_CFG_L2H_TIME_1 0x1A +#define MAX22216_CFG_CTRL0_1 0x1B +#define MAX22216_CFG_CTRL1_1 0x1C +#define MAX22216_CFG_DPM0_1 0x1D +#define MAX22216_CFG_DPM1_1 0x1E +#define MAX22216_CFG_IDC_THLD_1 0x1F +#define MAX22216_CFG_R_THLD_1 0x20 +#define MAX22216_CFG_IND_0_1 0x21 +#define MAX22216_CFG_IND_1_1 0x22 +#define MAX22216_CFG_P_1 0x23 +#define MAX22216_CFG_I_1 0x24 +#define MAX22216_CFG_DC_L2H_2 0x25 +#define MAX22216_CFG_DC_H_2 0x26 +#define MAX22216_CFG_DC_L_2 0x27 +#define MAX22216_CFG_L2H_TIME_2 0x28 +#define MAX22216_CFG_CTRL0_2 0x29 +#define MAX22216_CFG_CTRL1_2 0x2A +#define MAX22216_CFG_DPM0_2 0x2B +#define MAX22216_CFG_DPM1_2 0x2C +#define MAX22216_CFG_IDC_THLD_2 0x2D +#define MAX22216_CFG_R_THLD_2 0x2E +#define MAX22216_CFG_IND_0_2 0x2F +#define MAX22216_CFG_IND_1_2 0x30 +#define MAX22216_CFG_P_2 0x31 +#define MAX22216_CFG_I_2 0x32 +#define MAX22216_CFG_DC_L2H_3 0x33 +#define MAX22216_CFG_DC_H_3 0x34 +#define MAX22216_CFG_DC_L_3 0x35 +#define MAX22216_CFG_L2H_TIME_3 0x36 +#define MAX22216_CFG_CTRL0_3 0x37 +#define MAX22216_CFG_CTRL1_3 0x38 +#define MAX22216_CFG_DPM0_3 0x39 +#define MAX22216_CFG_DPM1_3 0x3A +#define MAX22216_CFG_IDC_THLD_3 0x3B +#define MAX22216_CFG_R_THLD_3 0x3C +#define MAX22216_CFG_IND_0_3 0x3D +#define MAX22216_CFG_IND_1_3 0x3E +#define MAX22216_CFG_P_3 0x3F +#define MAX22216_CFG_I_3 0x40 +#define MAX22216_I_DPM_PEAK_0 0x41 +#define MAX22216_I_DPM_VALLEY_0 0x42 +#define MAX22216_TRAVEL_TIME_0 0x43 +#define MAX22216_REACTION_TIME_0 0x44 +#define MAX22216_I_MONITOR_0 0x45 +#define MAX22216_I_AC_0 0x47 +#define MAX22216_RES_0 0x48 +#define MAX22216_PWM_DUTY_0 0x49 +#define MAX22216_I_DPM_PEAK_1 0x4A +#define MAX22216_I_DPM_VALLEY_1 0x4B +#define MAX22216_TRAVEL_TIME_1 0x4C +#define MAX22216_REACTION_TIME_1 0x4D +#define MAX22216_I_MONITOR_1 0x4E +#define MAX22216_I_AC_1 0x50 +#define MAX22216_RES_1 0x51 +#define MAX22216_PWM_DUTY_1 0x52 +#define MAX22216_I_DPM_PEAK_2 0x53 +#define MAX22216_I_DPM_VALLEY_2 0x54 +#define MAX22216_TRAVEL_TIME_2 0x55 +#define MAX22216_REACTION_TIME_2 0x56 +#define MAX22216_I_MONITOR_2 0x57 +#define MAX22216_I_AC_2 0x59 +#define MAX22216_RES_2 0x5A +#define MAX22216_PWM_DUTY_2 0x5B +#define MAX22216_I_DPM_PEAK_3 0x5C +#define MAX22216_I_DPM_VALLEY_3 0x5D +#define MAX22216_TRAVEL_TIME_3 0x5E +#define MAX22216_REACTION_TIME_3 0x5F +#define MAX22216_I_MONITOR_3 0x60 +#define MAX22216_I_AC_3 0x62 +#define MAX22216_RES_3 0x63 +#define MAX22216_PWM_DUTY_3 0x64 +#define MAX22216_FAULT0 0x65 +#define MAX22216_FAULT1 0x66 + +#define MAX22216_OTP_CONTROL 0x68 +#define MAX22216_OTP_STATUS 0x69 +#define MAX22216_OTP_DATA0 0x7A +#define MAX22216_OTP_DATA1 0x7B +#define MAX22216_OTP_ADDR 0x7C + + +// CRC Fields +#define __None__ 0 +#define MAX22216_CRC0_MASK 0x1 +#define MAX22216_CRC0_SHIFT 0 +#define MAX22216_CRC0_FIELD ((RegisterField) {MAX22216_CRC0_MASK, MAX22216_CRC0_SHIFT, __None__ , false}) +#define MAX22216_CRC1_MASK 0x2 +#define MAX22216_CRC1_SHIFT 1 +#define MAX22216_CRC1_FIELD ((RegisterField) {MAX22216_CRC1_MASK, MAX22216_CRC1_SHIFT, __None__ , false}) +#define MAX22216_CRC2_MASK 0x4 +#define MAX22216_CRC2_SHIFT 2 +#define MAX22216_CRC2_FIELD ((RegisterField) {MAX22216_CRC2_MASK, MAX22216_CRC2_SHIFT, __None__ , false}) +#define MAX22216_CRC3_MASK 0x8 +#define MAX22216_CRC3_SHIFT 3 +#define MAX22216_CRC3_FIELD ((RegisterField) {MAX22216_CRC3_MASK, MAX22216_CRC3_SHIFT, __None__, false}) +#define MAX22216_CRC4_MASK 0x10 +#define MAX22216_CRC4_SHIFT 4 +#define MAX22216_CRC4_FIELD ((RegisterField) {MAX22216_CRC4_MASK, MAX22216_CRC4_SHIFT, __None__, false}) +#define MAX22216_CRC4_SHIFT 4 +#define MAX22216_CRC4_FIELD ((RegisterField) {MAX22216_CRC4_MASK, MAX22216_CRC4_SHIFT, __None__, false}) +#define MAX22216_CRC5_MASK 0x20 +#define MAX22216_CRC5_SHIFT 5 +#define MAX22216_CRC5_FIELD ((RegisterField) {MAX22216_CRC5_MASK, MAX22216_CRC5_SHIFT, __None__, false}) + +// Register fields +#define MAX22216_SRT_PROG_MASK 0x00000001 +#define MAX22216_SRT_PROG_SHIFT 0 +#define MAX22216_SRT_PROG_FIELD ((RegisterField) {MAX22216_SRT_PROG_MASK, MAX22216_SRT_PROG_SHIFT, MAX22216_OTP_CONTROL, false}) +#define MAX22216_STOP_PROG_MASK 0x00000002 +#define MAX22216_STOP_PROG_SHIFT 1 +#define MAX22216_STOP_PROG_FIELD ((RegisterField) {MAX22216_STOP_PROG_MASK, MAX22216_STOP_PROG_SHIFT, MAX22216_OTP_CONTROL, false}) +#define MAX22216_VERI_FAIL_MASK 0x00000002 +#define MAX22216_VERI_FAIL_SHIFT 1 +#define MAX22216_VERI_FAIL_FIELD ((RegisterField) {MAX22216_VERI_FAIL_MASK, MAX22216_VERI_FAIL_SHIFT, MAX22216_OTP_STATUS, false}) +#define MAX22216_OTP_FULL_MASK 0x00000004 +#define MAX22216_OTP_FULL_SHIFT 2 +#define MAX22216_OTP_FULL_FIELD ((RegisterField) {MAX22216_OTP_FULL_MASK, MAX22216_OTP_FULL_SHIFT, MAX22216_OTP_STATUS, false}) +#define MAX22216_VPP_INIT_FAIL_MASK 0x00000008 +#define MAX22216_VPP_INIT_FAIL_SHIFT 3 +#define MAX22216_VPP_INIT_FAIL_FIELD ((RegisterField) {MAX22216_VPP_INIT_FAIL_MASK, MAX22216_VPP_INIT_FAIL_MASK, MAX22216_OTP_STATUS, false}) +#define MAX22216_OV_DURING_BURN_PULSE_MASK 0x00000010 +#define MAX22216_OV_DURING_BURN_PULSE_SHIFT 4 +#define MAX22216_OV_DURING_BURN_PULSE_FIELD ((RegisterField) {MAX22216_OV_DURING_BURN_PULSE_MASK, MAX22216_OV_DURING_BURN_PULSE_SHIFT, MAX22216_OTP_STATUS, false}) +#define MAX22216_ECC_ERR_1BIT_MASK 0x00000020 +#define MAX22216_ECC_ERR_1BIT_SHIFT 5 +#define MAX22216_ECC_ERR_1BIT_FIELD ((RegisterField) {MAX22216_ECC_ERR_1BIT_MASK, MAX22216_ECC_ERR_1BIT_SHIFT, MAX22216_OTP_STATUS, false}) +#define MAX22216_ECC_ERR_2BIT_MASK 0x00000040 +#define MAX22216_ECC_ERR_2BIT_SHIFT 6 +#define MAX22216_ECC_ERR_2BIT_FIELD ((RegisterField) {MAX22216_ECC_ERR_2BIT_MASK, MAX22216_ECC_ERR_2BIT_SHIFT, MAX22216_OTP_STATUS, false}) +#define MAX22216_DONE_MASK 0x00000080 +#define MAX22216_DONE_SHIFT 7 +#define MAX22216_DONE_FIELD ((RegisterField) {MAX22216_DONE_MASK, MAX22216_DONE_SHIFT, MAX22216_OTP_STATUS, false}) +#define MAX22216_OTP_FAIL_MASK ~(MAX22216_DONE_MASK) +#define MAX22216_OTP_FAIL_SHIFT 0 +#define MAX22216_OTP_FAIL_FIELD ((RegisterField) {MAX22216_OTP_FAIL_MASK, MAX22216_OTP_FAIL_SHIFT, MAX22216_OTP_STATUS, false}) +#define MAX22216_OTP_DATA0_MASK 0x000000FF +#define MAX22216_OTP_DATA0_SHIFT 0 +#define MAX22216_OTP_DATA0_FIELD ((RegisterField) {MAX22216_OTP_DATA0_MASK, MAX22216_OTP_DATA0_SHIFT, MAX22216_OTP_DATA0, false}) +#define MAX22216_OTP_DATA1_MASK 0x000000FF +#define MAX22216_OTP_DATA1_SHIFT 0 +#define MAX22216_OTP_DATA1_FIELD ((RegisterField) {MAX22216_OTP_DATA1_MASK, MAX22216_OTP_DATA1_SHIFT, MAX22216_OTP_DATA1, false}) +#define MAX22216_OTP_ADDR_MASK 0x000000FF +#define MAX22216_OTP_ADDR_SHIFT 0 +#define MAX22216_OTP_ADDR_FIELD ((RegisterField) {MAX22216_OTP_ADDR_MASK, MAX22216_OTP_ADDR_SHIFT, MAX22216_OTP_ADDR, false}) + +// Register fields in max22216 +#define MAX22216_CNTL0_MASK 0x00000001 +#define MAX22216_CNTL0_SHIFT 0 +#define MAX22216_CNTL0_FIELD ((RegisterField) {MAX22216_CNTL0_MASK, MAX22216_CNTL0_SHIFT, MAX22216_GLOBAL_CTRL, false}) +#define MAX22216_CNTL1_MASK 0x00000002 +#define MAX22216_CNTL1_SHIFT 1 +#define MAX22216_CNTL1_FIELD ((RegisterField) {MAX22216_CNTL1_MASK, MAX22216_CNTL1_SHIFT, MAX22216_GLOBAL_CTRL, false}) +#define MAX22216_CNTL2_MASK 0x00000004 +#define MAX22216_CNTL2_SHIFT 2 +#define MAX22216_CNTL2_FIELD ((RegisterField) {MAX22216_CNTL2_MASK, MAX22216_CNTL2_SHIFT, MAX22216_GLOBAL_CTRL, false}) +#define MAX22216_CNTL3_MASK 0x00000008 +#define MAX22216_CNTL3_SHIFT 3 +#define MAX22216_CNTL3_FIELD ((RegisterField) {MAX22216_CNTL3_MASK, MAX22216_CNTL3_SHIFT, MAX22216_GLOBAL_CTRL, false}) +#define MAX22216_F_PWM_M_MASK 0x000000F0 +#define MAX22216_F_PWM_M_SHIFT 4 +#define MAX22216_F_PWM_M_FIELD ((RegisterField) {MAX22216_F_PWM_M_MASK, MAX22216_F_PWM_M_SHIFT, MAX22216_GLOBAL_CTRL, false}) +#define MAX22216_CHS_MASK 0x0000000F +#define MAX22216_CHS_SHIFT 0 +#define MAX22216_CHS_FIELD ((RegisterField) {MAX22216_CHS_MASK, MAX22216_CHS_SHIFT, MAX22216_GLOBAL_CFG, false}) +#define MAX22216_VDRNVDRDUTY_MASK 0x00000010 +#define MAX22216_VDRNVDRDUTY_SHIFT 4 +#define MAX22216_VDRNVDRDUTY_FIELD ((RegisterField) {MAX22216_VDRNVDRDUTY_MASK, MAX22216_VDRNVDRDUTY_SHIFT, MAX22216_GLOBAL_CFG, false}) +#define MAX22216_STAT_POL_MASK 0x00000040 +#define MAX22216_STAT_POL_SHIFT 6 +#define MAX22216_STAT_POL_FIELD ((RegisterField) {MAX22216_STAT_POL_MASK, MAX22216_STAT_POL_SHIFT, MAX22216_GLOBAL_CFG, false}) +#define MAX22216_CNTL_POL_MASK 0x00000080 +#define MAX22216_CNTL_POL_SHIFT 7 +#define MAX22216_CNTL_POL_FIELD ((RegisterField) {MAX22216_CNTL_POL_MASK, MAX22216_CNTL_POL_SHIFT, MAX22216_GLOBAL_CFG, false}) +#define MAX22216_M_UVM_MASK 0x00000100 +#define MAX22216_M_UVM_SHIFT 8 +#define MAX22216_M_UVM_FIELD ((RegisterField) {MAX22216_M_UVM_MASK, MAX22216_M_UVM_SHIFT, MAX22216_GLOBAL_CFG, false}) +#define MAX22216_M_COMF_MASK 0x00000200 +#define MAX22216_M_COMF_SHIFT 9 +#define MAX22216_M_COMF_FIELD ((RegisterField) {MAX22216_M_COMF_MASK, MAX22216_M_COMF_SHIFT, MAX22216_GLOBAL_CFG, false}) +#define MAX22216_M_DPM_MASK 0x00000400 +#define MAX22216_M_DPM_SHIFT 10 +#define MAX22216_M_DPM_FIELD ((RegisterField) {MAX22216_M_DPM_MASK, MAX22216_M_DPM_SHIFT, MAX22216_GLOBAL_CFG, false}) +#define MAX22216_M_HHF_MASK 0x00000800 +#define MAX22216_M_HHF_SHIFT 11 +#define MAX22216_M_HHF_FIELD ((RegisterField) {MAX22216_M_HHF_MASK, MAX22216_M_HHF_SHIFT, MAX22216_GLOBAL_CFG, false}) +#define MAX22216_M_OLF_MASK 0x00001000 +#define MAX22216_M_OLF_SHIFT 12 +#define MAX22216_M_OLF_FIELD ((RegisterField) {MAX22216_M_OLF_MASK, MAX22216_M_OLF_SHIFT, MAX22216_GLOBAL_CFG, false}) +#define MAX22216_M_OCP_MASK 0x00002000 +#define MAX22216_M_OCP_SHIFT 13 +#define MAX22216_M_OCP_FIELD ((RegisterField) {MAX22216_M_OCP_MASK, MAX22216_M_OCP_SHIFT, MAX22216_GLOBAL_CFG, false}) +#define MAX22216_M_OVT_MASK 0x00004000 +#define MAX22216_M_OVT_SHIFT 14 +#define MAX22216_M_OVT_FIELD ((RegisterField) {MAX22216_M_OVT_MASK, MAX22216_M_OVT_SHIFT, MAX22216_GLOBAL_CFG, false}) +#define MAX22216_ACTIVE_MASK 0x00008000 +#define MAX22216_ACTIVE_SHIFT 15 +#define MAX22216_ACTIVE_FIELD ((RegisterField) {MAX22216_ACTIVE_MASK, MAX22216_ACTIVE_SHIFT, MAX22216_GLOBAL_CFG, false}) +#define MAX22216_RFU_MASK 0x00000001 +#define MAX22216_RFU_SHIFT 0 +#define MAX22216_RFU_FIELD ((RegisterField) {MAX22216_RFU_MASK, MAX22216_RFU_SHIFT, MAX22216_STATUS, false}) +#define MAX22216_UVM_MASK 0x00000002 +#define MAX22216_UVM_SHIFT 1 +#define MAX22216_UVM_FIELD ((RegisterField) {MAX22216_UVM_MASK, MAX22216_UVM_SHIFT, MAX22216_STATUS, false}) +#define MAX22216_COMER_MASK 0x00000004 +#define MAX22216_COMER_SHIFT 2 +#define MAX22216_COMER_FIELD ((RegisterField) {MAX22216_COMER_MASK, MAX22216_COMER_SHIFT, MAX22216_STATUS, false}) +#define MAX22216_DPM_MASK 0x00000008 +#define MAX22216_DPM_SHIFT 3 +#define MAX22216_DPM_FIELD ((RegisterField) {MAX22216_DPM_MASK, MAX22216_DPM_SHIFT, MAX22216_STATUS, false}) +#define MAX22216_HHF_MASK 0x00000010 +#define MAX22216_HHF_SHIFT 4 +#define MAX22216_HHF_FIELD ((RegisterField) {MAX22216_HHF_MASK, MAX22216_HHF_SHIFT, MAX22216_STATUS, false}) +#define MAX22216_OLF_MASK 0x00000020 +#define MAX22216_OLF_SHIFT 5 +#define MAX22216_OLF_FIELD ((RegisterField) {MAX22216_OLF_MASK, MAX22216_OLF_SHIFT, MAX22216_STATUS, false}) +#define MAX22216_OCP_MASK 0x00000040 +#define MAX22216_OCP_SHIFT 6 +#define MAX22216_OCP_FIELD ((RegisterField) {MAX22216_OCP_MASK, MAX22216_OCP_SHIFT, MAX22216_STATUS, false}) +#define MAX22216_OVT_MASK 0x00000080 +#define MAX22216_OVT_SHIFT 7 +#define MAX22216_OVT_FIELD ((RegisterField) {MAX22216_OVT_MASK, MAX22216_OVT_SHIFT, MAX22216_STATUS, false}) +#define MAX22216_IND_MASK 0x00000100 +#define MAX22216_IND_SHIFT 8 +#define MAX22216_IND_FIELD ((RegisterField) {MAX22216_IND_MASK, MAX22216_IND_SHIFT, MAX22216_STATUS, false}) +#define MAX22216_RES_MASK 0x00000200 +#define MAX22216_RES_SHIFT 9 +#define MAX22216_RES_FIELD ((RegisterField) {MAX22216_RES_MASK, MAX22216_RES_SHIFT, MAX22216_STATUS, false}) +#define MAX22216_MIN_T_ON_MASK 0x00000400 +#define MAX22216_MIN_T_ON_SHIFT 10 +#define MAX22216_MIN_T_ON_FIELD ((RegisterField) {MAX22216_MIN_T_ON_MASK, MAX22216_MIN_T_ON_SHIFT, MAX22216_STATUS, false}) +#define MAX22216_STT0_MASK 0x00000800 +#define MAX22216_STT0_SHIFT 11 +#define MAX22216_STT0_FIELD ((RegisterField) {MAX22216_STT0_MASK, MAX22216_STT0_SHIFT, MAX22216_STATUS, false}) +#define MAX22216_STT1_MASK 0x00001000 +#define MAX22216_STT1_SHIFT 12 +#define MAX22216_STT1_FIELD ((RegisterField) {MAX22216_STT1_MASK, MAX22216_STT1_SHIFT, MAX22216_STATUS, false}) +#define MAX22216_STT2_MASK 0x00002000 +#define MAX22216_STT2_SHIFT 13 +#define MAX22216_STT2_FIELD ((RegisterField) {MAX22216_STT2_MASK, MAX22216_STT2_SHIFT, MAX22216_STATUS, false}) +#define MAX22216_STT3_MASK 0x00004000 +#define MAX22216_STT3_SHIFT 14 +#define MAX22216_STT3_FIELD ((RegisterField) {MAX22216_STT3_MASK, MAX22216_STT3_SHIFT, MAX22216_STATUS, false}) +#define MAX22216_STAT_FUN_MASK 0x00000007 +#define MAX22216_STAT_FUN_SHIFT 0 +#define MAX22216_STAT_FUN_FIELD ((RegisterField) {MAX22216_STAT_FUN_MASK, MAX22216_STAT_FUN_SHIFT, MAX22216_STATUS_CFG, false}) +#define MAX22216_STAT_SEL0_MASK 0x00000008 +#define MAX22216_STAT_SEL0_SHIFT 3 +#define MAX22216_STAT_SEL0_FIELD ((RegisterField) {MAX22216_STAT_SEL0_MASK, MAX22216_STAT_SEL0_SHIFT, MAX22216_STATUS_CFG, false}) +#define MAX22216_STAT_SEL1_MASK 0x00000010 +#define MAX22216_STAT_SEL1_SHIFT 4 +#define MAX22216_STAT_SEL1_FIELD ((RegisterField) {MAX22216_STAT_SEL1_MASK, MAX22216_STAT_SEL1_SHIFT, MAX22216_STATUS_CFG, false}) +#define MAX22216_STRETCH_EN_MASK 0x00000060 +#define MAX22216_STRETCH_EN_SHIFT 5 +#define MAX22216_STRETCH_EN_FIELD ((RegisterField) {MAX22216_STRETCH_EN_MASK, MAX22216_STRETCH_EN_SHIFT, MAX22216_STATUS_CFG, false}) +#define MAX22216_EN_LDO_MASK 0x00000080 +#define MAX22216_EN_LDO_SHIFT 7 +#define MAX22216_EN_LDO_FIELD ((RegisterField) {MAX22216_EN_LDO_MASK, MAX22216_EN_LDO_SHIFT, MAX22216_STATUS_CFG, false}) +#define MAX22216_V5_NV3_MASK 0x00000100 +#define MAX22216_V5_NV3_SHIFT 8 +#define MAX22216_V5_NV3_FIELD ((RegisterField) {MAX22216_V5_NV3_MASK, MAX22216_V5_NV3_SHIFT, MAX22216_STATUS_CFG, false}) +#define MAX22216_M_UVM_CMP_MASK 0x00000200 +#define MAX22216_M_UVM_CMP_SHIFT 9 +#define MAX22216_M_UVM_CMP_FIELD ((RegisterField) {MAX22216_M_UVM_CMP_MASK, MAX22216_M_UVM_CMP_SHIFT, MAX22216_STATUS_CFG, false}) +#define MAX22216_DC_H2L_MASK 0x0000FFFF +#define MAX22216_DC_H2L_SHIFT 0 +#define MAX22216_DC_H2L_FIELD ((RegisterField) {MAX22216_DC_H2L_MASK, MAX22216_DC_H2L_SHIFT, MAX22216_DC_H2L, true}) +#define MAX22216_VM_MONITOR_MASK 0x00001FFF +#define MAX22216_VM_MONITOR_SHIFT 0 +#define MAX22216_VM_MONITOR_FIELD ((RegisterField) {MAX22216_VM_MONITOR_MASK, MAX22216_VM_MONITOR_SHIFT, MAX22216_VM_MONITOR, false}) +#define MAX22216_VM_THLD_DOWN_MASK 0x0000000F +#define MAX22216_VM_THLD_DOWN_SHIFT 0 +#define MAX22216_VM_THLD_DOWN_FIELD ((RegisterField) {MAX22216_VM_THLD_DOWN_MASK, MAX22216_VM_THLD_DOWN_SHIFT, MAX22216_VM_THRESHOLD, false}) +#define MAX22216_VM_THLD_UP_MASK 0x000000F0 +#define MAX22216_VM_THLD_UP_SHIFT 4 +#define MAX22216_VM_THLD_UP_FIELD ((RegisterField) {MAX22216_VM_THLD_UP_MASK, MAX22216_VM_THLD_UP_SHIFT, MAX22216_VM_THRESHOLD, false}) +#define MAX22216_F_AC_SCAN_MASK 0x00000FFF +#define MAX22216_F_AC_SCAN_SHIFT 0 +#define MAX22216_F_AC_SCAN_FIELD ((RegisterField) {MAX22216_F_AC_SCAN_MASK, MAX22216_F_AC_SCAN_SHIFT, MAX22216_F_AC, false}) +#define MAX22216_U_AC_SCAN_MASK 0x00007FFF +#define MAX22216_U_AC_SCAN_SHIFT 0 +#define MAX22216_U_AC_SCAN_FIELD ((RegisterField) {MAX22216_U_AC_SCAN_MASK, MAX22216_U_AC_SCAN_SHIFT, MAX22216_U_AC_SCAN, false}) +#define MAX22216_DC_L2H_MASK 0x0000FFFF +#define MAX22216_DC_L2H_SHIFT 0 +#define MAX22216_DC_L2H_FIELD ((RegisterField) {MAX22216_DC_L2H_MASK, MAX22216_DC_L2H_SHIFT, MAX22216_CFG_DC_L2H_0, true}) +#define MAX22216_DC_H_MASK 0x0000FFFF +#define MAX22216_DC_H_SHIFT 0 +#define MAX22216_DC_H_FIELD ((RegisterField) {MAX22216_DC_H_MASK, MAX22216_DC_H_SHIFT, MAX22216_CFG_DC_H_0, true}) +#define MAX22216_DC_L_MASK 0x0000FFFF +#define MAX22216_DC_L_SHIFT 0 +#define MAX22216_DC_L_FIELD ((RegisterField) {MAX22216_DC_L_MASK, MAX22216_DC_L_SHIFT, MAX22216_CFG_DC_L_0, true}) +#define MAX22216_TIME_L2H_MASK 0x0000FFFF +#define MAX22216_TIME_L2H_SHIFT 0 +#define MAX22216_TIME_L2H_FIELD ((RegisterField) {MAX22216_TIME_L2H_MASK, MAX22216_TIME_L2H_SHIFT, MAX22216_CFG_L2H_TIME_0, false}) +#define MAX22216_RAMP_MASK 0x000000FF +#define MAX22216_RAMP_SHIFT 0 +#define MAX22216_RAMP_FIELD ((RegisterField) {MAX22216_RAMP_MASK, MAX22216_RAMP_SHIFT, MAX22216_CFG_CTRL0_0, false}) +#define MAX22216_RUPE_MASK 0x00000100 +#define MAX22216_RUPE_SHIFT 8 +#define MAX22216_RUPE_FIELD ((RegisterField) {MAX22216_RUPE_MASK, MAX22216_RUPE_SHIFT, MAX22216_CFG_CTRL0_0, false}) +#define MAX22216_RMDE_MASK 0x00000200 +#define MAX22216_RMDE_SHIFT 9 +#define MAX22216_RMDE_FIELD ((RegisterField) {MAX22216_RMDE_MASK, MAX22216_RMDE_SHIFT, MAX22216_CFG_CTRL0_0, false}) +#define MAX22216_RDWE_MASK 0x00000400 +#define MAX22216_RDWE_SHIFT 10 +#define MAX22216_RDWE_FIELD ((RegisterField) {MAX22216_RDWE_MASK, MAX22216_RDWE_SHIFT, MAX22216_CFG_CTRL0_0, false}) +#define MAX22216_H2L_EN_MASK 0x00000800 +#define MAX22216_H2L_EN_SHIFT 11 +#define MAX22216_H2L_EN_FIELD ((RegisterField) {MAX22216_H2L_EN_MASK, MAX22216_H2L_EN_SHIFT, MAX22216_CFG_CTRL0_0, false}) +#define MAX22216_OL_EN_MASK 0x00001000 +#define MAX22216_OL_EN_SHIFT 12 +#define MAX22216_OL_EN_FIELD ((RegisterField) {MAX22216_OL_EN_MASK, MAX22216_OL_EN_SHIFT, MAX22216_CFG_CTRL0_0, false}) +#define MAX22216_HHF_EN_MASK 0x00002000 +#define MAX22216_HHF_EN_SHIFT 13 +#define MAX22216_HHF_EN_FIELD ((RegisterField) {MAX22216_HHF_EN_MASK, MAX22216_HHF_EN_SHIFT, MAX22216_CFG_CTRL0_0, false}) +#define MAX22216_CTRL_MODE_MASK 0x0000C000 +#define MAX22216_CTRL_MODE_SHIFT 14 +#define MAX22216_CTRL_MODE_FIELD ((RegisterField) {MAX22216_CTRL_MODE_MASK, MAX22216_CTRL_MODE_SHIFT, MAX22216_CFG_CTRL0_0, false}) +#define MAX22216_SNSF_MASK 0x00000003 +#define MAX22216_SNSF_SHIFT 0 +#define MAX22216_SNSF_FIELD ((RegisterField) {MAX22216_SNSF_MASK, MAX22216_SNSF_SHIFT, MAX22216_CFG_CTRL1_0, false}) +#define MAX22216_GAIN_MASK 0x0000000C +#define MAX22216_GAIN_SHIFT 2 +#define MAX22216_GAIN_FIELD ((RegisterField) {MAX22216_GAIN_MASK, MAX22216_GAIN_SHIFT, MAX22216_CFG_CTRL1_0, false}) +#define MAX22216_SLEW_RATE_MASK 0x00000030 +#define MAX22216_SLEW_RATE_SHIFT 4 +#define MAX22216_SLEW_RATE_FIELD ((RegisterField) {MAX22216_SLEW_RATE_MASK, MAX22216_SLEW_RATE_SHIFT, MAX22216_CFG_CTRL1_0, false}) +#define MAX22216_T_BLANKING_MASK 0x000000C0 +#define MAX22216_T_BLANKING_SHIFT 6 +#define MAX22216_T_BLANKING_FIELD ((RegisterField) {MAX22216_T_BLANKING_MASK, MAX22216_T_BLANKING_SHIFT, MAX22216_CFG_CTRL1_0, false}) +#define MAX22216_F_PWM_MASK 0x00000300 +#define MAX22216_F_PWM_SHIFT 8 +#define MAX22216_F_PWM_FIELD ((RegisterField) {MAX22216_F_PWM_MASK, MAX22216_F_PWM_SHIFT, MAX22216_CFG_CTRL1_0, false}) +#define MAX22216_HSNLS_MASK 0x00000400 +#define MAX22216_HSNLS_SHIFT 10 +#define MAX22216_HSNLS_FIELD ((RegisterField) {MAX22216_HSNLS_MASK, MAX22216_HSNLS_SHIFT, MAX22216_CFG_CTRL1_0, false}) +#define MAX22216_DPM_THLD_MASK 0x00000FFF +#define MAX22216_DPM_THLD_SHIFT 0 +#define MAX22216_DPM_THLD_FIELD ((RegisterField) {MAX22216_DPM_THLD_MASK, MAX22216_DPM_THLD_SHIFT, MAX22216_CFG_DPM0_0, false}) +#define MAX22216_DPM_START_MASK 0x000000FF +#define MAX22216_DPM_START_SHIFT 0 +#define MAX22216_DPM_START_FIELD ((RegisterField) {MAX22216_DPM_START_MASK, MAX22216_DPM_START_SHIFT, MAX22216_CFG_DPM1_0, false}) +#define MAX22216_DPM_MIN_NBR_MASK 0x00000F00 +#define MAX22216_DPM_MIN_NBR_SHIFT 8 +#define MAX22216_DPM_MIN_NBR_FIELD ((RegisterField) {MAX22216_DPM_MIN_NBR_MASK, MAX22216_DPM_MIN_NBR_SHIFT, MAX22216_CFG_DPM1_0, false}) +#define MAX22216_END_HIT_AUTO_MASK 0x00001000 +#define MAX22216_END_HIT_AUTO_SHIFT 12 +#define MAX22216_END_HIT_AUTO_FIELD ((RegisterField) {MAX22216_END_HIT_AUTO_MASK, MAX22216_END_HIT_AUTO_SHIFT, MAX22216_CFG_DPM1_0, false}) +#define MAX22216_END_HIT_TO_HIZ_AUTO_MASK 0x00002000 +#define MAX22216_END_HIT_TO_HIZ_AUTO_SHIFT 13 +#define MAX22216_END_HIT_TO_HIZ_AUTO_FIELD ((RegisterField) {MAX22216_END_HIT_TO_HIZ_AUTO_MASK, MAX22216_END_HIT_TO_HIZ_AUTO_SHIFT, MAX22216_CFG_DPM1_0, false}) +#define MAX22216_DPM_EN_MASK 0x00004000 +#define MAX22216_DPM_EN_SHIFT 14 +#define MAX22216_DPM_EN_FIELD ((RegisterField) {MAX22216_DPM_EN_MASK, MAX22216_DPM_EN_SHIFT, MAX22216_CFG_DPM1_0, false}) +#define MAX22216_IDC_THLD_MASK 0x0000FFFF +#define MAX22216_IDC_THLD_SHIFT 0 +#define MAX22216_IDC_THLD_FIELD ((RegisterField) {MAX22216_IDC_THLD_MASK, MAX22216_IDC_THLD_SHIFT, MAX22216_CFG_IDC_THLD_0, true}) +#define MAX22216_RES_THLD_MASK 0x0000FFFF +#define MAX22216_RES_THLD_SHIFT 0 +#define MAX22216_RES_THLD_FIELD ((RegisterField) {MAX22216_RES_THLD_MASK, MAX22216_RES_THLD_SHIFT, MAX22216_CFG_R_THLD_0, false}) +#define MAX22216_L_NBR_CALC_MASK 0x0000000F +#define MAX22216_L_NBR_CALC_SHIFT 0 +#define MAX22216_L_NBR_CALC_FIELD ((RegisterField) {MAX22216_L_NBR_CALC_MASK, MAX22216_L_NBR_CALC_SHIFT, MAX22216_CFG_IND_0_0, false}) +#define MAX22216_L_MEAS_WCYCLES_MASK 0x000000F0 +#define MAX22216_L_MEAS_WCYCLES_SHIFT 4 +#define MAX22216_L_MEAS_WCYCLES_FIELD ((RegisterField) {MAX22216_L_MEAS_WCYCLES_MASK, MAX22216_L_MEAS_WCYCLES_SHIFT, MAX22216_CFG_IND_0_0, false}) +#define MAX22216_L_MEAS_H_MASK 0x00000100 +#define MAX22216_L_MEAS_H_SHIFT 8 +#define MAX22216_L_MEAS_H_FIELD ((RegisterField) {MAX22216_L_MEAS_H_MASK, MAX22216_L_MEAS_H_SHIFT, MAX22216_CFG_IND_0_0, false}) +#define MAX22216_L_MEAS_L2H_MASK 0x00000200 +#define MAX22216_L_MEAS_L2H_SHIFT 9 +#define MAX22216_L_MEAS_L2H_FIELD ((RegisterField) {MAX22216_L_MEAS_L2H_MASK, MAX22216_L_MEAS_L2H_SHIFT, MAX22216_CFG_IND_0_0, false}) +#define MAX22216_L_MEAS_EN_MASK 0x00000400 +#define MAX22216_L_MEAS_EN_SHIFT 10 +#define MAX22216_L_MEAS_EN_FIELD ((RegisterField) {MAX22216_L_MEAS_EN_MASK, MAX22216_L_MEAS_EN_SHIFT, MAX22216_CFG_IND_0_0, false}) +#define MAX22216_DITH_EN_MASK 0x00000800 +#define MAX22216_DITH_EN_SHIFT 11 +#define MAX22216_DITH_EN_FIELD ((RegisterField) {MAX22216_DITH_EN_MASK, MAX22216_DITH_EN_SHIFT, MAX22216_CFG_IND_0_0, false}) +#define MAX22216_IAC_THLD_MASK 0x00000FFF +#define MAX22216_IAC_THLD_SHIFT 0 +#define MAX22216_IAC_THLD_FIELD ((RegisterField) {MAX22216_IAC_THLD_MASK, MAX22216_IAC_THLD_SHIFT, MAX22216_CFG_IND_1_0, false}) +#define MAX22216_CFG_P_MASK 0x0000FFFF +#define MAX22216_CFG_P_SHIFT 0 +#define MAX22216_CFG_P_FIELD ((RegisterField) {MAX22216_CFG_P_MASK, MAX22216_CFG_P_SHIFT, MAX22216_CFG_P_0, false}) +#define MAX22216_CFG_I_MASK 0x0000FFFF +#define MAX22216_CFG_I_SHIFT 0 +#define MAX22216_CFG_I_FIELD ((RegisterField) {MAX22216_CFG_I_MASK, MAX22216_CFG_I_SHIFT, MAX22216_CFG_I_0, false}) +#define MAX22216_I_DPM_PEAK_MASK 0x0000FFFF +#define MAX22216_I_DPM_PEAK_SHIFT 0 +#define MAX22216_I_DPM_PEAK_FIELD ((RegisterField) {MAX22216_I_DPM_PEAK_MASK, MAX22216_I_DPM_PEAK_SHIFT, MAX22216_I_DPM_PEAK_0, false}) +#define MAX22216_I_DPM_VALLEY_MASK 0x0000FFFF +#define MAX22216_I_DPM_VALLEY_SHIFT 0 +#define MAX22216_I_DPM_VALLEY_FIELD ((RegisterField) {MAX22216_I_DPM_VALLEY_MASK, MAX22216_I_DPM_VALLEY_SHIFT, MAX22216_I_DPM_VALLEY_0, false}) +#define MAX22216_TRAVEL_TIME_MASK 0x0000FFFF +#define MAX22216_TRAVEL_TIME_SHIFT 0 +#define MAX22216_TRAVEL_TIME_FIELD ((RegisterField) {MAX22216_TRAVEL_TIME_MASK, MAX22216_TRAVEL_TIME_SHIFT, MAX22216_TRAVEL_TIME_0, false}) +#define MAX22216_REACTION_TIME_MASK 0x0000FFFF +#define MAX22216_REACTION_TIME_SHIFT 0 +#define MAX22216_REACTION_TIME_FIELD ((RegisterField) {MAX22216_REACTION_TIME_MASK, MAX22216_REACTION_TIME_SHIFT, MAX22216_REACTION_TIME_0, false}) +#define MAX22216_I_MONITOR_MASK 0x0000FFFF +#define MAX22216_I_MONITOR_SHIFT 0 +#define MAX22216_I_MONITOR_FIELD ((RegisterField) {MAX22216_I_MONITOR_MASK, MAX22216_I_MONITOR_SHIFT, MAX22216_I_MONITOR_0, true}) +#define MAX22216_I_AC_MASK 0x0000FFFF +#define MAX22216_I_AC_SHIFT 0 +#define MAX22216_I_AC_FIELD ((RegisterField) {MAX22216_I_AC_MASK, MAX22216_I_AC_SHIFT, MAX22216_I_AC_0, true}) +#define MAX22216_PWM_DUTYCYCLE_MASK 0x0000FFFF +#define MAX22216_PWM_DUTYCYCLE_SHIFT 0 +#define MAX22216_PWM_DUTYCYCLE_FIELD ((RegisterField) {MAX22216_PWM_DUTYCYCLE_MASK, MAX22216_PWM_DUTYCYCLE_SHIFT, MAX22216_PWM_DUTY_0, false}) +#define MAX22216_OCP0_MASK 0x00000001 +#define MAX22216_OCP0_SHIFT 0 +#define MAX22216_OCP0_FIELD ((RegisterField) {MAX22216_OCP0_MASK, MAX22216_OCP0_SHIFT, MAX22216_FAULT0, false}) +#define MAX22216_OCP1_MASK 0x00000002 +#define MAX22216_OCP1_SHIFT 1 +#define MAX22216_OCP1_FIELD ((RegisterField) {MAX22216_OCP1_MASK, MAX22216_OCP1_SHIFT, MAX22216_FAULT0, false}) +#define MAX22216_OCP2_MASK 0x00000004 +#define MAX22216_OCP2_SHIFT 2 +#define MAX22216_OCP2_FIELD ((RegisterField) {MAX22216_OCP2_MASK, MAX22216_OCP2_SHIFT, MAX22216_FAULT0, false}) +#define MAX22216_OCP3_MASK 0x00000008 +#define MAX22216_OCP3_SHIFT 3 +#define MAX22216_OCP3_FIELD ((RegisterField) {MAX22216_OCP3_MASK, MAX22216_OCP3_SHIFT, MAX22216_FAULT0, false}) +#define MAX22216_HHF0_MASK 0x00000010 +#define MAX22216_HHF0_SHIFT 4 +#define MAX22216_HHF0_FIELD ((RegisterField) {MAX22216_HHF0_MASK, MAX22216_HHF0_SHIFT, MAX22216_FAULT0, false}) +#define MAX22216_HHF1_MASK 0x00000020 +#define MAX22216_HHF1_SHIFT 5 +#define MAX22216_HHF1_FIELD ((RegisterField) {MAX22216_HHF1_MASK, MAX22216_HHF1_SHIFT, MAX22216_FAULT0, false}) +#define MAX22216_HHF2_MASK 0x00000040 +#define MAX22216_HHF2_SHIFT 6 +#define MAX22216_HHF2_FIELD ((RegisterField) {MAX22216_HHF2_MASK, MAX22216_HHF2_SHIFT, MAX22216_FAULT0, false}) +#define MAX22216_HHF3_MASK 0x00000080 +#define MAX22216_HHF3_SHIFT 7 +#define MAX22216_HHF3_FIELD ((RegisterField) {MAX22216_HHF3_MASK, MAX22216_HHF3_SHIFT, MAX22216_FAULT0, false}) +#define MAX22216_OLF0_MASK 0x00000100 +#define MAX22216_OLF0_SHIFT 8 +#define MAX22216_OLF0_FIELD ((RegisterField) {MAX22216_OLF0_MASK, MAX22216_OLF0_SHIFT, MAX22216_FAULT0, false}) +#define MAX22216_OLF1_MASK 0x00000200 +#define MAX22216_OLF1_SHIFT 9 +#define MAX22216_OLF1_FIELD ((RegisterField) {MAX22216_OLF1_MASK, MAX22216_OLF1_SHIFT, MAX22216_FAULT0, false}) +#define MAX22216_OLF2_MASK 0x00000400 +#define MAX22216_OLF2_SHIFT 10 +#define MAX22216_OLF2_FIELD ((RegisterField) {MAX22216_OLF2_MASK, MAX22216_OLF2_SHIFT, MAX22216_FAULT0, false}) +#define MAX22216_OLF3_MASK 0x00000800 +#define MAX22216_OLF3_SHIFT 11 +#define MAX22216_OLF3_FIELD ((RegisterField) {MAX22216_OLF3_MASK, MAX22216_OLF3_SHIFT, MAX22216_FAULT0, false}) +#define MAX22216_DPM0_MASK 0x00001000 +#define MAX22216_DPM0_SHIFT 12 +#define MAX22216_DPM0_FIELD ((RegisterField) {MAX22216_DPM0_MASK, MAX22216_DPM0_SHIFT, MAX22216_FAULT0, false}) +#define MAX22216_DPM1_MASK 0x00002000 +#define MAX22216_DPM1_SHIFT 13 +#define MAX22216_DPM1_FIELD ((RegisterField) {MAX22216_DPM1_MASK, MAX22216_DPM1_SHIFT, MAX22216_FAULT0, false}) +#define MAX22216_DPM2_MASK 0x00004000 +#define MAX22216_DPM2_SHIFT 14 +#define MAX22216_DPM2_FIELD ((RegisterField) {MAX22216_DPM2_MASK, MAX22216_DPM2_SHIFT, MAX22216_FAULT0, false}) +#define MAX22216_DPM3_MASK 0x00008000 +#define MAX22216_DPM3_SHIFT 15 +#define MAX22216_DPM3_FIELD ((RegisterField) {MAX22216_DPM3_MASK, MAX22216_DPM3_SHIFT, MAX22216_FAULT0, false}) +#define MAX22216_IND0_MASK 0x00000001 +#define MAX22216_IND0_SHIFT 0 +#define MAX22216_IND0_FIELD ((RegisterField) {MAX22216_IND0_MASK, MAX22216_IND0_SHIFT, MAX22216_FAULT1, false}) +#define MAX22216_IND1_MASK 0x00000002 +#define MAX22216_IND1_SHIFT 1 +#define MAX22216_IND1_FIELD ((RegisterField) {MAX22216_IND1_MASK, MAX22216_IND1_SHIFT, MAX22216_FAULT1, false}) +#define MAX22216_IND2_MASK 0x00000004 +#define MAX22216_IND2_SHIFT 2 +#define MAX22216_IND2_FIELD ((RegisterField) {MAX22216_IND2_MASK, MAX22216_IND2_SHIFT, MAX22216_FAULT1, false}) +#define MAX22216_IND3_MASK 0x00000008 +#define MAX22216_IND3_SHIFT 3 +#define MAX22216_IND3_FIELD ((RegisterField) {MAX22216_IND3_MASK, MAX22216_IND3_SHIFT, MAX22216_FAULT1, false}) +#define MAX22216_RES0_MASK 0x00000080 +#define MAX22216_RES0_SHIFT 7 +#define MAX22216_RES0_FIELD ((RegisterField) {MAX22216_RES0_MASK, MAX22216_RES0_SHIFT, MAX22216_FAULT1, false}) +#define MAX22216_RES1_MASK 0x00000100 +#define MAX22216_RES1_SHIFT 8 +#define MAX22216_RES1_FIELD ((RegisterField) {MAX22216_RES1_MASK, MAX22216_RES1_SHIFT, MAX22216_FAULT1, false}) +#define MAX22216_RES2_MASK 0x00000200 +#define MAX22216_RES2_SHIFT 9 +#define MAX22216_RES2_FIELD ((RegisterField) {MAX22216_RES2_MASK, MAX22216_RES2_SHIFT, MAX22216_FAULT1, false}) +#define MAX22216_RES3_MASK 0x00000400 +#define MAX22216_RES3_SHIFT 10 +#define MAX22216_RES3_FIELD ((RegisterField) {MAX22216_RES3_MASK, MAX22216_RES3_SHIFT, MAX22216_FAULT1, false}) + +#endif diff --git a/firmware/lib/tmc/ic/MAX22216/README.md b/firmware/lib/tmc/ic/MAX22216/README.md new file mode 100755 index 0000000..7a4216a --- /dev/null +++ b/firmware/lib/tmc/ic/MAX22216/README.md @@ -0,0 +1,43 @@ +# max22216 + + +## How to use + +To access the max22216's registers, the TMC-API offers two functions: **max22216_readRegister** and **max22216_writeRegister**. +Each of these functions takes in an **icID**, which is used to identify the IC when multiple ICs are connected. This identifier is passed down to the callback functions (see How to Integrate). + +## How to integrate: overview + +1. Include all the files of the TMC-API/ic/tmc/max22216 folder into the custom project. +2. Include the max22216.h file in the custom source code. +3. Implement the necessary callback functions (see below). +4. (optional): Take a look at the Examples subfolder for ready-made examples of the TMC-API usage. + +## Accessing the max22216 via SPI +The following diagram depicts how to access the max22216 via SPI using the TMC-API. + +![screenshot](registercall_hierarchy_flowchart_SPI.svg) + +The description of the functions, in the above flowchart, are as follows: +- The functions max22216_readRegister and max22216_writeRegister are used to read and write the registers respectively. These functions check the current active bus and calls the bus-specific function i.e readRegisterSPI or writeRegisterSPI. +- These bus specific functions constructs the datagram and further calls the bus specific callback 'tmcXXXX_readWriteSPI. +- This callback function further calls the hardware specific read/write function for SPI and needs to be implemented externally. + +### How to integrate: Callback functions +To communicate with max22216 IC through SPI, there are two ways. One is with CRC check and the other is without CRC. For that, the callback function **'max22216_getCRCEnState()'** needs to be implemented. +Additionally, implement the following callback functions to access the chip via SPI: +1. **max22216_readWriteSPI()**, which is a HAL wrapper function that provides the necessary hardware access. This function should also set the chip select pin CSN to low before starting the data transfer and set to high upon completion. Please refer to the datasheet of the IC for further details. + +## Further info +### Dependency graph for the ICs with new register R/W mechanism +This graph illustrates the relationships between files within the TMC-API library, highlighting dependencies and identifying the files that are essential for integrating the library into the custom projects. + +![screenshot](uml-tmc-api.svg) + +### Example usage: TMC-Evalsystem +**For a reference usage of the TMC-API**, visit the [TMC-Evalsystem](https://github.com/analogdevicesinc/TMC-EvalSystem) + +## Migration status +The max22216 has been reworked to the access system described above. For more infos on the status of this and other ICs, check out the [migration page](https://github.com/analogdevicesinc/TMC-API/issues/53). + + diff --git a/firmware/lib/tmc/ic/MAX22216/registercall_hierarchy_flowchart_SPI.svg b/firmware/lib/tmc/ic/MAX22216/registercall_hierarchy_flowchart_SPI.svg new file mode 100755 index 0000000..cbad58f --- /dev/null +++ b/firmware/lib/tmc/ic/MAX22216/registercall_hierarchy_flowchart_SPI.svg @@ -0,0 +1,3 @@ + + +

HAL

HAL

APP (Eval)

APP (Eval)

API

API
Read a register
  •  Call tmcXXXX_readRegister function
Read a register...
Returns the register read value
Returns the register read value
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
tmcXXXX.c
tmcXXXX.c
SPI.c
SPI.c
tmcXXXX_eval.c
tmcXXXX_eval.c

 Implementation of SPI_readWrite
  • Sends and receives bytes on the SPI bus
Implementation of SPI_readWrite...
Returns the raw reply data
Returns the raw reply data

Implementation of tmcXXXX_readWriteSPI
  • Sets the CSN pin to LOW
  • Takes the array of data to write
  • Calls hardware function SPI_readWrite
  • Upon completion of data transfer,
    sets CSN to 
    HIGH
Implementation of tmcXXXX_readWriteSPI...
Passes on the raw reply data to the API
Passes on the raw reply data to the API
Implementation of readRegisterSPI
  • Constructs the datagram
  • Calls HAL wrapper function 
Implementation of readRegisterSPI...
tmcXXXX_readWriteSPI
tmcXXXX_readWriteSPI
Parses the reply and returns the register value
Parses the reply and returns the register value
Implementation of tmcXXXX_readRegister 
  • Check which bus is active SPI/UART. (e.g. SPI)
  • Calls bus-specific function (e.g. readRegisterSPI)
 
Implementation of tmcXXXX_readRegister...
Returns the register read value
Returns the register read value
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/MAX22216/uml-tmc-api.svg b/firmware/lib/tmc/ic/MAX22216/uml-tmc-api.svg new file mode 100755 index 0000000..5a5f8dd --- /dev/null +++ b/firmware/lib/tmc/ic/MAX22216/uml-tmc-api.svg @@ -0,0 +1,3 @@ + + +

TMCXXXX_HW_Abstraction.h



TMCXXXX_HW_Abstraction.h...
// Constants
#define TMCXXXX_MOTORS              
                          
// Register definitions
#define TMCXXXX_GCONF        
                          ⋮
// Register fields definitions
#define TMCXXXX_GCONF_OTPW_FIELD
                     
// Constants...

TMCXXXX.h



TMCXXXX.h...
extern void tmcXXXX_readWriteSPI();
extern void tmcXXXX_readWriteUART();
extern TMCXXXXBusType tmcXXXX_getBusType();
extern uint8_t tmcXXXX_getNodeAddress();
                                  ⋮
tmcXXXX_readRegister();
tmcXXXX_writeRegister();
                                  ⋮
extern void tmcXXXX_readWriteSPI();...

TMCXXXX.c



TMCXXXX.c...
const uint8_t tmcCRCTable_Poly7Reflected[256] = {...};
int32_t tmcXXXX_readRegister(){
/* Call tmcXXXX_getBusType();
 * Based on bus type, call readRegisterSPI/UART() that
 * further calls tmcXXXX_readWriteSPI/UART();
 * For UART it also calls tmcXXXX_getNodeAddress();
                                           ⋮
}
                                           ⋮
const uint8_t tmcCRCTable_Poly7Reflected[256] = {.....
TMC-API
TMC-API

TMCXXXX_Simple_Rotation.h


TMCXXXX_Simple_Rotation.h...
void initAllMotors();
             ⋮
  
void initAllMotors()...

TMCXXXX_Simple_Rotation.c


TMCXXXX_Simple_Rotation.c...
void initAllMotors(){

// Configuring registers to enable motor drivers etc..
tmcXXXX_writeRegister();
                    ⋮
}
                    ⋮
void initAllMotors(){...
Examples
Examples
User Project
User Project

User_Project.h


User_Project.h

User_Project.c








User_Project.c...

void tmcXXXX_readWriteSPI(){
                           ⋮
}
void tmcXXXX_readWriteUART(){
                           ⋮
}
TMCXXXXBusType tmcXXXX_getBusType(){
                           ⋮
}
uint8_t tmcXXXX_getNodeAddress(){
                           ⋮
}

// User Code
                           ⋮
void tmcXXXX_readWriteSPI(){...
#include "TMCXXXX_HW_Abstraction.h"
#include "TMCXXXX.h"
#include "TMCXXXX_Simple_Rotation.h"
                                ⋮
TMCXXXXBusType bus = IC_BUS_SPI/UART;
uint8_t nodeAddress = <nodeAddress>;
                                ⋮
#include "TMCXXXX_HW_Abstraction.h"...
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC2130/README.md b/firmware/lib/tmc/ic/TMC2130/README.md new file mode 100755 index 0000000..6540898 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2130/README.md @@ -0,0 +1,46 @@ +# TMC2130 + + +## How to use + +To access the TMC2130's registers, the TMC-API offers two functions: **tmc2130_readRegister** and **tmc2130_writeRegister**. +Each of these functions takes in an **icID**, which is used to identify the IC when multiple ICs are connected. This identifier is passed down to the callback functions (see How to Integrate). + +## How to integrate: overview + +1. Include all the files of the TMC-API/ic/tmc/TMC2130 folder into the custom project. +2. Include the TMC2130.h file in the custom source code. +3. Implement the necessary callback functions (see below). +4. (optional): Take a look at the Examples subfolder for ready-made examples of the TMC-API usage. + +## Accessing the TMC2130 via SPI +The following diagram depicts how to access the TMC2130 via SPI using the TMC-API. + +![screenshot](registercall_hierarchy_flowchart_SPI.svg) + +The description of the functions, in the above flowchart, are as follows: +- The functions tmc2130_readRegister and tmc2130_writeRegister are used to read and write the registers respectively. These functions check the current active bus and calls the bus-specific function i.e readRegisterSPI or writeRegisterSPI. +- These bus specific functions constructs the datagram and further calls the bus specific callback 'tmcXXXX_readWriteSPI. +- This callback function further calls the hardware specific read/write function for SPI and needs to be implemented externally. + +### How to integrate: Callback functions +To communicate with TMC2130 IC, the TMC-API library needs to know which bus (UART, SPI) it shall use. For that, the callback function **'tmc2130_getBusType()'** needs to be implemented. +Additionally, implement the following callback functions to access the chip via SPI: +1. **tmc2130_readWriteSPI()**, which is a HAL wrapper function that provides the necessary hardware access. This function should also set the chip select pin CSN to low before starting the data transfer and set to high upon completion. Please refer to the datasheet of the IC for further details. + +### Option to use the cache logic for Write-Only registers +The chip features write-only registers that are unable to be read, necessitating the creation of a shadow copy to cache their contents. This copy is automatically updated whenever data is written to these registers. This cache logic could be enabled by setting the macro **TMC2130_CACHE** to **'1'** or disabled by setting to **'0'** respectively. If this feature is enabled then there comes another option to use **tmc2130_cache** function, which is already implemeted in the API, by defining **TMC2130_ENABLE_TMC_CACHE** macro to **'1** or one can implement their own function. The function **tmc2130_cache** works for both reading from and writing to the shadow array. It first checks whether the register has write-only access and data needs to be read from the hadow copy. On the basis of that, it returns **true** or **false**. The shadowRegisters on the premade cache implementation need to be one per chip. **TMC2130_IC_CACHE_COUNT** is set to '1' by default and is user-overwritable. If multiple chips are being used in the same project, increment its value to the number of chips connected. + +## Further info +### Dependency graph for the ICs with new register R/W mechanism +This graph illustrates the relationships between files within the TMC-API library, highlighting dependencies and identifying the files that are essential for integrating the library into the custom projects. + +![screenshot](uml-tmc-api.svg) + +### Example usage: TMC-Evalsystem +**For a reference usage of the TMC-API**, visit the [TMC-Evalsystem](https://github.com/analogdevicesinc/TMC-EvalSystem) + +## Migration status +The TMC2130 has been reworked to the access system described above. For more infos on the status of this and other ICs, check out the [migration page](https://github.com/analogdevicesinc/TMC-API/issues/53). + + diff --git a/firmware/lib/tmc/ic/TMC2130/TMC2130.c b/firmware/lib/tmc/ic/TMC2130/TMC2130.c new file mode 100755 index 0000000..872a80f --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2130/TMC2130.c @@ -0,0 +1,192 @@ +/******************************************************************************* +* Copyright © 2017 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#include "TMC2130.h" + + +/**************************************************************** Cache Implementation *************************************************************************/ + +#if TMC2130_CACHE == 0 +static inline bool tmc2130_cache(uint16_t icID, TMC2130CacheOp operation, uint8_t address, uint32_t *value) +{ + UNUSED(icID); + UNUSED(address); + UNUSED(operation); + return false; +} +#else +#if TMC2130_ENABLE_TMC_CACHE == 1 + +uint8_t tmc2130_dirtyBits[TMC2130_IC_CACHE_COUNT][TMC2130_REGISTER_COUNT/8]= {0}; +int32_t tmc2130_shadowRegister[TMC2130_IC_CACHE_COUNT][TMC2130_REGISTER_COUNT]; + +void tmc2130_setDirtyBit(uint16_t icID, uint8_t index, bool value) + { + if(index >= TMC2130_REGISTER_COUNT) + return; + + uint8_t *tmp = &tmc2130_dirtyBits[icID][index / 8]; + uint8_t shift = (index % 8); + uint8_t mask = 1 << shift; + *tmp = (((*tmp) & (~(mask))) | (((value) << (shift)) & (mask))); +} + +bool tmc2130_getDirtyBit(uint16_t icID, uint8_t index) +{ + if(index >= TMC2130_REGISTER_COUNT) + return false; + + uint8_t *tmp = &tmc2130_dirtyBits[icID][index / 8]; + uint8_t shift = (index % 8); + return ((*tmp) >> shift) & 1; +} +/* + * This function is used to cache the value written to the Write-Only registers in the form of shadow array. + * The shadow copy is then used to read these kinds of registers. + */ + +bool tmc2130_cache(uint16_t icID, TMC2130CacheOp operation, uint8_t address, uint32_t *value) +{ + if (operation == TMC2130_CACHE_READ) + { + // Check if the value should come from cache + + // Only supported chips have a cache + if (icID >= TMC2130_IC_CACHE_COUNT) + return false; + + // Only non-readable registers care about caching + // Note: This could also be used to cache i.e. RW config registers to reduce bus accesses + if (TMC2130_IS_READABLE(tmc2130_registerAccess[address])) + return false; + + // Grab the value from the cache + *value = tmc2130_shadowRegister[icID][address]; + return true; + } + else if (operation == TMC2130_CACHE_WRITE || operation == TMC2130_CACHE_FILL_DEFAULT) + { + // Fill the cache + + // only supported chips have a cache + if (icID >= TMC2130_IC_CACHE_COUNT) + return false; + + // Write to the shadow register. + tmc2130_shadowRegister[icID][address] = *value; + // For write operations, mark the register dirty + if (operation == TMC2130_CACHE_WRITE) + { + tmc2130_setDirtyBit(icID, address, true); + } + + return true; + } + return false; +} + +void tmc2130_initCache() +{ + // Check if we have constants defined + if(ARRAY_SIZE(tmc2130_RegisterConstants) == 0) + return; + + size_t i, j, id; + + for(i = 0, j = 0; i < TMC2130_REGISTER_COUNT; i++) + { + // We only need to worry about hardware preset, write-only registers + // that have not yet been written (no dirty bit) here. + if(tmc2130_registerAccess[i] != TMC2130_ACCESS_W_PRESET) + continue; + + // Search the constant list for the current address. With the constant + // list being sorted in ascended order, we can walk through the list + // until the entry with an address equal or greater than i + while(j < ARRAY_SIZE(tmc2130_RegisterConstants) && (tmc2130_RegisterConstants[j].address < i)) + j++; + + // Abort when we reach the end of the constant list + if (j == ARRAY_SIZE(tmc2130_RegisterConstants)) + break; + + // If we have an entry for our current address, write the constant + if(tmc2130_RegisterConstants[j].address == i) + { + for (id = 0; id < TMC2130_IC_CACHE_COUNT; id++) + { + uint32_t temp = tmc2130_RegisterConstants[j].value; + tmc2130_cache(id, TMC2130_CACHE_FILL_DEFAULT, i, &temp); + } + } + } +} +#else +// User must implement their own cache +extern bool tmc2130_cache(uint16_t icID, TMC2130CacheOp operation, uint8_t address, uint32_t *value); +#endif +#endif + +/************************************************************* read / write Implementation *********************************************************************/ + +static int32_t readRegisterSPI(uint16_t icID, uint8_t address); +static void writeRegisterSPI(uint16_t icID, uint8_t address, int32_t value); + + +int32_t tmc2130_readRegister(uint16_t icID, uint8_t address) +{ + return readRegisterSPI(icID, address); +} +void tmc2130_writeRegister(uint16_t icID, uint8_t address, int32_t value) +{ + writeRegisterSPI(icID, address, value); +} + +int32_t readRegisterSPI(uint16_t icID, uint8_t address) +{ + + uint8_t data[5] = { 0 }; + uint32_t value; + + + // Read from cache for registers with write-only access + if (tmc2130_cache(icID, TMC2130_CACHE_READ, address, &value)) + return value; + + // clear write bit + data[0] = address & TMC2130_ADDRESS_MASK; + + // Send the read request + tmc2130_readWriteSPI(icID, &data[0], sizeof(data)); + + // Rewrite address and clear write bit + data[0] = address & TMC2130_ADDRESS_MASK; + + // Send another request to receive the read reply + tmc2130_readWriteSPI(icID, &data[0], sizeof(data)); + + return ((int32_t)data[1] << 24) | ((int32_t) data[2] << 16) | ((int32_t) data[3] << 8) | ((int32_t) data[4]); +} + +void writeRegisterSPI(uint16_t icID, uint8_t address, int32_t value) +{ + uint8_t data[5] = { 0 }; + + data[0] = address | TMC2130_WRITE_BIT; + data[1] = 0xFF & (value>>24); + data[2] = 0xFF & (value>>16); + data[3] = 0xFF & (value>>8); + data[4] = 0xFF & (value>>0); + + // Send the write request + tmc2130_readWriteSPI(icID, &data[0], sizeof(data)); + //Cache the registers with write-only access + tmc2130_cache(icID, TMC2130_CACHE_WRITE, address, (uint32_t *)&value); +} +/***************************************************************************************************************************************************************/ diff --git a/firmware/lib/tmc/ic/TMC2130/TMC2130.h b/firmware/lib/tmc/ic/TMC2130/TMC2130.h new file mode 100755 index 0000000..4a31f1d --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2130/TMC2130.h @@ -0,0 +1,222 @@ +/******************************************************************************* +* Copyright © 2017 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#ifndef TMC_IC_TMC2130_H_ +#define TMC_IC_TMC2130_H_ + +#include +#include +#include +#include "TMC2130_HW_Abstraction.h" + + + /******************************************************************************* + * API Configuration Defines + * These control optional features of the TMC-API implementation. + * These can be commented in/out here or defined from the build system. + *******************************************************************************/ + + // To enable the cache mechanism in order to keep the copy of all registers, set TMC2130_CACHE to '1'. + // With this mechanism the value of write-only registers could be read from their shadow copies. + #ifndef TMC2130_CACHE + #define TMC2130_CACHE 1 + //#define TMC2130_CACHE 0 + #endif + + // To use the caching mechanism already implemented by the TMC-API, set TMC2130_ENABLE_TMC_CACHE to '1'. + // Set TMC2130_ENABLE_TMC_CACHE to '0' if one wants to have their own cache implementation. + #ifndef TMC2130_ENABLE_TMC_CACHE + #define TMC2130_ENABLE_TMC_CACHE 1 + //#define TMC2130_ENABLE_TMC_CACHE 0 + #endif + + /******************************************************************************/ + + +#define DEFAULT_MOTOR 0 + +typedef enum { + IC_BUS_SPI, +} TMC2130BusType; + +// => TMC-API wrapper +extern void tmc2130_readWriteSPI(uint16_t icID, uint8_t *data, size_t dataLength); +// => TMC-API wrapper + +int32_t tmc2130_readRegister(uint16_t icID, uint8_t address); +void tmc2130_writeRegister(uint16_t icID, uint8_t address, int32_t value); + +typedef struct +{ + uint32_t mask; + uint8_t shift; + uint8_t address; + bool isSigned; +} TMC2130RegisterField; + +static inline uint32_t tmc2130_fieldExtract(uint32_t data, TMC2130RegisterField field) +{ + uint32_t value = (data & field.mask) >> field.shift; + + if (field.isSigned) + { + // Apply signedness conversion + uint32_t baseMask = field.mask >> field.shift; + uint32_t signMask = baseMask & (~baseMask >> 1); + value = (value ^ signMask) - signMask; + } + + return value; +} + +static inline uint32_t tmc2130_fieldRead(uint16_t icID, TMC2130RegisterField field) +{ + uint32_t value = tmc2130_readRegister(icID, field.address); + + return tmc2130_fieldExtract(value, field); +} + +static inline uint32_t tmc2130_fieldUpdate(uint32_t data, TMC2130RegisterField field, uint32_t value) +{ + return (data & (~field.mask)) | ((value << field.shift) & field.mask); +} + +static inline void tmc2130_fieldWrite(uint16_t icID, TMC2130RegisterField field, uint32_t value) +{ + uint32_t regValue = tmc2130_readRegister(icID, field.address); + + regValue = tmc2130_fieldUpdate(regValue, field, value); + + tmc2130_writeRegister(icID, field.address, regValue); +} + +/***************** The following code is TMC-EvalSystem specific and needs to be commented out when working with other MCUs e.g Arduino*****************************/ + + +/**************************************************************** Cache Implementation *************************************************************************/ +#if TMC2130_CACHE == 1 +#ifdef TMC2130_ENABLE_TMC_CACHE + +// By default, support one IC in the cache +#ifndef TMC2130_IC_CACHE_COUNT +#define TMC2130_IC_CACHE_COUNT 1 +#endif + +typedef enum { + TMC2130_CACHE_READ, + TMC2130_CACHE_WRITE, + // Special operation: Put content into the cache without marking the entry as dirty. + // Only used to initialize the cache with hardware defaults. This will allow reading + // from write-only registers that have a value inside them on reset. When using this + // operation, a restore will *not* rewrite that filled register! + TMC2130_CACHE_FILL_DEFAULT, +} TMC2130CacheOp; + +typedef struct{ + uint8_t address; + uint32_t value; +} TMC2130RegisterConstants; + + +// Default Register values +#define R10 0x00071703 // IHOLD_IRUN +#define R6C 0x000101D5 // CHOPCONF + + #define TMC2130_ACCESS_DIRTY 0x08 // Register has been written since reset -> shadow register is valid for restore + #define TMC2130_ACCESS_READ 0x01 + #define TMC2130_ACCESS_W_PRESET 0x42 + #define TMC2130_IS_READABLE(x) ((x) & TMC2130_ACCESS_READ) + #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) + +// Helper define: +// Most register permission arrays are initialized with 128 values. +// In those fields its quite hard to have an easy overview of available +// registers. For that, ____ is defined to 0, since 4 underscores are +// very easy to distinguish from the 2-digit hexadecimal values. +// This way, the used registers (permission != ACCESS_NONE) are easily spotted +// amongst unused (permission == ACCESS_NONE) registers. +#define ____ 0x00 + +// Helper define: +// Default reset values are not used if the corresponding register has a +// hardware preset. Since this is not directly visible in the default +// register reset values array, N_A is used as an indicator for a preset +// value, where any value will be ignored anyways (N_A: not available). +#define N_A 0 + +// Register access permissions: +// 0x00: none (reserved) +// 0x01: read +// 0x02: write +// 0x03: read/write +// 0x21: read, flag register (read to clear) +// 0x42: write, has hardware presets on reset +static const uint8_t tmc2130_registerAccess[TMC2130_REGISTER_COUNT] = +{ +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0x03, 0x21, ____, ____, 0x01, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x00 - 0x0F + 0x02, 0x02, 0x01, 0x02, 0x02, 0x02, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x10 - 0x1F + ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, 0x03, ____, ____, // 0x20 - 0x2F + ____, ____, ____, 0x02, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x30 - 0x3F + ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x40 - 0x4F + ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x50 - 0x5F + 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x01, 0x01, 0x03, 0x02, 0x02, 0x01, // 0x60 - 0x6F + 0x42, 0x01, 0x02, 0x01, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____ // 0x70 - 0x7F +}; + +static const int32_t tmc2130_sampleRegisterPreset[TMC2130_REGISTER_COUNT] = +{ +// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x00 - 0x0F + R10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x10 - 0x1F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x20 - 0x2F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x30 - 0x3F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x40 - 0x4F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x50 - 0x5F + N_A, N_A, N_A, N_A, N_A, N_A, N_A, N_A, N_A, N_A, 0, 0, R6C, 0, 0, 0, // 0x60 - 0x6F + N_A, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x70 - 0x7F +}; + +// Undefine the default register values. +// This prevents warnings in case multiple TMC-API chip headers are included at once +#undef R10 +#undef R6C + + +// Register constants (only required for 0x42 registers, since we do not have +// any way to find out the content but want to hold the actual value in the +// shadow register so an application (i.e. the TMCL IDE) can still display +// the values. This only works when the register content is constant. +static const TMC2130RegisterConstants tmc2130_RegisterConstants[] = +{ // Use ascending addresses! + { 0x60, 0xAAAAB554 }, // MSLUT[0] + { 0x61, 0x4A9554AA }, // MSLUT[1] + { 0x62, 0x24492929 }, // MSLUT[2] + { 0x63, 0x10104222 }, // MSLUT[3] + { 0x64, 0xFBFFFFFF }, // MSLUT[4] + { 0x65, 0xB5BB777D }, // MSLUT[5] + { 0x66, 0x49295556 }, // MSLUT[6] + { 0x67, 0x00404222 }, // MSLUT[7] + { 0x68, 0xFFFF8056 }, // MSLUTSEL + { 0x69, 0x00F70000 }, // MSLUTSTART + { 0x70, 0x00050480 } // PWMCONF +}; + +#undef R10 +#undef R6C + +extern uint8_t tmc2130_dirtyBits[TMC2130_IC_CACHE_COUNT][TMC2130_REGISTER_COUNT/8]; +extern int32_t tmc2130_shadowRegister[TMC2130_IC_CACHE_COUNT][TMC2130_REGISTER_COUNT]; +extern bool tmc2130_cache(uint16_t icID, TMC2130CacheOp operation, uint8_t address, uint32_t *value); +extern void tmc2130_initCache(void); +void tmc2130_setDirtyBit(uint16_t icID, uint8_t index, bool value); +bool tmc2130_getDirtyBit(uint16_t icID, uint8_t index); +#endif +#endif +#endif /* TMC_IC_TMC2130_H_ */ diff --git a/firmware/lib/tmc/ic/TMC2130/TMC2130_HW_Abstraction.h b/firmware/lib/tmc/ic/TMC2130/TMC2130_HW_Abstraction.h new file mode 100755 index 0000000..1c4dbab --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2130/TMC2130_HW_Abstraction.h @@ -0,0 +1,1134 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + +#ifndef TMC2130_HW_ABSTRACTION +#define TMC2130_HW_ABSTRACTION + + +// Constants + +#define TMC2130_REGISTER_COUNT 128 // Default register count +#define TMC2130_MOTORS 1 +#define TMC2130_WRITE_BIT 0x80 +#define TMC2130_ADDRESS_MASK 0x7F +#define TMC2130_MAX_VELOCITY (int32_t) 2147483647 +#define TMC2130_MAX_ACCELERATION (uint32_t) 16777215uL + + +// Registers + +#define TMC2130_GCONF 0x00 +#define TMC2130_GSTAT 0x01 +#define TMC2130_IOIN 0x04 + +#define TMC2130_IHOLD_IRUN 0x10 +#define TMC2130_TPOWERDOWN 0x11 +#define TMC2130_TSTEP 0x12 +#define TMC2130_TPWMTHRS 0x13 +#define TMC2130_TCOOLTHRS 0x14 +#define TMC2130_THIGH 0x15 + +#define TMC2130_XDIRECT 0x2D + +#define TMC2130_VDCMIN 0x33 + +#define TMC2130_MSLUT0 0x60 +#define TMC2130_MSLUT1 0x61 +#define TMC2130_MSLUT2 0x62 +#define TMC2130_MSLUT3 0x63 +#define TMC2130_MSLUT4 0x64 +#define TMC2130_MSLUT5 0x65 +#define TMC2130_MSLUT6 0x66 +#define TMC2130_MSLUT7 0x67 +#define TMC2130_MSLUTSEL 0x68 +#define TMC2130_MSLUTSTART 0x69 +#define TMC2130_MSCNT 0x6A +#define TMC2130_MSCURACT 0x6B + +#define TMC2130_CHOPCONF 0x6C +#define TMC2130_COOLCONF 0x6D +#define TMC2130_DCCTRL 0x6E +#define TMC2130_DRV_STATUS 0x6F +#define TMC2130_PWMCONF 0x70 +#define TMC2130_PWM_SCALE 0x71 +#define TMC2130_ENCM_CTRL 0x72 +#define TMC2130_LOST_STEPS 0x73 + +//2. definition +#define TMC2130_MSLUT__ 0x60 + + +// Register fields + +#define TMC2130_I_SCALE_ANALOG_MASK 0x00000001 +#define TMC2130_I_SCALE_ANALOG_SHIFT 0 +#define TMC2130_I_SCALE_ANALOG_FIELD ((TMC2130RegisterField) {TMC2130_I_SCALE_ANALOG_MASK, TMC2130_I_SCALE_ANALOG_SHIFT, TMC2130_GCONF, false}) +#define TMC2130_INTERNAL_RSENSE_MASK 0x00000002 +#define TMC2130_INTERNAL_RSENSE_SHIFT 1 +#define TMC2130_INTERNAL_RSENSE_FIELD ((TMC2130RegisterField) {TMC2130_INTERNAL_RSENSE_MASK, TMC2130_INTERNAL_RSENSE_SHIFT, TMC2130_GCONF, false}) +#define TMC2130_EN_PWM_MODE_MASK 0x00000004 +#define TMC2130_EN_PWM_MODE_SHIFT 2 +#define TMC2130_EN_PWM_MODE_FIELD ((TMC2130RegisterField) {TMC2130_EN_PWM_MODE_MASK, TMC2130_EN_PWM_MODE_SHIFT, TMC2130_GCONF, false}) +#define TMC2130_ENC_COMMUTATION_MASK 0x00000008 +#define TMC2130_ENC_COMMUTATION_SHIFT 3 +#define TMC2130_ENC_COMMUTATION_FIELD ((TMC2130RegisterField) {TMC2130_ENC_COMMUTATION_MASK, TMC2130_ENC_COMMUTATION_SHIFT, TMC2130_GCONF, false}) +#define TMC2130_SHAFT_MASK 0x00000010 +#define TMC2130_SHAFT_SHIFT 4 +#define TMC2130_SHAFT_FIELD ((TMC2130RegisterField) {TMC2130_SHAFT_MASK, TMC2130_SHAFT_SHIFT, TMC2130_GCONF, false}) +#define TMC2130_DIAG0_ERROR_MASK 0x00000020 +#define TMC2130_DIAG0_ERROR_SHIFT 5 +#define TMC2130_DIAG0_ERROR_FIELD ((TMC2130RegisterField) {TMC2130_DIAG0_ERROR_MASK, TMC2130_DIAG0_ERROR_SHIFT, TMC2130_GCONF, false}) +#define TMC2130_DIAG0_OTPW_MASK 0x00000040 +#define TMC2130_DIAG0_OTPW_SHIFT 6 +#define TMC2130_DIAG0_OTPW_FIELD ((TMC2130RegisterField) {TMC2130_DIAG0_OTPW_MASK, TMC2130_DIAG0_OTPW_SHIFT, TMC2130_GCONF, false}) +#define TMC2130_DIAG0_STALL_MASK 0x00000080 +#define TMC2130_DIAG0_STALL_SHIFT 7 +#define TMC2130_DIAG0_STALL_FIELD ((TMC2130RegisterField) {TMC2130_DIAG0_STALL_MASK, TMC2130_DIAG0_STALL_SHIFT, TMC2130_GCONF, false}) +#define TMC2130_DIAG1_STALL_MASK 0x00000100 +#define TMC2130_DIAG1_STALL_SHIFT 8 +#define TMC2130_DIAG1_STALL_FIELD ((TMC2130RegisterField) {TMC2130_DIAG1_STALL_MASK, TMC2130_DIAG1_STALL_SHIFT, TMC2130_GCONF, false}) +#define TMC2130_DIAG1_INDEX_MASK 0x00000200 +#define TMC2130_DIAG1_INDEX_SHIFT 9 +#define TMC2130_DIAG1_INDEX_FIELD ((TMC2130RegisterField) {TMC2130_DIAG1_INDEX_MASK, TMC2130_DIAG1_INDEX_SHIFT, TMC2130_GCONF, false}) +#define TMC2130_DIAG1_ONSTATE_MASK 0x00000400 +#define TMC2130_DIAG1_ONSTATE_SHIFT 10 +#define TMC2130_DIAG1_ONSTATE_FIELD ((TMC2130RegisterField) {TMC2130_DIAG1_ONSTATE_MASK, TMC2130_DIAG1_ONSTATE_SHIFT, TMC2130_GCONF, false}) +#define TMC2130_DIAG1_STEPS_SKIPPED_MASK 0x00000800 +#define TMC2130_DIAG1_STEPS_SKIPPED_SHIFT 11 +#define TMC2130_DIAG1_STEPS_SKIPPED_FIELD ((TMC2130RegisterField) {TMC2130_DIAG1_STEPS_SKIPPED_MASK, TMC2130_DIAG1_STEPS_SKIPPED_SHIFT, TMC2130_GCONF, false}) +#define TMC2130_DIAG0_INT_PUSHPULL_MASK 0x00001000 +#define TMC2130_DIAG0_INT_PUSHPULL_SHIFT 12 +#define TMC2130_DIAG0_INT_PUSHPULL_FIELD ((TMC2130RegisterField) {TMC2130_DIAG0_INT_PUSHPULL_MASK, TMC2130_DIAG0_INT_PUSHPULL_SHIFT, TMC2130_GCONF, false}) +#define TMC2130_DIAG1_POSCOMP_PUSHPULL_MASK 0x00002000 +#define TMC2130_DIAG1_POSCOMP_PUSHPULL_SHIFT 13 +#define TMC2130_DIAG1_POSCOMP_PUSHPULL_FIELD ((TMC2130RegisterField) {TMC2130_DIAG1_POSCOMP_PUSHPULL_MASK, TMC2130_DIAG1_POSCOMP_PUSHPULL_SHIFT, TMC2130_GCONF, false}) +#define TMC2130_SMALL_HYSTERESIS_MASK 0x00004000 +#define TMC2130_SMALL_HYSTERESIS_SHIFT 14 +#define TMC2130_SMALL_HYSTERESIS_FIELD ((TMC2130RegisterField) {TMC2130_SMALL_HYSTERESIS_MASK, TMC2130_SMALL_HYSTERESIS_SHIFT, TMC2130_GCONF, false}) +#define TMC2130_STOP_ENABLE_MASK 0x00008000 +#define TMC2130_STOP_ENABLE_SHIFT 15 +#define TMC2130_STOP_ENABLE_FIELD ((TMC2130RegisterField) {TMC2130_STOP_ENABLE_MASK, TMC2130_STOP_ENABLE_SHIFT, TMC2130_GCONF, false}) +#define TMC2130_DIRECT_MODE_MASK 0x00010000 +#define TMC2130_DIRECT_MODE_SHIFT 16 +#define TMC2130_DIRECT_MODE_FIELD ((TMC2130RegisterField) {TMC2130_DIRECT_MODE_MASK, TMC2130_DIRECT_MODE_SHIFT, TMC2130_GCONF, false}) +#define TMC2130_TEST_MODE_MASK 0x00020000 +#define TMC2130_TEST_MODE_SHIFT 17 +#define TMC2130_TEST_MODE_FIELD ((TMC2130RegisterField) {TMC2130_TEST_MODE_MASK, TMC2130_TEST_MODE_SHIFT, TMC2130_GCONF, false}) +#define TMC2130_RESET_MASK 0x00000001 +#define TMC2130_RESET_SHIFT 0 +#define TMC2130_RESET_FIELD ((TMC2130RegisterField) {TMC2130_RESET_MASK, TMC2130_RESET_SHIFT, TMC2130_GSTAT, false}) +#define TMC2130_DRV_ERR_MASK 0x00000002 +#define TMC2130_DRV_ERR_SHIFT 1 +#define TMC2130_DRV_ERR_FIELD ((TMC2130RegisterField) {TMC2130_DRV_ERR_MASK, TMC2130_DRV_ERR_SHIFT, TMC2130_GSTAT, false}) +#define TMC2130_UV_CP_MASK 0x00000004 +#define TMC2130_UV_CP_SHIFT 2 +#define TMC2130_UV_CP_FIELD ((TMC2130RegisterField) {TMC2130_UV_CP_MASK, TMC2130_UV_CP_SHIFT, TMC2130_GSTAT, false}) +#define TMC2130_REFL_STEP_MASK 0x00000001 +#define TMC2130_REFL_STEP_SHIFT 0 +#define TMC2130_REFL_STEP_FIELD ((TMC2130RegisterField) {TMC2130_REFL_STEP_MASK, TMC2130_REFL_STEP_SHIFT, TMC2130_IOIN, false}) +#define TMC2130_REFR_DIR_MASK 0x00000002 +#define TMC2130_REFR_DIR_SHIFT 1 +#define TMC2130_REFR_DIR_FIELD ((TMC2130RegisterField) {TMC2130_REFR_DIR_MASK, TMC2130_REFR_DIR_SHIFT, TMC2130_IOIN, false}) +#define TMC2130_ENCB_DCEN_CFG4_MASK 0x00000004 +#define TMC2130_ENCB_DCEN_CFG4_SHIFT 2 +#define TMC2130_ENCB_DCEN_CFG4_FIELD ((TMC2130RegisterField) {TMC2130_ENCB_DCEN_CFG4_MASK, TMC2130_ENCB_DCEN_CFG4_SHIFT, TMC2130_IOIN, false}) +#define TMC2130_ENCA_DCIN_CFG5_MASK 0x00000008 +#define TMC2130_ENCA_DCIN_CFG5_SHIFT 3 +#define TMC2130_ENCA_DCIN_CFG5_FIELD ((TMC2130RegisterField) {TMC2130_ENCA_DCIN_CFG5_MASK, TMC2130_ENCA_DCIN_CFG5_SHIFT, TMC2130_IOIN, false}) +#define TMC2130_DRV_ENN_CFG6_MASK 0x00000010 +#define TMC2130_DRV_ENN_CFG6_SHIFT 4 +#define TMC2130_DRV_ENN_CFG6_FIELD ((TMC2130RegisterField) {TMC2130_DRV_ENN_CFG6_MASK, TMC2130_DRV_ENN_CFG6_SHIFT, TMC2130_IOIN, false}) +#define TMC2130_ENC_N_DCO_MASK 0x00000020 +#define TMC2130_ENC_N_DCO_SHIFT 5 +#define TMC2130_ENC_N_DCO_FIELD ((TMC2130RegisterField) {TMC2130_ENC_N_DCO_MASK, TMC2130_ENC_N_DCO_SHIFT, TMC2130_IOIN, false}) +#define TMC2130_VERSION_MASK 0xFF000000 +#define TMC2130_VERSION_SHIFT 24 +#define TMC2130_VERSION_FIELD ((TMC2130RegisterField) {TMC2130_VERSION_MASK, TMC2130_VERSION_SHIFT, TMC2130_IOIN, false}) +#define TMC2130_IHOLD_MASK 0x0000001F +#define TMC2130_IHOLD_SHIFT 0 +#define TMC2130_IHOLD_FIELD ((TMC2130RegisterField) {TMC2130_IHOLD_MASK, TMC2130_IHOLD_SHIFT, TMC2130_IHOLD_IRUN, false}) +#define TMC2130_IRUN_MASK 0x00001F00 +#define TMC2130_IRUN_SHIFT 8 +#define TMC2130_IRUN_FIELD ((TMC2130RegisterField) {TMC2130_IRUN_MASK, TMC2130_IRUN_SHIFT, TMC2130_IHOLD_IRUN, false}) +#define TMC2130_IHOLDDELAY_MASK 0x000F0000 +#define TMC2130_IHOLDDELAY_SHIFT 16 +#define TMC2130_IHOLDDELAY_FIELD ((TMC2130RegisterField) {TMC2130_IHOLDDELAY_MASK, TMC2130_IHOLDDELAY_SHIFT, TMC2130_IHOLD_IRUN, false}) +#define TMC2130_TPOWERDOWN_MASK 0x000000FF +#define TMC2130_TPOWERDOWN_SHIFT 0 +#define TMC2130_TPOWERDOWN_FIELD ((TMC2130RegisterField) {TMC2130_TPOWERDOWN_MASK, TMC2130_TPOWERDOWN_SHIFT, TMC2130_TPOWERDOWN, false}) +#define TMC2130_TSTEP_MASK 0x000FFFFF +#define TMC2130_TSTEP_SHIFT 0 +#define TMC2130_TSTEP_FIELD ((TMC2130RegisterField) {TMC2130_TSTEP_MASK, TMC2130_TSTEP_SHIFT, TMC2130_TSTEP, false}) +#define TMC2130_TPWMTHRS_MASK 0x000FFFFF +#define TMC2130_TPWMTHRS_SHIFT 0 +#define TMC2130_TPWMTHRS_FIELD ((TMC2130RegisterField) {TMC2130_TPWMTHRS_MASK, TMC2130_TPWMTHRS_SHIFT, TMC2130_TPWMTHRS, false}) +#define TMC2130_TCOOLTHRS_MASK 0x000FFFFF +#define TMC2130_TCOOLTHRS_SHIFT 0 +#define TMC2130_TCOOLTHRS_FIELD ((TMC2130RegisterField) {TMC2130_TCOOLTHRS_MASK, TMC2130_TCOOLTHRS_SHIFT, TMC2130_TCOOLTHRS, false}) +#define TMC2130_THIGH_MASK 0x000FFFFF +#define TMC2130_THIGH_SHIFT 0 +#define TMC2130_THIGH_FIELD ((TMC2130RegisterField) {TMC2130_THIGH_MASK, TMC2130_THIGH_SHIFT, TMC2130_THIGH, false}) +#define TMC2130_DIRECT_CURRENT_A_MASK 0x000001FF +#define TMC2130_DIRECT_CURRENT_A_SHIFT 0 +#define TMC2130_DIRECT_CURRENT_A_FIELD ((TMC2130RegisterField) {TMC2130_DIRECT_CURRENT_A_MASK, TMC2130_DIRECT_CURRENT_A_SHIFT, TMC2130_XDIRECT, true}) +#define TMC2130_DIRECT_CURRENT_B_MASK 0x01FF0000 +#define TMC2130_DIRECT_CURRENT_B_SHIFT 16 +#define TMC2130_DIRECT_CURRENT_B_FIELD ((TMC2130RegisterField) {TMC2130_DIRECT_CURRENT_B_MASK, TMC2130_DIRECT_CURRENT_B_SHIFT, TMC2130_XDIRECT, true}) +#define TMC2130_VDCMIN_MASK 0x07FFFFFF +#define TMC2130_VDCMIN_SHIFT 0 +#define TMC2130_VDCMIN_FIELD ((TMC2130RegisterField) {TMC2130_VDCMIN_MASK, TMC2130_VDCMIN_SHIFT, TMC2130_VDCMIN, false}) +#define TMC2130_OFS0_MASK 0x00000001 +#define TMC2130_OFS0_SHIFT 0 +#define TMC2130_OFS0_FIELD ((TMC2130RegisterField) {TMC2130_OFS0_MASK, TMC2130_OFS0_SHIFT, TMC2130_MSLUT[0], false}) +#define TMC2130_OFS1_MASK 0x00000002 +#define TMC2130_OFS1_SHIFT 1 +#define TMC2130_OFS1_FIELD ((TMC2130RegisterField) {TMC2130_OFS1_MASK, TMC2130_OFS1_SHIFT, TMC2130_MSLUT[0], false}) +#define TMC2130_OFS2_MASK 0x00000004 +#define TMC2130_OFS2_SHIFT 2 +#define TMC2130_OFS2_FIELD ((TMC2130RegisterField) {TMC2130_OFS2_MASK, TMC2130_OFS2_SHIFT, TMC2130_MSLUT[0], false}) +#define TMC2130_OFS3_MASK 0x00000008 +#define TMC2130_OFS3_SHIFT 3 +#define TMC2130_OFS3_FIELD ((TMC2130RegisterField) {TMC2130_OFS3_MASK, TMC2130_OFS3_SHIFT, TMC2130_MSLUT[0], false}) +#define TMC2130_OFS4_MASK 0x00000010 +#define TMC2130_OFS4_SHIFT 4 +#define TMC2130_OFS4_FIELD ((TMC2130RegisterField) {TMC2130_OFS4_MASK, TMC2130_OFS4_SHIFT, TMC2130_MSLUT[0], false}) +#define TMC2130_OFS5_MASK 0x00000020 +#define TMC2130_OFS5_SHIFT 5 +#define TMC2130_OFS5_FIELD ((TMC2130RegisterField) {TMC2130_OFS5_MASK, TMC2130_OFS5_SHIFT, TMC2130_MSLUT[0], false}) +#define TMC2130_OFS6_MASK 0x00000040 +#define TMC2130_OFS6_SHIFT 6 +#define TMC2130_OFS6_FIELD ((TMC2130RegisterField) {TMC2130_OFS6_MASK, TMC2130_OFS6_SHIFT, TMC2130_MSLUT[0], false}) +#define TMC2130_OFS7_MASK 0x00000080 +#define TMC2130_OFS7_SHIFT 7 +#define TMC2130_OFS7_FIELD ((TMC2130RegisterField) {TMC2130_OFS7_MASK, TMC2130_OFS7_SHIFT, TMC2130_MSLUT[0], false}) +#define TMC2130_OFS8_MASK 0x00000100 +#define TMC2130_OFS8_SHIFT 8 +#define TMC2130_OFS8_FIELD ((TMC2130RegisterField) {TMC2130_OFS8_MASK, TMC2130_OFS8_SHIFT, TMC2130_MSLUT[0], false}) +#define TMC2130_OFS9_MASK 0x00000200 +#define TMC2130_OFS9_SHIFT 9 +#define TMC2130_OFS9_FIELD ((TMC2130RegisterField) {TMC2130_OFS9_MASK, TMC2130_OFS9_SHIFT, TMC2130_MSLUT[0], false}) +#define TMC2130_OFS10_MASK 0x00000400 +#define TMC2130_OFS10_SHIFT 10 +#define TMC2130_OFS10_FIELD ((TMC2130RegisterField) {TMC2130_OFS10_MASK, TMC2130_OFS10_SHIFT, TMC2130_MSLUT[0], false}) +#define TMC2130_OFS11_MASK 0x00000800 +#define TMC2130_OFS11_SHIFT 11 +#define TMC2130_OFS11_FIELD ((TMC2130RegisterField) {TMC2130_OFS11_MASK, TMC2130_OFS11_SHIFT, TMC2130_MSLUT[0], false}) +#define TMC2130_OFS12_MASK 0x00001000 +#define TMC2130_OFS12_SHIFT 12 +#define TMC2130_OFS12_FIELD ((TMC2130RegisterField) {TMC2130_OFS12_MASK, TMC2130_OFS12_SHIFT, TMC2130_MSLUT[0], false}) +#define TMC2130_OFS13_MASK 0x00002000 +#define TMC2130_OFS13_SHIFT 13 +#define TMC2130_OFS13_FIELD ((TMC2130RegisterField) {TMC2130_OFS13_MASK, TMC2130_OFS13_SHIFT, TMC2130_MSLUT[0], false}) +#define TMC2130_OFS14_MASK 0x00004000 +#define TMC2130_OFS14_SHIFT 14 +#define TMC2130_OFS14_FIELD ((TMC2130RegisterField) {TMC2130_OFS14_MASK, TMC2130_OFS14_SHIFT, TMC2130_MSLUT[0], false}) +#define TMC2130_OFS15_MASK 0x00008000 +#define TMC2130_OFS15_SHIFT 15 +#define TMC2130_OFS15_FIELD ((TMC2130RegisterField) {TMC2130_OFS15_MASK, TMC2130_OFS15_SHIFT, TMC2130_MSLUT[0], false}) +#define TMC2130_OFS16_MASK 0x00010000 +#define TMC2130_OFS16_SHIFT 16 +#define TMC2130_OFS16_FIELD ((TMC2130RegisterField) {TMC2130_OFS16_MASK, TMC2130_OFS16_SHIFT, TMC2130_MSLUT[0], false}) +#define TMC2130_OFS17_MASK 0x00020000 +#define TMC2130_OFS17_SHIFT 17 +#define TMC2130_OFS17_FIELD ((TMC2130RegisterField) {TMC2130_OFS17_MASK, TMC2130_OFS17_SHIFT, TMC2130_MSLUT[0], false}) +#define TMC2130_OFS18_MASK 0x00040000 +#define TMC2130_OFS18_SHIFT 18 +#define TMC2130_OFS18_FIELD ((TMC2130RegisterField) {TMC2130_OFS18_MASK, TMC2130_OFS18_SHIFT, TMC2130_MSLUT[0], false}) +#define TMC2130_OFS19_MASK 0x00080000 +#define TMC2130_OFS19_SHIFT 19 +#define TMC2130_OFS19_FIELD ((TMC2130RegisterField) {TMC2130_OFS19_MASK, TMC2130_OFS19_SHIFT, TMC2130_MSLUT[0], false}) +#define TMC2130_OFS20_MASK 0x00100000 +#define TMC2130_OFS20_SHIFT 20 +#define TMC2130_OFS20_FIELD ((TMC2130RegisterField) {TMC2130_OFS20_MASK, TMC2130_OFS20_SHIFT, TMC2130_MSLUT[0], false}) +#define TMC2130_OFS21_MASK 0x00200000 +#define TMC2130_OFS21_SHIFT 21 +#define TMC2130_OFS21_FIELD ((TMC2130RegisterField) {TMC2130_OFS21_MASK, TMC2130_OFS21_SHIFT, TMC2130_MSLUT[0], false}) +#define TMC2130_OFS22_MASK 0x00400000 +#define TMC2130_OFS22_SHIFT 22 +#define TMC2130_OFS22_FIELD ((TMC2130RegisterField) {TMC2130_OFS22_MASK, TMC2130_OFS22_SHIFT, TMC2130_MSLUT[0], false}) +#define TMC2130_OFS23_MASK 0x00800000 +#define TMC2130_OFS23_SHIFT 23 +#define TMC2130_OFS23_FIELD ((TMC2130RegisterField) {TMC2130_OFS23_MASK, TMC2130_OFS23_SHIFT, TMC2130_MSLUT[0], false}) +#define TMC2130_OFS24_MASK 0x01000000 +#define TMC2130_OFS24_SHIFT 24 +#define TMC2130_OFS24_FIELD ((TMC2130RegisterField) {TMC2130_OFS24_MASK, TMC2130_OFS24_SHIFT, TMC2130_MSLUT[0], false}) +#define TMC2130_OFS25_MASK 0x02000000 +#define TMC2130_OFS25_SHIFT 25 +#define TMC2130_OFS25_FIELD ((TMC2130RegisterField) {TMC2130_OFS25_MASK, TMC2130_OFS25_SHIFT, TMC2130_MSLUT[0], false}) +#define TMC2130_OFS26_MASK 0x04000000 +#define TMC2130_OFS26_SHIFT 26 +#define TMC2130_OFS26_FIELD ((TMC2130RegisterField) {TMC2130_OFS26_MASK, TMC2130_OFS26_SHIFT, TMC2130_MSLUT[0], false}) +#define TMC2130_OFS27_MASK 0x08000000 +#define TMC2130_OFS27_SHIFT 27 +#define TMC2130_OFS27_FIELD ((TMC2130RegisterField) {TMC2130_OFS27_MASK, TMC2130_OFS27_SHIFT, TMC2130_MSLUT[0], false}) +#define TMC2130_OFS28_MASK 0x10000000 +#define TMC2130_OFS28_SHIFT 28 +#define TMC2130_OFS28_FIELD ((TMC2130RegisterField) {TMC2130_OFS28_MASK, TMC2130_OFS28_SHIFT, TMC2130_MSLUT[0], false}) +#define TMC2130_OFS29_MASK 0x20000000 +#define TMC2130_OFS29_SHIFT 29 +#define TMC2130_OFS29_FIELD ((TMC2130RegisterField) {TMC2130_OFS29_MASK, TMC2130_OFS29_SHIFT, TMC2130_MSLUT[0], false}) +#define TMC2130_OFS30_MASK 0x40000000 +#define TMC2130_OFS30_SHIFT 30 +#define TMC2130_OFS30_FIELD ((TMC2130RegisterField) {TMC2130_OFS30_MASK, TMC2130_OFS30_SHIFT, TMC2130_MSLUT[0], false}) +#define TMC2130_OFS31_MASK 0x80000000 +#define TMC2130_OFS31_SHIFT 31 +#define TMC2130_OFS31_FIELD ((TMC2130RegisterField) {TMC2130_OFS31_MASK, TMC2130_OFS31_SHIFT, TMC2130_MSLUT[0], false}) +#define TMC2130_OFS32_MASK 0x00000001 +#define TMC2130_OFS32_SHIFT 0 +#define TMC2130_OFS32_FIELD ((TMC2130RegisterField) {TMC2130_OFS32_MASK, TMC2130_OFS32_SHIFT, TMC2130_MSLUT[1], false}) +#define TMC2130_OFS33_MASK 0x00000002 +#define TMC2130_OFS33_SHIFT 1 +#define TMC2130_OFS33_FIELD ((TMC2130RegisterField) {TMC2130_OFS33_MASK, TMC2130_OFS33_SHIFT, TMC2130_MSLUT[1], false}) +#define TMC2130_OFS34_MASK 0x00000004 +#define TMC2130_OFS34_SHIFT 2 +#define TMC2130_OFS34_FIELD ((TMC2130RegisterField) {TMC2130_OFS34_MASK, TMC2130_OFS34_SHIFT, TMC2130_MSLUT[1], false}) +#define TMC2130_OFS35_MASK 0x00000008 +#define TMC2130_OFS35_SHIFT 3 +#define TMC2130_OFS35_FIELD ((TMC2130RegisterField) {TMC2130_OFS35_MASK, TMC2130_OFS35_SHIFT, TMC2130_MSLUT[1], false}) +#define TMC2130_OFS36_MASK 0x00000010 +#define TMC2130_OFS36_SHIFT 4 +#define TMC2130_OFS36_FIELD ((TMC2130RegisterField) {TMC2130_OFS36_MASK, TMC2130_OFS36_SHIFT, TMC2130_MSLUT[1], false}) +#define TMC2130_OFS37_MASK 0x00000020 +#define TMC2130_OFS37_SHIFT 5 +#define TMC2130_OFS37_FIELD ((TMC2130RegisterField) {TMC2130_OFS37_MASK, TMC2130_OFS37_SHIFT, TMC2130_MSLUT[1], false}) +#define TMC2130_OFS38_MASK 0x00000040 +#define TMC2130_OFS38_SHIFT 6 +#define TMC2130_OFS38_FIELD ((TMC2130RegisterField) {TMC2130_OFS38_MASK, TMC2130_OFS38_SHIFT, TMC2130_MSLUT[1], false}) +#define TMC2130_OFS39_MASK 0x00000080 +#define TMC2130_OFS39_SHIFT 7 +#define TMC2130_OFS39_FIELD ((TMC2130RegisterField) {TMC2130_OFS39_MASK, TMC2130_OFS39_SHIFT, TMC2130_MSLUT[1], false}) +#define TMC2130_OFS40_MASK 0x00000100 +#define TMC2130_OFS40_SHIFT 8 +#define TMC2130_OFS40_FIELD ((TMC2130RegisterField) {TMC2130_OFS40_MASK, TMC2130_OFS40_SHIFT, TMC2130_MSLUT[1], false}) +#define TMC2130_OFS41_MASK 0x00000200 +#define TMC2130_OFS41_SHIFT 9 +#define TMC2130_OFS41_FIELD ((TMC2130RegisterField) {TMC2130_OFS41_MASK, TMC2130_OFS41_SHIFT, TMC2130_MSLUT[1], false}) +#define TMC2130_OFS42_MASK 0x00000400 +#define TMC2130_OFS42_SHIFT 10 +#define TMC2130_OFS42_FIELD ((TMC2130RegisterField) {TMC2130_OFS42_MASK, TMC2130_OFS42_SHIFT, TMC2130_MSLUT[1], false}) +#define TMC2130_OFS43_MASK 0x00000800 +#define TMC2130_OFS43_SHIFT 11 +#define TMC2130_OFS43_FIELD ((TMC2130RegisterField) {TMC2130_OFS43_MASK, TMC2130_OFS43_SHIFT, TMC2130_MSLUT[1], false}) +#define TMC2130_OFS44_MASK 0x00001000 +#define TMC2130_OFS44_SHIFT 12 +#define TMC2130_OFS44_FIELD ((TMC2130RegisterField) {TMC2130_OFS44_MASK, TMC2130_OFS44_SHIFT, TMC2130_MSLUT[1], false}) +#define TMC2130_OFS45_MASK 0x00002000 +#define TMC2130_OFS45_SHIFT 13 +#define TMC2130_OFS45_FIELD ((TMC2130RegisterField) {TMC2130_OFS45_MASK, TMC2130_OFS45_SHIFT, TMC2130_MSLUT[1], false}) +#define TMC2130_OFS46_MASK 0x00004000 +#define TMC2130_OFS46_SHIFT 14 +#define TMC2130_OFS46_FIELD ((TMC2130RegisterField) {TMC2130_OFS46_MASK, TMC2130_OFS46_SHIFT, TMC2130_MSLUT[1], false}) +#define TMC2130_OFS47_MASK 0x00008000 +#define TMC2130_OFS47_SHIFT 15 +#define TMC2130_OFS47_FIELD ((TMC2130RegisterField) {TMC2130_OFS47_MASK, TMC2130_OFS47_SHIFT, TMC2130_MSLUT[1], false}) +#define TMC2130_OFS48_MASK 0x00010000 +#define TMC2130_OFS48_SHIFT 16 +#define TMC2130_OFS48_FIELD ((TMC2130RegisterField) {TMC2130_OFS48_MASK, TMC2130_OFS48_SHIFT, TMC2130_MSLUT[1], false}) +#define TMC2130_OFS49_MASK 0x00020000 +#define TMC2130_OFS49_SHIFT 17 +#define TMC2130_OFS49_FIELD ((TMC2130RegisterField) {TMC2130_OFS49_MASK, TMC2130_OFS49_SHIFT, TMC2130_MSLUT[1], false}) +#define TMC2130_OFS50_MASK 0x00040000 +#define TMC2130_OFS50_SHIFT 18 +#define TMC2130_OFS50_FIELD ((TMC2130RegisterField) {TMC2130_OFS50_MASK, TMC2130_OFS50_SHIFT, TMC2130_MSLUT[1], false}) +#define TMC2130_OFS51_MASK 0x00080000 +#define TMC2130_OFS51_SHIFT 19 +#define TMC2130_OFS51_FIELD ((TMC2130RegisterField) {TMC2130_OFS51_MASK, TMC2130_OFS51_SHIFT, TMC2130_MSLUT[1], false}) +#define TMC2130_OFS52_MASK 0x00100000 +#define TMC2130_OFS52_SHIFT 20 +#define TMC2130_OFS52_FIELD ((TMC2130RegisterField) {TMC2130_OFS52_MASK, TMC2130_OFS52_SHIFT, TMC2130_MSLUT[1], false}) +#define TMC2130_OFS53_MASK 0x00200000 +#define TMC2130_OFS53_SHIFT 21 +#define TMC2130_OFS53_FIELD ((TMC2130RegisterField) {TMC2130_OFS53_MASK, TMC2130_OFS53_SHIFT, TMC2130_MSLUT[1], false}) +#define TMC2130_OFS54_MASK 0x00400000 +#define TMC2130_OFS54_SHIFT 22 +#define TMC2130_OFS54_FIELD ((TMC2130RegisterField) {TMC2130_OFS54_MASK, TMC2130_OFS54_SHIFT, TMC2130_MSLUT[1], false}) +#define TMC2130_OFS55_MASK 0x00800000 +#define TMC2130_OFS55_SHIFT 23 +#define TMC2130_OFS55_FIELD ((TMC2130RegisterField) {TMC2130_OFS55_MASK, TMC2130_OFS55_SHIFT, TMC2130_MSLUT[1], false}) +#define TMC2130_OFS56_MASK 0x01000000 +#define TMC2130_OFS56_SHIFT 24 +#define TMC2130_OFS56_FIELD ((TMC2130RegisterField) {TMC2130_OFS56_MASK, TMC2130_OFS56_SHIFT, TMC2130_MSLUT[1], false}) +#define TMC2130_OFS57_MASK 0x02000000 +#define TMC2130_OFS57_SHIFT 25 +#define TMC2130_OFS57_FIELD ((TMC2130RegisterField) {TMC2130_OFS57_MASK, TMC2130_OFS57_SHIFT, TMC2130_MSLUT[1], false}) +#define TMC2130_OFS58_MASK 0x04000000 +#define TMC2130_OFS58_SHIFT 26 +#define TMC2130_OFS58_FIELD ((TMC2130RegisterField) {TMC2130_OFS58_MASK, TMC2130_OFS58_SHIFT, TMC2130_MSLUT[1], false}) +#define TMC2130_OFS59_MASK 0x08000000 +#define TMC2130_OFS59_SHIFT 27 +#define TMC2130_OFS59_FIELD ((TMC2130RegisterField) {TMC2130_OFS59_MASK, TMC2130_OFS59_SHIFT, TMC2130_MSLUT[1], false}) +#define TMC2130_OFS60_MASK 0x10000000 +#define TMC2130_OFS60_SHIFT 28 +#define TMC2130_OFS60_FIELD ((TMC2130RegisterField) {TMC2130_OFS60_MASK, TMC2130_OFS60_SHIFT, TMC2130_MSLUT[1], false}) +#define TMC2130_OFS61_MASK 0x20000000 +#define TMC2130_OFS61_SHIFT 29 +#define TMC2130_OFS61_FIELD ((TMC2130RegisterField) {TMC2130_OFS61_MASK, TMC2130_OFS61_SHIFT, TMC2130_MSLUT[1], false}) +#define TMC2130_OFS62_MASK 0x40000000 +#define TMC2130_OFS62_SHIFT 30 +#define TMC2130_OFS62_FIELD ((TMC2130RegisterField) {TMC2130_OFS62_MASK, TMC2130_OFS62_SHIFT, TMC2130_MSLUT[1], false}) +#define TMC2130_OFS63_MASK 0x80000000 +#define TMC2130_OFS63_SHIFT 31 +#define TMC2130_OFS63_FIELD ((TMC2130RegisterField) {TMC2130_OFS63_MASK, TMC2130_OFS63_SHIFT, TMC2130_MSLUT[1], false}) +#define TMC2130_OFS64_MASK 0x00000001 +#define TMC2130_OFS64_SHIFT 0 +#define TMC2130_OFS64_FIELD ((TMC2130RegisterField) {TMC2130_OFS64_MASK, TMC2130_OFS64_SHIFT, TMC2130_MSLUT[2], false}) +#define TMC2130_OFS65_MASK 0x00000002 +#define TMC2130_OFS65_SHIFT 1 +#define TMC2130_OFS65_FIELD ((TMC2130RegisterField) {TMC2130_OFS65_MASK, TMC2130_OFS65_SHIFT, TMC2130_MSLUT[2], false}) +#define TMC2130_OFS66_MASK 0x00000004 +#define TMC2130_OFS66_SHIFT 2 +#define TMC2130_OFS66_FIELD ((TMC2130RegisterField) {TMC2130_OFS66_MASK, TMC2130_OFS66_SHIFT, TMC2130_MSLUT[2], false}) +#define TMC2130_OFS67_MASK 0x00000008 +#define TMC2130_OFS67_SHIFT 3 +#define TMC2130_OFS67_FIELD ((TMC2130RegisterField) {TMC2130_OFS67_MASK, TMC2130_OFS67_SHIFT, TMC2130_MSLUT[2], false}) +#define TMC2130_OFS68_MASK 0x00000010 +#define TMC2130_OFS68_SHIFT 4 +#define TMC2130_OFS68_FIELD ((TMC2130RegisterField) {TMC2130_OFS68_MASK, TMC2130_OFS68_SHIFT, TMC2130_MSLUT[2], false}) +#define TMC2130_OFS69_MASK 0x00000020 +#define TMC2130_OFS69_SHIFT 5 +#define TMC2130_OFS69_FIELD ((TMC2130RegisterField) {TMC2130_OFS69_MASK, TMC2130_OFS69_SHIFT, TMC2130_MSLUT[2], false}) +#define TMC2130_OFS70_MASK 0x00000040 +#define TMC2130_OFS70_SHIFT 6 +#define TMC2130_OFS70_FIELD ((TMC2130RegisterField) {TMC2130_OFS70_MASK, TMC2130_OFS70_SHIFT, TMC2130_MSLUT[2], false}) +#define TMC2130_OFS71_MASK 0x00000080 +#define TMC2130_OFS71_SHIFT 7 +#define TMC2130_OFS71_FIELD ((TMC2130RegisterField) {TMC2130_OFS71_MASK, TMC2130_OFS71_SHIFT, TMC2130_MSLUT[2], false}) +#define TMC2130_OFS72_MASK 0x00000100 +#define TMC2130_OFS72_SHIFT 8 +#define TMC2130_OFS72_FIELD ((TMC2130RegisterField) {TMC2130_OFS72_MASK, TMC2130_OFS72_SHIFT, TMC2130_MSLUT[2], false}) +#define TMC2130_OFS73_MASK 0x00000200 +#define TMC2130_OFS73_SHIFT 9 +#define TMC2130_OFS73_FIELD ((TMC2130RegisterField) {TMC2130_OFS73_MASK, TMC2130_OFS73_SHIFT, TMC2130_MSLUT[2], false}) +#define TMC2130_OFS74_MASK 0x00000400 +#define TMC2130_OFS74_SHIFT 10 +#define TMC2130_OFS74_FIELD ((TMC2130RegisterField) {TMC2130_OFS74_MASK, TMC2130_OFS74_SHIFT, TMC2130_MSLUT[2], false}) +#define TMC2130_OFS75_MASK 0x00000800 +#define TMC2130_OFS75_SHIFT 11 +#define TMC2130_OFS75_FIELD ((TMC2130RegisterField) {TMC2130_OFS75_MASK, TMC2130_OFS75_SHIFT, TMC2130_MSLUT[2], false}) +#define TMC2130_OFS76_MASK 0x00001000 +#define TMC2130_OFS76_SHIFT 12 +#define TMC2130_OFS76_FIELD ((TMC2130RegisterField) {TMC2130_OFS76_MASK, TMC2130_OFS76_SHIFT, TMC2130_MSLUT[2], false}) +#define TMC2130_OFS77_MASK 0x00002000 +#define TMC2130_OFS77_SHIFT 13 +#define TMC2130_OFS77_FIELD ((TMC2130RegisterField) {TMC2130_OFS77_MASK, TMC2130_OFS77_SHIFT, TMC2130_MSLUT[2], false}) +#define TMC2130_OFS78_MASK 0x00004000 +#define TMC2130_OFS78_SHIFT 14 +#define TMC2130_OFS78_FIELD ((TMC2130RegisterField) {TMC2130_OFS78_MASK, TMC2130_OFS78_SHIFT, TMC2130_MSLUT[2], false}) +#define TMC2130_OFS79_MASK 0x00008000 +#define TMC2130_OFS79_SHIFT 15 +#define TMC2130_OFS79_FIELD ((TMC2130RegisterField) {TMC2130_OFS79_MASK, TMC2130_OFS79_SHIFT, TMC2130_MSLUT[2], false}) +#define TMC2130_OFS80_MASK 0x00010000 +#define TMC2130_OFS80_SHIFT 16 +#define TMC2130_OFS80_FIELD ((TMC2130RegisterField) {TMC2130_OFS80_MASK, TMC2130_OFS80_SHIFT, TMC2130_MSLUT[2], false}) +#define TMC2130_OFS81_MASK 0x00020000 +#define TMC2130_OFS81_SHIFT 17 +#define TMC2130_OFS81_FIELD ((TMC2130RegisterField) {TMC2130_OFS81_MASK, TMC2130_OFS81_SHIFT, TMC2130_MSLUT[2], false}) +#define TMC2130_OFS82_MASK 0x00040000 +#define TMC2130_OFS82_SHIFT 18 +#define TMC2130_OFS82_FIELD ((TMC2130RegisterField) {TMC2130_OFS82_MASK, TMC2130_OFS82_SHIFT, TMC2130_MSLUT[2], false}) +#define TMC2130_OFS83_MASK 0x00080000 +#define TMC2130_OFS83_SHIFT 19 +#define TMC2130_OFS83_FIELD ((TMC2130RegisterField) {TMC2130_OFS83_MASK, TMC2130_OFS83_SHIFT, TMC2130_MSLUT[2], false}) +#define TMC2130_OFS84_MASK 0x00100000 +#define TMC2130_OFS84_SHIFT 20 +#define TMC2130_OFS84_FIELD ((TMC2130RegisterField) {TMC2130_OFS84_MASK, TMC2130_OFS84_SHIFT, TMC2130_MSLUT[2], false}) +#define TMC2130_OFS85_MASK 0x00200000 +#define TMC2130_OFS85_SHIFT 21 +#define TMC2130_OFS85_FIELD ((TMC2130RegisterField) {TMC2130_OFS85_MASK, TMC2130_OFS85_SHIFT, TMC2130_MSLUT[2], false}) +#define TMC2130_OFS86_MASK 0x00400000 +#define TMC2130_OFS86_SHIFT 22 +#define TMC2130_OFS86_FIELD ((TMC2130RegisterField) {TMC2130_OFS86_MASK, TMC2130_OFS86_SHIFT, TMC2130_MSLUT[2], false}) +#define TMC2130_OFS87_MASK 0x00800000 +#define TMC2130_OFS87_SHIFT 23 +#define TMC2130_OFS87_FIELD ((TMC2130RegisterField) {TMC2130_OFS87_MASK, TMC2130_OFS87_SHIFT, TMC2130_MSLUT[2], false}) +#define TMC2130_OFS88_MASK 0x01000000 +#define TMC2130_OFS88_SHIFT 24 +#define TMC2130_OFS88_FIELD ((TMC2130RegisterField) {TMC2130_OFS88_MASK, TMC2130_OFS88_SHIFT, TMC2130_MSLUT[2], false}) +#define TMC2130_OFS89_MASK 0x02000000 +#define TMC2130_OFS89_SHIFT 25 +#define TMC2130_OFS89_FIELD ((TMC2130RegisterField) {TMC2130_OFS89_MASK, TMC2130_OFS89_SHIFT, TMC2130_MSLUT[2], false}) +#define TMC2130_OFS90_MASK 0x04000000 +#define TMC2130_OFS90_SHIFT 26 +#define TMC2130_OFS90_FIELD ((TMC2130RegisterField) {TMC2130_OFS90_MASK, TMC2130_OFS90_SHIFT, TMC2130_MSLUT[2], false}) +#define TMC2130_OFS91_MASK 0x08000000 +#define TMC2130_OFS91_SHIFT 27 +#define TMC2130_OFS91_FIELD ((TMC2130RegisterField) {TMC2130_OFS91_MASK, TMC2130_OFS91_SHIFT, TMC2130_MSLUT[2], false}) +#define TMC2130_OFS92_MASK 0x10000000 +#define TMC2130_OFS92_SHIFT 28 +#define TMC2130_OFS92_FIELD ((TMC2130RegisterField) {TMC2130_OFS92_MASK, TMC2130_OFS92_SHIFT, TMC2130_MSLUT[2], false}) +#define TMC2130_OFS93_MASK 0x20000000 +#define TMC2130_OFS93_SHIFT 29 +#define TMC2130_OFS93_FIELD ((TMC2130RegisterField) {TMC2130_OFS93_MASK, TMC2130_OFS93_SHIFT, TMC2130_MSLUT[2], false}) +#define TMC2130_OFS94_MASK 0x40000000 +#define TMC2130_OFS94_SHIFT 30 +#define TMC2130_OFS94_FIELD ((TMC2130RegisterField) {TMC2130_OFS94_MASK, TMC2130_OFS94_SHIFT, TMC2130_MSLUT[2], false}) +#define TMC2130_OFS95_MASK 0x80000000 +#define TMC2130_OFS95_SHIFT 31 +#define TMC2130_OFS95_FIELD ((TMC2130RegisterField) {TMC2130_OFS95_MASK, TMC2130_OFS95_SHIFT, TMC2130_MSLUT[2], false}) +#define TMC2130_OFS96_MASK 0x00000001 +#define TMC2130_OFS96_SHIFT 0 +#define TMC2130_OFS96_FIELD ((TMC2130RegisterField) {TMC2130_OFS96_MASK, TMC2130_OFS96_SHIFT, TMC2130_MSLUT[3], false}) +#define TMC2130_OFS97_MASK 0x00000002 +#define TMC2130_OFS97_SHIFT 1 +#define TMC2130_OFS97_FIELD ((TMC2130RegisterField) {TMC2130_OFS97_MASK, TMC2130_OFS97_SHIFT, TMC2130_MSLUT[3], false}) +#define TMC2130_OFS98_MASK 0x00000004 +#define TMC2130_OFS98_SHIFT 2 +#define TMC2130_OFS98_FIELD ((TMC2130RegisterField) {TMC2130_OFS98_MASK, TMC2130_OFS98_SHIFT, TMC2130_MSLUT[3], false}) +#define TMC2130_OFS99_MASK 0x00000008 +#define TMC2130_OFS99_SHIFT 3 +#define TMC2130_OFS99_FIELD ((TMC2130RegisterField) {TMC2130_OFS99_MASK, TMC2130_OFS99_SHIFT, TMC2130_MSLUT[3], false}) +#define TMC2130_OFS100_MASK 0x00000010 +#define TMC2130_OFS100_SHIFT 4 +#define TMC2130_OFS100_FIELD ((TMC2130RegisterField) {TMC2130_OFS100_MASK, TMC2130_OFS100_SHIFT, TMC2130_MSLUT[3], false}) +#define TMC2130_OFS101_MASK 0x00000020 +#define TMC2130_OFS101_SHIFT 5 +#define TMC2130_OFS101_FIELD ((TMC2130RegisterField) {TMC2130_OFS101_MASK, TMC2130_OFS101_SHIFT, TMC2130_MSLUT[3], false}) +#define TMC2130_OFS102_MASK 0x00000040 +#define TMC2130_OFS102_SHIFT 6 +#define TMC2130_OFS102_FIELD ((TMC2130RegisterField) {TMC2130_OFS102_MASK, TMC2130_OFS102_SHIFT, TMC2130_MSLUT[3], false}) +#define TMC2130_OFS103_MASK 0x00000080 +#define TMC2130_OFS103_SHIFT 7 +#define TMC2130_OFS103_FIELD ((TMC2130RegisterField) {TMC2130_OFS103_MASK, TMC2130_OFS103_SHIFT, TMC2130_MSLUT[3], false}) +#define TMC2130_OFS104_MASK 0x00000100 +#define TMC2130_OFS104_SHIFT 8 +#define TMC2130_OFS104_FIELD ((TMC2130RegisterField) {TMC2130_OFS104_MASK, TMC2130_OFS104_SHIFT, TMC2130_MSLUT[3], false}) +#define TMC2130_OFS105_MASK 0x00000200 +#define TMC2130_OFS105_SHIFT 9 +#define TMC2130_OFS105_FIELD ((TMC2130RegisterField) {TMC2130_OFS105_MASK, TMC2130_OFS105_SHIFT, TMC2130_MSLUT[3], false}) +#define TMC2130_OFS106_MASK 0x00000400 +#define TMC2130_OFS106_SHIFT 10 +#define TMC2130_OFS106_FIELD ((TMC2130RegisterField) {TMC2130_OFS106_MASK, TMC2130_OFS106_SHIFT, TMC2130_MSLUT[3], false}) +#define TMC2130_OFS107_MASK 0x00000800 +#define TMC2130_OFS107_SHIFT 11 +#define TMC2130_OFS107_FIELD ((TMC2130RegisterField) {TMC2130_OFS107_MASK, TMC2130_OFS107_SHIFT, TMC2130_MSLUT[3], false}) +#define TMC2130_OFS108_MASK 0x00001000 +#define TMC2130_OFS108_SHIFT 12 +#define TMC2130_OFS108_FIELD ((TMC2130RegisterField) {TMC2130_OFS108_MASK, TMC2130_OFS108_SHIFT, TMC2130_MSLUT[3], false}) +#define TMC2130_OFS109_MASK 0x00002000 +#define TMC2130_OFS109_SHIFT 13 +#define TMC2130_OFS109_FIELD ((TMC2130RegisterField) {TMC2130_OFS109_MASK, TMC2130_OFS109_SHIFT, TMC2130_MSLUT[3], false}) +#define TMC2130_OFS110_MASK 0x00004000 +#define TMC2130_OFS110_SHIFT 14 +#define TMC2130_OFS110_FIELD ((TMC2130RegisterField) {TMC2130_OFS110_MASK, TMC2130_OFS110_SHIFT, TMC2130_MSLUT[3], false}) +#define TMC2130_OFS111_MASK 0x00008000 +#define TMC2130_OFS111_SHIFT 15 +#define TMC2130_OFS111_FIELD ((TMC2130RegisterField) {TMC2130_OFS111_MASK, TMC2130_OFS111_SHIFT, TMC2130_MSLUT[3], false}) +#define TMC2130_OFS112_MASK 0x00010000 +#define TMC2130_OFS112_SHIFT 16 +#define TMC2130_OFS112_FIELD ((TMC2130RegisterField) {TMC2130_OFS112_MASK, TMC2130_OFS112_SHIFT, TMC2130_MSLUT[3], false}) +#define TMC2130_OFS113_MASK 0x00020000 +#define TMC2130_OFS113_SHIFT 17 +#define TMC2130_OFS113_FIELD ((TMC2130RegisterField) {TMC2130_OFS113_MASK, TMC2130_OFS113_SHIFT, TMC2130_MSLUT[3], false}) +#define TMC2130_OFS114_MASK 0x00040000 +#define TMC2130_OFS114_SHIFT 18 +#define TMC2130_OFS114_FIELD ((TMC2130RegisterField) {TMC2130_OFS114_MASK, TMC2130_OFS114_SHIFT, TMC2130_MSLUT[3], false}) +#define TMC2130_OFS115_MASK 0x00080000 +#define TMC2130_OFS115_SHIFT 19 +#define TMC2130_OFS115_FIELD ((TMC2130RegisterField) {TMC2130_OFS115_MASK, TMC2130_OFS115_SHIFT, TMC2130_MSLUT[3], false}) +#define TMC2130_OFS116_MASK 0x00100000 +#define TMC2130_OFS116_SHIFT 20 +#define TMC2130_OFS116_FIELD ((TMC2130RegisterField) {TMC2130_OFS116_MASK, TMC2130_OFS116_SHIFT, TMC2130_MSLUT[3], false}) +#define TMC2130_OFS117_MASK 0x00200000 +#define TMC2130_OFS117_SHIFT 21 +#define TMC2130_OFS117_FIELD ((TMC2130RegisterField) {TMC2130_OFS117_MASK, TMC2130_OFS117_SHIFT, TMC2130_MSLUT[3], false}) +#define TMC2130_OFS118_MASK 0x00400000 +#define TMC2130_OFS118_SHIFT 22 +#define TMC2130_OFS118_FIELD ((TMC2130RegisterField) {TMC2130_OFS118_MASK, TMC2130_OFS118_SHIFT, TMC2130_MSLUT[3], false}) +#define TMC2130_OFS119_MASK 0x00800000 +#define TMC2130_OFS119_SHIFT 23 +#define TMC2130_OFS119_FIELD ((TMC2130RegisterField) {TMC2130_OFS119_MASK, TMC2130_OFS119_SHIFT, TMC2130_MSLUT[3], false}) +#define TMC2130_OFS120_MASK 0x01000000 +#define TMC2130_OFS120_SHIFT 24 +#define TMC2130_OFS120_FIELD ((TMC2130RegisterField) {TMC2130_OFS120_MASK, TMC2130_OFS120_SHIFT, TMC2130_MSLUT[3], false}) +#define TMC2130_OFS121_MASK 0x02000000 +#define TMC2130_OFS121_SHIFT 25 +#define TMC2130_OFS121_FIELD ((TMC2130RegisterField) {TMC2130_OFS121_MASK, TMC2130_OFS121_SHIFT, TMC2130_MSLUT[3], false}) +#define TMC2130_OFS122_MASK 0x04000000 +#define TMC2130_OFS122_SHIFT 26 +#define TMC2130_OFS122_FIELD ((TMC2130RegisterField) {TMC2130_OFS122_MASK, TMC2130_OFS122_SHIFT, TMC2130_MSLUT[3], false}) +#define TMC2130_OFS123_MASK 0x08000000 +#define TMC2130_OFS123_SHIFT 27 +#define TMC2130_OFS123_FIELD ((TMC2130RegisterField) {TMC2130_OFS123_MASK, TMC2130_OFS123_SHIFT, TMC2130_MSLUT[3], false}) +#define TMC2130_OFS124_MASK 0x10000000 +#define TMC2130_OFS124_SHIFT 28 +#define TMC2130_OFS124_FIELD ((TMC2130RegisterField) {TMC2130_OFS124_MASK, TMC2130_OFS124_SHIFT, TMC2130_MSLUT[3], false}) +#define TMC2130_OFS125_MASK 0x20000000 +#define TMC2130_OFS125_SHIFT 29 +#define TMC2130_OFS125_FIELD ((TMC2130RegisterField) {TMC2130_OFS125_MASK, TMC2130_OFS125_SHIFT, TMC2130_MSLUT[3], false}) +#define TMC2130_OFS126_MASK 0x40000000 +#define TMC2130_OFS126_SHIFT 30 +#define TMC2130_OFS126_FIELD ((TMC2130RegisterField) {TMC2130_OFS126_MASK, TMC2130_OFS126_SHIFT, TMC2130_MSLUT[3], false}) +#define TMC2130_OFS127_MASK 0x80000000 +#define TMC2130_OFS127_SHIFT 31 +#define TMC2130_OFS127_FIELD ((TMC2130RegisterField) {TMC2130_OFS127_MASK, TMC2130_OFS127_SHIFT, TMC2130_MSLUT[3], false}) +#define TMC2130_OFS128_MASK 0x00000001 +#define TMC2130_OFS128_SHIFT 0 +#define TMC2130_OFS128_FIELD ((TMC2130RegisterField) {TMC2130_OFS128_MASK, TMC2130_OFS128_SHIFT, TMC2130_MSLUT[4], false}) +#define TMC2130_OFS129_MASK 0x00000002 +#define TMC2130_OFS129_SHIFT 1 +#define TMC2130_OFS129_FIELD ((TMC2130RegisterField) {TMC2130_OFS129_MASK, TMC2130_OFS129_SHIFT, TMC2130_MSLUT[4], false}) +#define TMC2130_OFS130_MASK 0x00000004 +#define TMC2130_OFS130_SHIFT 2 +#define TMC2130_OFS130_FIELD ((TMC2130RegisterField) {TMC2130_OFS130_MASK, TMC2130_OFS130_SHIFT, TMC2130_MSLUT[4], false}) +#define TMC2130_OFS131_MASK 0x00000008 +#define TMC2130_OFS131_SHIFT 3 +#define TMC2130_OFS131_FIELD ((TMC2130RegisterField) {TMC2130_OFS131_MASK, TMC2130_OFS131_SHIFT, TMC2130_MSLUT[4], false}) +#define TMC2130_OFS132_MASK 0x00000010 +#define TMC2130_OFS132_SHIFT 4 +#define TMC2130_OFS132_FIELD ((TMC2130RegisterField) {TMC2130_OFS132_MASK, TMC2130_OFS132_SHIFT, TMC2130_MSLUT[4], false}) +#define TMC2130_OFS133_MASK 0x00000020 +#define TMC2130_OFS133_SHIFT 5 +#define TMC2130_OFS133_FIELD ((TMC2130RegisterField) {TMC2130_OFS133_MASK, TMC2130_OFS133_SHIFT, TMC2130_MSLUT[4], false}) +#define TMC2130_OFS134_MASK 0x00000040 +#define TMC2130_OFS134_SHIFT 6 +#define TMC2130_OFS134_FIELD ((TMC2130RegisterField) {TMC2130_OFS134_MASK, TMC2130_OFS134_SHIFT, TMC2130_MSLUT[4], false}) +#define TMC2130_OFS135_MASK 0x00000080 +#define TMC2130_OFS135_SHIFT 7 +#define TMC2130_OFS135_FIELD ((TMC2130RegisterField) {TMC2130_OFS135_MASK, TMC2130_OFS135_SHIFT, TMC2130_MSLUT[4], false}) +#define TMC2130_OFS136_MASK 0x00000100 +#define TMC2130_OFS136_SHIFT 8 +#define TMC2130_OFS136_FIELD ((TMC2130RegisterField) {TMC2130_OFS136_MASK, TMC2130_OFS136_SHIFT, TMC2130_MSLUT[4], false}) +#define TMC2130_OFS137_MASK 0x00000200 +#define TMC2130_OFS137_SHIFT 9 +#define TMC2130_OFS137_FIELD ((TMC2130RegisterField) {TMC2130_OFS137_MASK, TMC2130_OFS137_SHIFT, TMC2130_MSLUT[4], false}) +#define TMC2130_OFS138_MASK 0x00000400 +#define TMC2130_OFS138_SHIFT 10 +#define TMC2130_OFS138_FIELD ((TMC2130RegisterField) {TMC2130_OFS138_MASK, TMC2130_OFS138_SHIFT, TMC2130_MSLUT[4], false}) +#define TMC2130_OFS139_MASK 0x00000800 +#define TMC2130_OFS139_SHIFT 11 +#define TMC2130_OFS139_FIELD ((TMC2130RegisterField) {TMC2130_OFS139_MASK, TMC2130_OFS139_SHIFT, TMC2130_MSLUT[4], false}) +#define TMC2130_OFS140_MASK 0x00001000 +#define TMC2130_OFS140_SHIFT 12 +#define TMC2130_OFS140_FIELD ((TMC2130RegisterField) {TMC2130_OFS140_MASK, TMC2130_OFS140_SHIFT, TMC2130_MSLUT[4], false}) +#define TMC2130_OFS141_MASK 0x00002000 +#define TMC2130_OFS141_SHIFT 13 +#define TMC2130_OFS141_FIELD ((TMC2130RegisterField) {TMC2130_OFS141_MASK, TMC2130_OFS141_SHIFT, TMC2130_MSLUT[4], false}) +#define TMC2130_OFS142_MASK 0x00004000 +#define TMC2130_OFS142_SHIFT 14 +#define TMC2130_OFS142_FIELD ((TMC2130RegisterField) {TMC2130_OFS142_MASK, TMC2130_OFS142_SHIFT, TMC2130_MSLUT[4], false}) +#define TMC2130_OFS143_MASK 0x00008000 +#define TMC2130_OFS143_SHIFT 15 +#define TMC2130_OFS143_FIELD ((TMC2130RegisterField) {TMC2130_OFS143_MASK, TMC2130_OFS143_SHIFT, TMC2130_MSLUT[4], false}) +#define TMC2130_OFS144_MASK 0x00010000 +#define TMC2130_OFS144_SHIFT 16 +#define TMC2130_OFS144_FIELD ((TMC2130RegisterField) {TMC2130_OFS144_MASK, TMC2130_OFS144_SHIFT, TMC2130_MSLUT[4], false}) +#define TMC2130_OFS145_MASK 0x00020000 +#define TMC2130_OFS145_SHIFT 17 +#define TMC2130_OFS145_FIELD ((TMC2130RegisterField) {TMC2130_OFS145_MASK, TMC2130_OFS145_SHIFT, TMC2130_MSLUT[4], false}) +#define TMC2130_OFS146_MASK 0x00040000 +#define TMC2130_OFS146_SHIFT 18 +#define TMC2130_OFS146_FIELD ((TMC2130RegisterField) {TMC2130_OFS146_MASK, TMC2130_OFS146_SHIFT, TMC2130_MSLUT[4], false}) +#define TMC2130_OFS147_MASK 0x00080000 +#define TMC2130_OFS147_SHIFT 19 +#define TMC2130_OFS147_FIELD ((TMC2130RegisterField) {TMC2130_OFS147_MASK, TMC2130_OFS147_SHIFT, TMC2130_MSLUT[4], false}) +#define TMC2130_OFS148_MASK 0x00100000 +#define TMC2130_OFS148_SHIFT 20 +#define TMC2130_OFS148_FIELD ((TMC2130RegisterField) {TMC2130_OFS148_MASK, TMC2130_OFS148_SHIFT, TMC2130_MSLUT[4], false}) +#define TMC2130_OFS149_MASK 0x00200000 +#define TMC2130_OFS149_SHIFT 21 +#define TMC2130_OFS149_FIELD ((TMC2130RegisterField) {TMC2130_OFS149_MASK, TMC2130_OFS149_SHIFT, TMC2130_MSLUT[4], false}) +#define TMC2130_OFS150_MASK 0x00400000 +#define TMC2130_OFS150_SHIFT 22 +#define TMC2130_OFS150_FIELD ((TMC2130RegisterField) {TMC2130_OFS150_MASK, TMC2130_OFS150_SHIFT, TMC2130_MSLUT[4], false}) +#define TMC2130_OFS151_MASK 0x00800000 +#define TMC2130_OFS151_SHIFT 23 +#define TMC2130_OFS151_FIELD ((TMC2130RegisterField) {TMC2130_OFS151_MASK, TMC2130_OFS151_SHIFT, TMC2130_MSLUT[4], false}) +#define TMC2130_OFS152_MASK 0x01000000 +#define TMC2130_OFS152_SHIFT 24 +#define TMC2130_OFS152_FIELD ((TMC2130RegisterField) {TMC2130_OFS152_MASK, TMC2130_OFS152_SHIFT, TMC2130_MSLUT[4], false}) +#define TMC2130_OFS153_MASK 0x02000000 +#define TMC2130_OFS153_SHIFT 25 +#define TMC2130_OFS153_FIELD ((TMC2130RegisterField) {TMC2130_OFS153_MASK, TMC2130_OFS153_SHIFT, TMC2130_MSLUT[4], false}) +#define TMC2130_OFS154_MASK 0x04000000 +#define TMC2130_OFS154_SHIFT 26 +#define TMC2130_OFS154_FIELD ((TMC2130RegisterField) {TMC2130_OFS154_MASK, TMC2130_OFS154_SHIFT, TMC2130_MSLUT[4], false}) +#define TMC2130_OFS155_MASK 0x08000000 +#define TMC2130_OFS155_SHIFT 27 +#define TMC2130_OFS155_FIELD ((TMC2130RegisterField) {TMC2130_OFS155_MASK, TMC2130_OFS155_SHIFT, TMC2130_MSLUT[4], false}) +#define TMC2130_OFS156_MASK 0x10000000 +#define TMC2130_OFS156_SHIFT 28 +#define TMC2130_OFS156_FIELD ((TMC2130RegisterField) {TMC2130_OFS156_MASK, TMC2130_OFS156_SHIFT, TMC2130_MSLUT[4], false}) +#define TMC2130_OFS157_MASK 0x20000000 +#define TMC2130_OFS157_SHIFT 29 +#define TMC2130_OFS157_FIELD ((TMC2130RegisterField) {TMC2130_OFS157_MASK, TMC2130_OFS157_SHIFT, TMC2130_MSLUT[4], false}) +#define TMC2130_OFS158_MASK 0x40000000 +#define TMC2130_OFS158_SHIFT 30 +#define TMC2130_OFS158_FIELD ((TMC2130RegisterField) {TMC2130_OFS158_MASK, TMC2130_OFS158_SHIFT, TMC2130_MSLUT[4], false}) +#define TMC2130_OFS159_MASK 0x80000000 +#define TMC2130_OFS159_SHIFT 31 +#define TMC2130_OFS159_FIELD ((TMC2130RegisterField) {TMC2130_OFS159_MASK, TMC2130_OFS159_SHIFT, TMC2130_MSLUT[4], false}) +#define TMC2130_OFS160_MASK 0x00000001 +#define TMC2130_OFS160_SHIFT 0 +#define TMC2130_OFS160_FIELD ((TMC2130RegisterField) {TMC2130_OFS160_MASK, TMC2130_OFS160_SHIFT, TMC2130_MSLUT[5], false}) +#define TMC2130_OFS161_MASK 0x00000002 +#define TMC2130_OFS161_SHIFT 1 +#define TMC2130_OFS161_FIELD ((TMC2130RegisterField) {TMC2130_OFS161_MASK, TMC2130_OFS161_SHIFT, TMC2130_MSLUT[5], false}) +#define TMC2130_OFS162_MASK 0x00000004 +#define TMC2130_OFS162_SHIFT 2 +#define TMC2130_OFS162_FIELD ((TMC2130RegisterField) {TMC2130_OFS162_MASK, TMC2130_OFS162_SHIFT, TMC2130_MSLUT[5], false}) +#define TMC2130_OFS163_MASK 0x00000008 +#define TMC2130_OFS163_SHIFT 3 +#define TMC2130_OFS163_FIELD ((TMC2130RegisterField) {TMC2130_OFS163_MASK, TMC2130_OFS163_SHIFT, TMC2130_MSLUT[5], false}) +#define TMC2130_OFS164_MASK 0x00000010 +#define TMC2130_OFS164_SHIFT 4 +#define TMC2130_OFS164_FIELD ((TMC2130RegisterField) {TMC2130_OFS164_MASK, TMC2130_OFS164_SHIFT, TMC2130_MSLUT[5], false}) +#define TMC2130_OFS165_MASK 0x00000020 +#define TMC2130_OFS165_SHIFT 5 +#define TMC2130_OFS165_FIELD ((TMC2130RegisterField) {TMC2130_OFS165_MASK, TMC2130_OFS165_SHIFT, TMC2130_MSLUT[5], false}) +#define TMC2130_OFS166_MASK 0x00000040 +#define TMC2130_OFS166_SHIFT 6 +#define TMC2130_OFS166_FIELD ((TMC2130RegisterField) {TMC2130_OFS166_MASK, TMC2130_OFS166_SHIFT, TMC2130_MSLUT[5], false}) +#define TMC2130_OFS167_MASK 0x00000080 +#define TMC2130_OFS167_SHIFT 7 +#define TMC2130_OFS167_FIELD ((TMC2130RegisterField) {TMC2130_OFS167_MASK, TMC2130_OFS167_SHIFT, TMC2130_MSLUT[5], false}) +#define TMC2130_OFS168_MASK 0x00000100 +#define TMC2130_OFS168_SHIFT 8 +#define TMC2130_OFS168_FIELD ((TMC2130RegisterField) {TMC2130_OFS168_MASK, TMC2130_OFS168_SHIFT, TMC2130_MSLUT[5], false}) +#define TMC2130_OFS169_MASK 0x00000200 +#define TMC2130_OFS169_SHIFT 9 +#define TMC2130_OFS169_FIELD ((TMC2130RegisterField) {TMC2130_OFS169_MASK, TMC2130_OFS169_SHIFT, TMC2130_MSLUT[5], false}) +#define TMC2130_OFS170_MASK 0x00000400 +#define TMC2130_OFS170_SHIFT 10 +#define TMC2130_OFS170_FIELD ((TMC2130RegisterField) {TMC2130_OFS170_MASK, TMC2130_OFS170_SHIFT, TMC2130_MSLUT[5], false}) +#define TMC2130_OFS171_MASK 0x00000800 +#define TMC2130_OFS171_SHIFT 11 +#define TMC2130_OFS171_FIELD ((TMC2130RegisterField) {TMC2130_OFS171_MASK, TMC2130_OFS171_SHIFT, TMC2130_MSLUT[5], false}) +#define TMC2130_OFS172_MASK 0x00001000 +#define TMC2130_OFS172_SHIFT 12 +#define TMC2130_OFS172_FIELD ((TMC2130RegisterField) {TMC2130_OFS172_MASK, TMC2130_OFS172_SHIFT, TMC2130_MSLUT[5], false}) +#define TMC2130_OFS173_MASK 0x00002000 +#define TMC2130_OFS173_SHIFT 13 +#define TMC2130_OFS173_FIELD ((TMC2130RegisterField) {TMC2130_OFS173_MASK, TMC2130_OFS173_SHIFT, TMC2130_MSLUT[5], false}) +#define TMC2130_OFS174_MASK 0x00004000 +#define TMC2130_OFS174_SHIFT 14 +#define TMC2130_OFS174_FIELD ((TMC2130RegisterField) {TMC2130_OFS174_MASK, TMC2130_OFS174_SHIFT, TMC2130_MSLUT[5], false}) +#define TMC2130_OFS175_MASK 0x00008000 +#define TMC2130_OFS175_SHIFT 15 +#define TMC2130_OFS175_FIELD ((TMC2130RegisterField) {TMC2130_OFS175_MASK, TMC2130_OFS175_SHIFT, TMC2130_MSLUT[5], false}) +#define TMC2130_OFS176_MASK 0x00010000 +#define TMC2130_OFS176_SHIFT 16 +#define TMC2130_OFS176_FIELD ((TMC2130RegisterField) {TMC2130_OFS176_MASK, TMC2130_OFS176_SHIFT, TMC2130_MSLUT[5], false}) +#define TMC2130_OFS177_MASK 0x00020000 +#define TMC2130_OFS177_SHIFT 17 +#define TMC2130_OFS177_FIELD ((TMC2130RegisterField) {TMC2130_OFS177_MASK, TMC2130_OFS177_SHIFT, TMC2130_MSLUT[5], false}) +#define TMC2130_OFS178_MASK 0x00040000 +#define TMC2130_OFS178_SHIFT 18 +#define TMC2130_OFS178_FIELD ((TMC2130RegisterField) {TMC2130_OFS178_MASK, TMC2130_OFS178_SHIFT, TMC2130_MSLUT[5], false}) +#define TMC2130_OFS179_MASK 0x00080000 +#define TMC2130_OFS179_SHIFT 19 +#define TMC2130_OFS179_FIELD ((TMC2130RegisterField) {TMC2130_OFS179_MASK, TMC2130_OFS179_SHIFT, TMC2130_MSLUT[5], false}) +#define TMC2130_OFS180_MASK 0x00100000 +#define TMC2130_OFS180_SHIFT 20 +#define TMC2130_OFS180_FIELD ((TMC2130RegisterField) {TMC2130_OFS180_MASK, TMC2130_OFS180_SHIFT, TMC2130_MSLUT[5], false}) +#define TMC2130_OFS181_MASK 0x00200000 +#define TMC2130_OFS181_SHIFT 21 +#define TMC2130_OFS181_FIELD ((TMC2130RegisterField) {TMC2130_OFS181_MASK, TMC2130_OFS181_SHIFT, TMC2130_MSLUT[5], false}) +#define TMC2130_OFS182_MASK 0x00400000 +#define TMC2130_OFS182_SHIFT 22 +#define TMC2130_OFS182_FIELD ((TMC2130RegisterField) {TMC2130_OFS182_MASK, TMC2130_OFS182_SHIFT, TMC2130_MSLUT[5], false}) +#define TMC2130_OFS183_MASK 0x00800000 +#define TMC2130_OFS183_SHIFT 23 +#define TMC2130_OFS183_FIELD ((TMC2130RegisterField) {TMC2130_OFS183_MASK, TMC2130_OFS183_SHIFT, TMC2130_MSLUT[5], false}) +#define TMC2130_OFS184_MASK 0x01000000 +#define TMC2130_OFS184_SHIFT 24 +#define TMC2130_OFS184_FIELD ((TMC2130RegisterField) {TMC2130_OFS184_MASK, TMC2130_OFS184_SHIFT, TMC2130_MSLUT[5], false}) +#define TMC2130_OFS185_MASK 0x02000000 +#define TMC2130_OFS185_SHIFT 25 +#define TMC2130_OFS185_FIELD ((TMC2130RegisterField) {TMC2130_OFS185_MASK, TMC2130_OFS185_SHIFT, TMC2130_MSLUT[5], false}) +#define TMC2130_OFS186_MASK 0x04000000 +#define TMC2130_OFS186_SHIFT 26 +#define TMC2130_OFS186_FIELD ((TMC2130RegisterField) {TMC2130_OFS186_MASK, TMC2130_OFS186_SHIFT, TMC2130_MSLUT[5], false}) +#define TMC2130_OFS187_MASK 0x08000000 +#define TMC2130_OFS187_SHIFT 27 +#define TMC2130_OFS187_FIELD ((TMC2130RegisterField) {TMC2130_OFS187_MASK, TMC2130_OFS187_SHIFT, TMC2130_MSLUT[5], false}) +#define TMC2130_OFS188_MASK 0x10000000 +#define TMC2130_OFS188_SHIFT 28 +#define TMC2130_OFS188_FIELD ((TMC2130RegisterField) {TMC2130_OFS188_MASK, TMC2130_OFS188_SHIFT, TMC2130_MSLUT[5], false}) +#define TMC2130_OFS189_MASK 0x20000000 +#define TMC2130_OFS189_SHIFT 29 +#define TMC2130_OFS189_FIELD ((TMC2130RegisterField) {TMC2130_OFS189_MASK, TMC2130_OFS189_SHIFT, TMC2130_MSLUT[5], false}) +#define TMC2130_OFS190_MASK 0x40000000 +#define TMC2130_OFS190_SHIFT 30 +#define TMC2130_OFS190_FIELD ((TMC2130RegisterField) {TMC2130_OFS190_MASK, TMC2130_OFS190_SHIFT, TMC2130_MSLUT[5], false}) +#define TMC2130_OFS191_MASK 0x80000000 +#define TMC2130_OFS191_SHIFT 31 +#define TMC2130_OFS191_FIELD ((TMC2130RegisterField) {TMC2130_OFS191_MASK, TMC2130_OFS191_SHIFT, TMC2130_MSLUT[5], false}) +#define TMC2130_OFS192_MASK 0x00000001 +#define TMC2130_OFS192_SHIFT 0 +#define TMC2130_OFS192_FIELD ((TMC2130RegisterField) {TMC2130_OFS192_MASK, TMC2130_OFS192_SHIFT, TMC2130_MSLUT[6], false}) +#define TMC2130_OFS193_MASK 0x00000002 +#define TMC2130_OFS193_SHIFT 1 +#define TMC2130_OFS193_FIELD ((TMC2130RegisterField) {TMC2130_OFS193_MASK, TMC2130_OFS193_SHIFT, TMC2130_MSLUT[6], false}) +#define TMC2130_OFS194_MASK 0x00000004 +#define TMC2130_OFS194_SHIFT 2 +#define TMC2130_OFS194_FIELD ((TMC2130RegisterField) {TMC2130_OFS194_MASK, TMC2130_OFS194_SHIFT, TMC2130_MSLUT[6], false}) +#define TMC2130_OFS195_MASK 0x00000008 +#define TMC2130_OFS195_SHIFT 3 +#define TMC2130_OFS195_FIELD ((TMC2130RegisterField) {TMC2130_OFS195_MASK, TMC2130_OFS195_SHIFT, TMC2130_MSLUT[6], false}) +#define TMC2130_OFS196_MASK 0x00000010 +#define TMC2130_OFS196_SHIFT 4 +#define TMC2130_OFS196_FIELD ((TMC2130RegisterField) {TMC2130_OFS196_MASK, TMC2130_OFS196_SHIFT, TMC2130_MSLUT[6], false}) +#define TMC2130_OFS197_MASK 0x00000020 +#define TMC2130_OFS197_SHIFT 5 +#define TMC2130_OFS197_FIELD ((TMC2130RegisterField) {TMC2130_OFS197_MASK, TMC2130_OFS197_SHIFT, TMC2130_MSLUT[6], false}) +#define TMC2130_OFS198_MASK 0x00000040 +#define TMC2130_OFS198_SHIFT 6 +#define TMC2130_OFS198_FIELD ((TMC2130RegisterField) {TMC2130_OFS198_MASK, TMC2130_OFS198_SHIFT, TMC2130_MSLUT[6], false}) +#define TMC2130_OFS199_MASK 0x00000080 +#define TMC2130_OFS199_SHIFT 7 +#define TMC2130_OFS199_FIELD ((TMC2130RegisterField) {TMC2130_OFS199_MASK, TMC2130_OFS199_SHIFT, TMC2130_MSLUT[6], false}) +#define TMC2130_OFS200_MASK 0x00000100 +#define TMC2130_OFS200_SHIFT 8 +#define TMC2130_OFS200_FIELD ((TMC2130RegisterField) {TMC2130_OFS200_MASK, TMC2130_OFS200_SHIFT, TMC2130_MSLUT[6], false}) +#define TMC2130_OFS201_MASK 0x00000200 +#define TMC2130_OFS201_SHIFT 9 +#define TMC2130_OFS201_FIELD ((TMC2130RegisterField) {TMC2130_OFS201_MASK, TMC2130_OFS201_SHIFT, TMC2130_MSLUT[6], false}) +#define TMC2130_OFS202_MASK 0x00000400 +#define TMC2130_OFS202_SHIFT 10 +#define TMC2130_OFS202_FIELD ((TMC2130RegisterField) {TMC2130_OFS202_MASK, TMC2130_OFS202_SHIFT, TMC2130_MSLUT[6], false}) +#define TMC2130_OFS203_MASK 0x00000800 +#define TMC2130_OFS203_SHIFT 11 +#define TMC2130_OFS203_FIELD ((TMC2130RegisterField) {TMC2130_OFS203_MASK, TMC2130_OFS203_SHIFT, TMC2130_MSLUT[6], false}) +#define TMC2130_OFS204_MASK 0x00001000 +#define TMC2130_OFS204_SHIFT 12 +#define TMC2130_OFS204_FIELD ((TMC2130RegisterField) {TMC2130_OFS204_MASK, TMC2130_OFS204_SHIFT, TMC2130_MSLUT[6], false}) +#define TMC2130_OFS205_MASK 0x00002000 +#define TMC2130_OFS205_SHIFT 13 +#define TMC2130_OFS205_FIELD ((TMC2130RegisterField) {TMC2130_OFS205_MASK, TMC2130_OFS205_SHIFT, TMC2130_MSLUT[6], false}) +#define TMC2130_OFS206_MASK 0x00004000 +#define TMC2130_OFS206_SHIFT 14 +#define TMC2130_OFS206_FIELD ((TMC2130RegisterField) {TMC2130_OFS206_MASK, TMC2130_OFS206_SHIFT, TMC2130_MSLUT[6], false}) +#define TMC2130_OFS207_MASK 0x00008000 +#define TMC2130_OFS207_SHIFT 15 +#define TMC2130_OFS207_FIELD ((TMC2130RegisterField) {TMC2130_OFS207_MASK, TMC2130_OFS207_SHIFT, TMC2130_MSLUT[6], false}) +#define TMC2130_OFS208_MASK 0x00010000 +#define TMC2130_OFS208_SHIFT 16 +#define TMC2130_OFS208_FIELD ((TMC2130RegisterField) {TMC2130_OFS208_MASK, TMC2130_OFS208_SHIFT, TMC2130_MSLUT[6], false}) +#define TMC2130_OFS209_MASK 0x00020000 +#define TMC2130_OFS209_SHIFT 17 +#define TMC2130_OFS209_FIELD ((TMC2130RegisterField) {TMC2130_OFS209_MASK, TMC2130_OFS209_SHIFT, TMC2130_MSLUT[6], false}) +#define TMC2130_OFS210_MASK 0x00040000 +#define TMC2130_OFS210_SHIFT 18 +#define TMC2130_OFS210_FIELD ((TMC2130RegisterField) {TMC2130_OFS210_MASK, TMC2130_OFS210_SHIFT, TMC2130_MSLUT[6], false}) +#define TMC2130_OFS211_MASK 0x00080000 +#define TMC2130_OFS211_SHIFT 19 +#define TMC2130_OFS211_FIELD ((TMC2130RegisterField) {TMC2130_OFS211_MASK, TMC2130_OFS211_SHIFT, TMC2130_MSLUT[6], false}) +#define TMC2130_OFS212_MASK 0x00100000 +#define TMC2130_OFS212_SHIFT 20 +#define TMC2130_OFS212_FIELD ((TMC2130RegisterField) {TMC2130_OFS212_MASK, TMC2130_OFS212_SHIFT, TMC2130_MSLUT[6], false}) +#define TMC2130_OFS213_MASK 0x00200000 +#define TMC2130_OFS213_SHIFT 21 +#define TMC2130_OFS213_FIELD ((TMC2130RegisterField) {TMC2130_OFS213_MASK, TMC2130_OFS213_SHIFT, TMC2130_MSLUT[6], false}) +#define TMC2130_OFS214_MASK 0x00400000 +#define TMC2130_OFS214_SHIFT 22 +#define TMC2130_OFS214_FIELD ((TMC2130RegisterField) {TMC2130_OFS214_MASK, TMC2130_OFS214_SHIFT, TMC2130_MSLUT[6], false}) +#define TMC2130_OFS215_MASK 0x00800000 +#define TMC2130_OFS215_SHIFT 23 +#define TMC2130_OFS215_FIELD ((TMC2130RegisterField) {TMC2130_OFS215_MASK, TMC2130_OFS215_SHIFT, TMC2130_MSLUT[6], false}) +#define TMC2130_OFS216_MASK 0x01000000 +#define TMC2130_OFS216_SHIFT 24 +#define TMC2130_OFS216_FIELD ((TMC2130RegisterField) {TMC2130_OFS216_MASK, TMC2130_OFS216_SHIFT, TMC2130_MSLUT[6], false}) +#define TMC2130_OFS217_MASK 0x02000000 +#define TMC2130_OFS217_SHIFT 25 +#define TMC2130_OFS217_FIELD ((TMC2130RegisterField) {TMC2130_OFS217_MASK, TMC2130_OFS217_SHIFT, TMC2130_MSLUT[6], false}) +#define TMC2130_OFS218_MASK 0x04000000 +#define TMC2130_OFS218_SHIFT 26 +#define TMC2130_OFS218_FIELD ((TMC2130RegisterField) {TMC2130_OFS218_MASK, TMC2130_OFS218_SHIFT, TMC2130_MSLUT[6], false}) +#define TMC2130_OFS219_MASK 0x08000000 +#define TMC2130_OFS219_SHIFT 27 +#define TMC2130_OFS219_FIELD ((TMC2130RegisterField) {TMC2130_OFS219_MASK, TMC2130_OFS219_SHIFT, TMC2130_MSLUT[6], false}) +#define TMC2130_OFS220_MASK 0x10000000 +#define TMC2130_OFS220_SHIFT 28 +#define TMC2130_OFS220_FIELD ((TMC2130RegisterField) {TMC2130_OFS220_MASK, TMC2130_OFS220_SHIFT, TMC2130_MSLUT[6], false}) +#define TMC2130_OFS221_MASK 0x20000000 +#define TMC2130_OFS221_SHIFT 29 +#define TMC2130_OFS221_FIELD ((TMC2130RegisterField) {TMC2130_OFS221_MASK, TMC2130_OFS221_SHIFT, TMC2130_MSLUT[6], false}) +#define TMC2130_OFS222_MASK 0x40000000 +#define TMC2130_OFS222_SHIFT 30 +#define TMC2130_OFS222_FIELD ((TMC2130RegisterField) {TMC2130_OFS222_MASK, TMC2130_OFS222_SHIFT, TMC2130_MSLUT[6], false}) +#define TMC2130_OFS223_MASK 0x80000000 +#define TMC2130_OFS223_SHIFT 31 +#define TMC2130_OFS223_FIELD ((TMC2130RegisterField) {TMC2130_OFS223_MASK, TMC2130_OFS223_SHIFT, TMC2130_MSLUT[6], false}) +#define TMC2130_OFS224_MASK 0x00000001 +#define TMC2130_OFS224_SHIFT 0 +#define TMC2130_OFS224_FIELD ((TMC2130RegisterField) {TMC2130_OFS224_MASK, TMC2130_OFS224_SHIFT, TMC2130_MSLUT[7], false}) +#define TMC2130_OFS225_MASK 0x00000002 +#define TMC2130_OFS225_SHIFT 1 +#define TMC2130_OFS225_FIELD ((TMC2130RegisterField) {TMC2130_OFS225_MASK, TMC2130_OFS225_SHIFT, TMC2130_MSLUT[7], false}) +#define TMC2130_OFS226_MASK 0x00000004 +#define TMC2130_OFS226_SHIFT 2 +#define TMC2130_OFS226_FIELD ((TMC2130RegisterField) {TMC2130_OFS226_MASK, TMC2130_OFS226_SHIFT, TMC2130_MSLUT[7], false}) +#define TMC2130_OFS227_MASK 0x00000008 +#define TMC2130_OFS227_SHIFT 3 +#define TMC2130_OFS227_FIELD ((TMC2130RegisterField) {TMC2130_OFS227_MASK, TMC2130_OFS227_SHIFT, TMC2130_MSLUT[7], false}) +#define TMC2130_OFS228_MASK 0x00000010 +#define TMC2130_OFS228_SHIFT 4 +#define TMC2130_OFS228_FIELD ((TMC2130RegisterField) {TMC2130_OFS228_MASK, TMC2130_OFS228_SHIFT, TMC2130_MSLUT[7], false}) +#define TMC2130_OFS229_MASK 0x00000020 +#define TMC2130_OFS229_SHIFT 5 +#define TMC2130_OFS229_FIELD ((TMC2130RegisterField) {TMC2130_OFS229_MASK, TMC2130_OFS229_SHIFT, TMC2130_MSLUT[7], false}) +#define TMC2130_OFS230_MASK 0x00000040 +#define TMC2130_OFS230_SHIFT 6 +#define TMC2130_OFS230_FIELD ((TMC2130RegisterField) {TMC2130_OFS230_MASK, TMC2130_OFS230_SHIFT, TMC2130_MSLUT[7], false}) +#define TMC2130_OFS231_MASK 0x00000080 +#define TMC2130_OFS231_SHIFT 7 +#define TMC2130_OFS231_FIELD ((TMC2130RegisterField) {TMC2130_OFS231_MASK, TMC2130_OFS231_SHIFT, TMC2130_MSLUT[7], false}) +#define TMC2130_OFS232_MASK 0x00000100 +#define TMC2130_OFS232_SHIFT 8 +#define TMC2130_OFS232_FIELD ((TMC2130RegisterField) {TMC2130_OFS232_MASK, TMC2130_OFS232_SHIFT, TMC2130_MSLUT[7], false}) +#define TMC2130_OFS233_MASK 0x00000200 +#define TMC2130_OFS233_SHIFT 9 +#define TMC2130_OFS233_FIELD ((TMC2130RegisterField) {TMC2130_OFS233_MASK, TMC2130_OFS233_SHIFT, TMC2130_MSLUT[7], false}) +#define TMC2130_OFS234_MASK 0x00000400 +#define TMC2130_OFS234_SHIFT 10 +#define TMC2130_OFS234_FIELD ((TMC2130RegisterField) {TMC2130_OFS234_MASK, TMC2130_OFS234_SHIFT, TMC2130_MSLUT[7], false}) +#define TMC2130_OFS235_MASK 0x00000800 +#define TMC2130_OFS235_SHIFT 11 +#define TMC2130_OFS235_FIELD ((TMC2130RegisterField) {TMC2130_OFS235_MASK, TMC2130_OFS235_SHIFT, TMC2130_MSLUT[7], false}) +#define TMC2130_OFS236_MASK 0x00001000 +#define TMC2130_OFS236_SHIFT 12 +#define TMC2130_OFS236_FIELD ((TMC2130RegisterField) {TMC2130_OFS236_MASK, TMC2130_OFS236_SHIFT, TMC2130_MSLUT[7], false}) +#define TMC2130_OFS237_MASK 0x00002000 +#define TMC2130_OFS237_SHIFT 13 +#define TMC2130_OFS237_FIELD ((TMC2130RegisterField) {TMC2130_OFS237_MASK, TMC2130_OFS237_SHIFT, TMC2130_MSLUT[7], false}) +#define TMC2130_OFS238_MASK 0x00004000 +#define TMC2130_OFS238_SHIFT 14 +#define TMC2130_OFS238_FIELD ((TMC2130RegisterField) {TMC2130_OFS238_MASK, TMC2130_OFS238_SHIFT, TMC2130_MSLUT[7], false}) +#define TMC2130_OFS239_MASK 0x00008000 +#define TMC2130_OFS239_SHIFT 15 +#define TMC2130_OFS239_FIELD ((TMC2130RegisterField) {TMC2130_OFS239_MASK, TMC2130_OFS239_SHIFT, TMC2130_MSLUT[7], false}) +#define TMC2130_OFS240_MASK 0x00010000 +#define TMC2130_OFS240_SHIFT 16 +#define TMC2130_OFS240_FIELD ((TMC2130RegisterField) {TMC2130_OFS240_MASK, TMC2130_OFS240_SHIFT, TMC2130_MSLUT[7], false}) +#define TMC2130_OFS241_MASK 0x00020000 +#define TMC2130_OFS241_SHIFT 17 +#define TMC2130_OFS241_FIELD ((TMC2130RegisterField) {TMC2130_OFS241_MASK, TMC2130_OFS241_SHIFT, TMC2130_MSLUT[7], false}) +#define TMC2130_OFS242_MASK 0x00040000 +#define TMC2130_OFS242_SHIFT 18 +#define TMC2130_OFS242_FIELD ((TMC2130RegisterField) {TMC2130_OFS242_MASK, TMC2130_OFS242_SHIFT, TMC2130_MSLUT[7], false}) +#define TMC2130_OFS243_MASK 0x00080000 +#define TMC2130_OFS243_SHIFT 19 +#define TMC2130_OFS243_FIELD ((TMC2130RegisterField) {TMC2130_OFS243_MASK, TMC2130_OFS243_SHIFT, TMC2130_MSLUT[7], false}) +#define TMC2130_OFS244_MASK 0x00100000 +#define TMC2130_OFS244_SHIFT 20 +#define TMC2130_OFS244_FIELD ((TMC2130RegisterField) {TMC2130_OFS244_MASK, TMC2130_OFS244_SHIFT, TMC2130_MSLUT[7], false}) +#define TMC2130_OFS245_MASK 0x00200000 +#define TMC2130_OFS245_SHIFT 21 +#define TMC2130_OFS245_FIELD ((TMC2130RegisterField) {TMC2130_OFS245_MASK, TMC2130_OFS245_SHIFT, TMC2130_MSLUT[7], false}) +#define TMC2130_OFS246_MASK 0x00400000 +#define TMC2130_OFS246_SHIFT 22 +#define TMC2130_OFS246_FIELD ((TMC2130RegisterField) {TMC2130_OFS246_MASK, TMC2130_OFS246_SHIFT, TMC2130_MSLUT[7], false}) +#define TMC2130_OFS247_MASK 0x00800000 +#define TMC2130_OFS247_SHIFT 23 +#define TMC2130_OFS247_FIELD ((TMC2130RegisterField) {TMC2130_OFS247_MASK, TMC2130_OFS247_SHIFT, TMC2130_MSLUT[7], false}) +#define TMC2130_OFS248_MASK 0x01000000 +#define TMC2130_OFS248_SHIFT 24 +#define TMC2130_OFS248_FIELD ((TMC2130RegisterField) {TMC2130_OFS248_MASK, TMC2130_OFS248_SHIFT, TMC2130_MSLUT[7], false}) +#define TMC2130_OFS249_MASK 0x02000000 +#define TMC2130_OFS249_SHIFT 25 +#define TMC2130_OFS249_FIELD ((TMC2130RegisterField) {TMC2130_OFS249_MASK, TMC2130_OFS249_SHIFT, TMC2130_MSLUT[7], false}) +#define TMC2130_OFS250_MASK 0x04000000 +#define TMC2130_OFS250_SHIFT 26 +#define TMC2130_OFS250_FIELD ((TMC2130RegisterField) {TMC2130_OFS250_MASK, TMC2130_OFS250_SHIFT, TMC2130_MSLUT[7], false}) +#define TMC2130_OFS251_MASK 0x08000000 +#define TMC2130_OFS251_SHIFT 27 +#define TMC2130_OFS251_FIELD ((TMC2130RegisterField) {TMC2130_OFS251_MASK, TMC2130_OFS251_SHIFT, TMC2130_MSLUT[7], false}) +#define TMC2130_OFS252_MASK 0x10000000 +#define TMC2130_OFS252_SHIFT 28 +#define TMC2130_OFS252_FIELD ((TMC2130RegisterField) {TMC2130_OFS252_MASK, TMC2130_OFS252_SHIFT, TMC2130_MSLUT[7], false}) +#define TMC2130_OFS253_MASK 0x20000000 +#define TMC2130_OFS253_SHIFT 29 +#define TMC2130_OFS253_FIELD ((TMC2130RegisterField) {TMC2130_OFS253_MASK, TMC2130_OFS253_SHIFT, TMC2130_MSLUT[7], false}) +#define TMC2130_OFS254_MASK 0x40000000 +#define TMC2130_OFS254_SHIFT 30 +#define TMC2130_OFS254_FIELD ((TMC2130RegisterField) {TMC2130_OFS254_MASK, TMC2130_OFS254_SHIFT, TMC2130_MSLUT[7], false}) +#define TMC2130_OFS255_MASK 0x80000000 +#define TMC2130_OFS255_SHIFT 31 +#define TMC2130_OFS255_FIELD ((TMC2130RegisterField) {TMC2130_OFS255_MASK, TMC2130_OFS255_SHIFT, TMC2130_MSLUT[7], false}) +#define TMC2130_W0_MASK 0x00000003 +#define TMC2130_W0_SHIFT 0 +#define TMC2130_W0_FIELD ((TMC2130RegisterField) {TMC2130_W0_MASK, TMC2130_W0_SHIFT, TMC2130_MSLUTSEL, false}) +#define TMC2130_W1_MASK 0x0000000C +#define TMC2130_W1_SHIFT 2 +#define TMC2130_W1_FIELD ((TMC2130RegisterField) {TMC2130_W1_MASK, TMC2130_W1_SHIFT, TMC2130_MSLUTSEL, false}) +#define TMC2130_W2_MASK 0x00000030 +#define TMC2130_W2_SHIFT 4 +#define TMC2130_W2_FIELD ((TMC2130RegisterField) {TMC2130_W2_MASK, TMC2130_W2_SHIFT, TMC2130_MSLUTSEL, false}) +#define TMC2130_W3_MASK 0x000000C0 +#define TMC2130_W3_SHIFT 6 +#define TMC2130_W3_FIELD ((TMC2130RegisterField) {TMC2130_W3_MASK, TMC2130_W3_SHIFT, TMC2130_MSLUTSEL, false}) +#define TMC2130_X1_MASK 0x0000FF00 +#define TMC2130_X1_SHIFT 8 +#define TMC2130_X1_FIELD ((TMC2130RegisterField) {TMC2130_X1_MASK, TMC2130_X1_SHIFT, TMC2130_MSLUTSEL, false}) +#define TMC2130_X2_MASK 0x00FF0000 +#define TMC2130_X2_SHIFT 16 +#define TMC2130_X2_FIELD ((TMC2130RegisterField) {TMC2130_X2_MASK, TMC2130_X2_SHIFT, TMC2130_MSLUTSEL, false}) +#define TMC2130_X3_MASK 0xFF000000 +#define TMC2130_X3_SHIFT 24 +#define TMC2130_X3_FIELD ((TMC2130RegisterField) {TMC2130_X3_MASK, TMC2130_X3_SHIFT, TMC2130_MSLUTSEL, false}) +#define TMC2130_START_SIN_MASK 0x000000FF +#define TMC2130_START_SIN_SHIFT 0 +#define TMC2130_START_SIN_FIELD ((TMC2130RegisterField) {TMC2130_START_SIN_MASK, TMC2130_START_SIN_SHIFT, TMC2130_MSLUTSTART, false}) +#define TMC2130_START_SIN90_MASK 0x00FF0000 +#define TMC2130_START_SIN90_SHIFT 16 +#define TMC2130_START_SIN90_FIELD ((TMC2130RegisterField) {TMC2130_START_SIN90_MASK, TMC2130_START_SIN90_SHIFT, TMC2130_MSLUTSTART, false}) +#define TMC2130_MSCNT_MASK 0x000003FF +#define TMC2130_MSCNT_SHIFT 0 +#define TMC2130_MSCNT_FIELD ((TMC2130RegisterField) {TMC2130_MSCNT_MASK, TMC2130_MSCNT_SHIFT, TMC2130_MSCNT, false}) +#define TMC2130_CUR_A_MASK 0x000001FF +#define TMC2130_CUR_A_SHIFT 0 +#define TMC2130_CUR_A_FIELD ((TMC2130RegisterField) {TMC2130_CUR_A_MASK, TMC2130_CUR_A_SHIFT, TMC2130_MSCURACT, true}) +#define TMC2130_CUR_B_MASK 0x01FF0000 +#define TMC2130_CUR_B_SHIFT 16 +#define TMC2130_CUR_B_FIELD ((TMC2130RegisterField) {TMC2130_CUR_B_MASK, TMC2130_CUR_B_SHIFT, TMC2130_MSCURACT, true}) +#define TMC2130_TOFF_MASK 0x0000000F +#define TMC2130_TOFF_SHIFT 0 +#define TMC2130_TOFF_FIELD ((TMC2130RegisterField) {TMC2130_TOFF_MASK, TMC2130_TOFF_SHIFT, TMC2130_CHOPCONF, false}) +#define TMC2130_TFD_2__0__MASK 0x00000070 +#define TMC2130_TFD_2__0__SHIFT 4 +#define TMC2130_TFD_2__0__FIELD ((TMC2130RegisterField) {TMC2130_TFD_2__0__MASK, TMC2130_TFD_2__0__SHIFT, TMC2130_CHOPCONF, false}) +#define TMC2130_OFFSET_MASK 0x00000780 +#define TMC2130_OFFSET_SHIFT 7 +#define TMC2130_OFFSET_FIELD ((TMC2130RegisterField) {TMC2130_OFFSET_MASK, TMC2130_OFFSET_SHIFT, TMC2130_CHOPCONF, false}) +#define TMC2130_TFD___MASK 0x00000800 +#define TMC2130_TFD___SHIFT 11 +#define TMC2130_TFD___FIELD ((TMC2130RegisterField) {TMC2130_TFD___MASK, TMC2130_TFD___SHIFT, TMC2130_CHOPCONF, false}) +#define TMC2130_DISFDCC_MASK 0x00001000 +#define TMC2130_DISFDCC_SHIFT 12 +#define TMC2130_DISFDCC_FIELD ((TMC2130RegisterField) {TMC2130_DISFDCC_MASK, TMC2130_DISFDCC_SHIFT, TMC2130_CHOPCONF, false}) +#define TMC2130_RNDTF_MASK 0x00002000 +#define TMC2130_RNDTF_SHIFT 13 +#define TMC2130_RNDTF_FIELD ((TMC2130RegisterField) {TMC2130_RNDTF_MASK, TMC2130_RNDTF_SHIFT, TMC2130_CHOPCONF, false}) +#define TMC2130_CHM_MASK 0x00004000 +#define TMC2130_CHM_SHIFT 14 +#define TMC2130_CHM_FIELD ((TMC2130RegisterField) {TMC2130_CHM_MASK, TMC2130_CHM_SHIFT, TMC2130_CHOPCONF, false}) +#define TMC2130_TBL_MASK 0x00018000 +#define TMC2130_TBL_SHIFT 15 +#define TMC2130_TBL_FIELD ((TMC2130RegisterField) {TMC2130_TBL_MASK, TMC2130_TBL_SHIFT, TMC2130_CHOPCONF, false}) +#define TMC2130_VSENSE_MASK 0x00020000 +#define TMC2130_VSENSE_SHIFT 17 +#define TMC2130_VSENSE_FIELD ((TMC2130RegisterField) {TMC2130_VSENSE_MASK, TMC2130_VSENSE_SHIFT, TMC2130_CHOPCONF, false}) +#define TMC2130_VHIGHFS_MASK 0x00040000 +#define TMC2130_VHIGHFS_SHIFT 18 +#define TMC2130_VHIGHFS_FIELD ((TMC2130RegisterField) {TMC2130_VHIGHFS_MASK, TMC2130_VHIGHFS_SHIFT, TMC2130_CHOPCONF, false}) +#define TMC2130_VHIGHCHM_MASK 0x00080000 +#define TMC2130_VHIGHCHM_SHIFT 19 +#define TMC2130_VHIGHCHM_FIELD ((TMC2130RegisterField) {TMC2130_VHIGHCHM_MASK, TMC2130_VHIGHCHM_SHIFT, TMC2130_CHOPCONF, false}) +#define TMC2130_SYNC_MASK 0x00F00000 +#define TMC2130_SYNC_SHIFT 20 +#define TMC2130_SYNC_FIELD ((TMC2130RegisterField) {TMC2130_SYNC_MASK, TMC2130_SYNC_SHIFT, TMC2130_CHOPCONF, false}) +#define TMC2130_MRES_MASK 0x0F000000 +#define TMC2130_MRES_SHIFT 24 +#define TMC2130_MRES_FIELD ((TMC2130RegisterField) {TMC2130_MRES_MASK, TMC2130_MRES_SHIFT, TMC2130_CHOPCONF, false}) +#define TMC2130_INTPOL_MASK 0x10000000 +#define TMC2130_INTPOL_SHIFT 28 +#define TMC2130_INTPOL_FIELD ((TMC2130RegisterField) {TMC2130_INTPOL_MASK, TMC2130_INTPOL_SHIFT, TMC2130_CHOPCONF, false}) +#define TMC2130_DEDGE_MASK 0x20000000 +#define TMC2130_DEDGE_SHIFT 29 +#define TMC2130_DEDGE_FIELD ((TMC2130RegisterField) {TMC2130_DEDGE_MASK, TMC2130_DEDGE_SHIFT, TMC2130_CHOPCONF, false}) +#define TMC2130_DISS2G_MASK 0x40000000 +#define TMC2130_DISS2G_SHIFT 30 +#define TMC2130_DISS2G_FIELD ((TMC2130RegisterField) {TMC2130_DISS2G_MASK, TMC2130_DISS2G_SHIFT, TMC2130_CHOPCONF, false}) +#define TMC2130_HSTRT_MASK 0x00000070 +#define TMC2130_HSTRT_SHIFT 4 +#define TMC2130_HSTRT_FIELD ((TMC2130RegisterField) {TMC2130_HSTRT_MASK, TMC2130_HSTRT_SHIFT, TMC2130_CHOPCONF, false}) +#define TMC2130_HEND_MASK 0x00000780 +#define TMC2130_HEND_SHIFT 7 +#define TMC2130_HEND_FIELD ((TMC2130RegisterField) {TMC2130_HEND_MASK, TMC2130_HEND_SHIFT, TMC2130_CHOPCONF, false}) +#define TMC2130_SEMIN_MASK 0x0000000F +#define TMC2130_SEMIN_SHIFT 0 +#define TMC2130_SEMIN_FIELD ((TMC2130RegisterField) {TMC2130_SEMIN_MASK, TMC2130_SEMIN_SHIFT, TMC2130_COOLCONF, false}) +#define TMC2130_SEUP_MASK 0x00000060 +#define TMC2130_SEUP_SHIFT 5 +#define TMC2130_SEUP_FIELD ((TMC2130RegisterField) {TMC2130_SEUP_MASK, TMC2130_SEUP_SHIFT, TMC2130_COOLCONF, false}) +#define TMC2130_SEMAX_MASK 0x00000F00 +#define TMC2130_SEMAX_SHIFT 8 +#define TMC2130_SEMAX_FIELD ((TMC2130RegisterField) {TMC2130_SEMAX_MASK, TMC2130_SEMAX_SHIFT, TMC2130_COOLCONF, false}) +#define TMC2130_SEDN_MASK 0x00006000 +#define TMC2130_SEDN_SHIFT 13 +#define TMC2130_SEDN_FIELD ((TMC2130RegisterField) {TMC2130_SEDN_MASK, TMC2130_SEDN_SHIFT, TMC2130_COOLCONF, false}) +#define TMC2130_SEIMIN_MASK 0x00008000 +#define TMC2130_SEIMIN_SHIFT 15 +#define TMC2130_SEIMIN_FIELD ((TMC2130RegisterField) {TMC2130_SEIMIN_MASK, TMC2130_SEIMIN_SHIFT, TMC2130_COOLCONF, false}) +#define TMC2130_SGT_MASK 0x007F0000 +#define TMC2130_SGT_SHIFT 16 +#define TMC2130_SGT_FIELD ((TMC2130RegisterField) {TMC2130_SGT_MASK, TMC2130_SGT_SHIFT, TMC2130_COOLCONF, true}) +#define TMC2130_SFILT_MASK 0x01000000 +#define TMC2130_SFILT_SHIFT 24 +#define TMC2130_SFILT_FIELD ((TMC2130RegisterField) {TMC2130_SFILT_MASK, TMC2130_SFILT_SHIFT, TMC2130_COOLCONF, false}) +#define TMC2130_DC_TIME_MASK 0x000003FF +#define TMC2130_DC_TIME_SHIFT 0 +#define TMC2130_DC_TIME_FIELD ((TMC2130RegisterField) {TMC2130_DC_TIME_MASK, TMC2130_DC_TIME_SHIFT, TMC2130_DCCTRL, false}) +#define TMC2130_DC_SG_MASK 0x00FF0000 +#define TMC2130_DC_SG_SHIFT 16 +#define TMC2130_DC_SG_FIELD ((TMC2130RegisterField) {TMC2130_DC_SG_MASK, TMC2130_DC_SG_SHIFT, TMC2130_DCCTRL, false}) +#define TMC2130_SG_RESULT_MASK 0x000003FF +#define TMC2130_SG_RESULT_SHIFT 0 +#define TMC2130_SG_RESULT_FIELD ((TMC2130RegisterField) {TMC2130_SG_RESULT_MASK, TMC2130_SG_RESULT_SHIFT, TMC2130_DRV_STATUS, false}) +#define TMC2130_FSACTIVE_MASK 0x00008000 +#define TMC2130_FSACTIVE_SHIFT 15 +#define TMC2130_FSACTIVE_FIELD ((TMC2130RegisterField) {TMC2130_FSACTIVE_MASK, TMC2130_FSACTIVE_SHIFT, TMC2130_DRV_STATUS, false}) +#define TMC2130_CS_ACTUAL_MASK 0x001F0000 +#define TMC2130_CS_ACTUAL_SHIFT 16 +#define TMC2130_CS_ACTUAL_FIELD ((TMC2130RegisterField) {TMC2130_CS_ACTUAL_MASK, TMC2130_CS_ACTUAL_SHIFT, TMC2130_DRV_STATUS, false}) +#define TMC2130_STALLGUARD_MASK 0x01000000 +#define TMC2130_STALLGUARD_SHIFT 24 +#define TMC2130_STALLGUARD_FIELD ((TMC2130RegisterField) {TMC2130_STALLGUARD_MASK, TMC2130_STALLGUARD_SHIFT, TMC2130_DRV_STATUS, false}) +#define TMC2130_OT_MASK 0x02000000 +#define TMC2130_OT_SHIFT 25 +#define TMC2130_OT_FIELD ((TMC2130RegisterField) {TMC2130_OT_MASK, TMC2130_OT_SHIFT, TMC2130_DRV_STATUS, false}) +#define TMC2130_OTPW_MASK 0x04000000 +#define TMC2130_OTPW_SHIFT 26 +#define TMC2130_OTPW_FIELD ((TMC2130RegisterField) {TMC2130_OTPW_MASK, TMC2130_OTPW_SHIFT, TMC2130_DRV_STATUS, false}) +#define TMC2130_S2GA_MASK 0x08000000 +#define TMC2130_S2GA_SHIFT 27 +#define TMC2130_S2GA_FIELD ((TMC2130RegisterField) {TMC2130_S2GA_MASK, TMC2130_S2GA_SHIFT, TMC2130_DRV_STATUS, false}) +#define TMC2130_S2GB_MASK 0x10000000 +#define TMC2130_S2GB_SHIFT 28 +#define TMC2130_S2GB_FIELD ((TMC2130RegisterField) {TMC2130_S2GB_MASK, TMC2130_S2GB_SHIFT, TMC2130_DRV_STATUS, false}) +#define TMC2130_OLA_MASK 0x20000000 +#define TMC2130_OLA_SHIFT 29 +#define TMC2130_OLA_FIELD ((TMC2130RegisterField) {TMC2130_OLA_MASK, TMC2130_OLA_SHIFT, TMC2130_DRV_STATUS, false}) +#define TMC2130_OLB_MASK 0x40000000 +#define TMC2130_OLB_SHIFT 30 +#define TMC2130_OLB_FIELD ((TMC2130RegisterField) {TMC2130_OLB_MASK, TMC2130_OLB_SHIFT, TMC2130_DRV_STATUS, false}) +#define TMC2130_STST_MASK 0x80000000 +#define TMC2130_STST_SHIFT 31 +#define TMC2130_STST_FIELD ((TMC2130RegisterField) {TMC2130_STST_MASK, TMC2130_STST_SHIFT, TMC2130_DRV_STATUS, false}) +#define TMC2130_PWM_AMPL_MASK 0x000000FF +#define TMC2130_PWM_AMPL_SHIFT 0 +#define TMC2130_PWM_AMPL_FIELD ((TMC2130RegisterField) {TMC2130_PWM_AMPL_MASK, TMC2130_PWM_AMPL_SHIFT, TMC2130_PWMCONF, false}) +#define TMC2130_PWM_GRAD_MASK 0x0000FF00 +#define TMC2130_PWM_GRAD_SHIFT 8 +#define TMC2130_PWM_GRAD_FIELD ((TMC2130RegisterField) {TMC2130_PWM_GRAD_MASK, TMC2130_PWM_GRAD_SHIFT, TMC2130_PWMCONF, false}) +#define TMC2130_PWM_FREQ_MASK 0x00030000 +#define TMC2130_PWM_FREQ_SHIFT 16 +#define TMC2130_PWM_FREQ_FIELD ((TMC2130RegisterField) {TMC2130_PWM_FREQ_MASK, TMC2130_PWM_FREQ_SHIFT, TMC2130_PWMCONF, false}) +#define TMC2130_PWM_AUTOSCALE_MASK 0x00040000 +#define TMC2130_PWM_AUTOSCALE_SHIFT 18 +#define TMC2130_PWM_AUTOSCALE_FIELD ((TMC2130RegisterField) {TMC2130_PWM_AUTOSCALE_MASK, TMC2130_PWM_AUTOSCALE_SHIFT, TMC2130_PWMCONF, false}) +#define TMC2130_PWM_SYMMETRIC_MASK 0x00080000 +#define TMC2130_PWM_SYMMETRIC_SHIFT 19 +#define TMC2130_PWM_SYMMETRIC_FIELD ((TMC2130RegisterField) {TMC2130_PWM_SYMMETRIC_MASK, TMC2130_PWM_SYMMETRIC_SHIFT, TMC2130_PWMCONF, false}) +#define TMC2130_FREEWHEEL_MASK 0x00300000 +#define TMC2130_FREEWHEEL_SHIFT 20 +#define TMC2130_FREEWHEEL_FIELD ((TMC2130RegisterField) {TMC2130_FREEWHEEL_MASK, TMC2130_FREEWHEEL_SHIFT, TMC2130_PWMCONF, false}) +#define TMC2130_PWM_SCALE_MASK 0x000000FF +#define TMC2130_PWM_SCALE_SHIFT 0 +#define TMC2130_PWM_SCALE_FIELD ((TMC2130RegisterField) {TMC2130_PWM_SCALE_MASK, TMC2130_PWM_SCALE_SHIFT, TMC2130_PWM_SCALE, false}) +#define TMC2130_INV_MASK 0x00000001 +#define TMC2130_INV_SHIFT 0 +#define TMC2130_INV_FIELD ((TMC2130RegisterField) {TMC2130_INV_MASK, TMC2130_INV_SHIFT, TMC2130_ENCM_CTRL, false}) +#define TMC2130_MAXSPEED_MASK 0x00000002 +#define TMC2130_MAXSPEED_SHIFT 1 +#define TMC2130_MAXSPEED_FIELD ((TMC2130RegisterField) {TMC2130_MAXSPEED_MASK, TMC2130_MAXSPEED_SHIFT, TMC2130_ENCM_CTRL, false}) +#define TMC2130_LOST_STEPS_MASK 0x000FFFFF +#define TMC2130_LOST_STEPS_SHIFT 0 +#define TMC2130_LOST_STEPS_FIELD ((TMC2130RegisterField) {TMC2130_LOST_STEPS_MASK, TMC2130_LOST_STEPS_SHIFT, TMC2130_LOST_STEPS, false}) + +#endif diff --git a/firmware/lib/tmc/ic/TMC2130/registercall_hierarchy_flowchart_SPI.svg b/firmware/lib/tmc/ic/TMC2130/registercall_hierarchy_flowchart_SPI.svg new file mode 100755 index 0000000..cbad58f --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2130/registercall_hierarchy_flowchart_SPI.svg @@ -0,0 +1,3 @@ + + +

HAL

HAL

APP (Eval)

APP (Eval)

API

API
Read a register
  •  Call tmcXXXX_readRegister function
Read a register...
Returns the register read value
Returns the register read value
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
tmcXXXX.c
tmcXXXX.c
SPI.c
SPI.c
tmcXXXX_eval.c
tmcXXXX_eval.c

 Implementation of SPI_readWrite
  • Sends and receives bytes on the SPI bus
Implementation of SPI_readWrite...
Returns the raw reply data
Returns the raw reply data

Implementation of tmcXXXX_readWriteSPI
  • Sets the CSN pin to LOW
  • Takes the array of data to write
  • Calls hardware function SPI_readWrite
  • Upon completion of data transfer,
    sets CSN to 
    HIGH
Implementation of tmcXXXX_readWriteSPI...
Passes on the raw reply data to the API
Passes on the raw reply data to the API
Implementation of readRegisterSPI
  • Constructs the datagram
  • Calls HAL wrapper function 
Implementation of readRegisterSPI...
tmcXXXX_readWriteSPI
tmcXXXX_readWriteSPI
Parses the reply and returns the register value
Parses the reply and returns the register value
Implementation of tmcXXXX_readRegister 
  • Check which bus is active SPI/UART. (e.g. SPI)
  • Calls bus-specific function (e.g. readRegisterSPI)
 
Implementation of tmcXXXX_readRegister...
Returns the register read value
Returns the register read value
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC2130/uml-tmc-api.svg b/firmware/lib/tmc/ic/TMC2130/uml-tmc-api.svg new file mode 100755 index 0000000..5a5f8dd --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2130/uml-tmc-api.svg @@ -0,0 +1,3 @@ + + +

TMCXXXX_HW_Abstraction.h



TMCXXXX_HW_Abstraction.h...
// Constants
#define TMCXXXX_MOTORS              
                          
// Register definitions
#define TMCXXXX_GCONF        
                          ⋮
// Register fields definitions
#define TMCXXXX_GCONF_OTPW_FIELD
                     
// Constants...

TMCXXXX.h



TMCXXXX.h...
extern void tmcXXXX_readWriteSPI();
extern void tmcXXXX_readWriteUART();
extern TMCXXXXBusType tmcXXXX_getBusType();
extern uint8_t tmcXXXX_getNodeAddress();
                                  ⋮
tmcXXXX_readRegister();
tmcXXXX_writeRegister();
                                  ⋮
extern void tmcXXXX_readWriteSPI();...

TMCXXXX.c



TMCXXXX.c...
const uint8_t tmcCRCTable_Poly7Reflected[256] = {...};
int32_t tmcXXXX_readRegister(){
/* Call tmcXXXX_getBusType();
 * Based on bus type, call readRegisterSPI/UART() that
 * further calls tmcXXXX_readWriteSPI/UART();
 * For UART it also calls tmcXXXX_getNodeAddress();
                                           ⋮
}
                                           ⋮
const uint8_t tmcCRCTable_Poly7Reflected[256] = {.....
TMC-API
TMC-API

TMCXXXX_Simple_Rotation.h


TMCXXXX_Simple_Rotation.h...
void initAllMotors();
             ⋮
  
void initAllMotors()...

TMCXXXX_Simple_Rotation.c


TMCXXXX_Simple_Rotation.c...
void initAllMotors(){

// Configuring registers to enable motor drivers etc..
tmcXXXX_writeRegister();
                    ⋮
}
                    ⋮
void initAllMotors(){...
Examples
Examples
User Project
User Project

User_Project.h


User_Project.h

User_Project.c








User_Project.c...

void tmcXXXX_readWriteSPI(){
                           ⋮
}
void tmcXXXX_readWriteUART(){
                           ⋮
}
TMCXXXXBusType tmcXXXX_getBusType(){
                           ⋮
}
uint8_t tmcXXXX_getNodeAddress(){
                           ⋮
}

// User Code
                           ⋮
void tmcXXXX_readWriteSPI(){...
#include "TMCXXXX_HW_Abstraction.h"
#include "TMCXXXX.h"
#include "TMCXXXX_Simple_Rotation.h"
                                ⋮
TMCXXXXBusType bus = IC_BUS_SPI/UART;
uint8_t nodeAddress = <nodeAddress>;
                                ⋮
#include "TMCXXXX_HW_Abstraction.h"...
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC2160/README.md b/firmware/lib/tmc/ic/TMC2160/README.md new file mode 100755 index 0000000..d89ef2a --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2160/README.md @@ -0,0 +1,46 @@ +# TMC2160 + + +## How to use + +To access the TMC2160's registers, the TMC-API offers two functions: **tmc2160_readRegister** and **tmc2160_writeRegister**. +Each of these functions takes in an **icID**, which is used to identify the IC when multiple ICs are connected. This identifier is passed down to the callback functions (see How to Integrate). + +## How to integrate: overview + +1. Include all the files of the TMC-API/ic/tmc/TMC2160 folder into the custom project. +2. Include the TMC2160.h file in the custom source code. +3. Implement the necessary callback functions (see below). +4. (optional): Take a look at the Examples subfolder for ready-made examples of the TMC-API usage. + +## Accessing the TMC2160 via SPI +The following diagram depicts how to access the TMC2160 via SPI using the TMC-API. + +![screenshot](registercall_hierarchy_flowchart_SPI.svg) + +The description of the functions, in the above flowchart, are as follows: +- The functions tmc2160_readRegister and tmc2160_writeRegister are used to read and write the registers respectively. These functions check the current active bus and calls the bus-specific function i.e readRegisterSPI or writeRegisterSPI. +- These bus specific functions constructs the datagram and further calls the bus specific callback 'tmcXXXX_readWriteSPI. +- This callback function further calls the hardware specific read/write function for SPI and needs to be implemented externally. + +### How to integrate: Callback functions +To communicate with TMC2160 IC, the TMC-API library needs to know which bus (UART, SPI) it shall use. For that, the callback function **'tmc2160_getBusType()'** needs to be implemented. +Additionally, implement the following callback functions to access the chip via SPI: +1. **tmc2160_readWriteSPI()**, which is a HAL wrapper function that provides the necessary hardware access. This function should also set the chip select pin CSN to low before starting the data transfer and set to high upon completion. Please refer to the datasheet of the IC for further details. + +### Option to use the cache logic for Write-Only registers +The chip features write-only registers that are unable to be read, necessitating the creation of a shadow copy to cache their contents. This copy is automatically updated whenever data is written to these registers. This cache logic could be enabled by setting the macro **TMC2160_CACHE** to **'1'** or disabled by setting to **'0'** respectively. If this feature is enabled then there comes another option to use **tmc2160_cache** function, which is already implemeted in the API, by defining **TMC2160_ENABLE_TMC_CACHE** macro to **'1** or one can implement their own function. The function **tmc2160_cache** works for both reading from and writing to the shadow array. It first checks whether the register has write-only access and data needs to be read from the hadow copy. On the basis of that, it returns **true** or **false**. The shadowRegisters on the premade cache implementation need to be one per chip. **TMC2160_IC_CACHE_COUNT** is set to '1' by default and is user-overwritable. If multiple chips are being used in the same project, increment its value to the number of chips connected. + +## Further info +### Dependency graph for the ICs with new register R/W mechanism +This graph illustrates the relationships between files within the TMC-API library, highlighting dependencies and identifying the files that are essential for integrating the library into the custom projects. + +![screenshot](uml-tmc-api.svg) + +### Example usage: TMC-Evalsystem +**For a reference usage of the TMC-API**, visit the [TMC-Evalsystem](https://github.com/analogdevicesinc/TMC-EvalSystem) + +## Migration status +The TMC2160 has been reworked to the access system described above. For more infos on the status of this and other ICs, check out the [migration page](https://github.com/analogdevicesinc/TMC-API/issues/53). + + diff --git a/firmware/lib/tmc/ic/TMC2160/TMC2160.c b/firmware/lib/tmc/ic/TMC2160/TMC2160.c new file mode 100755 index 0000000..8a174ab --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2160/TMC2160.c @@ -0,0 +1,192 @@ +/******************************************************************************* +* Copyright © 2018 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#include "TMC2160.h" + +/**************************************************************** Cache Implementation *************************************************************************/ +#if TMC2160_CACHE == 0 +static inline bool tmc2160_cache(uint16_t icID, TMC2160CacheOp operation, uint8_t address, uint32_t *value) +{ + UNUSED(icID); + UNUSED(address); + UNUSED(operation); + return false; +} +#else +#if TMC2160_ENABLE_TMC_CACHE == 1 + +uint8_t tmc2160_dirtyBits[TMC2160_IC_CACHE_COUNT][TMC2160_REGISTER_COUNT/8]= {0}; +int32_t tmc2160_shadowRegister[TMC2160_IC_CACHE_COUNT][TMC2160_REGISTER_COUNT]; + +void tmc2160_setDirtyBit(uint16_t icID, uint8_t index, bool value) + { + if(index >= TMC2160_REGISTER_COUNT) + return; + + uint8_t *tmp = &tmc2160_dirtyBits[icID][index / 8]; + uint8_t shift = (index % 8); + uint8_t mask = 1 << shift; + *tmp = (((*tmp) & (~(mask))) | (((value) << (shift)) & (mask))); +} + +bool tmc2160_getDirtyBit(uint16_t icID, uint8_t index) +{ + if(index >= TMC2160_REGISTER_COUNT) + return false; + + uint8_t *tmp = &tmc2160_dirtyBits[icID][index / 8]; + uint8_t shift = (index % 8); + return ((*tmp) >> shift) & 1; +} +/* + * This function is used to cache the value written to the Write-Only registers in the form of shadow array. + * The shadow copy is then used to read these kinds of registers. + */ + +bool tmc2160_cache(uint16_t icID, TMC2160CacheOp operation, uint8_t address, uint32_t *value) +{ + if (operation == TMC2160_CACHE_READ) + { + // Check if the value should come from cache + + // Only supported chips have a cache + if (icID >= TMC2160_IC_CACHE_COUNT) + return false; + + // Only non-readable registers care about caching + // Note: This could also be used to cache i.e. RW config registers to reduce bus accesses + if (TMC2160_IS_READABLE(tmc2160_registerAccess[address])) + return false; + + // Grab the value from the cache + *value = tmc2160_shadowRegister[icID][address]; + return true; + } + else if (operation == TMC2160_CACHE_WRITE || operation == TMC2160_CACHE_FILL_DEFAULT) + { + // Fill the cache + + // only supported chips have a cache + if (icID >= TMC2160_IC_CACHE_COUNT) + return false; + + // Write to the shadow register. + tmc2160_shadowRegister[icID][address] = *value; + // For write operations, mark the register dirty + if (operation == TMC2160_CACHE_WRITE) + { + tmc2160_setDirtyBit(icID, address, true); + } + + return true; + } + return false; +} + +void tmc2160_initCache() +{ + // Check if we have constants defined + if(ARRAY_SIZE(tmc2160_RegisterConstants) == 0) + return; + + size_t i, j, id; + + for(i = 0, j = 0; i < TMC2160_REGISTER_COUNT; i++) + { + // We only need to worry about hardware preset, write-only registers + // that have not yet been written (no dirty bit) here. + if(tmc2160_registerAccess[i] != TMC2160_ACCESS_W_PRESET) + continue; + + // Search the constant list for the current address. With the constant + // list being sorted in ascended order, we can walk through the list + // until the entry with an address equal or greater than i + while(j < ARRAY_SIZE(tmc2160_RegisterConstants) && (tmc2160_RegisterConstants[j].address < i)) + j++; + + // Abort when we reach the end of the constant list + if (j == ARRAY_SIZE(tmc2160_RegisterConstants)) + break; + + // If we have an entry for our current address, write the constant + if(tmc2160_RegisterConstants[j].address == i) + { + for (id = 0; id < TMC2160_IC_CACHE_COUNT; id++) + { + uint32_t temp = tmc2160_RegisterConstants[j].value; + tmc2160_cache(id, TMC2160_CACHE_FILL_DEFAULT, i, &temp); + } + } + } +} +#else +// User must implement their own cache +extern bool tmc2160_cache(uint16_t icID, TMC2160CacheOp operation, uint8_t address, uint32_t *value); +#endif +#endif + +/************************************************************* read / write Implementation *********************************************************************/ + + +static int32_t readRegisterSPI(uint16_t icID, uint8_t address); +static void writeRegisterSPI(uint16_t icID, uint8_t address, int32_t value); + + +int32_t tmc2160_readRegister(uint16_t icID, uint8_t address) +{ + return readRegisterSPI(icID, address); + + // ToDo: Error handling +} +void tmc2160_writeRegister(uint16_t icID, uint8_t address, int32_t value) +{ + writeRegisterSPI(icID, address, value); +} + +int32_t readRegisterSPI(uint16_t icID, uint8_t address) +{ + uint8_t data[5] = { 0 }; + uint32_t value; + + // Read from cache for registers with write-only access + if (tmc2160_cache(icID, TMC2160_CACHE_READ, address, &value)) + return value; + + // clear write bit + data[0] = address & TMC2160_ADDRESS_MASK; + + // Send the read request + tmc2160_readWriteSPI(icID, &data[0], sizeof(data)); + + // Rewrite address and clear write bit + data[0] = address & TMC2160_ADDRESS_MASK; + + // Send another request to receive the read reply + tmc2160_readWriteSPI(icID, &data[0], sizeof(data)); + + return ((int32_t)data[1] << 24) | ((int32_t) data[2] << 16) | ((int32_t) data[3] << 8) | ((int32_t) data[4]); +} + +void writeRegisterSPI(uint16_t icID, uint8_t address, int32_t value) +{ + uint8_t data[5] = { 0 }; + + data[0] = address | TMC2160_WRITE_BIT; + data[1] = 0xFF & (value>>24); + data[2] = 0xFF & (value>>16); + data[3] = 0xFF & (value>>8); + data[4] = 0xFF & (value>>0); + + // Send the write request + tmc2160_readWriteSPI(icID, &data[0], sizeof(data)); + + //Cache the registers with write-only access + tmc2160_cache(icID, TMC2160_CACHE_WRITE, address, (uint32_t *)&value); + + } diff --git a/firmware/lib/tmc/ic/TMC2160/TMC2160.h b/firmware/lib/tmc/ic/TMC2160/TMC2160.h new file mode 100755 index 0000000..8479b28 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2160/TMC2160.h @@ -0,0 +1,224 @@ +/******************************************************************************* +* Copyright © 2018 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#ifndef TMC_IC_TMC2160_H_ +#define TMC_IC_TMC2160_H_ + +#include +#include +#include +#include "TMC2160_HW_Abstraction.h" + +/****************************************************************************** +* API Configuration Defines +* These control optional features of the TMC-API implementation. +* These can be commented in/out here or defined from the build system. +*******************************************************************************/ + +// Uncomment if you want to save space..... +// and put the table into your own .c file +//#define TMC_API_EXTERNAL_CRC_TABLE 1 + +// To enable the cache mechanism in order to keep the copy of all registers, set TMC2160_CACHE to '1'. +// With this mechanism the value of write-only registers could be read from their shadow copies. +#ifndef TMC2160_CACHE +#define TMC2160_CACHE 1 +//#define TMC2160_CACHE 0 +#endif + +// To use the caching mechanism already implemented by the TMC-API, set TMC2160_ENABLE_TMC_CACHE to '1'. +// Set TMC2160_ENABLE_TMC_CACHE to '0' if one wants to have their own cache implementation. +#ifndef TMC2160_ENABLE_TMC_CACHE +#define TMC2160_ENABLE_TMC_CACHE 1 +//#define TMC2160_ENABLE_TMC_CACHE 0 +#endif + +/******************************************************************************/ + + +/************************************************************* read / write Implementation *********************************************************************/ + +// => TMC-API wrapper +extern void tmc2160_readWriteSPI(uint16_t icID, uint8_t *data, size_t dataLength); +// => TMC-API wrapper + +int32_t tmc2160_readRegister(uint16_t icID, uint8_t address); +void tmc2160_writeRegister(uint16_t icID, uint8_t address, int32_t value); + +typedef struct +{ + uint32_t mask; + uint8_t shift; + uint8_t address; + bool isSigned; +} TMC2160RegisterField; + +static inline uint32_t tmc2160_fieldExtract(uint32_t data, TMC2160RegisterField field) +{ + uint32_t value = (data & field.mask) >> field.shift; + + if (field.isSigned) + { + // Apply signedness conversion + uint32_t baseMask = field.mask >> field.shift; + uint32_t signMask = baseMask & (~baseMask >> 1); + value = (value ^ signMask) - signMask; + } + + return value; +} + +static inline uint32_t tmc2160_fieldRead(uint16_t icID, TMC2160RegisterField field) +{ + uint32_t value = tmc2160_readRegister(icID, field.address); + + return tmc2160_fieldExtract(value, field); +} + +static inline uint32_t tmc2160_fieldUpdate(uint32_t data, TMC2160RegisterField field, uint32_t value) +{ + return (data & (~field.mask)) | ((value << field.shift) & field.mask); +} + +static inline void tmc2160_fieldWrite(uint16_t icID, TMC2160RegisterField field, uint32_t value) +{ + uint32_t regValue = tmc2160_readRegister(icID, field.address); + + regValue = tmc2160_fieldUpdate(regValue, field, value); + + tmc2160_writeRegister(icID, field.address, regValue); +} + + +/***************** The following code is TMC-EvalSystem specific and needs to be commented out when working with other MCUs e.g Arduino*****************************/ + + +/**************************************************************** Cache Implementation *************************************************************************/ +#if TMC2160_CACHE == 1 +#ifdef TMC2160_ENABLE_TMC_CACHE + +// By default, support one IC in the cache +#ifndef TMC2160_IC_CACHE_COUNT +#define TMC2160_IC_CACHE_COUNT 1 +#endif + +typedef enum { + TMC2160_CACHE_READ, + TMC2160_CACHE_WRITE, + // Special operation: Put content into the cache without marking the entry as dirty. + // Only used to initialize the cache with hardware defaults. This will allow reading + // from write-only registers that have a value inside them on reset. When using this + // operation, a restore will *not* rewrite that filled register! + TMC2160_CACHE_FILL_DEFAULT, +} TMC2160CacheOp; + +typedef struct{ + uint8_t address; + uint32_t value; +} TMC2160RegisterConstants; + + +#define TMC2160_ACCESS_DIRTY 0x08 // Register has been written since reset -> shadow register is valid for restore +#define TMC2160_ACCESS_READ 0x01 +#define TMC2160_ACCESS_W_PRESET 0x42 +#define TMC2160_IS_READABLE(x) ((x) & TMC2160_ACCESS_READ) +#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) + +// Default Register values +#define R10 0x00070A03 // IHOLD_IRUN +#define R6C 0x10410153 // CHOPCONF +#define R70 0xC40C001E // PWMCONF + + +// Helper define: +// Most register permission arrays are initialized with 128 values. +// In those fields its quite hard to have an easy overview of available +// registers. For that, ____ is defined to 0, since 4 underscores are +// very easy to distinguish from the 2-digit hexadecimal values. +// This way, the used registers (permission != ACCESS_NONE) are easily spotted +// amongst unused (permission == ACCESS_NONE) registers. +#define ____ 0x00 + +// Helper define: +// Default reset values are not used if the corresponding register has a +// hardware preset. Since this is not directly visible in the default +// register reset values array, N_A is used as an indicator for a preset +// value, where any value will be ignored anyways (N_A: not available). +#define N_A 0 + +// Register access permissions: +// 0x00: none (reserved) +// 0x01: read +// 0x02: write +// 0x03: read/write +// 0x11: read to clear +// 0x42: write, has hardware presets on reset +static const uint8_t tmc2160_registerAccess[TMC2160_REGISTER_COUNT] = +{ +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0x03, 0x23, 0x01, 0x02, 0x23, 0x02, 0x02, 0x01, 0x42, 0x42, 0x42, 0x02, 0x01, ____, ____, ____, // 0x00 - 0x0F + 0x02, 0x02, 0x01, 0x02, 0x02, 0x02, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x10 - 0x1F + 0x03, 0x03, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x02, 0x02, 0x02, 0x03, ____, ____, // 0x20 - 0x2F + ____, ____, ____, 0x02, 0x03, 0x23, 0x01, ____, 0x03, 0x03, 0x02, 0x23, 0x01, 0x02, ____, ____, // 0x30 - 0x3F + ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x40 - 0x4F + ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x50 - 0x5F + 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x01, 0x01, 0x03, 0x02, 0x02, 0x01, // 0x60 - 0x6F + 0x02, 0x01, 0x01, 0x01, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____ // 0x70 - 0x7F +}; + +static const int32_t tmc2160_sampleRegisterPreset[TMC2160_REGISTER_COUNT] = +{ +// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x00 - 0x0F + R10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x10 - 0x1F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x20 - 0x2F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x30 - 0x3F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x40 - 0x4F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x50 - 0x5F + N_A, N_A, N_A, N_A, N_A, N_A, N_A, N_A, N_A, N_A, 0, 0, R6C, 0, 0, 0, // 0x60 - 0x6F + R70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x70 - 0x7F +}; + +// Undefine the default register values. +// This prevents warnings in case multiple TMC-API chip headers are included at once +#undef R10 +#undef R6C +#undef R70 + +// Register constants (only required for 0x42 registers, since we do not have +// any way to find out the content but want to hold the actual value in the +// shadow register so an application (i.e. the TMCL IDE) can still display +// the values. This only works when the register content is constant. +static const TMC2160RegisterConstants tmc2160_RegisterConstants[] = +{ // Use ascending addresses! + { 0x08, 0x00000000 }, // FACTORY_CONF + { 0x09, 0x00000000 }, // SHORT_CONF + { 0x0A, 0x00000000 }, // DRV_CONF + { 0x60, 0xAAAAB554 }, // MSLUT[0] + { 0x61, 0x4A9554AA }, // MSLUT[1] + { 0x62, 0x24492929 }, // MSLUT[2] + { 0x63, 0x10104222 }, // MSLUT[3] + { 0x64, 0xFBFFFFFF }, // MSLUT[4] + { 0x65, 0xB5BB777D }, // MSLUT[5] + { 0x66, 0x49295556 }, // MSLUT[6] + { 0x67, 0x00404222 }, // MSLUT[7] + { 0x68, 0xFFFF8056 }, // MSLUTSEL + { 0x69, 0x00F70000 } // MSLUTSTART +}; + +extern uint8_t tmc2160_dirtyBits[TMC2160_IC_CACHE_COUNT][TMC2160_REGISTER_COUNT/8]; +extern int32_t tmc2160_shadowRegister[TMC2160_IC_CACHE_COUNT][TMC2160_REGISTER_COUNT]; +extern bool tmc2160_cache(uint16_t icID, TMC2160CacheOp operation, uint8_t address, uint32_t *value); +extern void tmc2160_initCache(void); +void tmc2160_setDirtyBit(uint16_t icID, uint8_t index, bool value); +bool tmc2160_getDirtyBit(uint16_t icID, uint8_t index); +#endif +#endif +/***************************************************************************************************************************************************/ +#endif /* TMC_IC_TMC2160_H_ */ diff --git a/firmware/lib/tmc/ic/TMC2160/TMC2160_HW_Abstraction.h b/firmware/lib/tmc/ic/TMC2160/TMC2160_HW_Abstraction.h new file mode 100755 index 0000000..639361f --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2160/TMC2160_HW_Abstraction.h @@ -0,0 +1,1226 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2023 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + +#ifndef TMC2160_HW_ABSTRACTION +#define TMC2160_HW_ABSTRACTION + + +// Constants + +#define TMC2160_REGISTER_COUNT 128 // Default register count +#define TMC2160_MOTORS 1 +#define TMC2160_WRITE_BIT 0x80 +#define TMC2160_ADDRESS_MASK 0x7F +#define TMC2160_MAX_VELOCITY (int32_t) 2147483647 +#define TMC2160_MAX_ACCELERATION (uint32_t) 4294967295u + +// Registers in TMC2160 + +#define TMC2160_GCONF 0x00 +#define TMC2160_GSTAT 0x01 +#define TMC2160_IOIN___OUTPUT 0x04 +#define TMC2160_X_COMPARE 0x05 +#define TMC2160_OTP_PROG 0x06 +#define TMC2160_OTP_READ 0x07 +#define TMC2160_FACTORY_CONF 0x08 +#define TMC2160_SHORT_CONF 0x09 +#define TMC2160_DRV_CONF 0x0A +#define TMC2160_GLOBAL_SCALER 0x0B +#define TMC2160_OFFSET_READ 0x0C +#define TMC2160_IHOLD_IRUN 0x10 +#define TMC2160_TPOWERDOWN 0x11 +#define TMC2160_TSTEP 0x12 +#define TMC2160_TPWMTHRS 0x13 +#define TMC2160_TCOOLTHRS 0x14 +#define TMC2160_THIGH 0x15 +#define TMC2160_XDIRECT 0x2D +#define TMC2160_VDCMIN 0x33 +#define TMC2160_MSLUT__ 0x60 +//#define TMC2160_MSLUT__ 0x61 +//#define TMC2160_MSLUT__ 0x62 +//#define TMC2160_MSLUT__ 0x63 +//#define TMC2160_MSLUT__ 0x64 +//#define TMC2160_MSLUT__ 0x65 +//#define TMC2160_MSLUT__ 0x66 +//#define TMC2160_MSLUT__ 0x67 +#define TMC2160_MSLUTSEL 0x68 +#define TMC2160_MSLUTSTART 0x69 +#define TMC2160_MSCNT 0x6A +#define TMC2160_MSCURACT 0x6B +#define TMC2160_CHOPCONF 0x6C +#define TMC2160_COOLCONF 0x6D +#define TMC2160_DCCTRL 0x6E +#define TMC2160_DRV_STATUS 0x6F +#define TMC2160_PWMCONF 0x70 +#define TMC2160_PWM_SCALE 0x71 +#define TMC2160_PWM_AUTO 0x72 +#define TMC2160_LOST_STEPS 0x73 + +// Register fields in TMC2160 + + +#define TMC2160_RECALIBRATE_MASK 0x00000001 +#define TMC2160_RECALIBRATE_SHIFT 0 +#define TMC2160_RECALIBRATE_FIELD ((TMC2160RegisterField) {TMC2160_RECALIBRATE_MASK, TMC2160_RECALIBRATE_SHIFT, TMC2160_GCONF, false}) +#define TMC2160_FASTSTANDSTILL_MASK 0x00000002 +#define TMC2160_FASTSTANDSTILL_SHIFT 1 +#define TMC2160_FASTSTANDSTILL_FIELD ((TMC2160RegisterField) {TMC2160_FASTSTANDSTILL_MASK, TMC2160_FASTSTANDSTILL_SHIFT, TMC2160_GCONF, false}) +#define TMC2160_EN_PWM_MODE_MASK 0x00000004 +#define TMC2160_EN_PWM_MODE_SHIFT 2 +#define TMC2160_EN_PWM_MODE_FIELD ((TMC2160RegisterField) {TMC2160_EN_PWM_MODE_MASK, TMC2160_EN_PWM_MODE_SHIFT, TMC2160_GCONF, false}) +#define TMC2160_MULTISTEP_FILT_MASK 0x00000008 +#define TMC2160_MULTISTEP_FILT_SHIFT 3 +#define TMC2160_MULTISTEP_FILT_FIELD ((TMC2160RegisterField) {TMC2160_MULTISTEP_FILT_MASK, TMC2160_MULTISTEP_FILT_SHIFT, TMC2160_GCONF, false}) +#define TMC2160_SHAFT_MASK 0x00000010 +#define TMC2160_SHAFT_SHIFT 4 +#define TMC2160_SHAFT_FIELD ((TMC2160RegisterField) {TMC2160_SHAFT_MASK, TMC2160_SHAFT_SHIFT, TMC2160_GCONF, false}) +#define TMC2160_DIAG0_ERROR__ONLY_WITH_SD_MODE_1__MASK 0x00000020 +#define TMC2160_DIAG0_ERROR__ONLY_WITH_SD_MODE_1__SHIFT 5 +#define TMC2160_DIAG0_ERROR__ONLY_WITH_SD_MODE_1__FIELD ((TMC2160RegisterField) {TMC2160_DIAG0_ERROR__ONLY_WITH_SD_MODE_1__MASK, TMC2160_DIAG0_ERROR__ONLY_WITH_SD_MODE_1__SHIFT, TMC2160_GCONF, false}) +#define TMC2160_DIAG0_OTPW__ONLY_WITH_SD_MODE_1__MASK 0x00000040 +#define TMC2160_DIAG0_OTPW__ONLY_WITH_SD_MODE_1__SHIFT 6 +#define TMC2160_DIAG0_OTPW__ONLY_WITH_SD_MODE_1__FIELD ((TMC2160RegisterField) {TMC2160_DIAG0_OTPW__ONLY_WITH_SD_MODE_1__MASK, TMC2160_DIAG0_OTPW__ONLY_WITH_SD_MODE_1__SHIFT, TMC2160_GCONF, false}) +#define TMC2160_DIAG0_STALL_MASK 0x00000080 +#define TMC2160_DIAG0_STALL_SHIFT 7 +#define TMC2160_DIAG0_STALL_FIELD ((TMC2160RegisterField) {TMC2160_DIAG0_STALL_MASK, TMC2160_DIAG0_STALL_SHIFT, TMC2160_GCONF, false}) +#define TMC2160_DIAG1_STALL_MASK 0x00000100 +#define TMC2160_DIAG1_STALL_SHIFT 8 +#define TMC2160_DIAG1_STALL_FIELD ((TMC2160RegisterField) {TMC2160_DIAG1_STALL_MASK, TMC2160_DIAG1_STALL_SHIFT, TMC2160_GCONF, false}) +#define TMC2160_DIAG1_INDEX_MASK 0x00000200 +#define TMC2160_DIAG1_INDEX_SHIFT 9 +#define TMC2160_DIAG1_INDEX_FIELD ((TMC2160RegisterField) {TMC2160_DIAG1_INDEX_MASK, TMC2160_DIAG1_INDEX_SHIFT, TMC2160_GCONF, false}) +#define TMC2160_DIAG1_ONSTATE_MASK 0x00000400 +#define TMC2160_DIAG1_ONSTATE_SHIFT 10 +#define TMC2160_DIAG1_ONSTATE_FIELD ((TMC2160RegisterField) {TMC2160_DIAG1_ONSTATE_MASK, TMC2160_DIAG1_ONSTATE_SHIFT, TMC2160_GCONF, false}) +#define TMC2160_DIAG1_STEPS_SKIPPED_MASK 0x00000800 +#define TMC2160_DIAG1_STEPS_SKIPPED_SHIFT 11 +#define TMC2160_DIAG1_STEPS_SKIPPED_FIELD ((TMC2160RegisterField) {TMC2160_DIAG1_STEPS_SKIPPED_MASK, TMC2160_DIAG1_STEPS_SKIPPED_SHIFT, TMC2160_GCONF, false}) +#define TMC2160_DIAG0_INT_PUSHPULL_MASK 0x00001000 +#define TMC2160_DIAG0_INT_PUSHPULL_SHIFT 12 +#define TMC2160_DIAG0_INT_PUSHPULL_FIELD ((TMC2160RegisterField) {TMC2160_DIAG0_INT_PUSHPULL_MASK, TMC2160_DIAG0_INT_PUSHPULL_SHIFT, TMC2160_GCONF, false}) +#define TMC2160_DIAG1_POSCOMP_PUSHPULL_MASK 0x00002000 +#define TMC2160_DIAG1_POSCOMP_PUSHPULL_SHIFT 13 +#define TMC2160_DIAG1_POSCOMP_PUSHPULL_FIELD ((TMC2160RegisterField) {TMC2160_DIAG1_POSCOMP_PUSHPULL_MASK, TMC2160_DIAG1_POSCOMP_PUSHPULL_SHIFT, TMC2160_GCONF, false}) +#define TMC2160_SMALL_HYSTERESIS_MASK 0x00004000 +#define TMC2160_SMALL_HYSTERESIS_SHIFT 14 +#define TMC2160_SMALL_HYSTERESIS_FIELD ((TMC2160RegisterField) {TMC2160_SMALL_HYSTERESIS_MASK, TMC2160_SMALL_HYSTERESIS_SHIFT, TMC2160_GCONF, false}) +#define TMC2160_STOP_ENABLE_MASK 0x00008000 +#define TMC2160_STOP_ENABLE_SHIFT 15 +#define TMC2160_STOP_ENABLE_FIELD ((TMC2160RegisterField) {TMC2160_STOP_ENABLE_MASK, TMC2160_STOP_ENABLE_SHIFT, TMC2160_GCONF, false}) +#define TMC2160_DIRECT_MODE_MASK 0x00010000 +#define TMC2160_DIRECT_MODE_SHIFT 16 +#define TMC2160_DIRECT_MODE_FIELD ((TMC2160RegisterField) {TMC2160_DIRECT_MODE_MASK, TMC2160_DIRECT_MODE_SHIFT, TMC2160_GCONF, false}) +#define TMC2160_TEST_MODE_MASK 0x00020000 +#define TMC2160_TEST_MODE_SHIFT 17 +#define TMC2160_TEST_MODE_FIELD ((TMC2160RegisterField) {TMC2160_TEST_MODE_MASK, TMC2160_TEST_MODE_SHIFT, TMC2160_GCONF, false}) +#define TMC2160_DIAG0_STEP_MASK 0x00000080 +#define TMC2160_DIAG0_STEP_SHIFT 7 +#define TMC2160_DIAG0_STEP_FIELD ((TMC2160RegisterField) {TMC2160_DIAG0_STEP_MASK, TMC2160_DIAG0_STEP_SHIFT, TMC2160_GCONF, false}) +#define TMC2160_DIAG1_DIR_MASK 0x00000100 +#define TMC2160_DIAG1_DIR_SHIFT 8 +#define TMC2160_DIAG1_DIR_FIELD ((TMC2160RegisterField) {TMC2160_DIAG1_DIR_MASK, TMC2160_DIAG1_DIR_SHIFT, TMC2160_GCONF, false}) +#define TMC2160_RESET_MASK 0x00000001 +#define TMC2160_RESET_SHIFT 0 +#define TMC2160_RESET_FIELD ((TMC2160RegisterField) {TMC2160_RESET_MASK, TMC2160_RESET_SHIFT, TMC2160_GSTAT, false}) +#define TMC2160_DRV_ERR_MASK 0x00000002 +#define TMC2160_DRV_ERR_SHIFT 1 +#define TMC2160_DRV_ERR_FIELD ((TMC2160RegisterField) {TMC2160_DRV_ERR_MASK, TMC2160_DRV_ERR_SHIFT, TMC2160_GSTAT, false}) +#define TMC2160_UV_CP_MASK 0x00000004 +#define TMC2160_UV_CP_SHIFT 2 +#define TMC2160_UV_CP_FIELD ((TMC2160RegisterField) {TMC2160_UV_CP_MASK, TMC2160_UV_CP_SHIFT, TMC2160_GSTAT, false}) +#define TMC2160_STEP_MASK 0x00000001 +#define TMC2160_STEP_SHIFT 0 +#define TMC2160_STEP_FIELD ((TMC2160RegisterField) {TMC2160_STEP_MASK, TMC2160_STEP_SHIFT, TMC2160_IOIN / OUTPUT, false}) +#define TMC2160_DIR_MASK 0x00000002 +#define TMC2160_DIR_SHIFT 1 +#define TMC2160_DIR_FIELD ((TMC2160RegisterField) {TMC2160_DIR_MASK, TMC2160_DIR_SHIFT, TMC2160_IOIN / OUTPUT, false}) +#define TMC2160_DCEN_CFG4_MASK 0x00000004 +#define TMC2160_DCEN_CFG4_SHIFT 2 +#define TMC2160_DCEN_CFG4_FIELD ((TMC2160RegisterField) {TMC2160_DCEN_CFG4_MASK, TMC2160_DCEN_CFG4_SHIFT, TMC2160_IOIN / OUTPUT, false}) +#define TMC2160_DCIN_CFG5_MASK 0x00000008 +#define TMC2160_DCIN_CFG5_SHIFT 3 +#define TMC2160_DCIN_CFG5_FIELD ((TMC2160RegisterField) {TMC2160_DCIN_CFG5_MASK, TMC2160_DCIN_CFG5_SHIFT, TMC2160_IOIN / OUTPUT, false}) +#define TMC2160_DRV_ENN_MASK 0x00000010 +#define TMC2160_DRV_ENN_SHIFT 4 +#define TMC2160_DRV_ENN_FIELD ((TMC2160RegisterField) {TMC2160_DRV_ENN_MASK, TMC2160_DRV_ENN_SHIFT, TMC2160_IOIN / OUTPUT, false}) +#define TMC2160_DCO_CFG6_MASK 0x00000020 +#define TMC2160_DCO_CFG6_SHIFT 5 +#define TMC2160_DCO_CFG6_FIELD ((TMC2160RegisterField) {TMC2160_DCO_CFG6_MASK, TMC2160_DCO_CFG6_SHIFT, TMC2160_IOIN / OUTPUT, false}) +#define TMC2160_VERSION_MASK 0xFF000000 +#define TMC2160_VERSION_SHIFT 24 +#define TMC2160_VERSION_FIELD ((TMC2160RegisterField) {TMC2160_VERSION_MASK, TMC2160_VERSION_SHIFT, TMC2160_IOIN / OUTPUT, false}) +#define TMC2160_OUTPUT_PIN_POLARITY_MASK 0x00000001 +#define TMC2160_OUTPUT_PIN_POLARITY_SHIFT 0 +#define TMC2160_OUTPUT_PIN_POLARITY_FIELD ((TMC2160RegisterField) {TMC2160_OUTPUT_PIN_POLARITY_MASK, TMC2160_OUTPUT_PIN_POLARITY_SHIFT, TMC2160_IOIN / OUTPUT, false}) +#define TMC2160_X_COMPARE_MASK 0xFFFFFFFF +#define TMC2160_X_COMPARE_SHIFT 0 +#define TMC2160_X_COMPARE_FIELD ((TMC2160RegisterField) {TMC2160_X_COMPARE_MASK, TMC2160_X_COMPARE_SHIFT, TMC2160_X_COMPARE, false}) +#define TMC2160_OTPBIT_MASK 0x00000007 +#define TMC2160_OTPBIT_SHIFT 0 +#define TMC2160_OTPBIT_FIELD ((TMC2160RegisterField) {TMC2160_OTPBIT_MASK, TMC2160_OTPBIT_SHIFT, TMC2160_OTP_PROG, false}) +#define TMC2160_OTPBYTE_MASK 0x00000030 +#define TMC2160_OTPBYTE_SHIFT 4 +#define TMC2160_OTPBYTE_FIELD ((TMC2160RegisterField) {TMC2160_OTPBYTE_MASK, TMC2160_OTPBYTE_SHIFT, TMC2160_OTP_PROG, false}) +#define TMC2160_OTPMAGIC_MASK 0x0000FF00 +#define TMC2160_OTPMAGIC_SHIFT 8 +#define TMC2160_OTPMAGIC_FIELD ((TMC2160RegisterField) {TMC2160_OTPMAGIC_MASK, TMC2160_OTPMAGIC_SHIFT, TMC2160_OTP_PROG, false}) +#define TMC2160_OTP_TBL_MASK 0x00000080 +#define TMC2160_OTP_TBL_SHIFT 7 +#define TMC2160_OTP_TBL_FIELD ((TMC2160RegisterField) {TMC2160_OTP_TBL_MASK, TMC2160_OTP_TBL_SHIFT, TMC2160_OTP_READ, false}) +#define TMC2160_OTP_BBM_MASK 0x00000040 +#define TMC2160_OTP_BBM_SHIFT 6 +#define TMC2160_OTP_BBM_FIELD ((TMC2160RegisterField) {TMC2160_OTP_BBM_MASK, TMC2160_OTP_BBM_SHIFT, TMC2160_OTP_READ, false}) +#define TMC2160_OTP_S2_LEVEL_MASK 0x00000020 +#define TMC2160_OTP_S2_LEVEL_SHIFT 5 +#define TMC2160_OTP_S2_LEVEL_FIELD ((TMC2160RegisterField) {TMC2160_OTP_S2_LEVEL_MASK, TMC2160_OTP_S2_LEVEL_SHIFT, TMC2160_OTP_READ, false}) +#define TMC2160_OTP_FCLKTRIM_MASK 0x0000001F +#define TMC2160_OTP_FCLKTRIM_SHIFT 0 +#define TMC2160_OTP_FCLKTRIM_FIELD ((TMC2160RegisterField) {TMC2160_OTP_FCLKTRIM_MASK, TMC2160_OTP_FCLKTRIM_SHIFT, TMC2160_OTP_READ, false}) +#define TMC2160_FCLKTRIM_MASK 0x0000001F +#define TMC2160_FCLKTRIM_SHIFT 0 +#define TMC2160_FCLKTRIM_FIELD ((TMC2160RegisterField) {TMC2160_FCLKTRIM_MASK, TMC2160_FCLKTRIM_SHIFT, TMC2160_FACTORY_CONF, false}) +#define TMC2160_S2VS_LEVEL_MASK 0x0000000F +#define TMC2160_S2VS_LEVEL_SHIFT 0 +#define TMC2160_S2VS_LEVEL_FIELD ((TMC2160RegisterField) {TMC2160_S2VS_LEVEL_MASK, TMC2160_S2VS_LEVEL_SHIFT, TMC2160_SHORT_CONF, false}) +#define TMC2160_S2GND_LEVEL_MASK 0x00000F00 +#define TMC2160_S2GND_LEVEL_SHIFT 8 +#define TMC2160_S2GND_LEVEL_FIELD ((TMC2160RegisterField) {TMC2160_S2GND_LEVEL_MASK, TMC2160_S2GND_LEVEL_SHIFT, TMC2160_SHORT_CONF, false}) +#define TMC2160_SHORTFILTER_MASK 0x00030000 +#define TMC2160_SHORTFILTER_SHIFT 16 +#define TMC2160_SHORTFILTER_FIELD ((TMC2160RegisterField) {TMC2160_SHORTFILTER_MASK, TMC2160_SHORTFILTER_SHIFT, TMC2160_SHORT_CONF, false}) +#define TMC2160_SHORTDELAY_MASK 0x00040000 +#define TMC2160_SHORTDELAY_SHIFT 18 +#define TMC2160_SHORTDELAY_FIELD ((TMC2160RegisterField) {TMC2160_SHORTDELAY_MASK, TMC2160_SHORTDELAY_SHIFT, TMC2160_SHORT_CONF, false}) +#define TMC2160_BBMTIME_MASK 0x0000001F +#define TMC2160_BBMTIME_SHIFT 0 +#define TMC2160_BBMTIME_FIELD ((TMC2160RegisterField) {TMC2160_BBMTIME_MASK, TMC2160_BBMTIME_SHIFT, TMC2160_DRV_CONF, false}) +#define TMC2160_BBMCLKS_MASK 0x00000F00 +#define TMC2160_BBMCLKS_SHIFT 8 +#define TMC2160_BBMCLKS_FIELD ((TMC2160RegisterField) {TMC2160_BBMCLKS_MASK, TMC2160_BBMCLKS_SHIFT, TMC2160_DRV_CONF, false}) +#define TMC2160_OTSELECT_MASK 0x00030000 +#define TMC2160_OTSELECT_SHIFT 16 +#define TMC2160_OTSELECT_FIELD ((TMC2160RegisterField) {TMC2160_OTSELECT_MASK, TMC2160_OTSELECT_SHIFT, TMC2160_DRV_CONF, false}) +#define TMC2160_DRVSTRENGTH_MASK 0x000C0000 +#define TMC2160_DRVSTRENGTH_SHIFT 18 +#define TMC2160_DRVSTRENGTH_FIELD ((TMC2160RegisterField) {TMC2160_DRVSTRENGTH_MASK, TMC2160_DRVSTRENGTH_SHIFT, TMC2160_DRV_CONF, false}) +#define TMC2160_FILT_ISENSE_MASK 0x00300000 +#define TMC2160_FILT_ISENSE_SHIFT 20 +#define TMC2160_FILT_ISENSE_FIELD ((TMC2160RegisterField) {TMC2160_FILT_ISENSE_MASK, TMC2160_FILT_ISENSE_SHIFT, TMC2160_DRV_CONF, false}) +#define TMC2160_GLOBAL_SCALER_MASK 0x000000FF +#define TMC2160_GLOBAL_SCALER_SHIFT 0 +#define TMC2160_GLOBAL_SCALER_FIELD ((TMC2160RegisterField) {TMC2160_GLOBAL_SCALER_MASK, TMC2160_GLOBAL_SCALER_SHIFT, TMC2160_GLOBAL_SCALER, false}) +#define TMC2160_OFFSET_READ_A_MASK 0x0000FF00 +#define TMC2160_OFFSET_READ_A_SHIFT 8 +#define TMC2160_OFFSET_READ_A_FIELD ((TMC2160RegisterField) {TMC2160_OFFSET_READ_A_MASK, TMC2160_OFFSET_READ_A_SHIFT, TMC2160_OFFSET_READ, true}) +#define TMC2160_OFFSET_READ_B_MASK 0x000000FF +#define TMC2160_OFFSET_READ_B_SHIFT 0 +#define TMC2160_OFFSET_READ_B_FIELD ((TMC2160RegisterField) {TMC2160_OFFSET_READ_B_MASK, TMC2160_OFFSET_READ_B_SHIFT, TMC2160_OFFSET_READ, true}) +#define TMC2160_IHOLD_MASK 0x0000001F +#define TMC2160_IHOLD_SHIFT 0 +#define TMC2160_IHOLD_FIELD ((TMC2160RegisterField) {TMC2160_IHOLD_MASK, TMC2160_IHOLD_SHIFT, TMC2160_IHOLD_IRUN, false}) +#define TMC2160_IRUN_MASK 0x00001F00 +#define TMC2160_IRUN_SHIFT 8 +#define TMC2160_IRUN_FIELD ((TMC2160RegisterField) {TMC2160_IRUN_MASK, TMC2160_IRUN_SHIFT, TMC2160_IHOLD_IRUN, false}) +#define TMC2160_IHOLDDELAY_MASK 0x000F0000 +#define TMC2160_IHOLDDELAY_SHIFT 16 +#define TMC2160_IHOLDDELAY_FIELD ((TMC2160RegisterField) {TMC2160_IHOLDDELAY_MASK, TMC2160_IHOLDDELAY_SHIFT, TMC2160_IHOLD_IRUN, false}) +#define TMC2160_TPOWERDOWN_MASK 0x000000FF +#define TMC2160_TPOWERDOWN_SHIFT 0 +#define TMC2160_TPOWERDOWN_FIELD ((TMC2160RegisterField) {TMC2160_TPOWERDOWN_MASK, TMC2160_TPOWERDOWN_SHIFT, TMC2160_TPOWERDOWN, false}) +#define TMC2160_TSTEP_MASK 0x000FFFFF +#define TMC2160_TSTEP_SHIFT 0 +#define TMC2160_TSTEP_FIELD ((TMC2160RegisterField) {TMC2160_TSTEP_MASK, TMC2160_TSTEP_SHIFT, TMC2160_TSTEP, false}) +#define TMC2160_TPWMTHRS_MASK 0x000FFFFF +#define TMC2160_TPWMTHRS_SHIFT 0 +#define TMC2160_TPWMTHRS_FIELD ((TMC2160RegisterField) {TMC2160_TPWMTHRS_MASK, TMC2160_TPWMTHRS_SHIFT, TMC2160_TPWMTHRS, false}) +#define TMC2160_TCOOLTHRS_MASK 0x000FFFFF +#define TMC2160_TCOOLTHRS_SHIFT 0 +#define TMC2160_TCOOLTHRS_FIELD ((TMC2160RegisterField) {TMC2160_TCOOLTHRS_MASK, TMC2160_TCOOLTHRS_SHIFT, TMC2160_TCOOLTHRS, false}) +#define TMC2160_THIGH_MASK 0x000FFFFF +#define TMC2160_THIGH_SHIFT 0 +#define TMC2160_THIGH_FIELD ((TMC2160RegisterField) {TMC2160_THIGH_MASK, TMC2160_THIGH_SHIFT, TMC2160_THIGH, false}) +#define TMC2160_DIRECT_CURRENT_A_MASK 0x000001FF +#define TMC2160_DIRECT_CURRENT_A_SHIFT 0 +#define TMC2160_DIRECT_CURRENT_A_FIELD ((TMC2160RegisterField) {TMC2160_DIRECT_CURRENT_A_MASK, TMC2160_DIRECT_CURRENT_A_SHIFT, TMC2160_XDIRECT, true}) +#define TMC2160_DIRECT_CURRENT_B_MASK 0x01FF0000 +#define TMC2160_DIRECT_CURRENT_B_SHIFT 16 +#define TMC2160_DIRECT_CURRENT_B_FIELD ((TMC2160RegisterField) {TMC2160_DIRECT_CURRENT_B_MASK, TMC2160_DIRECT_CURRENT_B_SHIFT, TMC2160_XDIRECT, true}) +#define TMC2160_VDCMIN_MASK 0x007FFFFF +#define TMC2160_VDCMIN_SHIFT 0 +#define TMC2160_VDCMIN_FIELD ((TMC2160RegisterField) {TMC2160_VDCMIN_MASK, TMC2160_VDCMIN_SHIFT, TMC2160_VDCMIN, false}) +#define TMC2160_OFS0_MASK 0x00000001 +#define TMC2160_OFS0_SHIFT 0 +#define TMC2160_OFS0_FIELD ((TMC2160RegisterField) {TMC2160_OFS0_MASK, TMC2160_OFS0_SHIFT, TMC2160_MSLUT[0], false}) +#define TMC2160_OFS1_MASK 0x00000002 +#define TMC2160_OFS1_SHIFT 1 +#define TMC2160_OFS1_FIELD ((TMC2160RegisterField) {TMC2160_OFS1_MASK, TMC2160_OFS1_SHIFT, TMC2160_MSLUT[0], false}) +#define TMC2160_OFS2_MASK 0x00000004 +#define TMC2160_OFS2_SHIFT 2 +#define TMC2160_OFS2_FIELD ((TMC2160RegisterField) {TMC2160_OFS2_MASK, TMC2160_OFS2_SHIFT, TMC2160_MSLUT[0], false}) +#define TMC2160_OFS3_MASK 0x00000008 +#define TMC2160_OFS3_SHIFT 3 +#define TMC2160_OFS3_FIELD ((TMC2160RegisterField) {TMC2160_OFS3_MASK, TMC2160_OFS3_SHIFT, TMC2160_MSLUT[0], false}) +#define TMC2160_OFS4_MASK 0x00000010 +#define TMC2160_OFS4_SHIFT 4 +#define TMC2160_OFS4_FIELD ((TMC2160RegisterField) {TMC2160_OFS4_MASK, TMC2160_OFS4_SHIFT, TMC2160_MSLUT[0], false}) +#define TMC2160_OFS5_MASK 0x00000020 +#define TMC2160_OFS5_SHIFT 5 +#define TMC2160_OFS5_FIELD ((TMC2160RegisterField) {TMC2160_OFS5_MASK, TMC2160_OFS5_SHIFT, TMC2160_MSLUT[0], false}) +#define TMC2160_OFS6_MASK 0x00000040 +#define TMC2160_OFS6_SHIFT 6 +#define TMC2160_OFS6_FIELD ((TMC2160RegisterField) {TMC2160_OFS6_MASK, TMC2160_OFS6_SHIFT, TMC2160_MSLUT[0], false}) +#define TMC2160_OFS7_MASK 0x00000080 +#define TMC2160_OFS7_SHIFT 7 +#define TMC2160_OFS7_FIELD ((TMC2160RegisterField) {TMC2160_OFS7_MASK, TMC2160_OFS7_SHIFT, TMC2160_MSLUT[0], false}) +#define TMC2160_OFS8_MASK 0x00000100 +#define TMC2160_OFS8_SHIFT 8 +#define TMC2160_OFS8_FIELD ((TMC2160RegisterField) {TMC2160_OFS8_MASK, TMC2160_OFS8_SHIFT, TMC2160_MSLUT[0], false}) +#define TMC2160_OFS9_MASK 0x00000200 +#define TMC2160_OFS9_SHIFT 9 +#define TMC2160_OFS9_FIELD ((TMC2160RegisterField) {TMC2160_OFS9_MASK, TMC2160_OFS9_SHIFT, TMC2160_MSLUT[0], false}) +#define TMC2160_OFS10_MASK 0x00000400 +#define TMC2160_OFS10_SHIFT 10 +#define TMC2160_OFS10_FIELD ((TMC2160RegisterField) {TMC2160_OFS10_MASK, TMC2160_OFS10_SHIFT, TMC2160_MSLUT[0], false}) +#define TMC2160_OFS11_MASK 0x00000800 +#define TMC2160_OFS11_SHIFT 11 +#define TMC2160_OFS11_FIELD ((TMC2160RegisterField) {TMC2160_OFS11_MASK, TMC2160_OFS11_SHIFT, TMC2160_MSLUT[0], false}) +#define TMC2160_OFS12_MASK 0x00001000 +#define TMC2160_OFS12_SHIFT 12 +#define TMC2160_OFS12_FIELD ((TMC2160RegisterField) {TMC2160_OFS12_MASK, TMC2160_OFS12_SHIFT, TMC2160_MSLUT[0], false}) +#define TMC2160_OFS13_MASK 0x00002000 +#define TMC2160_OFS13_SHIFT 13 +#define TMC2160_OFS13_FIELD ((TMC2160RegisterField) {TMC2160_OFS13_MASK, TMC2160_OFS13_SHIFT, TMC2160_MSLUT[0], false}) +#define TMC2160_OFS14_MASK 0x00004000 +#define TMC2160_OFS14_SHIFT 14 +#define TMC2160_OFS14_FIELD ((TMC2160RegisterField) {TMC2160_OFS14_MASK, TMC2160_OFS14_SHIFT, TMC2160_MSLUT[0], false}) +#define TMC2160_OFS15_MASK 0x00008000 +#define TMC2160_OFS15_SHIFT 15 +#define TMC2160_OFS15_FIELD ((TMC2160RegisterField) {TMC2160_OFS15_MASK, TMC2160_OFS15_SHIFT, TMC2160_MSLUT[0], false}) +#define TMC2160_OFS16_MASK 0x00010000 +#define TMC2160_OFS16_SHIFT 16 +#define TMC2160_OFS16_FIELD ((TMC2160RegisterField) {TMC2160_OFS16_MASK, TMC2160_OFS16_SHIFT, TMC2160_MSLUT[0], false}) +#define TMC2160_OFS17_MASK 0x00020000 +#define TMC2160_OFS17_SHIFT 17 +#define TMC2160_OFS17_FIELD ((TMC2160RegisterField) {TMC2160_OFS17_MASK, TMC2160_OFS17_SHIFT, TMC2160_MSLUT[0], false}) +#define TMC2160_OFS18_MASK 0x00040000 +#define TMC2160_OFS18_SHIFT 18 +#define TMC2160_OFS18_FIELD ((TMC2160RegisterField) {TMC2160_OFS18_MASK, TMC2160_OFS18_SHIFT, TMC2160_MSLUT[0], false}) +#define TMC2160_OFS19_MASK 0x00080000 +#define TMC2160_OFS19_SHIFT 19 +#define TMC2160_OFS19_FIELD ((TMC2160RegisterField) {TMC2160_OFS19_MASK, TMC2160_OFS19_SHIFT, TMC2160_MSLUT[0], false}) +#define TMC2160_OFS20_MASK 0x00100000 +#define TMC2160_OFS20_SHIFT 20 +#define TMC2160_OFS20_FIELD ((TMC2160RegisterField) {TMC2160_OFS20_MASK, TMC2160_OFS20_SHIFT, TMC2160_MSLUT[0], false}) +#define TMC2160_OFS21_MASK 0x00200000 +#define TMC2160_OFS21_SHIFT 21 +#define TMC2160_OFS21_FIELD ((TMC2160RegisterField) {TMC2160_OFS21_MASK, TMC2160_OFS21_SHIFT, TMC2160_MSLUT[0], false}) +#define TMC2160_OFS22_MASK 0x00400000 +#define TMC2160_OFS22_SHIFT 22 +#define TMC2160_OFS22_FIELD ((TMC2160RegisterField) {TMC2160_OFS22_MASK, TMC2160_OFS22_SHIFT, TMC2160_MSLUT[0], false}) +#define TMC2160_OFS23_MASK 0x00800000 +#define TMC2160_OFS23_SHIFT 23 +#define TMC2160_OFS23_FIELD ((TMC2160RegisterField) {TMC2160_OFS23_MASK, TMC2160_OFS23_SHIFT, TMC2160_MSLUT[0], false}) +#define TMC2160_OFS24_MASK 0x01000000 +#define TMC2160_OFS24_SHIFT 24 +#define TMC2160_OFS24_FIELD ((TMC2160RegisterField) {TMC2160_OFS24_MASK, TMC2160_OFS24_SHIFT, TMC2160_MSLUT[0], false}) +#define TMC2160_OFS25_MASK 0x02000000 +#define TMC2160_OFS25_SHIFT 25 +#define TMC2160_OFS25_FIELD ((TMC2160RegisterField) {TMC2160_OFS25_MASK, TMC2160_OFS25_SHIFT, TMC2160_MSLUT[0], false}) +#define TMC2160_OFS26_MASK 0x04000000 +#define TMC2160_OFS26_SHIFT 26 +#define TMC2160_OFS26_FIELD ((TMC2160RegisterField) {TMC2160_OFS26_MASK, TMC2160_OFS26_SHIFT, TMC2160_MSLUT[0], false}) +#define TMC2160_OFS27_MASK 0x08000000 +#define TMC2160_OFS27_SHIFT 27 +#define TMC2160_OFS27_FIELD ((TMC2160RegisterField) {TMC2160_OFS27_MASK, TMC2160_OFS27_SHIFT, TMC2160_MSLUT[0], false}) +#define TMC2160_OFS28_MASK 0x10000000 +#define TMC2160_OFS28_SHIFT 28 +#define TMC2160_OFS28_FIELD ((TMC2160RegisterField) {TMC2160_OFS28_MASK, TMC2160_OFS28_SHIFT, TMC2160_MSLUT[0], false}) +#define TMC2160_OFS29_MASK 0x20000000 +#define TMC2160_OFS29_SHIFT 29 +#define TMC2160_OFS29_FIELD ((TMC2160RegisterField) {TMC2160_OFS29_MASK, TMC2160_OFS29_SHIFT, TMC2160_MSLUT[0], false}) +#define TMC2160_OFS30_MASK 0x40000000 +#define TMC2160_OFS30_SHIFT 30 +#define TMC2160_OFS30_FIELD ((TMC2160RegisterField) {TMC2160_OFS30_MASK, TMC2160_OFS30_SHIFT, TMC2160_MSLUT[0], false}) +#define TMC2160_OFS31_MASK 0x80000000 +#define TMC2160_OFS31_SHIFT 31 +#define TMC2160_OFS31_FIELD ((TMC2160RegisterField) {TMC2160_OFS31_MASK, TMC2160_OFS31_SHIFT, TMC2160_MSLUT[0], false}) +#define TMC2160_OFS32_MASK 0x00000001 +#define TMC2160_OFS32_SHIFT 0 +#define TMC2160_OFS32_FIELD ((TMC2160RegisterField) {TMC2160_OFS32_MASK, TMC2160_OFS32_SHIFT, TMC2160_MSLUT[1], false}) +#define TMC2160_OFS33_MASK 0x00000002 +#define TMC2160_OFS33_SHIFT 1 +#define TMC2160_OFS33_FIELD ((TMC2160RegisterField) {TMC2160_OFS33_MASK, TMC2160_OFS33_SHIFT, TMC2160_MSLUT[1], false}) +#define TMC2160_OFS34_MASK 0x00000004 +#define TMC2160_OFS34_SHIFT 2 +#define TMC2160_OFS34_FIELD ((TMC2160RegisterField) {TMC2160_OFS34_MASK, TMC2160_OFS34_SHIFT, TMC2160_MSLUT[1], false}) +#define TMC2160_OFS35_MASK 0x00000008 +#define TMC2160_OFS35_SHIFT 3 +#define TMC2160_OFS35_FIELD ((TMC2160RegisterField) {TMC2160_OFS35_MASK, TMC2160_OFS35_SHIFT, TMC2160_MSLUT[1], false}) +#define TMC2160_OFS36_MASK 0x00000010 +#define TMC2160_OFS36_SHIFT 4 +#define TMC2160_OFS36_FIELD ((TMC2160RegisterField) {TMC2160_OFS36_MASK, TMC2160_OFS36_SHIFT, TMC2160_MSLUT[1], false}) +#define TMC2160_OFS37_MASK 0x00000020 +#define TMC2160_OFS37_SHIFT 5 +#define TMC2160_OFS37_FIELD ((TMC2160RegisterField) {TMC2160_OFS37_MASK, TMC2160_OFS37_SHIFT, TMC2160_MSLUT[1], false}) +#define TMC2160_OFS38_MASK 0x00000040 +#define TMC2160_OFS38_SHIFT 6 +#define TMC2160_OFS38_FIELD ((TMC2160RegisterField) {TMC2160_OFS38_MASK, TMC2160_OFS38_SHIFT, TMC2160_MSLUT[1], false}) +#define TMC2160_OFS39_MASK 0x00000080 +#define TMC2160_OFS39_SHIFT 7 +#define TMC2160_OFS39_FIELD ((TMC2160RegisterField) {TMC2160_OFS39_MASK, TMC2160_OFS39_SHIFT, TMC2160_MSLUT[1], false}) +#define TMC2160_OFS40_MASK 0x00000100 +#define TMC2160_OFS40_SHIFT 8 +#define TMC2160_OFS40_FIELD ((TMC2160RegisterField) {TMC2160_OFS40_MASK, TMC2160_OFS40_SHIFT, TMC2160_MSLUT[1], false}) +#define TMC2160_OFS41_MASK 0x00000200 +#define TMC2160_OFS41_SHIFT 9 +#define TMC2160_OFS41_FIELD ((TMC2160RegisterField) {TMC2160_OFS41_MASK, TMC2160_OFS41_SHIFT, TMC2160_MSLUT[1], false}) +#define TMC2160_OFS42_MASK 0x00000400 +#define TMC2160_OFS42_SHIFT 10 +#define TMC2160_OFS42_FIELD ((TMC2160RegisterField) {TMC2160_OFS42_MASK, TMC2160_OFS42_SHIFT, TMC2160_MSLUT[1], false}) +#define TMC2160_OFS43_MASK 0x00000800 +#define TMC2160_OFS43_SHIFT 11 +#define TMC2160_OFS43_FIELD ((TMC2160RegisterField) {TMC2160_OFS43_MASK, TMC2160_OFS43_SHIFT, TMC2160_MSLUT[1], false}) +#define TMC2160_OFS44_MASK 0x00001000 +#define TMC2160_OFS44_SHIFT 12 +#define TMC2160_OFS44_FIELD ((TMC2160RegisterField) {TMC2160_OFS44_MASK, TMC2160_OFS44_SHIFT, TMC2160_MSLUT[1], false}) +#define TMC2160_OFS45_MASK 0x00002000 +#define TMC2160_OFS45_SHIFT 13 +#define TMC2160_OFS45_FIELD ((TMC2160RegisterField) {TMC2160_OFS45_MASK, TMC2160_OFS45_SHIFT, TMC2160_MSLUT[1], false}) +#define TMC2160_OFS46_MASK 0x00004000 +#define TMC2160_OFS46_SHIFT 14 +#define TMC2160_OFS46_FIELD ((TMC2160RegisterField) {TMC2160_OFS46_MASK, TMC2160_OFS46_SHIFT, TMC2160_MSLUT[1], false}) +#define TMC2160_OFS47_MASK 0x00008000 +#define TMC2160_OFS47_SHIFT 15 +#define TMC2160_OFS47_FIELD ((TMC2160RegisterField) {TMC2160_OFS47_MASK, TMC2160_OFS47_SHIFT, TMC2160_MSLUT[1], false}) +#define TMC2160_OFS48_MASK 0x00010000 +#define TMC2160_OFS48_SHIFT 16 +#define TMC2160_OFS48_FIELD ((TMC2160RegisterField) {TMC2160_OFS48_MASK, TMC2160_OFS48_SHIFT, TMC2160_MSLUT[1], false}) +#define TMC2160_OFS49_MASK 0x00020000 +#define TMC2160_OFS49_SHIFT 17 +#define TMC2160_OFS49_FIELD ((TMC2160RegisterField) {TMC2160_OFS49_MASK, TMC2160_OFS49_SHIFT, TMC2160_MSLUT[1], false}) +#define TMC2160_OFS50_MASK 0x00040000 +#define TMC2160_OFS50_SHIFT 18 +#define TMC2160_OFS50_FIELD ((TMC2160RegisterField) {TMC2160_OFS50_MASK, TMC2160_OFS50_SHIFT, TMC2160_MSLUT[1], false}) +#define TMC2160_OFS51_MASK 0x00080000 +#define TMC2160_OFS51_SHIFT 19 +#define TMC2160_OFS51_FIELD ((TMC2160RegisterField) {TMC2160_OFS51_MASK, TMC2160_OFS51_SHIFT, TMC2160_MSLUT[1], false}) +#define TMC2160_OFS52_MASK 0x00100000 +#define TMC2160_OFS52_SHIFT 20 +#define TMC2160_OFS52_FIELD ((TMC2160RegisterField) {TMC2160_OFS52_MASK, TMC2160_OFS52_SHIFT, TMC2160_MSLUT[1], false}) +#define TMC2160_OFS53_MASK 0x00200000 +#define TMC2160_OFS53_SHIFT 21 +#define TMC2160_OFS53_FIELD ((TMC2160RegisterField) {TMC2160_OFS53_MASK, TMC2160_OFS53_SHIFT, TMC2160_MSLUT[1], false}) +#define TMC2160_OFS54_MASK 0x00400000 +#define TMC2160_OFS54_SHIFT 22 +#define TMC2160_OFS54_FIELD ((TMC2160RegisterField) {TMC2160_OFS54_MASK, TMC2160_OFS54_SHIFT, TMC2160_MSLUT[1], false}) +#define TMC2160_OFS55_MASK 0x00800000 +#define TMC2160_OFS55_SHIFT 23 +#define TMC2160_OFS55_FIELD ((TMC2160RegisterField) {TMC2160_OFS55_MASK, TMC2160_OFS55_SHIFT, TMC2160_MSLUT[1], false}) +#define TMC2160_OFS56_MASK 0x01000000 +#define TMC2160_OFS56_SHIFT 24 +#define TMC2160_OFS56_FIELD ((TMC2160RegisterField) {TMC2160_OFS56_MASK, TMC2160_OFS56_SHIFT, TMC2160_MSLUT[1], false}) +#define TMC2160_OFS57_MASK 0x02000000 +#define TMC2160_OFS57_SHIFT 25 +#define TMC2160_OFS57_FIELD ((TMC2160RegisterField) {TMC2160_OFS57_MASK, TMC2160_OFS57_SHIFT, TMC2160_MSLUT[1], false}) +#define TMC2160_OFS58_MASK 0x04000000 +#define TMC2160_OFS58_SHIFT 26 +#define TMC2160_OFS58_FIELD ((TMC2160RegisterField) {TMC2160_OFS58_MASK, TMC2160_OFS58_SHIFT, TMC2160_MSLUT[1], false}) +#define TMC2160_OFS59_MASK 0x08000000 +#define TMC2160_OFS59_SHIFT 27 +#define TMC2160_OFS59_FIELD ((TMC2160RegisterField) {TMC2160_OFS59_MASK, TMC2160_OFS59_SHIFT, TMC2160_MSLUT[1], false}) +#define TMC2160_OFS60_MASK 0x10000000 +#define TMC2160_OFS60_SHIFT 28 +#define TMC2160_OFS60_FIELD ((TMC2160RegisterField) {TMC2160_OFS60_MASK, TMC2160_OFS60_SHIFT, TMC2160_MSLUT[1], false}) +#define TMC2160_OFS61_MASK 0x20000000 +#define TMC2160_OFS61_SHIFT 29 +#define TMC2160_OFS61_FIELD ((TMC2160RegisterField) {TMC2160_OFS61_MASK, TMC2160_OFS61_SHIFT, TMC2160_MSLUT[1], false}) +#define TMC2160_OFS62_MASK 0x40000000 +#define TMC2160_OFS62_SHIFT 30 +#define TMC2160_OFS62_FIELD ((TMC2160RegisterField) {TMC2160_OFS62_MASK, TMC2160_OFS62_SHIFT, TMC2160_MSLUT[1], false}) +#define TMC2160_OFS63_MASK 0x80000000 +#define TMC2160_OFS63_SHIFT 31 +#define TMC2160_OFS63_FIELD ((TMC2160RegisterField) {TMC2160_OFS63_MASK, TMC2160_OFS63_SHIFT, TMC2160_MSLUT[1], false}) +#define TMC2160_OFS64_MASK 0x00000001 +#define TMC2160_OFS64_SHIFT 0 +#define TMC2160_OFS64_FIELD ((TMC2160RegisterField) {TMC2160_OFS64_MASK, TMC2160_OFS64_SHIFT, TMC2160_MSLUT[2], false}) +#define TMC2160_OFS65_MASK 0x00000002 +#define TMC2160_OFS65_SHIFT 1 +#define TMC2160_OFS65_FIELD ((TMC2160RegisterField) {TMC2160_OFS65_MASK, TMC2160_OFS65_SHIFT, TMC2160_MSLUT[2], false}) +#define TMC2160_OFS66_MASK 0x00000004 +#define TMC2160_OFS66_SHIFT 2 +#define TMC2160_OFS66_FIELD ((TMC2160RegisterField) {TMC2160_OFS66_MASK, TMC2160_OFS66_SHIFT, TMC2160_MSLUT[2], false}) +#define TMC2160_OFS67_MASK 0x00000008 +#define TMC2160_OFS67_SHIFT 3 +#define TMC2160_OFS67_FIELD ((TMC2160RegisterField) {TMC2160_OFS67_MASK, TMC2160_OFS67_SHIFT, TMC2160_MSLUT[2], false}) +#define TMC2160_OFS68_MASK 0x00000010 +#define TMC2160_OFS68_SHIFT 4 +#define TMC2160_OFS68_FIELD ((TMC2160RegisterField) {TMC2160_OFS68_MASK, TMC2160_OFS68_SHIFT, TMC2160_MSLUT[2], false}) +#define TMC2160_OFS69_MASK 0x00000020 +#define TMC2160_OFS69_SHIFT 5 +#define TMC2160_OFS69_FIELD ((TMC2160RegisterField) {TMC2160_OFS69_MASK, TMC2160_OFS69_SHIFT, TMC2160_MSLUT[2], false}) +#define TMC2160_OFS70_MASK 0x00000040 +#define TMC2160_OFS70_SHIFT 6 +#define TMC2160_OFS70_FIELD ((TMC2160RegisterField) {TMC2160_OFS70_MASK, TMC2160_OFS70_SHIFT, TMC2160_MSLUT[2], false}) +#define TMC2160_OFS71_MASK 0x00000080 +#define TMC2160_OFS71_SHIFT 7 +#define TMC2160_OFS71_FIELD ((TMC2160RegisterField) {TMC2160_OFS71_MASK, TMC2160_OFS71_SHIFT, TMC2160_MSLUT[2], false}) +#define TMC2160_OFS72_MASK 0x00000100 +#define TMC2160_OFS72_SHIFT 8 +#define TMC2160_OFS72_FIELD ((TMC2160RegisterField) {TMC2160_OFS72_MASK, TMC2160_OFS72_SHIFT, TMC2160_MSLUT[2], false}) +#define TMC2160_OFS73_MASK 0x00000200 +#define TMC2160_OFS73_SHIFT 9 +#define TMC2160_OFS73_FIELD ((TMC2160RegisterField) {TMC2160_OFS73_MASK, TMC2160_OFS73_SHIFT, TMC2160_MSLUT[2], false}) +#define TMC2160_OFS74_MASK 0x00000400 +#define TMC2160_OFS74_SHIFT 10 +#define TMC2160_OFS74_FIELD ((TMC2160RegisterField) {TMC2160_OFS74_MASK, TMC2160_OFS74_SHIFT, TMC2160_MSLUT[2], false}) +#define TMC2160_OFS75_MASK 0x00000800 +#define TMC2160_OFS75_SHIFT 11 +#define TMC2160_OFS75_FIELD ((TMC2160RegisterField) {TMC2160_OFS75_MASK, TMC2160_OFS75_SHIFT, TMC2160_MSLUT[2], false}) +#define TMC2160_OFS76_MASK 0x00001000 +#define TMC2160_OFS76_SHIFT 12 +#define TMC2160_OFS76_FIELD ((TMC2160RegisterField) {TMC2160_OFS76_MASK, TMC2160_OFS76_SHIFT, TMC2160_MSLUT[2], false}) +#define TMC2160_OFS77_MASK 0x00002000 +#define TMC2160_OFS77_SHIFT 13 +#define TMC2160_OFS77_FIELD ((TMC2160RegisterField) {TMC2160_OFS77_MASK, TMC2160_OFS77_SHIFT, TMC2160_MSLUT[2], false}) +#define TMC2160_OFS78_MASK 0x00004000 +#define TMC2160_OFS78_SHIFT 14 +#define TMC2160_OFS78_FIELD ((TMC2160RegisterField) {TMC2160_OFS78_MASK, TMC2160_OFS78_SHIFT, TMC2160_MSLUT[2], false}) +#define TMC2160_OFS79_MASK 0x00008000 +#define TMC2160_OFS79_SHIFT 15 +#define TMC2160_OFS79_FIELD ((TMC2160RegisterField) {TMC2160_OFS79_MASK, TMC2160_OFS79_SHIFT, TMC2160_MSLUT[2], false}) +#define TMC2160_OFS80_MASK 0x00010000 +#define TMC2160_OFS80_SHIFT 16 +#define TMC2160_OFS80_FIELD ((TMC2160RegisterField) {TMC2160_OFS80_MASK, TMC2160_OFS80_SHIFT, TMC2160_MSLUT[2], false}) +#define TMC2160_OFS81_MASK 0x00020000 +#define TMC2160_OFS81_SHIFT 17 +#define TMC2160_OFS81_FIELD ((TMC2160RegisterField) {TMC2160_OFS81_MASK, TMC2160_OFS81_SHIFT, TMC2160_MSLUT[2], false}) +#define TMC2160_OFS82_MASK 0x00040000 +#define TMC2160_OFS82_SHIFT 18 +#define TMC2160_OFS82_FIELD ((TMC2160RegisterField) {TMC2160_OFS82_MASK, TMC2160_OFS82_SHIFT, TMC2160_MSLUT[2], false}) +#define TMC2160_OFS83_MASK 0x00080000 +#define TMC2160_OFS83_SHIFT 19 +#define TMC2160_OFS83_FIELD ((TMC2160RegisterField) {TMC2160_OFS83_MASK, TMC2160_OFS83_SHIFT, TMC2160_MSLUT[2], false}) +#define TMC2160_OFS84_MASK 0x00100000 +#define TMC2160_OFS84_SHIFT 20 +#define TMC2160_OFS84_FIELD ((TMC2160RegisterField) {TMC2160_OFS84_MASK, TMC2160_OFS84_SHIFT, TMC2160_MSLUT[2], false}) +#define TMC2160_OFS85_MASK 0x00200000 +#define TMC2160_OFS85_SHIFT 21 +#define TMC2160_OFS85_FIELD ((TMC2160RegisterField) {TMC2160_OFS85_MASK, TMC2160_OFS85_SHIFT, TMC2160_MSLUT[2], false}) +#define TMC2160_OFS86_MASK 0x00400000 +#define TMC2160_OFS86_SHIFT 22 +#define TMC2160_OFS86_FIELD ((TMC2160RegisterField) {TMC2160_OFS86_MASK, TMC2160_OFS86_SHIFT, TMC2160_MSLUT[2], false}) +#define TMC2160_OFS87_MASK 0x00800000 +#define TMC2160_OFS87_SHIFT 23 +#define TMC2160_OFS87_FIELD ((TMC2160RegisterField) {TMC2160_OFS87_MASK, TMC2160_OFS87_SHIFT, TMC2160_MSLUT[2], false}) +#define TMC2160_OFS88_MASK 0x01000000 +#define TMC2160_OFS88_SHIFT 24 +#define TMC2160_OFS88_FIELD ((TMC2160RegisterField) {TMC2160_OFS88_MASK, TMC2160_OFS88_SHIFT, TMC2160_MSLUT[2], false}) +#define TMC2160_OFS89_MASK 0x02000000 +#define TMC2160_OFS89_SHIFT 25 +#define TMC2160_OFS89_FIELD ((TMC2160RegisterField) {TMC2160_OFS89_MASK, TMC2160_OFS89_SHIFT, TMC2160_MSLUT[2], false}) +#define TMC2160_OFS90_MASK 0x04000000 +#define TMC2160_OFS90_SHIFT 26 +#define TMC2160_OFS90_FIELD ((TMC2160RegisterField) {TMC2160_OFS90_MASK, TMC2160_OFS90_SHIFT, TMC2160_MSLUT[2], false}) +#define TMC2160_OFS91_MASK 0x08000000 +#define TMC2160_OFS91_SHIFT 27 +#define TMC2160_OFS91_FIELD ((TMC2160RegisterField) {TMC2160_OFS91_MASK, TMC2160_OFS91_SHIFT, TMC2160_MSLUT[2], false}) +#define TMC2160_OFS92_MASK 0x10000000 +#define TMC2160_OFS92_SHIFT 28 +#define TMC2160_OFS92_FIELD ((TMC2160RegisterField) {TMC2160_OFS92_MASK, TMC2160_OFS92_SHIFT, TMC2160_MSLUT[2], false}) +#define TMC2160_OFS93_MASK 0x20000000 +#define TMC2160_OFS93_SHIFT 29 +#define TMC2160_OFS93_FIELD ((TMC2160RegisterField) {TMC2160_OFS93_MASK, TMC2160_OFS93_SHIFT, TMC2160_MSLUT[2], false}) +#define TMC2160_OFS94_MASK 0x40000000 +#define TMC2160_OFS94_SHIFT 30 +#define TMC2160_OFS94_FIELD ((TMC2160RegisterField) {TMC2160_OFS94_MASK, TMC2160_OFS94_SHIFT, TMC2160_MSLUT[2], false}) +#define TMC2160_OFS95_MASK 0x80000000 +#define TMC2160_OFS95_SHIFT 31 +#define TMC2160_OFS95_FIELD ((TMC2160RegisterField) {TMC2160_OFS95_MASK, TMC2160_OFS95_SHIFT, TMC2160_MSLUT[2], false}) +#define TMC2160_OFS96_MASK 0x00000001 +#define TMC2160_OFS96_SHIFT 0 +#define TMC2160_OFS96_FIELD ((TMC2160RegisterField) {TMC2160_OFS96_MASK, TMC2160_OFS96_SHIFT, TMC2160_MSLUT[3], false}) +#define TMC2160_OFS97_MASK 0x00000002 +#define TMC2160_OFS97_SHIFT 1 +#define TMC2160_OFS97_FIELD ((TMC2160RegisterField) {TMC2160_OFS97_MASK, TMC2160_OFS97_SHIFT, TMC2160_MSLUT[3], false}) +#define TMC2160_OFS98_MASK 0x00000004 +#define TMC2160_OFS98_SHIFT 2 +#define TMC2160_OFS98_FIELD ((TMC2160RegisterField) {TMC2160_OFS98_MASK, TMC2160_OFS98_SHIFT, TMC2160_MSLUT[3], false}) +#define TMC2160_OFS99_MASK 0x00000008 +#define TMC2160_OFS99_SHIFT 3 +#define TMC2160_OFS99_FIELD ((TMC2160RegisterField) {TMC2160_OFS99_MASK, TMC2160_OFS99_SHIFT, TMC2160_MSLUT[3], false}) +#define TMC2160_OFS100_MASK 0x00000010 +#define TMC2160_OFS100_SHIFT 4 +#define TMC2160_OFS100_FIELD ((TMC2160RegisterField) {TMC2160_OFS100_MASK, TMC2160_OFS100_SHIFT, TMC2160_MSLUT[3], false}) +#define TMC2160_OFS101_MASK 0x00000020 +#define TMC2160_OFS101_SHIFT 5 +#define TMC2160_OFS101_FIELD ((TMC2160RegisterField) {TMC2160_OFS101_MASK, TMC2160_OFS101_SHIFT, TMC2160_MSLUT[3], false}) +#define TMC2160_OFS102_MASK 0x00000040 +#define TMC2160_OFS102_SHIFT 6 +#define TMC2160_OFS102_FIELD ((TMC2160RegisterField) {TMC2160_OFS102_MASK, TMC2160_OFS102_SHIFT, TMC2160_MSLUT[3], false}) +#define TMC2160_OFS103_MASK 0x00000080 +#define TMC2160_OFS103_SHIFT 7 +#define TMC2160_OFS103_FIELD ((TMC2160RegisterField) {TMC2160_OFS103_MASK, TMC2160_OFS103_SHIFT, TMC2160_MSLUT[3], false}) +#define TMC2160_OFS104_MASK 0x00000100 +#define TMC2160_OFS104_SHIFT 8 +#define TMC2160_OFS104_FIELD ((TMC2160RegisterField) {TMC2160_OFS104_MASK, TMC2160_OFS104_SHIFT, TMC2160_MSLUT[3], false}) +#define TMC2160_OFS105_MASK 0x00000200 +#define TMC2160_OFS105_SHIFT 9 +#define TMC2160_OFS105_FIELD ((TMC2160RegisterField) {TMC2160_OFS105_MASK, TMC2160_OFS105_SHIFT, TMC2160_MSLUT[3], false}) +#define TMC2160_OFS106_MASK 0x00000400 +#define TMC2160_OFS106_SHIFT 10 +#define TMC2160_OFS106_FIELD ((TMC2160RegisterField) {TMC2160_OFS106_MASK, TMC2160_OFS106_SHIFT, TMC2160_MSLUT[3], false}) +#define TMC2160_OFS107_MASK 0x00000800 +#define TMC2160_OFS107_SHIFT 11 +#define TMC2160_OFS107_FIELD ((TMC2160RegisterField) {TMC2160_OFS107_MASK, TMC2160_OFS107_SHIFT, TMC2160_MSLUT[3], false}) +#define TMC2160_OFS108_MASK 0x00001000 +#define TMC2160_OFS108_SHIFT 12 +#define TMC2160_OFS108_FIELD ((TMC2160RegisterField) {TMC2160_OFS108_MASK, TMC2160_OFS108_SHIFT, TMC2160_MSLUT[3], false}) +#define TMC2160_OFS109_MASK 0x00002000 +#define TMC2160_OFS109_SHIFT 13 +#define TMC2160_OFS109_FIELD ((TMC2160RegisterField) {TMC2160_OFS109_MASK, TMC2160_OFS109_SHIFT, TMC2160_MSLUT[3], false}) +#define TMC2160_OFS110_MASK 0x00004000 +#define TMC2160_OFS110_SHIFT 14 +#define TMC2160_OFS110_FIELD ((TMC2160RegisterField) {TMC2160_OFS110_MASK, TMC2160_OFS110_SHIFT, TMC2160_MSLUT[3], false}) +#define TMC2160_OFS111_MASK 0x00008000 +#define TMC2160_OFS111_SHIFT 15 +#define TMC2160_OFS111_FIELD ((TMC2160RegisterField) {TMC2160_OFS111_MASK, TMC2160_OFS111_SHIFT, TMC2160_MSLUT[3], false}) +#define TMC2160_OFS112_MASK 0x00010000 +#define TMC2160_OFS112_SHIFT 16 +#define TMC2160_OFS112_FIELD ((TMC2160RegisterField) {TMC2160_OFS112_MASK, TMC2160_OFS112_SHIFT, TMC2160_MSLUT[3], false}) +#define TMC2160_OFS113_MASK 0x00020000 +#define TMC2160_OFS113_SHIFT 17 +#define TMC2160_OFS113_FIELD ((TMC2160RegisterField) {TMC2160_OFS113_MASK, TMC2160_OFS113_SHIFT, TMC2160_MSLUT[3], false}) +#define TMC2160_OFS114_MASK 0x00040000 +#define TMC2160_OFS114_SHIFT 18 +#define TMC2160_OFS114_FIELD ((TMC2160RegisterField) {TMC2160_OFS114_MASK, TMC2160_OFS114_SHIFT, TMC2160_MSLUT[3], false}) +#define TMC2160_OFS115_MASK 0x00080000 +#define TMC2160_OFS115_SHIFT 19 +#define TMC2160_OFS115_FIELD ((TMC2160RegisterField) {TMC2160_OFS115_MASK, TMC2160_OFS115_SHIFT, TMC2160_MSLUT[3], false}) +#define TMC2160_OFS116_MASK 0x00100000 +#define TMC2160_OFS116_SHIFT 20 +#define TMC2160_OFS116_FIELD ((TMC2160RegisterField) {TMC2160_OFS116_MASK, TMC2160_OFS116_SHIFT, TMC2160_MSLUT[3], false}) +#define TMC2160_OFS117_MASK 0x00200000 +#define TMC2160_OFS117_SHIFT 21 +#define TMC2160_OFS117_FIELD ((TMC2160RegisterField) {TMC2160_OFS117_MASK, TMC2160_OFS117_SHIFT, TMC2160_MSLUT[3], false}) +#define TMC2160_OFS118_MASK 0x00400000 +#define TMC2160_OFS118_SHIFT 22 +#define TMC2160_OFS118_FIELD ((TMC2160RegisterField) {TMC2160_OFS118_MASK, TMC2160_OFS118_SHIFT, TMC2160_MSLUT[3], false}) +#define TMC2160_OFS119_MASK 0x00800000 +#define TMC2160_OFS119_SHIFT 23 +#define TMC2160_OFS119_FIELD ((TMC2160RegisterField) {TMC2160_OFS119_MASK, TMC2160_OFS119_SHIFT, TMC2160_MSLUT[3], false}) +#define TMC2160_OFS120_MASK 0x01000000 +#define TMC2160_OFS120_SHIFT 24 +#define TMC2160_OFS120_FIELD ((TMC2160RegisterField) {TMC2160_OFS120_MASK, TMC2160_OFS120_SHIFT, TMC2160_MSLUT[3], false}) +#define TMC2160_OFS121_MASK 0x02000000 +#define TMC2160_OFS121_SHIFT 25 +#define TMC2160_OFS121_FIELD ((TMC2160RegisterField) {TMC2160_OFS121_MASK, TMC2160_OFS121_SHIFT, TMC2160_MSLUT[3], false}) +#define TMC2160_OFS122_MASK 0x04000000 +#define TMC2160_OFS122_SHIFT 26 +#define TMC2160_OFS122_FIELD ((TMC2160RegisterField) {TMC2160_OFS122_MASK, TMC2160_OFS122_SHIFT, TMC2160_MSLUT[3], false}) +#define TMC2160_OFS123_MASK 0x08000000 +#define TMC2160_OFS123_SHIFT 27 +#define TMC2160_OFS123_FIELD ((TMC2160RegisterField) {TMC2160_OFS123_MASK, TMC2160_OFS123_SHIFT, TMC2160_MSLUT[3], false}) +#define TMC2160_OFS124_MASK 0x10000000 +#define TMC2160_OFS124_SHIFT 28 +#define TMC2160_OFS124_FIELD ((TMC2160RegisterField) {TMC2160_OFS124_MASK, TMC2160_OFS124_SHIFT, TMC2160_MSLUT[3], false}) +#define TMC2160_OFS125_MASK 0x20000000 +#define TMC2160_OFS125_SHIFT 29 +#define TMC2160_OFS125_FIELD ((TMC2160RegisterField) {TMC2160_OFS125_MASK, TMC2160_OFS125_SHIFT, TMC2160_MSLUT[3], false}) +#define TMC2160_OFS126_MASK 0x40000000 +#define TMC2160_OFS126_SHIFT 30 +#define TMC2160_OFS126_FIELD ((TMC2160RegisterField) {TMC2160_OFS126_MASK, TMC2160_OFS126_SHIFT, TMC2160_MSLUT[3], false}) +#define TMC2160_OFS127_MASK 0x80000000 +#define TMC2160_OFS127_SHIFT 31 +#define TMC2160_OFS127_FIELD ((TMC2160RegisterField) {TMC2160_OFS127_MASK, TMC2160_OFS127_SHIFT, TMC2160_MSLUT[3], false}) +#define TMC2160_OFS128_MASK 0x00000001 +#define TMC2160_OFS128_SHIFT 0 +#define TMC2160_OFS128_FIELD ((TMC2160RegisterField) {TMC2160_OFS128_MASK, TMC2160_OFS128_SHIFT, TMC2160_MSLUT[4], false}) +#define TMC2160_OFS129_MASK 0x00000002 +#define TMC2160_OFS129_SHIFT 1 +#define TMC2160_OFS129_FIELD ((TMC2160RegisterField) {TMC2160_OFS129_MASK, TMC2160_OFS129_SHIFT, TMC2160_MSLUT[4], false}) +#define TMC2160_OFS130_MASK 0x00000004 +#define TMC2160_OFS130_SHIFT 2 +#define TMC2160_OFS130_FIELD ((TMC2160RegisterField) {TMC2160_OFS130_MASK, TMC2160_OFS130_SHIFT, TMC2160_MSLUT[4], false}) +#define TMC2160_OFS131_MASK 0x00000008 +#define TMC2160_OFS131_SHIFT 3 +#define TMC2160_OFS131_FIELD ((TMC2160RegisterField) {TMC2160_OFS131_MASK, TMC2160_OFS131_SHIFT, TMC2160_MSLUT[4], false}) +#define TMC2160_OFS132_MASK 0x00000010 +#define TMC2160_OFS132_SHIFT 4 +#define TMC2160_OFS132_FIELD ((TMC2160RegisterField) {TMC2160_OFS132_MASK, TMC2160_OFS132_SHIFT, TMC2160_MSLUT[4], false}) +#define TMC2160_OFS133_MASK 0x00000020 +#define TMC2160_OFS133_SHIFT 5 +#define TMC2160_OFS133_FIELD ((TMC2160RegisterField) {TMC2160_OFS133_MASK, TMC2160_OFS133_SHIFT, TMC2160_MSLUT[4], false}) +#define TMC2160_OFS134_MASK 0x00000040 +#define TMC2160_OFS134_SHIFT 6 +#define TMC2160_OFS134_FIELD ((TMC2160RegisterField) {TMC2160_OFS134_MASK, TMC2160_OFS134_SHIFT, TMC2160_MSLUT[4], false}) +#define TMC2160_OFS135_MASK 0x00000080 +#define TMC2160_OFS135_SHIFT 7 +#define TMC2160_OFS135_FIELD ((TMC2160RegisterField) {TMC2160_OFS135_MASK, TMC2160_OFS135_SHIFT, TMC2160_MSLUT[4], false}) +#define TMC2160_OFS136_MASK 0x00000100 +#define TMC2160_OFS136_SHIFT 8 +#define TMC2160_OFS136_FIELD ((TMC2160RegisterField) {TMC2160_OFS136_MASK, TMC2160_OFS136_SHIFT, TMC2160_MSLUT[4], false}) +#define TMC2160_OFS137_MASK 0x00000200 +#define TMC2160_OFS137_SHIFT 9 +#define TMC2160_OFS137_FIELD ((TMC2160RegisterField) {TMC2160_OFS137_MASK, TMC2160_OFS137_SHIFT, TMC2160_MSLUT[4], false}) +#define TMC2160_OFS138_MASK 0x00000400 +#define TMC2160_OFS138_SHIFT 10 +#define TMC2160_OFS138_FIELD ((TMC2160RegisterField) {TMC2160_OFS138_MASK, TMC2160_OFS138_SHIFT, TMC2160_MSLUT[4], false}) +#define TMC2160_OFS139_MASK 0x00000800 +#define TMC2160_OFS139_SHIFT 11 +#define TMC2160_OFS139_FIELD ((TMC2160RegisterField) {TMC2160_OFS139_MASK, TMC2160_OFS139_SHIFT, TMC2160_MSLUT[4], false}) +#define TMC2160_OFS140_MASK 0x00001000 +#define TMC2160_OFS140_SHIFT 12 +#define TMC2160_OFS140_FIELD ((TMC2160RegisterField) {TMC2160_OFS140_MASK, TMC2160_OFS140_SHIFT, TMC2160_MSLUT[4], false}) +#define TMC2160_OFS141_MASK 0x00002000 +#define TMC2160_OFS141_SHIFT 13 +#define TMC2160_OFS141_FIELD ((TMC2160RegisterField) {TMC2160_OFS141_MASK, TMC2160_OFS141_SHIFT, TMC2160_MSLUT[4], false}) +#define TMC2160_OFS142_MASK 0x00004000 +#define TMC2160_OFS142_SHIFT 14 +#define TMC2160_OFS142_FIELD ((TMC2160RegisterField) {TMC2160_OFS142_MASK, TMC2160_OFS142_SHIFT, TMC2160_MSLUT[4], false}) +#define TMC2160_OFS143_MASK 0x00008000 +#define TMC2160_OFS143_SHIFT 15 +#define TMC2160_OFS143_FIELD ((TMC2160RegisterField) {TMC2160_OFS143_MASK, TMC2160_OFS143_SHIFT, TMC2160_MSLUT[4], false}) +#define TMC2160_OFS144_MASK 0x00010000 +#define TMC2160_OFS144_SHIFT 16 +#define TMC2160_OFS144_FIELD ((TMC2160RegisterField) {TMC2160_OFS144_MASK, TMC2160_OFS144_SHIFT, TMC2160_MSLUT[4], false}) +#define TMC2160_OFS145_MASK 0x00020000 +#define TMC2160_OFS145_SHIFT 17 +#define TMC2160_OFS145_FIELD ((TMC2160RegisterField) {TMC2160_OFS145_MASK, TMC2160_OFS145_SHIFT, TMC2160_MSLUT[4], false}) +#define TMC2160_OFS146_MASK 0x00040000 +#define TMC2160_OFS146_SHIFT 18 +#define TMC2160_OFS146_FIELD ((TMC2160RegisterField) {TMC2160_OFS146_MASK, TMC2160_OFS146_SHIFT, TMC2160_MSLUT[4], false}) +#define TMC2160_OFS147_MASK 0x00080000 +#define TMC2160_OFS147_SHIFT 19 +#define TMC2160_OFS147_FIELD ((TMC2160RegisterField) {TMC2160_OFS147_MASK, TMC2160_OFS147_SHIFT, TMC2160_MSLUT[4], false}) +#define TMC2160_OFS148_MASK 0x00100000 +#define TMC2160_OFS148_SHIFT 20 +#define TMC2160_OFS148_FIELD ((TMC2160RegisterField) {TMC2160_OFS148_MASK, TMC2160_OFS148_SHIFT, TMC2160_MSLUT[4], false}) +#define TMC2160_OFS149_MASK 0x00200000 +#define TMC2160_OFS149_SHIFT 21 +#define TMC2160_OFS149_FIELD ((TMC2160RegisterField) {TMC2160_OFS149_MASK, TMC2160_OFS149_SHIFT, TMC2160_MSLUT[4], false}) +#define TMC2160_OFS150_MASK 0x00400000 +#define TMC2160_OFS150_SHIFT 22 +#define TMC2160_OFS150_FIELD ((TMC2160RegisterField) {TMC2160_OFS150_MASK, TMC2160_OFS150_SHIFT, TMC2160_MSLUT[4], false}) +#define TMC2160_OFS151_MASK 0x00800000 +#define TMC2160_OFS151_SHIFT 23 +#define TMC2160_OFS151_FIELD ((TMC2160RegisterField) {TMC2160_OFS151_MASK, TMC2160_OFS151_SHIFT, TMC2160_MSLUT[4], false}) +#define TMC2160_OFS152_MASK 0x01000000 +#define TMC2160_OFS152_SHIFT 24 +#define TMC2160_OFS152_FIELD ((TMC2160RegisterField) {TMC2160_OFS152_MASK, TMC2160_OFS152_SHIFT, TMC2160_MSLUT[4], false}) +#define TMC2160_OFS153_MASK 0x02000000 +#define TMC2160_OFS153_SHIFT 25 +#define TMC2160_OFS153_FIELD ((TMC2160RegisterField) {TMC2160_OFS153_MASK, TMC2160_OFS153_SHIFT, TMC2160_MSLUT[4], false}) +#define TMC2160_OFS154_MASK 0x04000000 +#define TMC2160_OFS154_SHIFT 26 +#define TMC2160_OFS154_FIELD ((TMC2160RegisterField) {TMC2160_OFS154_MASK, TMC2160_OFS154_SHIFT, TMC2160_MSLUT[4], false}) +#define TMC2160_OFS155_MASK 0x08000000 +#define TMC2160_OFS155_SHIFT 27 +#define TMC2160_OFS155_FIELD ((TMC2160RegisterField) {TMC2160_OFS155_MASK, TMC2160_OFS155_SHIFT, TMC2160_MSLUT[4], false}) +#define TMC2160_OFS156_MASK 0x10000000 +#define TMC2160_OFS156_SHIFT 28 +#define TMC2160_OFS156_FIELD ((TMC2160RegisterField) {TMC2160_OFS156_MASK, TMC2160_OFS156_SHIFT, TMC2160_MSLUT[4], false}) +#define TMC2160_OFS157_MASK 0x20000000 +#define TMC2160_OFS157_SHIFT 29 +#define TMC2160_OFS157_FIELD ((TMC2160RegisterField) {TMC2160_OFS157_MASK, TMC2160_OFS157_SHIFT, TMC2160_MSLUT[4], false}) +#define TMC2160_OFS158_MASK 0x40000000 +#define TMC2160_OFS158_SHIFT 30 +#define TMC2160_OFS158_FIELD ((TMC2160RegisterField) {TMC2160_OFS158_MASK, TMC2160_OFS158_SHIFT, TMC2160_MSLUT[4], false}) +#define TMC2160_OFS159_MASK 0x80000000 +#define TMC2160_OFS159_SHIFT 31 +#define TMC2160_OFS159_FIELD ((TMC2160RegisterField) {TMC2160_OFS159_MASK, TMC2160_OFS159_SHIFT, TMC2160_MSLUT[4], false}) +#define TMC2160_OFS160_MASK 0x00000001 +#define TMC2160_OFS160_SHIFT 0 +#define TMC2160_OFS160_FIELD ((TMC2160RegisterField) {TMC2160_OFS160_MASK, TMC2160_OFS160_SHIFT, TMC2160_MSLUT[5], false}) +#define TMC2160_OFS161_MASK 0x00000002 +#define TMC2160_OFS161_SHIFT 1 +#define TMC2160_OFS161_FIELD ((TMC2160RegisterField) {TMC2160_OFS161_MASK, TMC2160_OFS161_SHIFT, TMC2160_MSLUT[5], false}) +#define TMC2160_OFS162_MASK 0x00000004 +#define TMC2160_OFS162_SHIFT 2 +#define TMC2160_OFS162_FIELD ((TMC2160RegisterField) {TMC2160_OFS162_MASK, TMC2160_OFS162_SHIFT, TMC2160_MSLUT[5], false}) +#define TMC2160_OFS163_MASK 0x00000008 +#define TMC2160_OFS163_SHIFT 3 +#define TMC2160_OFS163_FIELD ((TMC2160RegisterField) {TMC2160_OFS163_MASK, TMC2160_OFS163_SHIFT, TMC2160_MSLUT[5], false}) +#define TMC2160_OFS164_MASK 0x00000010 +#define TMC2160_OFS164_SHIFT 4 +#define TMC2160_OFS164_FIELD ((TMC2160RegisterField) {TMC2160_OFS164_MASK, TMC2160_OFS164_SHIFT, TMC2160_MSLUT[5], false}) +#define TMC2160_OFS165_MASK 0x00000020 +#define TMC2160_OFS165_SHIFT 5 +#define TMC2160_OFS165_FIELD ((TMC2160RegisterField) {TMC2160_OFS165_MASK, TMC2160_OFS165_SHIFT, TMC2160_MSLUT[5], false}) +#define TMC2160_OFS166_MASK 0x00000040 +#define TMC2160_OFS166_SHIFT 6 +#define TMC2160_OFS166_FIELD ((TMC2160RegisterField) {TMC2160_OFS166_MASK, TMC2160_OFS166_SHIFT, TMC2160_MSLUT[5], false}) +#define TMC2160_OFS167_MASK 0x00000080 +#define TMC2160_OFS167_SHIFT 7 +#define TMC2160_OFS167_FIELD ((TMC2160RegisterField) {TMC2160_OFS167_MASK, TMC2160_OFS167_SHIFT, TMC2160_MSLUT[5], false}) +#define TMC2160_OFS168_MASK 0x00000100 +#define TMC2160_OFS168_SHIFT 8 +#define TMC2160_OFS168_FIELD ((TMC2160RegisterField) {TMC2160_OFS168_MASK, TMC2160_OFS168_SHIFT, TMC2160_MSLUT[5], false}) +#define TMC2160_OFS169_MASK 0x00000200 +#define TMC2160_OFS169_SHIFT 9 +#define TMC2160_OFS169_FIELD ((TMC2160RegisterField) {TMC2160_OFS169_MASK, TMC2160_OFS169_SHIFT, TMC2160_MSLUT[5], false}) +#define TMC2160_OFS170_MASK 0x00000400 +#define TMC2160_OFS170_SHIFT 10 +#define TMC2160_OFS170_FIELD ((TMC2160RegisterField) {TMC2160_OFS170_MASK, TMC2160_OFS170_SHIFT, TMC2160_MSLUT[5], false}) +#define TMC2160_OFS171_MASK 0x00000800 +#define TMC2160_OFS171_SHIFT 11 +#define TMC2160_OFS171_FIELD ((TMC2160RegisterField) {TMC2160_OFS171_MASK, TMC2160_OFS171_SHIFT, TMC2160_MSLUT[5], false}) +#define TMC2160_OFS172_MASK 0x00001000 +#define TMC2160_OFS172_SHIFT 12 +#define TMC2160_OFS172_FIELD ((TMC2160RegisterField) {TMC2160_OFS172_MASK, TMC2160_OFS172_SHIFT, TMC2160_MSLUT[5], false}) +#define TMC2160_OFS173_MASK 0x00002000 +#define TMC2160_OFS173_SHIFT 13 +#define TMC2160_OFS173_FIELD ((TMC2160RegisterField) {TMC2160_OFS173_MASK, TMC2160_OFS173_SHIFT, TMC2160_MSLUT[5], false}) +#define TMC2160_OFS174_MASK 0x00004000 +#define TMC2160_OFS174_SHIFT 14 +#define TMC2160_OFS174_FIELD ((TMC2160RegisterField) {TMC2160_OFS174_MASK, TMC2160_OFS174_SHIFT, TMC2160_MSLUT[5], false}) +#define TMC2160_OFS175_MASK 0x00008000 +#define TMC2160_OFS175_SHIFT 15 +#define TMC2160_OFS175_FIELD ((TMC2160RegisterField) {TMC2160_OFS175_MASK, TMC2160_OFS175_SHIFT, TMC2160_MSLUT[5], false}) +#define TMC2160_OFS176_MASK 0x00010000 +#define TMC2160_OFS176_SHIFT 16 +#define TMC2160_OFS176_FIELD ((TMC2160RegisterField) {TMC2160_OFS176_MASK, TMC2160_OFS176_SHIFT, TMC2160_MSLUT[5], false}) +#define TMC2160_OFS177_MASK 0x00020000 +#define TMC2160_OFS177_SHIFT 17 +#define TMC2160_OFS177_FIELD ((TMC2160RegisterField) {TMC2160_OFS177_MASK, TMC2160_OFS177_SHIFT, TMC2160_MSLUT[5], false}) +#define TMC2160_OFS178_MASK 0x00040000 +#define TMC2160_OFS178_SHIFT 18 +#define TMC2160_OFS178_FIELD ((TMC2160RegisterField) {TMC2160_OFS178_MASK, TMC2160_OFS178_SHIFT, TMC2160_MSLUT[5], false}) +#define TMC2160_OFS179_MASK 0x00080000 +#define TMC2160_OFS179_SHIFT 19 +#define TMC2160_OFS179_FIELD ((TMC2160RegisterField) {TMC2160_OFS179_MASK, TMC2160_OFS179_SHIFT, TMC2160_MSLUT[5], false}) +#define TMC2160_OFS180_MASK 0x00100000 +#define TMC2160_OFS180_SHIFT 20 +#define TMC2160_OFS180_FIELD ((TMC2160RegisterField) {TMC2160_OFS180_MASK, TMC2160_OFS180_SHIFT, TMC2160_MSLUT[5], false}) +#define TMC2160_OFS181_MASK 0x00200000 +#define TMC2160_OFS181_SHIFT 21 +#define TMC2160_OFS181_FIELD ((TMC2160RegisterField) {TMC2160_OFS181_MASK, TMC2160_OFS181_SHIFT, TMC2160_MSLUT[5], false}) +#define TMC2160_OFS182_MASK 0x00400000 +#define TMC2160_OFS182_SHIFT 22 +#define TMC2160_OFS182_FIELD ((TMC2160RegisterField) {TMC2160_OFS182_MASK, TMC2160_OFS182_SHIFT, TMC2160_MSLUT[5], false}) +#define TMC2160_OFS183_MASK 0x00800000 +#define TMC2160_OFS183_SHIFT 23 +#define TMC2160_OFS183_FIELD ((TMC2160RegisterField) {TMC2160_OFS183_MASK, TMC2160_OFS183_SHIFT, TMC2160_MSLUT[5], false}) +#define TMC2160_OFS184_MASK 0x01000000 +#define TMC2160_OFS184_SHIFT 24 +#define TMC2160_OFS184_FIELD ((TMC2160RegisterField) {TMC2160_OFS184_MASK, TMC2160_OFS184_SHIFT, TMC2160_MSLUT[5], false}) +#define TMC2160_OFS185_MASK 0x02000000 +#define TMC2160_OFS185_SHIFT 25 +#define TMC2160_OFS185_FIELD ((TMC2160RegisterField) {TMC2160_OFS185_MASK, TMC2160_OFS185_SHIFT, TMC2160_MSLUT[5], false}) +#define TMC2160_OFS186_MASK 0x04000000 +#define TMC2160_OFS186_SHIFT 26 +#define TMC2160_OFS186_FIELD ((TMC2160RegisterField) {TMC2160_OFS186_MASK, TMC2160_OFS186_SHIFT, TMC2160_MSLUT[5], false}) +#define TMC2160_OFS187_MASK 0x08000000 +#define TMC2160_OFS187_SHIFT 27 +#define TMC2160_OFS187_FIELD ((TMC2160RegisterField) {TMC2160_OFS187_MASK, TMC2160_OFS187_SHIFT, TMC2160_MSLUT[5], false}) +#define TMC2160_OFS188_MASK 0x10000000 +#define TMC2160_OFS188_SHIFT 28 +#define TMC2160_OFS188_FIELD ((TMC2160RegisterField) {TMC2160_OFS188_MASK, TMC2160_OFS188_SHIFT, TMC2160_MSLUT[5], false}) +#define TMC2160_OFS189_MASK 0x20000000 +#define TMC2160_OFS189_SHIFT 29 +#define TMC2160_OFS189_FIELD ((TMC2160RegisterField) {TMC2160_OFS189_MASK, TMC2160_OFS189_SHIFT, TMC2160_MSLUT[5], false}) +#define TMC2160_OFS190_MASK 0x40000000 +#define TMC2160_OFS190_SHIFT 30 +#define TMC2160_OFS190_FIELD ((TMC2160RegisterField) {TMC2160_OFS190_MASK, TMC2160_OFS190_SHIFT, TMC2160_MSLUT[5], false}) +#define TMC2160_OFS191_MASK 0x80000000 +#define TMC2160_OFS191_SHIFT 31 +#define TMC2160_OFS191_FIELD ((TMC2160RegisterField) {TMC2160_OFS191_MASK, TMC2160_OFS191_SHIFT, TMC2160_MSLUT[5], false}) +#define TMC2160_OFS192_MASK 0x00000001 +#define TMC2160_OFS192_SHIFT 0 +#define TMC2160_OFS192_FIELD ((TMC2160RegisterField) {TMC2160_OFS192_MASK, TMC2160_OFS192_SHIFT, TMC2160_MSLUT[6], false}) +#define TMC2160_OFS193_MASK 0x00000002 +#define TMC2160_OFS193_SHIFT 1 +#define TMC2160_OFS193_FIELD ((TMC2160RegisterField) {TMC2160_OFS193_MASK, TMC2160_OFS193_SHIFT, TMC2160_MSLUT[6], false}) +#define TMC2160_OFS194_MASK 0x00000004 +#define TMC2160_OFS194_SHIFT 2 +#define TMC2160_OFS194_FIELD ((TMC2160RegisterField) {TMC2160_OFS194_MASK, TMC2160_OFS194_SHIFT, TMC2160_MSLUT[6], false}) +#define TMC2160_OFS195_MASK 0x00000008 +#define TMC2160_OFS195_SHIFT 3 +#define TMC2160_OFS195_FIELD ((TMC2160RegisterField) {TMC2160_OFS195_MASK, TMC2160_OFS195_SHIFT, TMC2160_MSLUT[6], false}) +#define TMC2160_OFS196_MASK 0x00000010 +#define TMC2160_OFS196_SHIFT 4 +#define TMC2160_OFS196_FIELD ((TMC2160RegisterField) {TMC2160_OFS196_MASK, TMC2160_OFS196_SHIFT, TMC2160_MSLUT[6], false}) +#define TMC2160_OFS197_MASK 0x00000020 +#define TMC2160_OFS197_SHIFT 5 +#define TMC2160_OFS197_FIELD ((TMC2160RegisterField) {TMC2160_OFS197_MASK, TMC2160_OFS197_SHIFT, TMC2160_MSLUT[6], false}) +#define TMC2160_OFS198_MASK 0x00000040 +#define TMC2160_OFS198_SHIFT 6 +#define TMC2160_OFS198_FIELD ((TMC2160RegisterField) {TMC2160_OFS198_MASK, TMC2160_OFS198_SHIFT, TMC2160_MSLUT[6], false}) +#define TMC2160_OFS199_MASK 0x00000080 +#define TMC2160_OFS199_SHIFT 7 +#define TMC2160_OFS199_FIELD ((TMC2160RegisterField) {TMC2160_OFS199_MASK, TMC2160_OFS199_SHIFT, TMC2160_MSLUT[6], false}) +#define TMC2160_OFS200_MASK 0x00000100 +#define TMC2160_OFS200_SHIFT 8 +#define TMC2160_OFS200_FIELD ((TMC2160RegisterField) {TMC2160_OFS200_MASK, TMC2160_OFS200_SHIFT, TMC2160_MSLUT[6], false}) +#define TMC2160_OFS201_MASK 0x00000200 +#define TMC2160_OFS201_SHIFT 9 +#define TMC2160_OFS201_FIELD ((TMC2160RegisterField) {TMC2160_OFS201_MASK, TMC2160_OFS201_SHIFT, TMC2160_MSLUT[6], false}) +#define TMC2160_OFS202_MASK 0x00000400 +#define TMC2160_OFS202_SHIFT 10 +#define TMC2160_OFS202_FIELD ((TMC2160RegisterField) {TMC2160_OFS202_MASK, TMC2160_OFS202_SHIFT, TMC2160_MSLUT[6], false}) +#define TMC2160_OFS203_MASK 0x00000800 +#define TMC2160_OFS203_SHIFT 11 +#define TMC2160_OFS203_FIELD ((TMC2160RegisterField) {TMC2160_OFS203_MASK, TMC2160_OFS203_SHIFT, TMC2160_MSLUT[6], false}) +#define TMC2160_OFS204_MASK 0x00001000 +#define TMC2160_OFS204_SHIFT 12 +#define TMC2160_OFS204_FIELD ((TMC2160RegisterField) {TMC2160_OFS204_MASK, TMC2160_OFS204_SHIFT, TMC2160_MSLUT[6], false}) +#define TMC2160_OFS205_MASK 0x00002000 +#define TMC2160_OFS205_SHIFT 13 +#define TMC2160_OFS205_FIELD ((TMC2160RegisterField) {TMC2160_OFS205_MASK, TMC2160_OFS205_SHIFT, TMC2160_MSLUT[6], false}) +#define TMC2160_OFS206_MASK 0x00004000 +#define TMC2160_OFS206_SHIFT 14 +#define TMC2160_OFS206_FIELD ((TMC2160RegisterField) {TMC2160_OFS206_MASK, TMC2160_OFS206_SHIFT, TMC2160_MSLUT[6], false}) +#define TMC2160_OFS207_MASK 0x00008000 +#define TMC2160_OFS207_SHIFT 15 +#define TMC2160_OFS207_FIELD ((TMC2160RegisterField) {TMC2160_OFS207_MASK, TMC2160_OFS207_SHIFT, TMC2160_MSLUT[6], false}) +#define TMC2160_OFS208_MASK 0x00010000 +#define TMC2160_OFS208_SHIFT 16 +#define TMC2160_OFS208_FIELD ((TMC2160RegisterField) {TMC2160_OFS208_MASK, TMC2160_OFS208_SHIFT, TMC2160_MSLUT[6], false}) +#define TMC2160_OFS209_MASK 0x00020000 +#define TMC2160_OFS209_SHIFT 17 +#define TMC2160_OFS209_FIELD ((TMC2160RegisterField) {TMC2160_OFS209_MASK, TMC2160_OFS209_SHIFT, TMC2160_MSLUT[6], false}) +#define TMC2160_OFS210_MASK 0x00040000 +#define TMC2160_OFS210_SHIFT 18 +#define TMC2160_OFS210_FIELD ((TMC2160RegisterField) {TMC2160_OFS210_MASK, TMC2160_OFS210_SHIFT, TMC2160_MSLUT[6], false}) +#define TMC2160_OFS211_MASK 0x00080000 +#define TMC2160_OFS211_SHIFT 19 +#define TMC2160_OFS211_FIELD ((TMC2160RegisterField) {TMC2160_OFS211_MASK, TMC2160_OFS211_SHIFT, TMC2160_MSLUT[6], false}) +#define TMC2160_OFS212_MASK 0x00100000 +#define TMC2160_OFS212_SHIFT 20 +#define TMC2160_OFS212_FIELD ((TMC2160RegisterField) {TMC2160_OFS212_MASK, TMC2160_OFS212_SHIFT, TMC2160_MSLUT[6], false}) +#define TMC2160_OFS213_MASK 0x00200000 +#define TMC2160_OFS213_SHIFT 21 +#define TMC2160_OFS213_FIELD ((TMC2160RegisterField) {TMC2160_OFS213_MASK, TMC2160_OFS213_SHIFT, TMC2160_MSLUT[6], false}) +#define TMC2160_OFS214_MASK 0x00400000 +#define TMC2160_OFS214_SHIFT 22 +#define TMC2160_OFS214_FIELD ((TMC2160RegisterField) {TMC2160_OFS214_MASK, TMC2160_OFS214_SHIFT, TMC2160_MSLUT[6], false}) +#define TMC2160_OFS215_MASK 0x00800000 +#define TMC2160_OFS215_SHIFT 23 +#define TMC2160_OFS215_FIELD ((TMC2160RegisterField) {TMC2160_OFS215_MASK, TMC2160_OFS215_SHIFT, TMC2160_MSLUT[6], false}) +#define TMC2160_OFS216_MASK 0x01000000 +#define TMC2160_OFS216_SHIFT 24 +#define TMC2160_OFS216_FIELD ((TMC2160RegisterField) {TMC2160_OFS216_MASK, TMC2160_OFS216_SHIFT, TMC2160_MSLUT[6], false}) +#define TMC2160_OFS217_MASK 0x02000000 +#define TMC2160_OFS217_SHIFT 25 +#define TMC2160_OFS217_FIELD ((TMC2160RegisterField) {TMC2160_OFS217_MASK, TMC2160_OFS217_SHIFT, TMC2160_MSLUT[6], false}) +#define TMC2160_OFS218_MASK 0x04000000 +#define TMC2160_OFS218_SHIFT 26 +#define TMC2160_OFS218_FIELD ((TMC2160RegisterField) {TMC2160_OFS218_MASK, TMC2160_OFS218_SHIFT, TMC2160_MSLUT[6], false}) +#define TMC2160_OFS219_MASK 0x08000000 +#define TMC2160_OFS219_SHIFT 27 +#define TMC2160_OFS219_FIELD ((TMC2160RegisterField) {TMC2160_OFS219_MASK, TMC2160_OFS219_SHIFT, TMC2160_MSLUT[6], false}) +#define TMC2160_OFS220_MASK 0x10000000 +#define TMC2160_OFS220_SHIFT 28 +#define TMC2160_OFS220_FIELD ((TMC2160RegisterField) {TMC2160_OFS220_MASK, TMC2160_OFS220_SHIFT, TMC2160_MSLUT[6], false}) +#define TMC2160_OFS221_MASK 0x20000000 +#define TMC2160_OFS221_SHIFT 29 +#define TMC2160_OFS221_FIELD ((TMC2160RegisterField) {TMC2160_OFS221_MASK, TMC2160_OFS221_SHIFT, TMC2160_MSLUT[6], false}) +#define TMC2160_OFS222_MASK 0x40000000 +#define TMC2160_OFS222_SHIFT 30 +#define TMC2160_OFS222_FIELD ((TMC2160RegisterField) {TMC2160_OFS222_MASK, TMC2160_OFS222_SHIFT, TMC2160_MSLUT[6], false}) +#define TMC2160_OFS223_MASK 0x80000000 +#define TMC2160_OFS223_SHIFT 31 +#define TMC2160_OFS223_FIELD ((TMC2160RegisterField) {TMC2160_OFS223_MASK, TMC2160_OFS223_SHIFT, TMC2160_MSLUT[6], false}) +#define TMC2160_OFS224_MASK 0x00000001 +#define TMC2160_OFS224_SHIFT 0 +#define TMC2160_OFS224_FIELD ((TMC2160RegisterField) {TMC2160_OFS224_MASK, TMC2160_OFS224_SHIFT, TMC2160_MSLUT[7], false}) +#define TMC2160_OFS225_MASK 0x00000002 +#define TMC2160_OFS225_SHIFT 1 +#define TMC2160_OFS225_FIELD ((TMC2160RegisterField) {TMC2160_OFS225_MASK, TMC2160_OFS225_SHIFT, TMC2160_MSLUT[7], false}) +#define TMC2160_OFS226_MASK 0x00000004 +#define TMC2160_OFS226_SHIFT 2 +#define TMC2160_OFS226_FIELD ((TMC2160RegisterField) {TMC2160_OFS226_MASK, TMC2160_OFS226_SHIFT, TMC2160_MSLUT[7], false}) +#define TMC2160_OFS227_MASK 0x00000008 +#define TMC2160_OFS227_SHIFT 3 +#define TMC2160_OFS227_FIELD ((TMC2160RegisterField) {TMC2160_OFS227_MASK, TMC2160_OFS227_SHIFT, TMC2160_MSLUT[7], false}) +#define TMC2160_OFS228_MASK 0x00000010 +#define TMC2160_OFS228_SHIFT 4 +#define TMC2160_OFS228_FIELD ((TMC2160RegisterField) {TMC2160_OFS228_MASK, TMC2160_OFS228_SHIFT, TMC2160_MSLUT[7], false}) +#define TMC2160_OFS229_MASK 0x00000020 +#define TMC2160_OFS229_SHIFT 5 +#define TMC2160_OFS229_FIELD ((TMC2160RegisterField) {TMC2160_OFS229_MASK, TMC2160_OFS229_SHIFT, TMC2160_MSLUT[7], false}) +#define TMC2160_OFS230_MASK 0x00000040 +#define TMC2160_OFS230_SHIFT 6 +#define TMC2160_OFS230_FIELD ((TMC2160RegisterField) {TMC2160_OFS230_MASK, TMC2160_OFS230_SHIFT, TMC2160_MSLUT[7], false}) +#define TMC2160_OFS231_MASK 0x00000080 +#define TMC2160_OFS231_SHIFT 7 +#define TMC2160_OFS231_FIELD ((TMC2160RegisterField) {TMC2160_OFS231_MASK, TMC2160_OFS231_SHIFT, TMC2160_MSLUT[7], false}) +#define TMC2160_OFS232_MASK 0x00000100 +#define TMC2160_OFS232_SHIFT 8 +#define TMC2160_OFS232_FIELD ((TMC2160RegisterField) {TMC2160_OFS232_MASK, TMC2160_OFS232_SHIFT, TMC2160_MSLUT[7], false}) +#define TMC2160_OFS233_MASK 0x00000200 +#define TMC2160_OFS233_SHIFT 9 +#define TMC2160_OFS233_FIELD ((TMC2160RegisterField) {TMC2160_OFS233_MASK, TMC2160_OFS233_SHIFT, TMC2160_MSLUT[7], false}) +#define TMC2160_OFS234_MASK 0x00000400 +#define TMC2160_OFS234_SHIFT 10 +#define TMC2160_OFS234_FIELD ((TMC2160RegisterField) {TMC2160_OFS234_MASK, TMC2160_OFS234_SHIFT, TMC2160_MSLUT[7], false}) +#define TMC2160_OFS235_MASK 0x00000800 +#define TMC2160_OFS235_SHIFT 11 +#define TMC2160_OFS235_FIELD ((TMC2160RegisterField) {TMC2160_OFS235_MASK, TMC2160_OFS235_SHIFT, TMC2160_MSLUT[7], false}) +#define TMC2160_OFS236_MASK 0x00001000 +#define TMC2160_OFS236_SHIFT 12 +#define TMC2160_OFS236_FIELD ((TMC2160RegisterField) {TMC2160_OFS236_MASK, TMC2160_OFS236_SHIFT, TMC2160_MSLUT[7], false}) +#define TMC2160_OFS237_MASK 0x00002000 +#define TMC2160_OFS237_SHIFT 13 +#define TMC2160_OFS237_FIELD ((TMC2160RegisterField) {TMC2160_OFS237_MASK, TMC2160_OFS237_SHIFT, TMC2160_MSLUT[7], false}) +#define TMC2160_OFS238_MASK 0x00004000 +#define TMC2160_OFS238_SHIFT 14 +#define TMC2160_OFS238_FIELD ((TMC2160RegisterField) {TMC2160_OFS238_MASK, TMC2160_OFS238_SHIFT, TMC2160_MSLUT[7], false}) +#define TMC2160_OFS239_MASK 0x00008000 +#define TMC2160_OFS239_SHIFT 15 +#define TMC2160_OFS239_FIELD ((TMC2160RegisterField) {TMC2160_OFS239_MASK, TMC2160_OFS239_SHIFT, TMC2160_MSLUT[7], false}) +#define TMC2160_OFS240_MASK 0x00010000 +#define TMC2160_OFS240_SHIFT 16 +#define TMC2160_OFS240_FIELD ((TMC2160RegisterField) {TMC2160_OFS240_MASK, TMC2160_OFS240_SHIFT, TMC2160_MSLUT[7], false}) +#define TMC2160_OFS241_MASK 0x00020000 +#define TMC2160_OFS241_SHIFT 17 +#define TMC2160_OFS241_FIELD ((TMC2160RegisterField) {TMC2160_OFS241_MASK, TMC2160_OFS241_SHIFT, TMC2160_MSLUT[7], false}) +#define TMC2160_OFS242_MASK 0x00040000 +#define TMC2160_OFS242_SHIFT 18 +#define TMC2160_OFS242_FIELD ((TMC2160RegisterField) {TMC2160_OFS242_MASK, TMC2160_OFS242_SHIFT, TMC2160_MSLUT[7], false}) +#define TMC2160_OFS243_MASK 0x00080000 +#define TMC2160_OFS243_SHIFT 19 +#define TMC2160_OFS243_FIELD ((TMC2160RegisterField) {TMC2160_OFS243_MASK, TMC2160_OFS243_SHIFT, TMC2160_MSLUT[7], false}) +#define TMC2160_OFS244_MASK 0x00100000 +#define TMC2160_OFS244_SHIFT 20 +#define TMC2160_OFS244_FIELD ((TMC2160RegisterField) {TMC2160_OFS244_MASK, TMC2160_OFS244_SHIFT, TMC2160_MSLUT[7], false}) +#define TMC2160_OFS245_MASK 0x00200000 +#define TMC2160_OFS245_SHIFT 21 +#define TMC2160_OFS245_FIELD ((TMC2160RegisterField) {TMC2160_OFS245_MASK, TMC2160_OFS245_SHIFT, TMC2160_MSLUT[7], false}) +#define TMC2160_OFS246_MASK 0x00400000 +#define TMC2160_OFS246_SHIFT 22 +#define TMC2160_OFS246_FIELD ((TMC2160RegisterField) {TMC2160_OFS246_MASK, TMC2160_OFS246_SHIFT, TMC2160_MSLUT[7], false}) +#define TMC2160_OFS247_MASK 0x00800000 +#define TMC2160_OFS247_SHIFT 23 +#define TMC2160_OFS247_FIELD ((TMC2160RegisterField) {TMC2160_OFS247_MASK, TMC2160_OFS247_SHIFT, TMC2160_MSLUT[7], false}) +#define TMC2160_OFS248_MASK 0x01000000 +#define TMC2160_OFS248_SHIFT 24 +#define TMC2160_OFS248_FIELD ((TMC2160RegisterField) {TMC2160_OFS248_MASK, TMC2160_OFS248_SHIFT, TMC2160_MSLUT[7], false}) +#define TMC2160_OFS249_MASK 0x02000000 +#define TMC2160_OFS249_SHIFT 25 +#define TMC2160_OFS249_FIELD ((TMC2160RegisterField) {TMC2160_OFS249_MASK, TMC2160_OFS249_SHIFT, TMC2160_MSLUT[7], false}) +#define TMC2160_OFS250_MASK 0x04000000 +#define TMC2160_OFS250_SHIFT 26 +#define TMC2160_OFS250_FIELD ((TMC2160RegisterField) {TMC2160_OFS250_MASK, TMC2160_OFS250_SHIFT, TMC2160_MSLUT[7], false}) +#define TMC2160_OFS251_MASK 0x08000000 +#define TMC2160_OFS251_SHIFT 27 +#define TMC2160_OFS251_FIELD ((TMC2160RegisterField) {TMC2160_OFS251_MASK, TMC2160_OFS251_SHIFT, TMC2160_MSLUT[7], false}) +#define TMC2160_OFS252_MASK 0x10000000 +#define TMC2160_OFS252_SHIFT 28 +#define TMC2160_OFS252_FIELD ((TMC2160RegisterField) {TMC2160_OFS252_MASK, TMC2160_OFS252_SHIFT, TMC2160_MSLUT[7], false}) +#define TMC2160_OFS253_MASK 0x20000000 +#define TMC2160_OFS253_SHIFT 29 +#define TMC2160_OFS253_FIELD ((TMC2160RegisterField) {TMC2160_OFS253_MASK, TMC2160_OFS253_SHIFT, TMC2160_MSLUT[7], false}) +#define TMC2160_OFS254_MASK 0x40000000 +#define TMC2160_OFS254_SHIFT 30 +#define TMC2160_OFS254_FIELD ((TMC2160RegisterField) {TMC2160_OFS254_MASK, TMC2160_OFS254_SHIFT, TMC2160_MSLUT[7], false}) +#define TMC2160_OFS255_MASK 0x80000000 +#define TMC2160_OFS255_SHIFT 31 +#define TMC2160_OFS255_FIELD ((TMC2160RegisterField) {TMC2160_OFS255_MASK, TMC2160_OFS255_SHIFT, TMC2160_MSLUT[7], false}) +#define TMC2160_W0_MASK 0x00000003 +#define TMC2160_W0_SHIFT 0 +#define TMC2160_W0_FIELD ((TMC2160RegisterField) {TMC2160_W0_MASK, TMC2160_W0_SHIFT, TMC2160_MSLUTSEL, false}) +#define TMC2160_W1_MASK 0x0000000C +#define TMC2160_W1_SHIFT 2 +#define TMC2160_W1_FIELD ((TMC2160RegisterField) {TMC2160_W1_MASK, TMC2160_W1_SHIFT, TMC2160_MSLUTSEL, false}) +#define TMC2160_W2_MASK 0x00000030 +#define TMC2160_W2_SHIFT 4 +#define TMC2160_W2_FIELD ((TMC2160RegisterField) {TMC2160_W2_MASK, TMC2160_W2_SHIFT, TMC2160_MSLUTSEL, false}) +#define TMC2160_W3_MASK 0x000000C0 +#define TMC2160_W3_SHIFT 6 +#define TMC2160_W3_FIELD ((TMC2160RegisterField) {TMC2160_W3_MASK, TMC2160_W3_SHIFT, TMC2160_MSLUTSEL, false}) +#define TMC2160_X1_MASK 0x0000FF00 +#define TMC2160_X1_SHIFT 8 +#define TMC2160_X1_FIELD ((TMC2160RegisterField) {TMC2160_X1_MASK, TMC2160_X1_SHIFT, TMC2160_MSLUTSEL, false}) +#define TMC2160_X2_MASK 0x00FF0000 +#define TMC2160_X2_SHIFT 16 +#define TMC2160_X2_FIELD ((TMC2160RegisterField) {TMC2160_X2_MASK, TMC2160_X2_SHIFT, TMC2160_MSLUTSEL, false}) +#define TMC2160_X3_MASK 0xFF000000 +#define TMC2160_X3_SHIFT 24 +#define TMC2160_X3_FIELD ((TMC2160RegisterField) {TMC2160_X3_MASK, TMC2160_X3_SHIFT, TMC2160_MSLUTSEL, false}) +#define TMC2160_START_SIN_MASK 0x000000FF +#define TMC2160_START_SIN_SHIFT 0 +#define TMC2160_START_SIN_FIELD ((TMC2160RegisterField) {TMC2160_START_SIN_MASK, TMC2160_START_SIN_SHIFT, TMC2160_MSLUTSTART, false}) +#define TMC2160_START_SIN90_MASK 0x00FF0000 +#define TMC2160_START_SIN90_SHIFT 16 +#define TMC2160_START_SIN90_FIELD ((TMC2160RegisterField) {TMC2160_START_SIN90_MASK, TMC2160_START_SIN90_SHIFT, TMC2160_MSLUTSTART, false}) +#define TMC2160_MSCNT_MASK 0x000003FF +#define TMC2160_MSCNT_SHIFT 0 +#define TMC2160_MSCNT_FIELD ((TMC2160RegisterField) {TMC2160_MSCNT_MASK, TMC2160_MSCNT_SHIFT, TMC2160_MSCNT, false}) +#define TMC2160_CUR_A_MASK 0x000001FF +#define TMC2160_CUR_A_SHIFT 0 +#define TMC2160_CUR_A_FIELD ((TMC2160RegisterField) {TMC2160_CUR_A_MASK, TMC2160_CUR_A_SHIFT, TMC2160_MSCURACT, true}) +#define TMC2160_CUR_B_MASK 0x01FF0000 +#define TMC2160_CUR_B_SHIFT 16 +#define TMC2160_CUR_B_FIELD ((TMC2160RegisterField) {TMC2160_CUR_B_MASK, TMC2160_CUR_B_SHIFT, TMC2160_MSCURACT, true}) +#define TMC2160_TOFF_MASK 0x0000000F +#define TMC2160_TOFF_SHIFT 0 +#define TMC2160_TOFF_FIELD ((TMC2160RegisterField) {TMC2160_TOFF_MASK, TMC2160_TOFF_SHIFT, TMC2160_CHOPCONF, false}) +#define TMC2160_TFD_2__0__MASK 0x00000070 +#define TMC2160_TFD_2__0__SHIFT 4 +#define TMC2160_TFD_2__0__FIELD ((TMC2160RegisterField) {TMC2160_TFD_2__0__MASK, TMC2160_TFD_2__0__SHIFT, TMC2160_CHOPCONF, false}) +#define TMC2160_OFFSET_MASK 0x00000780 +#define TMC2160_OFFSET_SHIFT 7 +#define TMC2160_OFFSET_FIELD ((TMC2160RegisterField) {TMC2160_OFFSET_MASK, TMC2160_OFFSET_SHIFT, TMC2160_CHOPCONF, false}) +#define TMC2160_TFD___MASK 0x00000800 +#define TMC2160_TFD___SHIFT 11 +#define TMC2160_TFD___FIELD ((TMC2160RegisterField) {TMC2160_TFD___MASK, TMC2160_TFD___SHIFT, TMC2160_CHOPCONF, false}) +#define TMC2160_DISFDCC_MASK 0x00001000 +#define TMC2160_DISFDCC_SHIFT 12 +#define TMC2160_DISFDCC_FIELD ((TMC2160RegisterField) {TMC2160_DISFDCC_MASK, TMC2160_DISFDCC_SHIFT, TMC2160_CHOPCONF, false}) +#define TMC2160_CHM_MASK 0x00004000 +#define TMC2160_CHM_SHIFT 14 +#define TMC2160_CHM_FIELD ((TMC2160RegisterField) {TMC2160_CHM_MASK, TMC2160_CHM_SHIFT, TMC2160_CHOPCONF, false}) +#define TMC2160_TBL_MASK 0x00018000 +#define TMC2160_TBL_SHIFT 15 +#define TMC2160_TBL_FIELD ((TMC2160RegisterField) {TMC2160_TBL_MASK, TMC2160_TBL_SHIFT, TMC2160_CHOPCONF, false}) +#define TMC2160_VHIGHFS_MASK 0x00040000 +#define TMC2160_VHIGHFS_SHIFT 18 +#define TMC2160_VHIGHFS_FIELD ((TMC2160RegisterField) {TMC2160_VHIGHFS_MASK, TMC2160_VHIGHFS_SHIFT, TMC2160_CHOPCONF, false}) +#define TMC2160_VHIGHCHM_MASK 0x00080000 +#define TMC2160_VHIGHCHM_SHIFT 19 +#define TMC2160_VHIGHCHM_FIELD ((TMC2160RegisterField) {TMC2160_VHIGHCHM_MASK, TMC2160_VHIGHCHM_SHIFT, TMC2160_CHOPCONF, false}) +#define TMC2160_TPFD_MASK 0x00F00000 +#define TMC2160_TPFD_SHIFT 20 +#define TMC2160_TPFD_FIELD ((TMC2160RegisterField) {TMC2160_TPFD_MASK, TMC2160_TPFD_SHIFT, TMC2160_CHOPCONF, false}) +#define TMC2160_MRES_MASK 0x0F000000 +#define TMC2160_MRES_SHIFT 24 +#define TMC2160_MRES_FIELD ((TMC2160RegisterField) {TMC2160_MRES_MASK, TMC2160_MRES_SHIFT, TMC2160_CHOPCONF, false}) +#define TMC2160_INTPOL_MASK 0x10000000 +#define TMC2160_INTPOL_SHIFT 28 +#define TMC2160_INTPOL_FIELD ((TMC2160RegisterField) {TMC2160_INTPOL_MASK, TMC2160_INTPOL_SHIFT, TMC2160_CHOPCONF, false}) +#define TMC2160_DEDGE_MASK 0x20000000 +#define TMC2160_DEDGE_SHIFT 29 +#define TMC2160_DEDGE_FIELD ((TMC2160RegisterField) {TMC2160_DEDGE_MASK, TMC2160_DEDGE_SHIFT, TMC2160_CHOPCONF, false}) +#define TMC2160_DISS2G_MASK 0x40000000 +#define TMC2160_DISS2G_SHIFT 30 +#define TMC2160_DISS2G_FIELD ((TMC2160RegisterField) {TMC2160_DISS2G_MASK, TMC2160_DISS2G_SHIFT, TMC2160_CHOPCONF, false}) +#define TMC2160_DISS2VS_MASK 0x80000000 +#define TMC2160_DISS2VS_SHIFT 31 +#define TMC2160_DISS2VS_FIELD ((TMC2160RegisterField) {TMC2160_DISS2VS_MASK, TMC2160_DISS2VS_SHIFT, TMC2160_CHOPCONF, false}) +#define TMC2160_RNDTF_MASK 0x00002000 +#define TMC2160_RNDTF_SHIFT 13 +#define TMC2160_RNDTF_FIELD ((TMC2160RegisterField) {TMC2160_RNDTF_MASK, TMC2160_RNDTF_SHIFT, TMC2160_CHOPCONF, false}) +#define TMC2160_VSENSE_MASK 0x00020000 +#define TMC2160_VSENSE_SHIFT 17 +#define TMC2160_VSENSE_FIELD ((TMC2160RegisterField) {TMC2160_VSENSE_MASK, TMC2160_VSENSE_SHIFT, TMC2160_CHOPCONF, false}) +#define TMC2160_HSTRT_MASK 0x00000070 +#define TMC2160_HSTRT_SHIFT 4 +#define TMC2160_HSTRT_FIELD ((TMC2160RegisterField) {TMC2160_HSTRT_MASK, TMC2160_HSTRT_SHIFT, TMC2160_CHOPCONF, false}) +#define TMC2160_HEND_MASK 0x00000780 +#define TMC2160_HEND_SHIFT 7 +#define TMC2160_HEND_FIELD ((TMC2160RegisterField) {TMC2160_HEND_MASK, TMC2160_HEND_SHIFT, TMC2160_CHOPCONF, false}) +#define TMC2160_SEMIN_MASK 0x0000000F +#define TMC2160_SEMIN_SHIFT 0 +#define TMC2160_SEMIN_FIELD ((TMC2160RegisterField) {TMC2160_SEMIN_MASK, TMC2160_SEMIN_SHIFT, TMC2160_COOLCONF, false}) +#define TMC2160_SEUP_MASK 0x00000060 +#define TMC2160_SEUP_SHIFT 5 +#define TMC2160_SEUP_FIELD ((TMC2160RegisterField) {TMC2160_SEUP_MASK, TMC2160_SEUP_SHIFT, TMC2160_COOLCONF, false}) +#define TMC2160_SEMAX_MASK 0x00000F00 +#define TMC2160_SEMAX_SHIFT 8 +#define TMC2160_SEMAX_FIELD ((TMC2160RegisterField) {TMC2160_SEMAX_MASK, TMC2160_SEMAX_SHIFT, TMC2160_COOLCONF, false}) +#define TMC2160_SEDN_MASK 0x00006000 +#define TMC2160_SEDN_SHIFT 13 +#define TMC2160_SEDN_FIELD ((TMC2160RegisterField) {TMC2160_SEDN_MASK, TMC2160_SEDN_SHIFT, TMC2160_COOLCONF, false}) +#define TMC2160_SEIMIN_MASK 0x00008000 +#define TMC2160_SEIMIN_SHIFT 15 +#define TMC2160_SEIMIN_FIELD ((TMC2160RegisterField) {TMC2160_SEIMIN_MASK, TMC2160_SEIMIN_SHIFT, TMC2160_COOLCONF, false}) +#define TMC2160_SGT_MASK 0x007F0000 +#define TMC2160_SGT_SHIFT 16 +#define TMC2160_SGT_FIELD ((TMC2160RegisterField) {TMC2160_SGT_MASK, TMC2160_SGT_SHIFT, TMC2160_COOLCONF, true}) +#define TMC2160_SFILT_MASK 0x01000000 +#define TMC2160_SFILT_SHIFT 24 +#define TMC2160_SFILT_FIELD ((TMC2160RegisterField) {TMC2160_SFILT_MASK, TMC2160_SFILT_SHIFT, TMC2160_COOLCONF, false}) +#define TMC2160_DC_TIME_MASK 0x000003FF +#define TMC2160_DC_TIME_SHIFT 0 +#define TMC2160_DC_TIME_FIELD ((TMC2160RegisterField) {TMC2160_DC_TIME_MASK, TMC2160_DC_TIME_SHIFT, TMC2160_DCCTRL, false}) +#define TMC2160_DC_SG_MASK 0x00FF0000 +#define TMC2160_DC_SG_SHIFT 16 +#define TMC2160_DC_SG_FIELD ((TMC2160RegisterField) {TMC2160_DC_SG_MASK, TMC2160_DC_SG_SHIFT, TMC2160_DCCTRL, false}) +#define TMC2160_SG_RESULT_MASK 0x000003FF +#define TMC2160_SG_RESULT_SHIFT 0 +#define TMC2160_SG_RESULT_FIELD ((TMC2160RegisterField) {TMC2160_SG_RESULT_MASK, TMC2160_SG_RESULT_SHIFT, TMC2160_DRV_STATUS, false}) +#define TMC2160_S2VSA_MASK 0x00001000 +#define TMC2160_S2VSA_SHIFT 12 +#define TMC2160_S2VSA_FIELD ((TMC2160RegisterField) {TMC2160_S2VSA_MASK, TMC2160_S2VSA_SHIFT, TMC2160_DRV_STATUS, false}) +#define TMC2160_S2VSB_MASK 0x00002000 +#define TMC2160_S2VSB_SHIFT 13 +#define TMC2160_S2VSB_FIELD ((TMC2160RegisterField) {TMC2160_S2VSB_MASK, TMC2160_S2VSB_SHIFT, TMC2160_DRV_STATUS, false}) +#define TMC2160_STEALTH_MASK 0x00004000 +#define TMC2160_STEALTH_SHIFT 14 +#define TMC2160_STEALTH_FIELD ((TMC2160RegisterField) {TMC2160_STEALTH_MASK, TMC2160_STEALTH_SHIFT, TMC2160_DRV_STATUS, false}) +#define TMC2160_FSACTIVE_MASK 0x00008000 +#define TMC2160_FSACTIVE_SHIFT 15 +#define TMC2160_FSACTIVE_FIELD ((TMC2160RegisterField) {TMC2160_FSACTIVE_MASK, TMC2160_FSACTIVE_SHIFT, TMC2160_DRV_STATUS, false}) +#define TMC2160_CS_ACTUAL_MASK 0x001F0000 +#define TMC2160_CS_ACTUAL_SHIFT 16 +#define TMC2160_CS_ACTUAL_FIELD ((TMC2160RegisterField) {TMC2160_CS_ACTUAL_MASK, TMC2160_CS_ACTUAL_SHIFT, TMC2160_DRV_STATUS, false}) +#define TMC2160_STALLGUARD_MASK 0x01000000 +#define TMC2160_STALLGUARD_SHIFT 24 +#define TMC2160_STALLGUARD_FIELD ((TMC2160RegisterField) {TMC2160_STALLGUARD_MASK, TMC2160_STALLGUARD_SHIFT, TMC2160_DRV_STATUS, false}) +#define TMC2160_OT_MASK 0x02000000 +#define TMC2160_OT_SHIFT 25 +#define TMC2160_OT_FIELD ((TMC2160RegisterField) {TMC2160_OT_MASK, TMC2160_OT_SHIFT, TMC2160_DRV_STATUS, false}) +#define TMC2160_OTPW_MASK 0x04000000 +#define TMC2160_OTPW_SHIFT 26 +#define TMC2160_OTPW_FIELD ((TMC2160RegisterField) {TMC2160_OTPW_MASK, TMC2160_OTPW_SHIFT, TMC2160_DRV_STATUS, false}) +#define TMC2160_S2GA_MASK 0x08000000 +#define TMC2160_S2GA_SHIFT 27 +#define TMC2160_S2GA_FIELD ((TMC2160RegisterField) {TMC2160_S2GA_MASK, TMC2160_S2GA_SHIFT, TMC2160_DRV_STATUS, false}) +#define TMC2160_S2GB_MASK 0x10000000 +#define TMC2160_S2GB_SHIFT 28 +#define TMC2160_S2GB_FIELD ((TMC2160RegisterField) {TMC2160_S2GB_MASK, TMC2160_S2GB_SHIFT, TMC2160_DRV_STATUS, false}) +#define TMC2160_OLA_MASK 0x20000000 +#define TMC2160_OLA_SHIFT 29 +#define TMC2160_OLA_FIELD ((TMC2160RegisterField) {TMC2160_OLA_MASK, TMC2160_OLA_SHIFT, TMC2160_DRV_STATUS, false}) +#define TMC2160_OLB_MASK 0x40000000 +#define TMC2160_OLB_SHIFT 30 +#define TMC2160_OLB_FIELD ((TMC2160RegisterField) {TMC2160_OLB_MASK, TMC2160_OLB_SHIFT, TMC2160_DRV_STATUS, false}) +#define TMC2160_STST_MASK 0x80000000 +#define TMC2160_STST_SHIFT 31 +#define TMC2160_STST_FIELD ((TMC2160RegisterField) {TMC2160_STST_MASK, TMC2160_STST_SHIFT, TMC2160_DRV_STATUS, false}) +#define TMC2160_PWM_OFS_MASK 0x000000FF +#define TMC2160_PWM_OFS_SHIFT 0 +#define TMC2160_PWM_OFS_FIELD ((TMC2160RegisterField) {TMC2160_PWM_OFS_MASK, TMC2160_PWM_OFS_SHIFT, TMC2160_PWMCONF, false}) +#define TMC2160_PWM_GRAD_MASK 0x0000FF00 +#define TMC2160_PWM_GRAD_SHIFT 8 +#define TMC2160_PWM_GRAD_FIELD ((TMC2160RegisterField) {TMC2160_PWM_GRAD_MASK, TMC2160_PWM_GRAD_SHIFT, TMC2160_PWMCONF, false}) +#define TMC2160_PWM_FREQ_MASK 0x00030000 +#define TMC2160_PWM_FREQ_SHIFT 16 +#define TMC2160_PWM_FREQ_FIELD ((TMC2160RegisterField) {TMC2160_PWM_FREQ_MASK, TMC2160_PWM_FREQ_SHIFT, TMC2160_PWMCONF, false}) +#define TMC2160_PWM_AUTOSCALE_MASK 0x00040000 +#define TMC2160_PWM_AUTOSCALE_SHIFT 18 +#define TMC2160_PWM_AUTOSCALE_FIELD ((TMC2160RegisterField) {TMC2160_PWM_AUTOSCALE_MASK, TMC2160_PWM_AUTOSCALE_SHIFT, TMC2160_PWMCONF, false}) +#define TMC2160_PWM_AUTOGRAD_MASK 0x00080000 +#define TMC2160_PWM_AUTOGRAD_SHIFT 19 +#define TMC2160_PWM_AUTOGRAD_FIELD ((TMC2160RegisterField) {TMC2160_PWM_AUTOGRAD_MASK, TMC2160_PWM_AUTOGRAD_SHIFT, TMC2160_PWMCONF, false}) +#define TMC2160_FREEWHEEL_MASK 0x00300000 +#define TMC2160_FREEWHEEL_SHIFT 20 +#define TMC2160_FREEWHEEL_FIELD ((TMC2160RegisterField) {TMC2160_FREEWHEEL_MASK, TMC2160_FREEWHEEL_SHIFT, TMC2160_PWMCONF, false}) +#define TMC2160_PWM_REG_MASK 0x0F000000 +#define TMC2160_PWM_REG_SHIFT 24 +#define TMC2160_PWM_REG_FIELD ((TMC2160RegisterField) {TMC2160_PWM_REG_MASK, TMC2160_PWM_REG_SHIFT, TMC2160_PWMCONF, false}) +#define TMC2160_PWM_LIM_MASK 0xF0000000 +#define TMC2160_PWM_LIM_SHIFT 28 +#define TMC2160_PWM_LIM_FIELD ((TMC2160RegisterField) {TMC2160_PWM_LIM_MASK, TMC2160_PWM_LIM_SHIFT, TMC2160_PWMCONF, false}) +#define TMC2160_PWM_SCALE_SUM_MASK 0x000000FF +#define TMC2160_PWM_SCALE_SUM_SHIFT 0 +#define TMC2160_PWM_SCALE_SUM_FIELD ((TMC2160RegisterField) {TMC2160_PWM_SCALE_SUM_MASK, TMC2160_PWM_SCALE_SUM_SHIFT, TMC2160_PWM_SCALE, false}) +#define TMC2160_PWM_SCALE_AUTO_MASK 0x01FF0000 +#define TMC2160_PWM_SCALE_AUTO_SHIFT 16 +#define TMC2160_PWM_SCALE_AUTO_FIELD ((TMC2160RegisterField) {TMC2160_PWM_SCALE_AUTO_MASK, TMC2160_PWM_SCALE_AUTO_SHIFT, TMC2160_PWM_SCALE, true}) +#define TMC2160_PWM_OFS_AUTO_MASK 0x000000FF +#define TMC2160_PWM_OFS_AUTO_SHIFT 0 +#define TMC2160_PWM_OFS_AUTO_FIELD ((TMC2160RegisterField) {TMC2160_PWM_OFS_AUTO_MASK, TMC2160_PWM_OFS_AUTO_SHIFT, TMC2160_PWM_AUTO, false}) +#define TMC2160_PWM_GRAD_AUTO_MASK 0x00FF0000 +#define TMC2160_PWM_GRAD_AUTO_SHIFT 16 +#define TMC2160_PWM_GRAD_AUTO_FIELD ((TMC2160RegisterField) {TMC2160_PWM_GRAD_AUTO_MASK, TMC2160_PWM_GRAD_AUTO_SHIFT, TMC2160_PWM_AUTO, false}) +#define TMC2160_LOST_STEPS_MASK 0x000FFFFF +#define TMC2160_LOST_STEPS_SHIFT 0 +#define TMC2160_LOST_STEPS_FIELD ((TMC2160RegisterField) {TMC2160_LOST_STEPS_MASK, TMC2160_LOST_STEPS_SHIFT, TMC2160_LOST_STEPS, false}) + +#endif diff --git a/firmware/lib/tmc/ic/TMC2160/registercall_hierarchy_flowchart_SPI.svg b/firmware/lib/tmc/ic/TMC2160/registercall_hierarchy_flowchart_SPI.svg new file mode 100755 index 0000000..cbad58f --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2160/registercall_hierarchy_flowchart_SPI.svg @@ -0,0 +1,3 @@ + + +

HAL

HAL

APP (Eval)

APP (Eval)

API

API
Read a register
  •  Call tmcXXXX_readRegister function
Read a register...
Returns the register read value
Returns the register read value
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
tmcXXXX.c
tmcXXXX.c
SPI.c
SPI.c
tmcXXXX_eval.c
tmcXXXX_eval.c

 Implementation of SPI_readWrite
  • Sends and receives bytes on the SPI bus
Implementation of SPI_readWrite...
Returns the raw reply data
Returns the raw reply data

Implementation of tmcXXXX_readWriteSPI
  • Sets the CSN pin to LOW
  • Takes the array of data to write
  • Calls hardware function SPI_readWrite
  • Upon completion of data transfer,
    sets CSN to 
    HIGH
Implementation of tmcXXXX_readWriteSPI...
Passes on the raw reply data to the API
Passes on the raw reply data to the API
Implementation of readRegisterSPI
  • Constructs the datagram
  • Calls HAL wrapper function 
Implementation of readRegisterSPI...
tmcXXXX_readWriteSPI
tmcXXXX_readWriteSPI
Parses the reply and returns the register value
Parses the reply and returns the register value
Implementation of tmcXXXX_readRegister 
  • Check which bus is active SPI/UART. (e.g. SPI)
  • Calls bus-specific function (e.g. readRegisterSPI)
 
Implementation of tmcXXXX_readRegister...
Returns the register read value
Returns the register read value
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC2160/uml-tmc-api.svg b/firmware/lib/tmc/ic/TMC2160/uml-tmc-api.svg new file mode 100755 index 0000000..5a5f8dd --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2160/uml-tmc-api.svg @@ -0,0 +1,3 @@ + + +

TMCXXXX_HW_Abstraction.h



TMCXXXX_HW_Abstraction.h...
// Constants
#define TMCXXXX_MOTORS              
                          
// Register definitions
#define TMCXXXX_GCONF        
                          ⋮
// Register fields definitions
#define TMCXXXX_GCONF_OTPW_FIELD
                     
// Constants...

TMCXXXX.h



TMCXXXX.h...
extern void tmcXXXX_readWriteSPI();
extern void tmcXXXX_readWriteUART();
extern TMCXXXXBusType tmcXXXX_getBusType();
extern uint8_t tmcXXXX_getNodeAddress();
                                  ⋮
tmcXXXX_readRegister();
tmcXXXX_writeRegister();
                                  ⋮
extern void tmcXXXX_readWriteSPI();...

TMCXXXX.c



TMCXXXX.c...
const uint8_t tmcCRCTable_Poly7Reflected[256] = {...};
int32_t tmcXXXX_readRegister(){
/* Call tmcXXXX_getBusType();
 * Based on bus type, call readRegisterSPI/UART() that
 * further calls tmcXXXX_readWriteSPI/UART();
 * For UART it also calls tmcXXXX_getNodeAddress();
                                           ⋮
}
                                           ⋮
const uint8_t tmcCRCTable_Poly7Reflected[256] = {.....
TMC-API
TMC-API

TMCXXXX_Simple_Rotation.h


TMCXXXX_Simple_Rotation.h...
void initAllMotors();
             ⋮
  
void initAllMotors()...

TMCXXXX_Simple_Rotation.c


TMCXXXX_Simple_Rotation.c...
void initAllMotors(){

// Configuring registers to enable motor drivers etc..
tmcXXXX_writeRegister();
                    ⋮
}
                    ⋮
void initAllMotors(){...
Examples
Examples
User Project
User Project

User_Project.h


User_Project.h

User_Project.c








User_Project.c...

void tmcXXXX_readWriteSPI(){
                           ⋮
}
void tmcXXXX_readWriteUART(){
                           ⋮
}
TMCXXXXBusType tmcXXXX_getBusType(){
                           ⋮
}
uint8_t tmcXXXX_getNodeAddress(){
                           ⋮
}

// User Code
                           ⋮
void tmcXXXX_readWriteSPI(){...
#include "TMCXXXX_HW_Abstraction.h"
#include "TMCXXXX.h"
#include "TMCXXXX_Simple_Rotation.h"
                                ⋮
TMCXXXXBusType bus = IC_BUS_SPI/UART;
uint8_t nodeAddress = <nodeAddress>;
                                ⋮
#include "TMCXXXX_HW_Abstraction.h"...
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC2208/README.md b/firmware/lib/tmc/ic/TMC2208/README.md new file mode 100755 index 0000000..0c53d5c --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2208/README.md @@ -0,0 +1,52 @@ +# TMC2208 + + +## How to use + +To access the TMC2208's registers, the TMC-API offers two functions: **tmc2208_readRegister** and **tmc2208_writeRegister**. +Each of these functions takes in an **icID**, which is used to identify the IC when multiple ICs are connected. This identifier is passed down to the callback functions (see How to Integrate). + +## How to integrate: overview + +1. Include all the files of the TMC-API/ic/tmc/TMC2208 folder into the custom project. +2. Include the TMC2208.h file in the custom source code. +3. Implement the necessary callback functions (see below). +4. (optional): Take a look at the Examples subfolder for ready-made examples of the TMC-API usage. + +## Accessing the TMC2208 via UART +The following diagram depicts how to access the TMC2208 via UART using the TMC-API. + +![screenshot](registercall_hierarchy_flowchart_UART.svg) + +The description of the functions, in the above flowchart, are as follows: +- The functions tmc2208_readRegister and tmc2208_writeRegister are used to read and write the registers respectively. These functions check the current active bus and calls the bus-specific function i.e readRegisterUART or writeRegisterUART. +- These bus specific functions constructs the datagram and further calls the bus specific callback 'tmcXXXX_readWriteUART. +- This callback function further calls the hardware specific read/write function for UART and needs to be implemented externally. + +### How to integrate: Callback functions +Implement the following callback functions to access the chip via UART: +1. **tmc2208_readWriteUART()**, which is a HAL wrapper function that provides the necessary hardware access. +2. **tmc2208_getNodeAddress()**, that returns the node/slave address. Node address could be set in NODECONF (0x3) register and the address could be incremented as defined by AD0, AD1 and AD2. (Node address + ADx) must be less than 255. For further details please consult the datasheet of TMC2208. + +### Sharing the CRC table with other TMC-API chips +The TMC2208 UART protocol uses an 8 bit CRC. For calculating this, a table-based algorithm is used. This table (tmcCRCTable_Poly7Reflected[256]) is 256 bytes big and identical across multiple different Trinamic chips (i.e. TMC2208). +If multiple Trinamic chips are being used in the same project, avoiding redundant copies of this table could save memory. It is possible to substitute this CRC table with another CRC table. + +### Option to use the cache logic for Write-Only registers +The chip features write-only registers that are unable to be read, necessitating the creation of a shadow copy to cache their contents. This copy is automatically updated whenever data is written to these registers. This cache logic could be enabled by setting the macro **TMC2208_CACHE** to **'1'** or disabled by setting to **'0'** respectively. If this feature is enabled then there comes another option to use **tmc2208_cache** function, which is already implemeted in the API, by defining **TMC2208_ENABLE_TMC_CACHE** macro to **'1** or one can implement their own function. + +The function **tmc2208_cache** works for both reading from and writing to the shadow array. It first checks whether the register has write-only access and data needs to be read from the shadow copy. On the basis of that, it returns **true** or **false**. The shadowRegisters on the premade cache implementation need to be one per chip. **TMC2208_IC_CACHE_COUNT** is set to '1' by default and is user-overwritable. If multiple chips are being used in the same project, increment its value to the number of chips connected. + +## Further info +### Dependency graph for the ICs with new register R/W mechanism +This graph illustrates the relationships between files within the TMC-API library, highlighting dependencies and identifying the files that are essential for integrating the library into the custom projects. + +![screenshot](uml-tmc-api.svg) + +### Example usage: TMC-Evalsystem +**For a reference usage of the TMC-API**, visit the [TMC-Evalsystem](https://github.com/analogdevicesinc/TMC-EvalSystem) + +## Migration status +The TMC2208 has been reworked to the access system described above. For more infos on the status of this and other ICs, check out the [migration page](https://github.com/analogdevicesinc/TMC-API/issues/53). + + diff --git a/firmware/lib/tmc/ic/TMC2208/TMC2208.c b/firmware/lib/tmc/ic/TMC2208/TMC2208.c new file mode 100755 index 0000000..5f92478 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2208/TMC2208.c @@ -0,0 +1,208 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#include "TMC2208.h" + + +#ifdef TMC_API_EXTERNAL_CRC_TABLE +extern const uint8_t tmcCRCTable_Poly7Reflected[256]; +#else +const uint8_t tmcCRCTable_Poly7Reflected[256] = { + 0x00, 0x91, 0xE3, 0x72, 0x07, 0x96, 0xE4, 0x75, 0x0E, 0x9F, 0xED, 0x7C, 0x09, 0x98, 0xEA, 0x7B, + 0x1C, 0x8D, 0xFF, 0x6E, 0x1B, 0x8A, 0xF8, 0x69, 0x12, 0x83, 0xF1, 0x60, 0x15, 0x84, 0xF6, 0x67, + 0x38, 0xA9, 0xDB, 0x4A, 0x3F, 0xAE, 0xDC, 0x4D, 0x36, 0xA7, 0xD5, 0x44, 0x31, 0xA0, 0xD2, 0x43, + 0x24, 0xB5, 0xC7, 0x56, 0x23, 0xB2, 0xC0, 0x51, 0x2A, 0xBB, 0xC9, 0x58, 0x2D, 0xBC, 0xCE, 0x5F, + 0x70, 0xE1, 0x93, 0x02, 0x77, 0xE6, 0x94, 0x05, 0x7E, 0xEF, 0x9D, 0x0C, 0x79, 0xE8, 0x9A, 0x0B, + 0x6C, 0xFD, 0x8F, 0x1E, 0x6B, 0xFA, 0x88, 0x19, 0x62, 0xF3, 0x81, 0x10, 0x65, 0xF4, 0x86, 0x17, + 0x48, 0xD9, 0xAB, 0x3A, 0x4F, 0xDE, 0xAC, 0x3D, 0x46, 0xD7, 0xA5, 0x34, 0x41, 0xD0, 0xA2, 0x33, + 0x54, 0xC5, 0xB7, 0x26, 0x53, 0xC2, 0xB0, 0x21, 0x5A, 0xCB, 0xB9, 0x28, 0x5D, 0xCC, 0xBE, 0x2F, + 0xE0, 0x71, 0x03, 0x92, 0xE7, 0x76, 0x04, 0x95, 0xEE, 0x7F, 0x0D, 0x9C, 0xE9, 0x78, 0x0A, 0x9B, + 0xFC, 0x6D, 0x1F, 0x8E, 0xFB, 0x6A, 0x18, 0x89, 0xF2, 0x63, 0x11, 0x80, 0xF5, 0x64, 0x16, 0x87, + 0xD8, 0x49, 0x3B, 0xAA, 0xDF, 0x4E, 0x3C, 0xAD, 0xD6, 0x47, 0x35, 0xA4, 0xD1, 0x40, 0x32, 0xA3, + 0xC4, 0x55, 0x27, 0xB6, 0xC3, 0x52, 0x20, 0xB1, 0xCA, 0x5B, 0x29, 0xB8, 0xCD, 0x5C, 0x2E, 0xBF, + 0x90, 0x01, 0x73, 0xE2, 0x97, 0x06, 0x74, 0xE5, 0x9E, 0x0F, 0x7D, 0xEC, 0x99, 0x08, 0x7A, 0xEB, + 0x8C, 0x1D, 0x6F, 0xFE, 0x8B, 0x1A, 0x68, 0xF9, 0x82, 0x13, 0x61, 0xF0, 0x85, 0x14, 0x66, 0xF7, + 0xA8, 0x39, 0x4B, 0xDA, 0xAF, 0x3E, 0x4C, 0xDD, 0xA6, 0x37, 0x45, 0xD4, 0xA1, 0x30, 0x42, 0xD3, + 0xB4, 0x25, 0x57, 0xC6, 0xB3, 0x22, 0x50, 0xC1, 0xBA, 0x2B, 0x59, 0xC8, 0xBD, 0x2C, 0x5E, 0xCF, +}; +#endif + +/**************************************************************** Cache Implementation *************************************************************************/ +#if TMC2208_CACHE == 0 +static inline bool tmc2208_cache(uint16_t icID, TMC2208CacheOp operation, uint8_t address, uint32_t *value) +{ + UNUSED(icID); + UNUSED(address); + UNUSED(operation); + return false; +} +#else +#if TMC2208_ENABLE_TMC_CACHE == 1 +uint8_t tmc2208_dirtyBits[TMC2208_IC_CACHE_COUNT][TMC2208_REGISTER_COUNT/8]= {0}; +int32_t tmc2208_shadowRegister[TMC2208_IC_CACHE_COUNT][TMC2208_REGISTER_COUNT]; + +void tmc2208_setDirtyBit(uint16_t icID, uint8_t index, bool value) +{ + if(index >= TMC2208_REGISTER_COUNT) + return; + + uint8_t *tmp = &tmc2208_dirtyBits[icID][index / 8]; + uint8_t shift = (index % 8); + uint8_t mask = 1 << shift; + *tmp = (((*tmp) & (~(mask))) | (((value) << (shift)) & (mask))); +} + +bool tmc2208_getDirtyBit(uint16_t icID, uint8_t index) +{ + if(index >= TMC2208_REGISTER_COUNT) + return false; + + uint8_t *tmp = &tmc2208_dirtyBits[icID][index / 8]; + uint8_t shift = (index % 8); + return ((*tmp) >> shift) & 1; +} + +/* + * This function is used to cache the value written to the Write-Only registers in the form of shadow array. + * The shadow copy is then used to read these kinds of registers. + */ +bool tmc2208_cache(uint16_t icID, TMC2208CacheOp operation, uint8_t address, uint32_t *value) +{ + if (operation == TMC2208_CACHE_READ) + { + // Check if the value should come from cache + + // Only supported chips have a cache + if (icID >= TMC2208_IC_CACHE_COUNT) + return false; + + // Only non-readable registers care about caching + // Note: This could also be used to cache i.e. RW config registers to reduce bus accesses + if (TMC2208_IS_READABLE(tmc2208_registerAccess[address])) + return false; + + // Grab the value from the cache + *value = tmc2208_shadowRegister[icID][address]; + return true; + } + else if (operation == TMC2208_CACHE_WRITE || operation == TMC2208_CACHE_FILL_DEFAULT) + { + // Fill the cache + + // only supported chips have a cache + if (icID >= TMC2208_IC_CACHE_COUNT) + return false; + + // Write to the shadow register and mark the register dirty + tmc2208_shadowRegister[icID][address] = *value; + if (operation == TMC2208_CACHE_WRITE) + { + tmc2208_setDirtyBit(icID, address, true); + } + return true; + } + return false; +} + +#else +// User must implement their own cache +extern bool tmc2208_cache(uint16_t icID, TMC2208CacheOp operation, uint8_t address, uint32_t *value); +#endif +#endif + +/************************************************************** Register read / write Implementation ******************************************************************/ + +static int32_t readRegisterUART(uint16_t icID, uint8_t registerAddress); +static void writeRegisterUART(uint16_t icID, uint8_t registerAddress, int32_t value); +static uint8_t CRC8(uint8_t *data, uint32_t bytes); + +int32_t tmc2208_readRegister(uint16_t icID, uint8_t address) +{ + uint32_t value; + + // Read from cache for registers with write-only access + if (tmc2208_cache(icID, TMC2208_CACHE_READ, address, &value)) + return value; + + return readRegisterUART(icID, address); + + // ToDo: Error handling +} +void tmc2208_writeRegister(uint16_t icID, uint8_t address, int32_t value) +{ + writeRegisterUART(icID, address, value); +} + +int32_t readRegisterUART(uint16_t icID, uint8_t registerAddress) +{ + uint8_t data[8] = {0}; + + registerAddress = registerAddress & TMC2208_ADDRESS_MASK; + + data[0] = 0x05; + data[1] = tmc2208_getNodeAddress(icID); + data[2] = registerAddress; + data[3] = CRC8(data, 3); + + if (!tmc2208_readWriteUART(icID, &data[0], 4, 8)) + return 0; + + // Byte 0: Sync nibble correct? + if (data[0] != 0x05) + return 0; + + // Byte 1: Master address correct? + if (data[1] != 0xFF) + return 0; + + // Byte 2: Address correct? + if (data[2] != registerAddress) + return 0; + + // Byte 7: CRC correct? + if (data[7] != CRC8(data, 7)) + return 0; + + return ((uint32_t) data[3] << 24) | ((uint32_t) data[4] << 16) | ((uint32_t) data[5] << 8) | data[6]; +} + +void writeRegisterUART(uint16_t icID, uint8_t registerAddress, int32_t value) +{ + uint8_t data[8]; + + data[0] = 0x05; + data[1] = tmc2208_getNodeAddress(icID); + data[2] = registerAddress | TMC2208_WRITE_BIT; + data[3] = (value >> 24) & 0xFF; + data[4] = (value >> 16) & 0xFF; + data[5] = (value >> 8) & 0xFF; + data[6] = (value) & 0xFF; + data[7] = CRC8(data, 7); + + tmc2208_readWriteUART(icID, &data[0], 8, 0); + + //Cache the registers with write-only access + tmc2208_cache(icID, TMC2208_CACHE_WRITE, registerAddress, (uint32_t *)&value); +} + +static uint8_t CRC8(uint8_t *data, uint32_t bytes) +{ + uint8_t result = 0; + while (bytes--) result = tmcCRCTable_Poly7Reflected[result ^ *data++]; + + // Flip the result around + // swap odd and even bits + result = ((result >> 1) & 0x55) | ((result & 0x55) << 1); + // swap consecutive pairs + result = ((result >> 2) & 0x33) | ((result & 0x33) << 2); + // swap nibbles ... + result = ((result >> 4) & 0x0F) | ((result & 0x0F) << 4); + + return result; +} diff --git a/firmware/lib/tmc/ic/TMC2208/TMC2208.h b/firmware/lib/tmc/ic/TMC2208/TMC2208.h new file mode 100755 index 0000000..fae1588 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2208/TMC2208.h @@ -0,0 +1,183 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#ifndef TMC_IC_TMC2208_H_ +#define TMC_IC_TMC2208_H_ + +#include +#include +#include +#include "TMC2208_HW_Abstraction.h" + + +/******************************************************************************* +* API Configuration Defines +* These control optional features of the TMC-API implementation. +* These can be commented in/out here or defined from the build system. +*******************************************************************************/ + +// Uncomment if you want to save space..... +// and put the table into your own .c file +//#define TMC_API_EXTERNAL_CRC_TABLE 1 + +// To enable the cache mechanism in order to keep the copy of all registers, set TMC2208_CACHE to '1'. +// With this mechanism the value of write-only registers could be read from their shadow copies. +#ifndef TMC2208_CACHE +#define TMC2208_CACHE 1 +//#define TMC2208_CACHE 0 +#endif + +// To use the caching mechanism already implemented by the TMC-API, set TMC2208_ENABLE_TMC_CACHE to '1'. +// Set TMC2208_ENABLE_TMC_CACHE to '0' if one wants to have their own cache implementation. +#ifndef TMC2208_ENABLE_TMC_CACHE +#define TMC2208_ENABLE_TMC_CACHE 1 +//#define TMC2208_ENABLE_TMC_CACHE 0 +#endif + +/******************************************************************************/ + +typedef struct +{ + uint32_t mask; + uint8_t shift; + uint8_t address; + bool isSigned; +} RegisterField; + +// => TMC-API wrapper +extern bool tmc2208_readWriteUART(uint16_t icID, uint8_t *data, size_t writeLength, size_t readLength); +extern uint8_t tmc2208_getNodeAddress(uint16_t icID); +// => TMC-API wrapper + +int32_t tmc2208_readRegister(uint16_t icID, uint8_t address); +void tmc2208_writeRegister(uint16_t icID, uint8_t address, int32_t value); + + +static inline uint32_t tmc2208_fieldExtract(uint32_t data, RegisterField field) +{ + uint32_t value = (data & field.mask) >> field.shift; + + if (field.isSigned) + { + // Apply signedness conversion + uint32_t baseMask = field.mask >> field.shift; + uint32_t signMask = baseMask & (~baseMask >> 1); + value = (value ^ signMask) - signMask; + } + + return value; +} + +static inline uint32_t tmc2208_fieldRead(uint16_t icID, RegisterField field) +{ + uint32_t value = tmc2208_readRegister(icID, field.address); + + return tmc2208_fieldExtract(value, field); +} + +static inline uint32_t tmc2208_fieldUpdate(uint32_t data, RegisterField field, uint32_t value) +{ + return (data & (~field.mask)) | ((value << field.shift) & field.mask); +} + +static inline void tmc2208_fieldWrite(uint16_t icID, RegisterField field, uint32_t value) +{ + uint32_t regValue = tmc2208_readRegister(icID, field.address); + + regValue = tmc2208_fieldUpdate(regValue, field, value); + + tmc2208_writeRegister(icID, field.address, regValue); +} + +/**************************************************************** Cache Implementation *************************************************************************/ + +#if TMC2208_CACHE == 1 +#if TMC2208_ENABLE_TMC_CACHE == 1 + +// By default, support one IC in the cache +#ifndef TMC2208_IC_CACHE_COUNT +#define TMC2208_IC_CACHE_COUNT 1 +#endif + +typedef enum { + // Cache operations for chip read and write operations + TMC2208_CACHE_READ, + TMC2208_CACHE_WRITE, + + // Special operation: Put content into the cache without marking the entry as dirty. + // Only used to initialize the cache with hardware defaults. This will allow reading + // from write-only registers that have a value inside them on reset. When using this + // operation, a restore will *not* rewrite that filled register! + TMC2208_CACHE_FILL_DEFAULT, +} TMC2208CacheOp; + +#define TMC2208_ACCESS_READ 0x01 +#define TMC2208_IS_READABLE(x) ((x) & TMC2208_ACCESS_READ) +#define ____ 0x00 + +// Default Register values +#define R00 0x00000041 // GCONF +#define R10 0x00071703 // IHOLD_IRUN +#define R11 0x00000014 // TPOWERDOWN +#define R6C 0x10000053 // CHOPCONF +#define R70 0xC10D0024 // PWMCONF + +// Register access permissions: +// 0x00: none (reserved) +// 0x01: read +// 0x02: write +// 0x03: read/write +// 0x13: read/write, separate functions/values for reading or writing +// 0x21: read, flag register (read to clear) +// 0x42: write, has hardware presets on reset +static const uint8_t tmc2208_registerAccess[TMC2208_REGISTER_COUNT] = +{ +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0x03, 0x23, 0x01, 0x02, 0x02, 0x01, 0x01, 0x03, ____, ____, ____, ____, ____, ____, ____, ____, // 0x00 - 0x0F + 0x02, 0x02, 0x01, 0x02, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x10 - 0x1F + ____, ____, 0x02, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x20 - 0x2F + ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x30 - 0x3F + 0x02, 0x01, 0x02, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x40 - 0x4F + ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x50 - 0x5F + ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, 0x01, 0x01, 0x03, ____, ____, 0x01, // 0x60 - 0x6F + 0x03, 0x01, 0x01, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____ // 0x70 - 0x7F +}; + +static const int32_t tmc2208_sampleRegisterPreset[TMC2208_REGISTER_COUNT] = +{ +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + R00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x00 - 0x0F + R10, R11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x10 - 0x1F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x20 - 0x2F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x30 - 0x3F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x40 - 0x4F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x50 - 0x5F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, R6C, 0, 0, 0, // 0x60 - 0x6F + R70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // 0x70 - 0x7F +}; + +// Undefine the default register values. +// This prevents warnings in case multiple TMC-API chip headers are included at once +#undef R00 +#undef R10 +#undef R11 +#undef R6C +#undef R70 + +extern uint8_t tmc2208_dirtyBits[TMC2208_IC_CACHE_COUNT][TMC2208_REGISTER_COUNT/8]; +extern int32_t tmc2208_shadowRegister[TMC2208_IC_CACHE_COUNT][TMC2208_REGISTER_COUNT]; +void tmc2208_setDirtyBit(uint16_t icID, uint8_t index, bool value); +bool tmc2208_getDirtyBit(uint16_t icID, uint8_t index); +extern bool tmc2208_cache(uint16_t icID, TMC2208CacheOp operation, uint8_t address, uint32_t *value); +#endif +#endif + +/***************************************************************************************************************************************************/ + +#endif /* TMC_IC_TMC2208_H_ */ diff --git a/firmware/lib/tmc/ic/TMC2208/TMC2208_HW_Abstraction.h b/firmware/lib/tmc/ic/TMC2208/TMC2208_HW_Abstraction.h new file mode 100755 index 0000000..da2ace0 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2208/TMC2208_HW_Abstraction.h @@ -0,0 +1,288 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + +#ifndef TMC2208_HW_ABSTRACTION +#define TMC2208_HW_ABSTRACTION + + +// Constants + +#define TMC2208_MOTORS 1 +#define TMC2208_REGISTER_COUNT 128 // Default register count +#define TMC2208_WRITE_BIT 0x80 +#define TMC2208_ADDRESS_MASK 0x7F +#define TMC2208_MAX_VELOCITY (int32_t) 2147483647 +#define TMC2208_MAX_ACCELERATION (uint32_t) 4294967295uL + + +// Registers in TMC2208 +// ===== TMC2208 & 2202 & TMC2208 & 2220 & 2225 "Donkey Kong" family register set ===== + +#define TMC2208_GCONF 0x00 +#define TMC2208_GSTAT 0x01 +#define TMC2208_IFCNT 0x02 +#define TMC2208_SLAVECONF 0x03 +#define TMC2208_OTP_PROG 0x04 +#define TMC2208_OTP_READ 0x05 +#define TMC2208_IOIN 0x06 +#define TMC2208_FACTORY_CONF 0x07 +#define TMC2208_IHOLD_IRUN 0x10 +#define TMC2208_TPOWERDOWN 0x11 +#define TMC2208_TSTEP 0x12 +#define TMC2208_TPWMTHRS 0x13 +#define TMC2208_VACTUAL 0x22 +#define TMC2208_MSCNT 0x6A +#define TMC2208_MSCURACT 0x6B +#define TMC2208_CHOPCONF 0x6C +#define TMC2208_DRVSTATUS 0x6F +#define TMC2208_PWMCONF 0x70 +#define TMC2208_PWM_SCALE 0x71 +#define TMC2208_PWM_AUTO 0x72 + + +// Register fields in TMC2208 + +#define TMC2208_I_SCALE_ANALOG_MASK 0x00000001 +#define TMC2208_I_SCALE_ANALOG_SHIFT 0 +#define TMC2208_I_SCALE_ANALOG_FIELD ((RegisterField) {TMC2208_I_SCALE_ANALOG_MASK, TMC2208_I_SCALE_ANALOG_SHIFT, TMC2208_GCONF, false}) +#define TMC2208_INTERNAL_RSENSE_MASK 0x00000002 +#define TMC2208_INTERNAL_RSENSE_SHIFT 1 +#define TMC2208_INTERNAL_RSENSE_FIELD ((RegisterField) {TMC2208_INTERNAL_RSENSE_MASK, TMC2208_INTERNAL_RSENSE_SHIFT, TMC2208_GCONF, false}) +#define TMC2208_EN_SPREADCYCLE_MASK 0x00000004 +#define TMC2208_EN_SPREADCYCLE_SHIFT 2 +#define TMC2208_EN_SPREADCYCLE_FIELD ((RegisterField) {TMC2208_EN_SPREADCYCLE_MASK, TMC2208_EN_SPREADCYCLE_SHIFT, TMC2208_GCONF, false}) +#define TMC2208_SHAFT_MASK 0x00000008 +#define TMC2208_SHAFT_SHIFT 3 +#define TMC2208_SHAFT_FIELD ((RegisterField) {TMC2208_SHAFT_MASK, TMC2208_SHAFT_SHIFT, TMC2208_GCONF, false}) +#define TMC2208_INDEX_OTPW_MASK 0x00000010 +#define TMC2208_INDEX_OTPW_SHIFT 4 +#define TMC2208_INDEX_OTPW_FIELD ((RegisterField) {TMC2208_INDEX_OTPW_MASK, TMC2208_INDEX_OTPW_SHIFT, TMC2208_GCONF, false}) +#define TMC2208_INDEX_STEP_MASK 0x00000020 +#define TMC2208_INDEX_STEP_SHIFT 5 +#define TMC2208_INDEX_STEP_FIELD ((RegisterField) {TMC2208_INDEX_STEP_MASK, TMC2208_INDEX_STEP_SHIFT, TMC2208_GCONF, false}) +#define TMC2208_PDN_DISABLE_MASK 0x00000040 +#define TMC2208_PDN_DISABLE_SHIFT 6 +#define TMC2208_PDN_DISABLE_FIELD ((RegisterField) {TMC2208_PDN_DISABLE_MASK, TMC2208_PDN_DISABLE_SHIFT, TMC2208_GCONF, false}) +#define TMC2208_MSTEP_REG_SELECT_MASK 0x00000080 +#define TMC2208_MSTEP_REG_SELECT_SHIFT 7 +#define TMC2208_MSTEP_REG_SELECT_FIELD ((RegisterField) {TMC2208_MSTEP_REG_SELECT_MASK, TMC2208_MSTEP_REG_SELECT_SHIFT, TMC2208_GCONF, false}) +#define TMC2208_MULTISTEP_FILT_MASK 0x00000100 +#define TMC2208_MULTISTEP_FILT_SHIFT 8 +#define TMC2208_MULTISTEP_FILT_FIELD ((RegisterField) {TMC2208_MULTISTEP_FILT_MASK, TMC2208_MULTISTEP_FILT_SHIFT, TMC2208_GCONF, false}) +#define TMC2208_TEST_MODE_MASK 0x00000200 +#define TMC2208_TEST_MODE_SHIFT 9 +#define TMC2208_TEST_MODE_FIELD ((RegisterField) {TMC2208_TEST_MODE_MASK, TMC2208_TEST_MODE_SHIFT, TMC2208_GCONF, false}) +#define TMC2208_RESET_MASK 0x00000001 +#define TMC2208_RESET_SHIFT 0 +#define TMC2208_RESET_FIELD ((RegisterField) {TMC2208_RESET_MASK, TMC2208_RESET_SHIFT, TMC2208_GSTAT, false}) +#define TMC2208_DRV_ERR_MASK 0x00000002 +#define TMC2208_DRV_ERR_SHIFT 1 +#define TMC2208_DRV_ERR_FIELD ((RegisterField) {TMC2208_DRV_ERR_MASK, TMC2208_DRV_ERR_SHIFT, TMC2208_GSTAT, false}) +#define TMC2208_UV_CP_MASK 0x00000004 +#define TMC2208_UV_CP_SHIFT 2 +#define TMC2208_UV_CP_FIELD ((RegisterField) {TMC2208_UV_CP_MASK, TMC2208_UV_CP_SHIFT, TMC2208_GSTAT, false}) +#define TMC2208_IFCNT_MASK 0x000000FF +#define TMC2208_IFCNT_SHIFT 0 +#define TMC2208_IFCNT_FIELD ((RegisterField) {TMC2208_IFCNT_MASK, TMC2208_IFCNT_SHIFT, TMC2208_IFCNT, false}) +#define TMC2208_SLAVECONF_MASK 0x00000F00 +#define TMC2208_SLAVECONF_SHIFT 8 +#define TMC2208_SLAVECONF_FIELD ((RegisterField) {TMC2208_SLAVECONF_MASK, TMC2208_SLAVECONF_SHIFT, TMC2208_SLAVECONF, false}) +#define TMC2208_OTPBIT_MASK 0x00000007 +#define TMC2208_OTPBIT_SHIFT 0 +#define TMC2208_OTPBIT_FIELD ((RegisterField) {TMC2208_OTPBIT_MASK, TMC2208_OTPBIT_SHIFT, TMC2208_OTP_PROG, false}) +#define TMC2208_OTPBYTE_MASK 0x00000030 +#define TMC2208_OTPBYTE_SHIFT 4 +#define TMC2208_OTPBYTE_FIELD ((RegisterField) {TMC2208_OTPBYTE_MASK, TMC2208_OTPBYTE_SHIFT, TMC2208_OTP_PROG, false}) +#define TMC2208_OTPMAGIC_MASK 0x0000FF00 +#define TMC2208_OTPMAGIC_SHIFT 8 +#define TMC2208_OTPMAGIC_FIELD ((RegisterField) {TMC2208_OTPMAGIC_MASK, TMC2208_OTPMAGIC_SHIFT, TMC2208_OTP_PROG, false}) +#define TMC2208_OTP0_BYTE_0_READ_DATA_MASK 0x000000FF +#define TMC2208_OTP0_BYTE_0_READ_DATA_SHIFT 0 +#define TMC2208_OTP0_BYTE_0_READ_DATA_FIELD ((RegisterField) {TMC2208_OTP0_BYTE_0_READ_DATA_MASK, TMC2208_OTP0_BYTE_0_READ_DATA_SHIFT, TMC2208_OTP_READ, false}) +#define TMC2208_OTP1_BYTE_1_READ_DATA_MASK 0x0000FF00 +#define TMC2208_OTP1_BYTE_1_READ_DATA_SHIFT 8 +#define TMC2208_OTP1_BYTE_1_READ_DATA_FIELD ((RegisterField) {TMC2208_OTP1_BYTE_1_READ_DATA_MASK, TMC2208_OTP1_BYTE_1_READ_DATA_SHIFT, TMC2208_OTP_READ, false}) +#define TMC2208_OTP2_BYTE_2_READ_DATA_MASK 0x00FF0000 +#define TMC2208_OTP2_BYTE_2_READ_DATA_SHIFT 16 +#define TMC2208_OTP2_BYTE_2_READ_DATA_FIELD ((RegisterField) {TMC2208_OTP2_BYTE_2_READ_DATA_MASK, TMC2208_OTP2_BYTE_2_READ_DATA_SHIFT, TMC2208_OTP_READ, false}) +#define TMC2208_ENN_MASK 0x00000001 +#define TMC2208_ENN_SHIFT 0 +#define TMC2208_ENN_FIELD ((RegisterField) {TMC2208_ENN_MASK, TMC2208_ENN_SHIFT, TMC2208_IOIN, false}) +#define TMC2208_MS1_MASK 0x00000004 +#define TMC2208_MS1_SHIFT 2 +#define TMC2208_MS1_FIELD ((RegisterField) {TMC2208_MS1_MASK, TMC2208_MS1_SHIFT, TMC2208_IOIN, false}) +#define TMC2208_MS2_MASK 0x00000008 +#define TMC2208_MS2_SHIFT 3 +#define TMC2208_MS2_FIELD ((RegisterField) {TMC2208_MS2_MASK, TMC2208_MS2_SHIFT, TMC2208_IOIN, false}) +#define TMC2208_DIAG_MASK 0x00000010 +#define TMC2208_DIAG_SHIFT 4 +#define TMC2208_DIAG_FIELD ((RegisterField) {TMC2208_DIAG_MASK, TMC2208_DIAG_SHIFT, TMC2208_IOIN, false}) +#define TMC2208_PDN_UART_MASK 0x00000040 +#define TMC2208_PDN_UART_SHIFT 6 +#define TMC2208_PDN_UART_FIELD ((RegisterField) {TMC2208_PDN_UART_MASK, TMC2208_PDN_UART_SHIFT, TMC2208_IOIN, false}) +#define TMC2208_STEP_MASK 0x00000080 +#define TMC2208_STEP_SHIFT 7 +#define TMC2208_STEP_FIELD ((RegisterField) {TMC2208_STEP_MASK, TMC2208_STEP_SHIFT, TMC2208_IOIN, false}) +#define TMC2208_SEL_A_MASK 0x00000100 +#define TMC2208_SEL_A_SHIFT 8 +#define TMC2208_SEL_A_FIELD ((RegisterField) {TMC2208_SEL_A_MASK, TMC2208_SEL_A_SHIFT, TMC2208_IOIN, false}) +#define TMC2208_DIR_MASK 0x00000200 +#define TMC2208_DIR_SHIFT 9 +#define TMC2208_DIR_FIELD ((RegisterField) {TMC2208_DIR_MASK, TMC2208_DIR_SHIFT, TMC2208_IOIN, false}) +#define TMC2208_VERSION_MASK 0xFF000000 +#define TMC2208_VERSION_SHIFT 24 +#define TMC2208_VERSION_FIELD ((RegisterField) {TMC2208_VERSION_MASK, TMC2208_VERSION_SHIFT, TMC2208_IOIN, false}) +#define TMC2208_FCLKTRIM_MASK 0x0000001F +#define TMC2208_FCLKTRIM_SHIFT 0 +#define TMC2208_FCLKTRIM_FIELD ((RegisterField) {TMC2208_FCLKTRIM_MASK, TMC2208_FCLKTRIM_SHIFT, TMC2208_FACTORY_CONF, false}) +#define TMC2208_OTTRIM_MASK 0x00000300 +#define TMC2208_OTTRIM_SHIFT 8 +#define TMC2208_OTTRIM_FIELD ((RegisterField) {TMC2208_OTTRIM_MASK, TMC2208_OTTRIM_SHIFT, TMC2208_FACTORY_CONF, false}) +#define TMC2208_IHOLD_MASK 0x0000001F +#define TMC2208_IHOLD_SHIFT 0 +#define TMC2208_IHOLD_FIELD ((RegisterField) {TMC2208_IHOLD_MASK, TMC2208_IHOLD_SHIFT, TMC2208_IHOLD_IRUN, false}) +#define TMC2208_IRUN_MASK 0x00001F00 +#define TMC2208_IRUN_SHIFT 8 +#define TMC2208_IRUN_FIELD ((RegisterField) {TMC2208_IRUN_MASK, TMC2208_IRUN_SHIFT, TMC2208_IHOLD_IRUN, false}) +#define TMC2208_IHOLDDELAY_MASK 0x000F0000 +#define TMC2208_IHOLDDELAY_SHIFT 16 +#define TMC2208_IHOLDDELAY_FIELD ((RegisterField) {TMC2208_IHOLDDELAY_MASK, TMC2208_IHOLDDELAY_SHIFT, TMC2208_IHOLD_IRUN, false}) +#define TMC2208_TPOWERDOWN_MASK 0x000000FF +#define TMC2208_TPOWERDOWN_SHIFT 0 +#define TMC2208_TPOWERDOWN_FIELD ((RegisterField) {TMC2208_TPOWERDOWN_MASK, TMC2208_TPOWERDOWN_SHIFT, TMC2208_TPOWERDOWN, false}) +#define TMC2208_TSTEP_MASK 0x000FFFFF +#define TMC2208_TSTEP_SHIFT 0 +#define TMC2208_TSTEP_FIELD ((RegisterField) {TMC2208_TSTEP_MASK, TMC2208_TSTEP_SHIFT, TMC2208_TSTEP, false}) +#define TMC2208_TPWMTHRS_MASK 0x000FFFFF +#define TMC2208_TPWMTHRS_SHIFT 0 +#define TMC2208_TPWMTHRS_FIELD ((RegisterField) {TMC2208_TPWMTHRS_MASK, TMC2208_TPWMTHRS_SHIFT, TMC2208_TPWMTHRS, false}) +#define TMC2208_VACTUAL_MASK 0x00FFFFFF +#define TMC2208_VACTUAL_SHIFT 0 +#define TMC2208_VACTUAL_FIELD ((RegisterField) {TMC2208_VACTUAL_MASK, TMC2208_VACTUAL_SHIFT, TMC2208_VACTUAL, true}) +#define TMC2208_MSCNT_MASK 0x000003FF +#define TMC2208_MSCNT_SHIFT 0 +#define TMC2208_MSCNT_FIELD ((RegisterField) {TMC2208_MSCNT_MASK, TMC2208_MSCNT_SHIFT, TMC2208_MSCNT, false}) +#define TMC2208_CUR_A_MASK 0x000001FF +#define TMC2208_CUR_A_SHIFT 0 +#define TMC2208_CUR_A_FIELD ((RegisterField) {TMC2208_CUR_A_MASK, TMC2208_CUR_A_SHIFT, TMC2208_MSCURACT, true}) +#define TMC2208_CUR_B_MASK 0x01FF0000 +#define TMC2208_CUR_B_SHIFT 16 +#define TMC2208_CUR_B_FIELD ((RegisterField) {TMC2208_CUR_B_MASK, TMC2208_CUR_B_SHIFT, TMC2208_MSCURACT, true}) +#define TMC2208_TOFF_MASK 0x0000000F +#define TMC2208_TOFF_SHIFT 0 +#define TMC2208_TOFF_FIELD ((RegisterField) {TMC2208_TOFF_MASK, TMC2208_TOFF_SHIFT, TMC2208_CHOPCONF, false}) +#define TMC2208_HSTRT_MASK 0x00000070 +#define TMC2208_HSTRT_SHIFT 4 +#define TMC2208_HSTRT_FIELD ((RegisterField) {TMC2208_HSTRT_MASK, TMC2208_HSTRT_SHIFT, TMC2208_CHOPCONF, false}) +#define TMC2208_HEND_MASK 0x00000780 +#define TMC2208_HEND_SHIFT 7 +#define TMC2208_HEND_FIELD ((RegisterField) {TMC2208_HEND_MASK, TMC2208_HEND_SHIFT, TMC2208_CHOPCONF, false}) +#define TMC2208_TBL_MASK 0x00018000 +#define TMC2208_TBL_SHIFT 15 +#define TMC2208_TBL_FIELD ((RegisterField) {TMC2208_TBL_MASK, TMC2208_TBL_SHIFT, TMC2208_CHOPCONF, false}) +#define TMC2208_VSENSE_MASK 0x00020000 +#define TMC2208_VSENSE_SHIFT 17 +#define TMC2208_VSENSE_FIELD ((RegisterField) {TMC2208_VSENSE_MASK, TMC2208_VSENSE_SHIFT, TMC2208_CHOPCONF, false}) +#define TMC2208_MRES_MASK 0x0F000000 +#define TMC2208_MRES_SHIFT 24 +#define TMC2208_MRES_FIELD ((RegisterField) {TMC2208_MRES_MASK, TMC2208_MRES_SHIFT, TMC2208_CHOPCONF, false}) +#define TMC2208_INTPOL_MASK 0x10000000 +#define TMC2208_INTPOL_SHIFT 28 +#define TMC2208_INTPOL_FIELD ((RegisterField) {TMC2208_INTPOL_MASK, TMC2208_INTPOL_SHIFT, TMC2208_CHOPCONF, false}) +#define TMC2208_DEDGE_MASK 0x20000000 +#define TMC2208_DEDGE_SHIFT 29 +#define TMC2208_DEDGE_FIELD ((RegisterField) {TMC2208_DEDGE_MASK, TMC2208_DEDGE_SHIFT, TMC2208_CHOPCONF, false}) +#define TMC2208_DISS2G_MASK 0x40000000 +#define TMC2208_DISS2G_SHIFT 30 +#define TMC2208_DISS2G_FIELD ((RegisterField) {TMC2208_DISS2G_MASK, TMC2208_DISS2G_SHIFT, TMC2208_CHOPCONF, false}) +#define TMC2208_DISS2VS_MASK 0x80000000 +#define TMC2208_DISS2VS_SHIFT 31 +#define TMC2208_DISS2VS_FIELD ((RegisterField) {TMC2208_DISS2VS_MASK, TMC2208_DISS2VS_SHIFT, TMC2208_CHOPCONF, false}) +#define TMC2208_OTPW_MASK 0x00000001 +#define TMC2208_OTPW_SHIFT 0 +#define TMC2208_OTPW_FIELD ((RegisterField) {TMC2208_OTPW_MASK, TMC2208_OTPW_SHIFT, TMC2208_DRV_STATUS, false}) +#define TMC2208_OT_MASK 0x00000002 +#define TMC2208_OT_SHIFT 1 +#define TMC2208_OT_FIELD ((RegisterField) {TMC2208_OT_MASK, TMC2208_OT_SHIFT, TMC2208_DRV_STATUS, false}) +#define TMC2208_S2GA_MASK 0x00000004 +#define TMC2208_S2GA_SHIFT 2 +#define TMC2208_S2GA_FIELD ((RegisterField) {TMC2208_S2GA_MASK, TMC2208_S2GA_SHIFT, TMC2208_DRV_STATUS, false}) +#define TMC2208_S2GB_MASK 0x00000008 +#define TMC2208_S2GB_SHIFT 3 +#define TMC2208_S2GB_FIELD ((RegisterField) {TMC2208_S2GB_MASK, TMC2208_S2GB_SHIFT, TMC2208_DRV_STATUS, false}) +#define TMC2208_S2VSA_MASK 0x00000010 +#define TMC2208_S2VSA_SHIFT 4 +#define TMC2208_S2VSA_FIELD ((RegisterField) {TMC2208_S2VSA_MASK, TMC2208_S2VSA_SHIFT, TMC2208_DRV_STATUS, false}) +#define TMC2208_S2VSB_MASK 0x00000020 +#define TMC2208_S2VSB_SHIFT 5 +#define TMC2208_S2VSB_FIELD ((RegisterField) {TMC2208_S2VSB_MASK, TMC2208_S2VSB_SHIFT, TMC2208_DRV_STATUS, false}) +#define TMC2208_OLA_MASK 0x00000040 +#define TMC2208_OLA_SHIFT 6 +#define TMC2208_OLA_FIELD ((RegisterField) {TMC2208_OLA_MASK, TMC2208_OLA_SHIFT, TMC2208_DRV_STATUS, false}) +#define TMC2208_OLB_MASK 0x00000080 +#define TMC2208_OLB_SHIFT 7 +#define TMC2208_OLB_FIELD ((RegisterField) {TMC2208_OLB_MASK, TMC2208_OLB_SHIFT, TMC2208_DRV_STATUS, false}) +#define TMC2208_T120_MASK 0x00000100 +#define TMC2208_T120_SHIFT 8 +#define TMC2208_T120_FIELD ((RegisterField) {TMC2208_T120_MASK, TMC2208_T120_SHIFT, TMC2208_DRV_STATUS, false}) +#define TMC2208_T143_MASK 0x00000200 +#define TMC2208_T143_SHIFT 9 +#define TMC2208_T143_FIELD ((RegisterField) {TMC2208_T143_MASK, TMC2208_T143_SHIFT, TMC2208_DRV_STATUS, false}) +#define TMC2208_T150_MASK 0x00000400 +#define TMC2208_T150_SHIFT 10 +#define TMC2208_T150_FIELD ((RegisterField) {TMC2208_T150_MASK, TMC2208_T150_SHIFT, TMC2208_DRV_STATUS, false}) +#define TMC2208_T157_MASK 0x00000800 +#define TMC2208_T157_SHIFT 11 +#define TMC2208_T157_FIELD ((RegisterField) {TMC2208_T157_MASK, TMC2208_T157_SHIFT, TMC2208_DRV_STATUS, false}) +#define TMC2208_CS_ACTUAL_MASK 0x001F0000 +#define TMC2208_CS_ACTUAL_SHIFT 16 +#define TMC2208_CS_ACTUAL_FIELD ((RegisterField) {TMC2208_CS_ACTUAL_MASK, TMC2208_CS_ACTUAL_SHIFT, TMC2208_DRV_STATUS, false}) +#define TMC2208_STEALTH_MASK 0x40000000 +#define TMC2208_STEALTH_SHIFT 30 +#define TMC2208_STEALTH_FIELD ((RegisterField) {TMC2208_STEALTH_MASK, TMC2208_STEALTH_SHIFT, TMC2208_DRV_STATUS, false}) +#define TMC2208_STST_MASK 0x80000000 +#define TMC2208_STST_SHIFT 31 +#define TMC2208_STST_FIELD ((RegisterField) {TMC2208_STST_MASK, TMC2208_STST_SHIFT, TMC2208_DRV_STATUS, false}) +#define TMC2208_PWM_OFS_MASK 0x000000FF +#define TMC2208_PWM_OFS_SHIFT 0 +#define TMC2208_PWM_OFS_FIELD ((RegisterField) {TMC2208_PWM_OFS_MASK, TMC2208_PWM_OFS_SHIFT, TMC2208_PWMCONF, false}) +#define TMC2208_PWM_GRAD_MASK 0x0000FF00 +#define TMC2208_PWM_GRAD_SHIFT 8 +#define TMC2208_PWM_GRAD_FIELD ((RegisterField) {TMC2208_PWM_GRAD_MASK, TMC2208_PWM_GRAD_SHIFT, TMC2208_PWMCONF, false}) +#define TMC2208_PWM_FREQ_MASK 0x00030000 +#define TMC2208_PWM_FREQ_SHIFT 16 +#define TMC2208_PWM_FREQ_FIELD ((RegisterField) {TMC2208_PWM_FREQ_MASK, TMC2208_PWM_FREQ_SHIFT, TMC2208_PWMCONF, false}) +#define TMC2208_PWM_AUTOSCALE_MASK 0x00040000 +#define TMC2208_PWM_AUTOSCALE_SHIFT 18 +#define TMC2208_PWM_AUTOSCALE_FIELD ((RegisterField) {TMC2208_PWM_AUTOSCALE_MASK, TMC2208_PWM_AUTOSCALE_SHIFT, TMC2208_PWMCONF, false}) +#define TMC2208_PWM_AUTOGRAD_MASK 0x00080000 +#define TMC2208_PWM_AUTOGRAD_SHIFT 19 +#define TMC2208_PWM_AUTOGRAD_FIELD ((RegisterField) {TMC2208_PWM_AUTOGRAD_MASK, TMC2208_PWM_AUTOGRAD_SHIFT, TMC2208_PWMCONF, false}) +#define TMC2208_FREEWHEEL_MASK 0x00300000 +#define TMC2208_FREEWHEEL_SHIFT 20 +#define TMC2208_FREEWHEEL_FIELD ((RegisterField) {TMC2208_FREEWHEEL_MASK, TMC2208_FREEWHEEL_SHIFT, TMC2208_PWMCONF, false}) +#define TMC2208_PWM_REG_MASK 0x0F000000 +#define TMC2208_PWM_REG_SHIFT 24 +#define TMC2208_PWM_REG_FIELD ((RegisterField) {TMC2208_PWM_REG_MASK, TMC2208_PWM_REG_SHIFT, TMC2208_PWMCONF, false}) +#define TMC2208_PWM_LIM_MASK 0xF0000000 +#define TMC2208_PWM_LIM_SHIFT 28 +#define TMC2208_PWM_LIM_FIELD ((RegisterField) {TMC2208_PWM_LIM_MASK, TMC2208_PWM_LIM_SHIFT, TMC2208_PWMCONF, false}) +#define TMC2208_PWM_SCALE_SUM_MASK 0x000000FF +#define TMC2208_PWM_SCALE_SUM_SHIFT 0 +#define TMC2208_PWM_SCALE_SUM_FIELD ((RegisterField) {TMC2208_PWM_SCALE_SUM_MASK, TMC2208_PWM_SCALE_SUM_SHIFT, TMC2208_PWM_SCALE, false}) +#define TMC2208_PWM_SCALE_AUTO_MASK 0x01FF0000 +#define TMC2208_PWM_SCALE_AUTO_SHIFT 16 +#define TMC2208_PWM_SCALE_AUTO_FIELD ((RegisterField) {TMC2208_PWM_SCALE_AUTO_MASK, TMC2208_PWM_SCALE_AUTO_SHIFT, TMC2208_PWM_SCALE, true}) +#define TMC2208_PWM_OFS_AUTO_MASK 0x000000FF +#define TMC2208_PWM_OFS_AUTO_SHIFT 0 +#define TMC2208_PWM_OFS_AUTO_FIELD ((RegisterField) {TMC2208_PWM_OFS_AUTO_MASK, TMC2208_PWM_OFS_AUTO_SHIFT, TMC2208_PWM_AUTO, false}) +#define TMC2208_PWM_GRAD_AUTO_MASK 0x00FF0000 +#define TMC2208_PWM_GRAD_AUTO_SHIFT 16 +#define TMC2208_PWM_GRAD_AUTO_FIELD ((RegisterField) {TMC2208_PWM_GRAD_AUTO_MASK, TMC2208_PWM_GRAD_AUTO_SHIFT, TMC2208_PWM_AUTO, false}) + +#endif diff --git a/firmware/lib/tmc/ic/TMC2208/registercall_hierarchy_flowchart_UART.svg b/firmware/lib/tmc/ic/TMC2208/registercall_hierarchy_flowchart_UART.svg new file mode 100755 index 0000000..425f60a --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2208/registercall_hierarchy_flowchart_UART.svg @@ -0,0 +1,3 @@ + + +

HAL

HAL

APP (Eval)

APP (Eval)

API

API
Read a register
  •  Call tmcXXXX_readRegister function
Read a register...
Returns the register read value
Returns the register read value
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
tmcXXXX.c
tmcXXXX.c
UART.c
UART.c
tmcXXXX_eval.c
tmcXXXX_eval.c

 Implementation of UART_readWrite
  • Sends and receives bytes on the UART bus
Implementation of UART_readWrite...
Returns the raw reply data
Returns the raw reply data

Implementation of tmcXXXX_readWriteUART
  • Takes the array of data to write
  • Calls hardware function UART_readWrite
Implementation of tmcXXXX_readWriteUART...
Passes on the raw reply data to the API
Passes on the raw reply data to the API
Implementation of readRegisterUART
  • Constructs the datagram
  • Calls HAL wrapper function 
Implementation of readRegisterUART...
tmcXXXX_readWriteUART
tmcXXXX_readWriteUART
Parses the reply and returns the register value
Parses the reply and returns the register value
Implementation of tmcXXXX_readRegister 
  • Check which bus is active SPI/UART. (e.g. UART)
  • Calls bus-specific function (e.g. readRegisterUART)
 
Implementation of tmcXXXX_readRegister...
Returns the register read value
Returns the register read value
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC2208/uml-tmc-api.svg b/firmware/lib/tmc/ic/TMC2208/uml-tmc-api.svg new file mode 100755 index 0000000..5a5f8dd --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2208/uml-tmc-api.svg @@ -0,0 +1,3 @@ + + +

TMCXXXX_HW_Abstraction.h



TMCXXXX_HW_Abstraction.h...
// Constants
#define TMCXXXX_MOTORS              
                          
// Register definitions
#define TMCXXXX_GCONF        
                          ⋮
// Register fields definitions
#define TMCXXXX_GCONF_OTPW_FIELD
                     
// Constants...

TMCXXXX.h



TMCXXXX.h...
extern void tmcXXXX_readWriteSPI();
extern void tmcXXXX_readWriteUART();
extern TMCXXXXBusType tmcXXXX_getBusType();
extern uint8_t tmcXXXX_getNodeAddress();
                                  ⋮
tmcXXXX_readRegister();
tmcXXXX_writeRegister();
                                  ⋮
extern void tmcXXXX_readWriteSPI();...

TMCXXXX.c



TMCXXXX.c...
const uint8_t tmcCRCTable_Poly7Reflected[256] = {...};
int32_t tmcXXXX_readRegister(){
/* Call tmcXXXX_getBusType();
 * Based on bus type, call readRegisterSPI/UART() that
 * further calls tmcXXXX_readWriteSPI/UART();
 * For UART it also calls tmcXXXX_getNodeAddress();
                                           ⋮
}
                                           ⋮
const uint8_t tmcCRCTable_Poly7Reflected[256] = {.....
TMC-API
TMC-API

TMCXXXX_Simple_Rotation.h


TMCXXXX_Simple_Rotation.h...
void initAllMotors();
             ⋮
  
void initAllMotors()...

TMCXXXX_Simple_Rotation.c


TMCXXXX_Simple_Rotation.c...
void initAllMotors(){

// Configuring registers to enable motor drivers etc..
tmcXXXX_writeRegister();
                    ⋮
}
                    ⋮
void initAllMotors(){...
Examples
Examples
User Project
User Project

User_Project.h


User_Project.h

User_Project.c








User_Project.c...

void tmcXXXX_readWriteSPI(){
                           ⋮
}
void tmcXXXX_readWriteUART(){
                           ⋮
}
TMCXXXXBusType tmcXXXX_getBusType(){
                           ⋮
}
uint8_t tmcXXXX_getNodeAddress(){
                           ⋮
}

// User Code
                           ⋮
void tmcXXXX_readWriteSPI(){...
#include "TMCXXXX_HW_Abstraction.h"
#include "TMCXXXX.h"
#include "TMCXXXX_Simple_Rotation.h"
                                ⋮
TMCXXXXBusType bus = IC_BUS_SPI/UART;
uint8_t nodeAddress = <nodeAddress>;
                                ⋮
#include "TMCXXXX_HW_Abstraction.h"...
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC2209/Examples/TMC2209_Simple_Rotation.c b/firmware/lib/tmc/ic/TMC2209/Examples/TMC2209_Simple_Rotation.c new file mode 100755 index 0000000..6b96430 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2209/Examples/TMC2209_Simple_Rotation.c @@ -0,0 +1,22 @@ +/******************************************************************************* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#include "TMC2209_Simple_Rotation.h" + +/* + * Configures the registers with the right settings that are needed for rotating the motor. + * E.g Enabling driver, setting IRUN current etc. + */ +void initAllMotors(uint16_t icID) +{ + tmc2209_writeRegister(icID, TMC2209_GCONF, 0x00000040); + tmc2209_writeRegister(icID, TMC2209_IHOLD_IRUN, 0x00071703); + tmc2209_writeRegister(icID, TMC2209_TPOWERDOWN, 0x00000014); + tmc2209_writeRegister(icID, TMC2209_CHOPCONF, 0x10000053); + tmc2209_writeRegister(icID, TMC2209_PWMCONF, 0xC10D0024); + + // Generate step pulse (S/D) externally via the connected microcontroller. +} diff --git a/firmware/lib/tmc/ic/TMC2209/Examples/TMC2209_Simple_Rotation.h b/firmware/lib/tmc/ic/TMC2209/Examples/TMC2209_Simple_Rotation.h new file mode 100755 index 0000000..e3b7366 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2209/Examples/TMC2209_Simple_Rotation.h @@ -0,0 +1,14 @@ +/******************************************************************************* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#ifndef TMC2209_SIMPLE_ROTATION_H_ +#define TMC2209_SIMPLE_ROTATION_H_ + +#include "TMC2209.h" + +void initAllMotors(uint16_t icID); + +#endif diff --git a/firmware/lib/tmc/ic/TMC2209/README.md b/firmware/lib/tmc/ic/TMC2209/README.md new file mode 100755 index 0000000..d55806e --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2209/README.md @@ -0,0 +1,52 @@ +# TMC2209 + + +## How to use + +To access the TMC2209's registers, the TMC-API offers two functions: **tmc2209_readRegister** and **tmc2209_writeRegister**. +Each of these functions takes in an **icID**, which is used to identify the IC when multiple ICs are connected. This identifier is passed down to the callback functions (see How to Integrate). + +## How to integrate: overview + +1. Include all the files of the TMC-API/ic/tmc/TMC2209 folder into the custom project. +2. Include the TMC2209.h file in the custom source code. +3. Implement the necessary callback functions (see below). +4. (optional): Take a look at the Examples subfolder for ready-made examples of the TMC-API usage. + +## Accessing the TMC2209 via UART +The following diagram depicts how to access the TMC2209 via UART using the TMC-API. + +![screenshot](registercall_hierarchy_flowchart_UART.svg) + +The description of the functions, in the above flowchart, are as follows: +- The functions tmc2209_readRegister and tmc2209_writeRegister are used to read and write the registers respectively. These functions check the current active bus and calls the bus-specific function i.e readRegisterUART or writeRegisterUART. +- These bus specific functions constructs the datagram and further calls the bus specific callback 'tmcXXXX_readWriteUART. +- This callback function further calls the hardware specific read/write function for UART and needs to be implemented externally. + +### How to integrate: Callback functions +To communicate with TMC2209 IC, implement the following callback functions to access the chip via UART: +1. **tmc2209_readWriteUART()**, which is a HAL wrapper function that provides the necessary hardware access. +2. **tmc2209_getNodeAddress()**, that returns the node/slave address. Node address could be set in NODECONF (0x3) register and the address could be incremented as defined by AD0, AD1 and AD2. (Node address + ADx) must be less than 255. For further details please consult the datasheet of TMC2209. + +### Sharing the CRC table with other TMC-API chips +The TMC2209 UART protocol uses an 8 bit CRC. For calculating this, a table-based algorithm is used. This table (tmcCRCTable_Poly7Reflected[256]) is 256 bytes big and identical across multiple different Trinamic chips (i.e. TMC2209). +If multiple Trinamic chips are being used in the same project, avoiding redundant copies of this table could save memory. It is possible to substitute this CRC table with another CRC table. + +### Option to use the cache logic for Write-Only registers +The chip features write-only registers that are unable to be read, necessitating the creation of a shadow copy to cache their contents. This copy is automatically updated whenever data is written to these registers. This cache logic could be enabled by setting the macro **TMC2209_CACHE** to **'1'** or disabled by setting to **'0'** respectively. If this feature is enabled then there comes another option to use **tmc2209_cache** function, which is already implemeted in the API, by defining **TMC2209_ENABLE_TMC_CACHE** macro to **'1** or one can implement their own function. + +The function **tmc2209_cache** works for both reading from and writing to the shadow array. It first checks whether the register has write-only access and data needs to be read from the shadow copy. On the basis of that, it returns **true** or **false**. The shadowRegisters on the premade cache implementation need to be one per chip. **TMC2209_IC_CACHE_COUNT** is set to '1' by default and is user-overwritable. If multiple chips are being used in the same project, increment its value to the number of chips connected. + +## Further info +### Dependency graph for the ICs with new register R/W mechanism +This graph illustrates the relationships between files within the TMC-API library, highlighting dependencies and identifying the files that are essential for integrating the library into the custom projects. + +![screenshot](uml-tmc-api.svg) + +### Example usage: TMC-Evalsystem +**For a reference usage of the TMC-API**, visit the [TMC-Evalsystem](https://github.com/analogdevicesinc/TMC-EvalSystem) + +## Migration status +The TMC2209 has been reworked to the access system described above. For more infos on the status of this and other ICs, check out the [migration page](https://github.com/analogdevicesinc/TMC-API/issues/53). + + diff --git a/firmware/lib/tmc/ic/TMC2209/TMC2209.c b/firmware/lib/tmc/ic/TMC2209/TMC2209.c new file mode 100755 index 0000000..083c254 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2209/TMC2209.c @@ -0,0 +1,209 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#include "TMC2209.h" + + +#ifdef TMC_API_EXTERNAL_CRC_TABLE +extern const uint8_t tmcCRCTable_Poly7Reflected[256]; +#else +const uint8_t tmcCRCTable_Poly7Reflected[256] = { + 0x00, 0x91, 0xE3, 0x72, 0x07, 0x96, 0xE4, 0x75, 0x0E, 0x9F, 0xED, 0x7C, 0x09, 0x98, 0xEA, 0x7B, + 0x1C, 0x8D, 0xFF, 0x6E, 0x1B, 0x8A, 0xF8, 0x69, 0x12, 0x83, 0xF1, 0x60, 0x15, 0x84, 0xF6, 0x67, + 0x38, 0xA9, 0xDB, 0x4A, 0x3F, 0xAE, 0xDC, 0x4D, 0x36, 0xA7, 0xD5, 0x44, 0x31, 0xA0, 0xD2, 0x43, + 0x24, 0xB5, 0xC7, 0x56, 0x23, 0xB2, 0xC0, 0x51, 0x2A, 0xBB, 0xC9, 0x58, 0x2D, 0xBC, 0xCE, 0x5F, + 0x70, 0xE1, 0x93, 0x02, 0x77, 0xE6, 0x94, 0x05, 0x7E, 0xEF, 0x9D, 0x0C, 0x79, 0xE8, 0x9A, 0x0B, + 0x6C, 0xFD, 0x8F, 0x1E, 0x6B, 0xFA, 0x88, 0x19, 0x62, 0xF3, 0x81, 0x10, 0x65, 0xF4, 0x86, 0x17, + 0x48, 0xD9, 0xAB, 0x3A, 0x4F, 0xDE, 0xAC, 0x3D, 0x46, 0xD7, 0xA5, 0x34, 0x41, 0xD0, 0xA2, 0x33, + 0x54, 0xC5, 0xB7, 0x26, 0x53, 0xC2, 0xB0, 0x21, 0x5A, 0xCB, 0xB9, 0x28, 0x5D, 0xCC, 0xBE, 0x2F, + 0xE0, 0x71, 0x03, 0x92, 0xE7, 0x76, 0x04, 0x95, 0xEE, 0x7F, 0x0D, 0x9C, 0xE9, 0x78, 0x0A, 0x9B, + 0xFC, 0x6D, 0x1F, 0x8E, 0xFB, 0x6A, 0x18, 0x89, 0xF2, 0x63, 0x11, 0x80, 0xF5, 0x64, 0x16, 0x87, + 0xD8, 0x49, 0x3B, 0xAA, 0xDF, 0x4E, 0x3C, 0xAD, 0xD6, 0x47, 0x35, 0xA4, 0xD1, 0x40, 0x32, 0xA3, + 0xC4, 0x55, 0x27, 0xB6, 0xC3, 0x52, 0x20, 0xB1, 0xCA, 0x5B, 0x29, 0xB8, 0xCD, 0x5C, 0x2E, 0xBF, + 0x90, 0x01, 0x73, 0xE2, 0x97, 0x06, 0x74, 0xE5, 0x9E, 0x0F, 0x7D, 0xEC, 0x99, 0x08, 0x7A, 0xEB, + 0x8C, 0x1D, 0x6F, 0xFE, 0x8B, 0x1A, 0x68, 0xF9, 0x82, 0x13, 0x61, 0xF0, 0x85, 0x14, 0x66, 0xF7, + 0xA8, 0x39, 0x4B, 0xDA, 0xAF, 0x3E, 0x4C, 0xDD, 0xA6, 0x37, 0x45, 0xD4, 0xA1, 0x30, 0x42, 0xD3, + 0xB4, 0x25, 0x57, 0xC6, 0xB3, 0x22, 0x50, 0xC1, 0xBA, 0x2B, 0x59, 0xC8, 0xBD, 0x2C, 0x5E, 0xCF, +}; +#endif + +#if TMC2209_CACHE == 0 +static inline bool tmc2209_cache(uint16_t icID, TMC2209CacheOp operation, uint8_t address, uint32_t *value) +{ + UNUSED(icID); + UNUSED(address); + UNUSED(operation); + return false; +} +#else +#if TMC2209_ENABLE_TMC_CACHE == 1 + +uint8_t tmc2209_dirtyBits[TMC2209_IC_CACHE_COUNT][TMC2209_REGISTER_COUNT/8]= {0}; +int32_t tmc2209_shadowRegister[TMC2209_IC_CACHE_COUNT][TMC2209_REGISTER_COUNT]; + +void tmc2209_setDirtyBit(uint16_t icID, uint8_t index, bool value) +{ + if(index >= TMC2209_REGISTER_COUNT) + return; + + uint8_t *tmp = &tmc2209_dirtyBits[icID][index / 8]; + uint8_t shift = (index % 8); + uint8_t mask = 1 << shift; + *tmp = (((*tmp) & (~(mask))) | (((value) << (shift)) & (mask))); +} + +bool tmc2209_getDirtyBit(uint16_t icID, uint8_t index) +{ + if(index >= TMC2209_REGISTER_COUNT) + return false; + + uint8_t *tmp = &tmc2209_dirtyBits[icID][index / 8]; + uint8_t shift = (index % 8); + return ((*tmp) >> shift) & 1; +} + +/* + * This function is used to cache the value written to the Write-Only registers in the form of shadow array. + * The shadow copy is then used to read these kinds of registers. + */ +bool tmc2209_cache(uint16_t icID, TMC2209CacheOp operation, uint8_t address, uint32_t *value) +{ + if (operation == TMC2209_CACHE_READ) + { + // Check if the value should come from cache + + // Only supported chips have a cache + if (icID >= TMC2209_IC_CACHE_COUNT) + return false; + + // Only non-readable registers care about caching + // Note: This could also be used to cache i.e. RW config registers to reduce bus accesses + if (TMC2209_IS_READABLE(tmc2209_registerAccess[address])) + return false; + + // Grab the value from the cache + *value = tmc2209_shadowRegister[icID][address]; + return true; + } + else if (operation == TMC2209_CACHE_WRITE || operation == TMC2209_CACHE_FILL_DEFAULT) + { + // Fill the cache + + // only supported chips have a cache + if (icID >= TMC2209_IC_CACHE_COUNT) + return false; + + // Write to the shadow register. + tmc2209_shadowRegister[icID][address] = *value; + // For write operations, mark the register dirty + if (operation == TMC2209_CACHE_WRITE) + { + tmc2209_setDirtyBit(icID, address, true); + } + + return true; + } + return false; +} +#else +// User must implement their own cache +extern bool tmc2209_cache(uint16_t icID, TMC2209CacheOp operation, uint8_t address, uint32_t *value); +#endif +#endif + +int32_t readRegisterUART(uint16_t icID, uint8_t address); +void writeRegisterUART(uint16_t icID ,uint8_t address, int32_t value); +static uint8_t CRC8(uint8_t *data, uint32_t bytes); + +void tmc2209_writeRegister(uint16_t icID, uint8_t address, int32_t value) +{ + writeRegisterUART(icID, (uint8_t) address, value); +} + +int32_t tmc2209_readRegister(uint16_t icID, uint8_t address) +{ + return readRegisterUART(icID, (uint8_t) address); +} + +int32_t readRegisterUART(uint16_t icID, uint8_t address) +{ + uint32_t value; + + // Read from cache for registers with write-only access + if (tmc2209_cache(icID, TMC2209_CACHE_READ, address, &value)) + return value; + + uint8_t data[8] = { 0 }; + + address = address & TMC2209_ADDRESS_MASK; + data[0] = 0x05; + data[1] = tmc2209_getNodeAddress(icID); //targetAddressUart; + data[2] = address; + data[3] = CRC8(data, 3); + + if (!tmc2209_readWriteUART(icID, &data[0], 4, 8)) + return 0; + + // Byte 0: Sync nibble correct? + if (data[0] != 0x05) + return 0; + + // Byte 1: Master address correct? + if (data[1] != 0xFF) + return 0; + + // Byte 2: Address correct? + if (data[2] != address) + return 0; + + // Byte 7: CRC correct? + if (data[7] != CRC8(data, 7)) + return 0; + + return ((uint32_t)data[3] << 24) | ((uint32_t)data[4] << 16) | (data[5] << 8) | data[6]; +} + +void writeRegisterUART(uint16_t icID, uint8_t address, int32_t value) +{ + uint8_t data[8]; + + data[0] = 0x05; + data[1] = (uint8_t)tmc2209_getNodeAddress(icID); //targetAddressUart; + data[2] = address | TMC_WRITE_BIT; + data[3] = (value >> 24) & 0xFF; + data[4] = (value >> 16) & 0xFF; + data[5] = (value >> 8 ) & 0xFF; + data[6] = (value ) & 0xFF; + data[7] = CRC8(data, 7); + + tmc2209_readWriteUART(icID, &data[0], 8, 0); + + //Cache the registers with write-only access + tmc2209_cache(icID, TMC2209_CACHE_WRITE, address, (uint32_t *)&value); +} + +static uint8_t CRC8(uint8_t *data, uint32_t bytes) +{ + uint8_t result = 0; + + while(bytes--) + result = tmcCRCTable_Poly7Reflected[result ^ *data++]; + + // Flip the result around + // swap odd and even bits + result = ((result >> 1) & 0x55) | ((result & 0x55) << 1); + // swap consecutive pairs + result = ((result >> 2) & 0x33) | ((result & 0x33) << 2); + // swap nibbles ... + result = ((result >> 4) & 0x0F) | ((result & 0x0F) << 4); + + return result; +} + + diff --git a/firmware/lib/tmc/ic/TMC2209/TMC2209.h b/firmware/lib/tmc/ic/TMC2209/TMC2209.h new file mode 100755 index 0000000..d04b2cf --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2209/TMC2209.h @@ -0,0 +1,179 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#ifndef TMC_IC_TMC2209_H_ +#define TMC_IC_TMC2209_H_ + +#include +#include +#include +#include "TMC2209_HW_Abstraction.h" + +/******************************************************************************* +* API Configuration Defines +* These control optional features of the TMC-API implementation. +* These can be commented in/out here or defined from the build system. +*******************************************************************************/ + +// Uncomment if you want to save space..... +// and put the table into your own .c file +//#define TMC_API_EXTERNAL_CRC_TABLE 1 + +// To enable the cache mechanism in order to keep the copy of all registers, set TMC2209_CACHE to '1'. +// With this mechanism the value of write-only registers could be read from their shadow copies. +#ifndef TMC2209_CACHE +#define TMC2209_CACHE 1 +//#define TMC2209_CACHE 0 +#endif + +// To use the caching mechanism already implemented by the TMC-API, set TMC2209_ENABLE_TMC_CACHE to '1'. +// Set TMC2209_ENABLE_TMC_CACHE to '0' if one wants to have their own cache implementation. +#ifndef TMC2209_ENABLE_TMC_CACHE +#define TMC2209_ENABLE_TMC_CACHE 1 +//#define TMC2209_ENABLE_TMC_CACHE 0 +#endif + +/******************************************************************************/ + +// => TMC-API wrapper +extern bool tmc2209_readWriteUART(uint16_t icID, uint8_t *data, size_t writeLength, size_t readLength); +extern uint8_t tmc2209_getNodeAddress(uint16_t icID); +// => TMC-API wrapper + +int32_t tmc2209_readRegister(uint16_t icID, uint8_t address); +void tmc2209_writeRegister(uint16_t icID, uint8_t address, int32_t value); + +typedef struct +{ + uint32_t mask; + uint8_t shift; + uint8_t address; + bool isSigned; +} RegisterField; + +static inline uint32_t tmc2209_fieldExtract(uint32_t data, RegisterField field) +{ + uint32_t value = (data & field.mask) >> field.shift; + + if (field.isSigned) + { + // Apply signedness conversion + uint32_t baseMask = field.mask >> field.shift; + uint32_t signMask = baseMask & (~baseMask >> 1); + value = (value ^ signMask) - signMask; + } + + return value; +} + +static inline uint32_t tmc2209_fieldRead(uint16_t icID, RegisterField field) +{ + uint32_t value = tmc2209_readRegister(icID, field.address); + + return tmc2209_fieldExtract(value, field); +} + +static inline uint32_t tmc2209_fieldUpdate(uint32_t data, RegisterField field, uint32_t value) +{ + return (data & (~field.mask)) | ((value << field.shift) & field.mask); +} + +static inline void tmc2209_fieldWrite(uint16_t icID, RegisterField field, uint32_t value) +{ + uint32_t regValue = tmc2209_readRegister(icID, field.address); + + regValue = tmc2209_fieldUpdate(regValue, field, value); + + tmc2209_writeRegister(icID, field.address, regValue); +} + +/**************************************************************** Cache Implementation *************************************************************************/ +#if TMC2209_CACHE == 1 +#if TMC2209_ENABLE_TMC_CACHE == 1 + +// By default, support one IC in the cache +#ifndef TMC2209_IC_CACHE_COUNT +#define TMC2209_IC_CACHE_COUNT 1 +#endif + +typedef enum { + // Cache operations for chip read and write operations + TMC2209_CACHE_READ, + TMC2209_CACHE_WRITE, + + // Special operation: Put content into the cache without marking the entry as dirty. + // Only used to initialize the cache with hardware defaults. This will allow reading + // from write-only registers that have a value inside them on reset. When using this + // operation, a restore will *not* rewrite that filled register! + TMC2209_CACHE_FILL_DEFAULT, +} TMC2209CacheOp; + +#define TMC2209_ACCESS_READ 0x01 +#define TMC2209_IS_READABLE(x) ((x) & TMC2209_ACCESS_READ) + +// Default Register values +#define R00 0x00000040 // GCONF +#define R10 0x00071703 // IHOLD_IRUN +#define R11 0x00000014 // TPOWERDOWN +#define R6C 0x10000053 // CHOPCONF +#define R70 0xC10D0024 // PWMCONF + +#define ____ 0x00 + +// Register access permissions: +// 0x00: none (reserved) +// 0x01: read +// 0x02: write +// 0x03: read/write +// 0x23: read/write, flag register (write to clear) +static const uint8_t tmc2209_registerAccess[TMC2209_REGISTER_COUNT] = +{ +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0x03, 0x23, 0x01, 0x02, 0x02, 0x01, 0x01, 0x03, ____, ____, ____, ____, ____, ____, ____, ____, // 0x00 - 0x0F + 0x02, 0x02, 0x01, 0x02, 0x02, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x10 - 0x1F + ____, ____, 0x02, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x20 - 0x2F + ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x30 - 0x3F + 0x02, 0x01, 0x02, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x40 - 0x4F + ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x50 - 0x5F + ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, 0x01, 0x01, 0x03, ____, ____, 0x01, // 0x60 - 0x6F + 0x03, 0x01, 0x01, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____ // 0x70 - 0x7F +}; + +static const int32_t tmc2209_sampleRegisterPreset[TMC2209_REGISTER_COUNT] = +{ +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + R00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x00 - 0x0F + R10, R11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x10 - 0x1F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x20 - 0x2F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x30 - 0x3F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x40 - 0x4F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x50 - 0x5F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, R6C, 0, 0, 0, // 0x60 - 0x6F + R70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // 0x70 - 0x7F +}; + +// Undefine the default register values. +// This prevents warnings in case multiple TMC-API chip headers are included at once +#undef R00 +#undef R10 +#undef R11 +#undef R6C +#undef R70 + +extern uint8_t tmc2209_dirtyBits[TMC2209_IC_CACHE_COUNT][TMC2209_REGISTER_COUNT/8]; +extern int32_t tmc2209_shadowRegister[TMC2209_IC_CACHE_COUNT][TMC2209_REGISTER_COUNT]; +void tmc2209_setDirtyBit(uint16_t icID, uint8_t index, bool value); +bool tmc2209_getDirtyBit(uint16_t icID, uint8_t index); +extern bool tmc2209_cache(uint16_t icID, TMC2209CacheOp operation, uint8_t address, uint32_t *value); +#endif +#endif + +/***************************************************************************************************************************************************/ + +#endif /* TMC_IC_TMC2209_H_ */ diff --git a/firmware/lib/tmc/ic/TMC2209/TMC2209_HW_Abstraction.h b/firmware/lib/tmc/ic/TMC2209/TMC2209_HW_Abstraction.h new file mode 100755 index 0000000..c8548e0 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2209/TMC2209_HW_Abstraction.h @@ -0,0 +1,307 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + +#ifndef TMC2209_HW_ABSTRACTION +#define TMC2209_HW_ABSTRACTION + +//constants + +#define TMC2209_MOTORS 1 +#define TMC2209_REGISTER_COUNT 128 +#define TMC_WRITE_BIT 0x80 +#define TMC2209_ADDRESS_MASK 0x7F +#define TMC2209_MAX_VELOCITY (int32_t) 2147483647 +#define TMC2209_MAX_ACCELERATION (uint32_t) 16777215uL + +// ===== TMC2209 & 2202 & TMC2209 & 2220 & 2225 "Donkey Kong" family register set ===== + +#define TMC2209_GCONF 0x00 +#define TMC2209_GSTAT 0x01 +#define TMC2209_IFCNT 0x02 +#define TMC2209_SLAVECONF 0x03 +#define TMC2209_OTP_PROG 0x04 +#define TMC2209_OTP_READ 0x05 +#define TMC2209_IOIN 0x06 +#define TMC2209_FACTORY_CONF 0x07 + +#define TMC2209_IHOLD_IRUN 0x10 +#define TMC2209_TPOWERDOWN 0x11 +#define TMC2209_TSTEP 0x12 +#define TMC2209_TPWMTHRS 0x13 +#define TMC2209_TCOOLTHRS 0x14 + +#define TMC2209_VACTUAL 0x22 + +#define TMC2209_SGTHRS 0x40 +#define TMC2209_SG_RESULT 0x41 +#define TMC2209_COOLCONF 0x42 + +#define TMC2209_MSCNT 0x6A +#define TMC2209_MSCURACT 0x6B +#define TMC2209_CHOPCONF 0x6C +#define TMC2209_DRV_STATUS 0x6F +#define TMC2209_PWMCONF 0x70 +#define TMC2209_PWM_SCALE 0x71 +#define TMC2209_PWM_AUTO 0x72 + +// Register fields in TMC2209 + +#define TMC2209_I_SCALE_ANALOG_MASK 0x01 // GCONF // I_scale_analog (Reset default=1) +#define TMC2209_I_SCALE_ANALOG_SHIFT 0 // min.: 0, max.: 1, default: 0 +#define TMC2209_I_SCALE_ANALOG_FIELD ((RegisterField) { TMC2209_I_SCALE_ANALOG_MASK, TMC2209_I_SCALE_ANALOG_SHIFT, TMC2209_GCONF, false }) +#define TMC2209_INTERNAL_RSENSE_MASK 0x02 // GCONF // internal_Rsense (Reset default: OTP) +#define TMC2209_INTERNAL_RSENSE_SHIFT 1 // min.: 0, max.: 1, default: 0 +#define TMC2209_INTERNAL_RSENSE_FIELD ((RegisterField) { TMC2209_INTERNAL_RSENSE_MASK, TMC2209_INTERNAL_RSENSE_SHIFT, TMC2209_GCONF, false }) +#define TMC2209_EN_SPREADCYCLE_MASK 0x04 // GCONF // en_spreadCycle (Reset default: OTP) +#define TMC2209_EN_SPREADCYCLE_SHIFT 2 // min.: 0, max.: 1, default: 0 +#define TMC2209_EN_SPREADCYCLE_FIELD ((RegisterField) { TMC2209_EN_SPREADCYCLE_MASK, TMC2209_EN_SPREADCYCLE_SHIFT, TMC2209_GCONF, false }) +#define TMC2209_SHAFT_MASK 0x08 // GCONF // controls motor direction +#define TMC2209_SHAFT_SHIFT 3 // min.: 0, max.: 1, default: 0 +#define TMC2209_SHAFT_FIELD ((RegisterField) { TMC2209_SHAFT_MASK, TMC2209_SHAFT_SHIFT, TMC2209_GCONF, false }) +#define TMC2209_INDEX_OTPW_MASK 0x10 // GCONF // index_otpw +#define TMC2209_INDEX_OTPW_SHIFT 4 // min.: 0, max.: 1, default: 0 +#define TMC2209_INDEX_OTPW_FIELD ((RegisterField) { TMC2209_INDEX_OTPW_MASK, TMC2209_INDEX_OTPW_SHIFT, TMC2209_GCONF, false }) +#define TMC2209_INDEX_STEP_MASK 0x20 // GCONF // index_step +#define TMC2209_INDEX_STEP_SHIFT 5 // min.: 0, max.: 1, default: 0 +#define TMC2209_INDEX_STEP_FIELD ((RegisterField) { TMC2209_INDEX_STEP_MASK, TMC2209_INDEX_STEP_SHIFT, TMC2209_GCONF, false }) +#define TMC2209_PDN_DISABLE_MASK 0x40 // GCONF // pdn_disable +#define TMC2209_PDN_DISABLE_SHIFT 6 // min.: 0, max.: 1, default: 0 +#define TMC2209_PDN_DISABLE_FIELD ((RegisterField) { TMC2209_PDN_DISABLE_MASK, TMC2209_PDN_DISABLE_SHIFT, TMC2209_GCONF, false }) +#define TMC2209_MSTEP_REG_SELECT_MASK 0x80 // GCONF // mstep_reg_select +#define TMC2209_MSTEP_REG_SELECT_SHIFT 7 // min.: 0, max.: 1, default: 0 +#define TMC2209_MSTEP_REG_SELECT_FIELD ((RegisterField) { TMC2209_MSTEP_REG_SELECT_MASK, TMC2209_MSTEP_REG_SELECT_SHIFT, TMC2209_GCONF, false }) +#define TMC2209_MULTISTEP_FILT_MASK 0x0100 // GCONF // multistep_filt (Reset default=1) +#define TMC2209_MULTISTEP_FILT_SHIFT 8 // min.: 0, max.: 1, default: 0 +#define TMC2209_MULTISTEP_FILT_FIELD ((RegisterField) { TMC2209_MULTISTEP_FILT_MASK, TMC2209_MULTISTEP_FILT_SHIFT, TMC2209_GCONF, false }) +#define TMC2209_TEST_MODE_MASK 0x0200 // GCONF // test_mode 0 +#define TMC2209_TEST_MODE_SHIFT 9 // min.: 0, max.: 1, default: 0 +#define TMC2209_TEST_MODE_FIELD ((RegisterField) { TMC2209_TEST_MODE_MASK, TMC2209_TEST_MODE_SHIFT, TMC2209_GCONF, false }) +#define TMC2209_RESET_MASK 0x01 // GSTAT // reset +#define TMC2209_RESET_SHIFT 0 // min.: 0, max.: 1, default: 0 +#define TMC2209_RESET_FIELD ((RegisterField) { TMC2209_RESET_MASK, TMC2209_RESET_SHIFT, TMC2209_GSTAT, false }) +#define TMC2209_DRV_ERR_MASK 0x02 // GSTAT // drv_err +#define TMC2209_DRV_ERR_SHIFT 1 // min.: 0, max.: 1, default: 0 +#define TMC2209_DRV_ERR_FIELD ((RegisterField) { TMC2209_DRV_ERR_MASK, TMC2209_DRV_ERR_SHIFT, TMC2209_GSTAT, false }) +#define TMC2209_UV_CP_MASK 0x04 // GSTAT // uv_cp +#define TMC2209_UV_CP_SHIFT 2 // min.: 0, max.: 1, default: 0 +#define TMC2209_UV_CP_FIELD ((RegisterField) { TMC2209_UV_CP_MASK, TMC2209_UV_CP_SHIFT, TMC2209_GSTAT, false }) +#define TMC2209_IFCNT_MASK 0xFF // IFCNT // Interface transmission counter. This register becomes incremented with each successful UART interface write access. Read out to check the serial transmission for lost data. Read accesses do not change the content. The counter wraps around from 255 to 0. +#define TMC2209_IFCNT_SHIFT 0 // min.: 0, max.: 255, default: 0 +#define TMC2209_IFCNT_FIELD ((RegisterField) { TMC2209_IFCNT_MASK, TMC2209_IFCNT_SHIFT, TMC2209_IFCNT, false }) +#define TMC2209_SLAVECONF_MASK 0x0F00 // SLAVECONF // SENDDELAY for read access (time until reply is sent): 0, 1: 8 bit times 2, 3: 3*8 bit times 4, 5: 5*8 bit times 6, 7: 7*8 bit times 8, 9: 9*8 bit times 10, 11: 11*8 bit times 12, 13: 13*8 bit times 14, 15: 15*8 bit times +#define TMC2209_SLAVECONF_SHIFT 8 // min.: 0, max.: 15, default: 0 +#define TMC2209_SLAVECONF_FIELD ((RegisterField) { TMC2209_SLAVECONF_MASK, TMC2209_SLAVECONF_SHIFT, TMC2209_SLAVECONF, false }) +#define TMC2209_OTPBIT_MASK 0x07 // OTP_PROG // Selection of OTP bit to be programmed to the selected byte location (n=0..7: programs bit n to a logic 1) +#define TMC2209_OTPBIT_SHIFT 0 // min.: 0, max.: 7, default: 0 +#define TMC2209_OTPBIT_FIELD ((RegisterField) { TMC2209_OTPBIT_MASK, TMC2209_OTPBIT_SHIFT, TMC2209_OTP_PROG, false }) +#define TMC2209_OTPBYTE_MASK 0x30 // OTP_PROG // Selection of OTP programming location (0, 1 or 2) +#define TMC2209_OTPBYTE_SHIFT 4 // min.: 0, max.: 3, default: 0 +#define TMC2209_OTPBYTE_FIELD ((RegisterField) { TMC2209_OTPBYTE_MASK, TMC2209_OTPBYTE_SHIFT, TMC2209_OTP_PROG, false }) +#define TMC2209_OTPMAGIC_MASK 0xFF00 // OTP_PROG // Set to 0xBD to enable programming. A programming time of minimum 10ms per bit is recommended (check by reading OTP_READ). +#define TMC2209_OTPMAGIC_SHIFT 8 // min.: 0, max.: 255, default: 0 +#define TMC2209_OTPMAGIC_FIELD ((RegisterField) { TMC2209_OTPMAGIC_MASK, TMC2209_OTPMAGIC_SHIFT, TMC2209_OTP_PROG, false }) +#define TMC2209_OTP0_BYTE_0_READ_DATA_MASK 0x01 // OTP_READ // to be detailed +#define TMC2209_OTP0_BYTE_0_READ_DATA_SHIFT 0 // min.: 0, max.: 255, default: 0 +#define TMC2209_OTP0_BYTE_0_READ_DATA_FIELD ((RegisterField) { TMC2209_OTP0_BYTE_0_READ_DATA_MASK, TMC2209_OTP0_BYTE_0_READ_DATA_SHIFT, TMC2209_OTP_READ, false }) +#define TMC2209_OTP1_BYTE_1_READ_DATA_MASK 0x02 // OTP_READ // to be detailed +#define TMC2209_OTP1_BYTE_1_READ_DATA_SHIFT 8 // min.: 0, max.: 255, default: 0 +#define TMC2209_OTP1_BYTE_1_READ_DATA_FIELD ((RegisterField) { TMC2209_OTP1_BYTE_1_READ_DATA_MASK, TMC2209_OTP1_BYTE_1_READ_DATA_SHIFT, TMC2209_OTP_READ, false }) +#define TMC2209_OTP2_BYTE_2_READ_DATA_MASK 0x04 // OTP_READ // to be detailed +#define TMC2209_OTP2_BYTE_2_READ_DATA_SHIFT 16 // min.: 0, max.: 255, default: 0 +#define TMC2209_OTP2_BYTE_2_READ_DATA_FIELD ((RegisterField) { TMC2209_OTP2_BYTE_2_READ_DATA_MASK, TMC2209_OTP2_BYTE_2_READ_DATA_SHIFT, TMC2209_OTP_READ, false }) +#define TMC2209_ENN_MASK 0x01 // IOIN // +#define TMC2209_ENN_SHIFT 0 // min.: 0, max.: 1, default: 0 +#define TMC2209_ENN_FIELD ((RegisterField) { TMC2209_ENN_MASK, TMC2209_ENN_SHIFT, TMC2209_IOIN, false }) +#define TMC2209_MS1_MASK 0x04 // IOIN // +#define TMC2209_MS1_SHIFT 2 // min.: 0, max.: 1, default: 0 +#define TMC2209_MS1_FIELD ((RegisterField) { TMC2209_MS1_MASK, TMC2209_MS1_SHIFT, TMC2209_IOIN, false }) +#define TMC2209_MS2_MASK 0x08 // IOIN // +#define TMC2209_MS2_SHIFT 3 // min.: 0, max.: 1, default: 0 +#define TMC2209_MS2_FIELD ((RegisterField) { TMC2209_MS2_MASK, TMC2209_MS2_SHIFT, TMC2209_IOIN, false }) +#define TMC2209_DIAG_MASK 0x10 // IOIN // +#define TMC2209_DIAG_SHIFT 4 // min.: 0, max.: 1, default: 0 +#define TMC2209_DIAG_FIELD ((RegisterField) { TMC2209_DIAG_MASK, TMC2209_DIAG_SHIFT, TMC2209_IOIN, false }) +#define TMC2209_PDN_UART_MASK 0x40 // IOIN // +#define TMC2209_PDN_UART_SHIFT 6 // min.: 0, max.: 1, default: 0 +#define TMC2209_PDN_UART_FIELD ((RegisterField) { TMC2209_PDN_UART_MASK, TMC2209_PDN_UART_SHIFT, TMC2209_IOIN, false }) +#define TMC2209_STEP_MASK 0x80 // IOIN // +#define TMC2209_STEP_SHIFT 7 // min.: 0, max.: 1, default: 0 +#define TMC2209_STEP_FIELD ((RegisterField) { TMC2209_STEP_MASK, TMC2209_STEP_SHIFT, TMC2209_IOIN, false }) +#define TMC2209_SEL_A_MASK 0x0100 // IOIN // Driver type +#define TMC2209_SEL_A_SHIFT 8 // min.: 0, max.: 1, default: 0 +#define TMC2209_SEL_A_FIELD ((RegisterField) { TMC2209_SEL_A_MASK, TMC2209_SEL_A_SHIFT, TMC2209_IOIN, false }) +#define TMC2209_DIR_MASK 0x0200 // IOIN // +#define TMC2209_DIR_SHIFT 9 // min.: 0, max.: 1, default: 0 +#define TMC2209_DIR_FIELD ((RegisterField) { TMC2209_DIR_MASK, TMC2209_DIR_SHIFT, TMC2209_IOIN, false }) +#define TMC2209_VERSION_MASK 0xFF000000 // IOIN // VERSION: 0x20=first version of the IC Identical numbers mean full digital compatibility. +#define TMC2209_VERSION_SHIFT 24 // min.: 0, max.: 255, default: 0 +#define TMC2209_VERSION_FIELD ((RegisterField) { TMC2209_VERSION_MASK, TMC2209_VERSION_SHIFT, TMC2209_IOIN, false }) +#define TMC2209_FCLKTRIM_MASK 0x1F // FACTORY_CONF // FCLKTRIM (Reset default: OTP) 0-31: Lowest to highest clock frequency. Check at charge pump output. The frequency span is not guaranteed, but it is tested, that tuning to 12MHz internal clock is possible. The devices come preset to 12MHz clock frequency by OTP programming. +#define TMC2209_FCLKTRIM_SHIFT 0 // min.: 0, max.: 31, default: 0 +#define TMC2209_FCLKTRIM_FIELD ((RegisterField) { TMC2209_FCLKTRIM_MASK, TMC2209_FCLKTRIM_SHIFT, TMC2209_FACTORY_CONF, false }) +#define TMC2209_OTTRIM_MASK 0x30 // FACTORY_CONF // OTTRIM (Default: OTP) %00: OT=143°C, OTPW=120°C %01: OT=150°C, OTPW=120°C %10: OT=150°C, OTPW=143°C %11: OT=157°C, OTPW=143°C +#define TMC2209_OTTRIM_SHIFT 8 // min.: 0, max.: 3, default: 0 +#define TMC2209_OTTRIM_FIELD ((RegisterField) { TMC2209_OTTRIM_MASK, TMC2209_OTTRIM_SHIFT, TMC2209_FACTORY_CONF, false }) +#define TMC2209_IHOLD_MASK 0x1F // IHOLD_IRUN // IHOLD (Reset default: OTP) Standstill current (0=1/32...31=32/32) In combination with stealthChop mode, setting IHOLD=0 allows to choose freewheeling or coil short circuit (passive braking) for motor stand still. +#define TMC2209_IHOLD_SHIFT 0 // min.: 0, max.: 31, default: 0 +#define TMC2209_IHOLD_FIELD ((RegisterField) { TMC2209_IHOLD_MASK, TMC2209_IHOLD_SHIFT, TMC2209_IHOLD_IRUN, false }) +#define TMC2209_IRUN_MASK 0x1F00 // IHOLD_IRUN // IRUN (Reset default=31) Motor run current (0=1/32...31=32/32) Hint: Choose sense resistors in a way, that normal IRUN is 16 to 31 for best microstep performance. +#define TMC2209_IRUN_SHIFT 8 // min.: 0, max.: 31, default: 0 +#define TMC2209_IRUN_FIELD ((RegisterField) { TMC2209_IRUN_MASK, TMC2209_IRUN_SHIFT, TMC2209_IHOLD_IRUN, false }) +#define TMC2209_IHOLDDELAY_MASK 0x0F0000 // IHOLD_IRUN // IHOLDDELAY (Reset default: OTP) Controls the number of clock cycles for motor power down after standstill is detected (stst=1) and TPOWERDOWN has expired. The smooth transition avoids a motor jerk upon power down. 0: instant power down 1..15: Delay per current reduction step in multiple of 2^18 clocks +#define TMC2209_IHOLDDELAY_SHIFT 16 // min.: 0, max.: 15, default: 0 +#define TMC2209_IHOLDDELAY_FIELD ((RegisterField) { TMC2209_IHOLDDELAY_MASK, TMC2209_IHOLDDELAY_SHIFT, TMC2209_IHOLD_IRUN, false }) +#define TMC2209_TPOWERDOWN_MASK 0xFF // TPOWERDOWN // (Reset default=20) Sets the delay time from stand still (stst) detection to motor current power down. Time range is about 0 to 5.6 seconds. 0...((2^8)-1) * 2^18 tclk Attention: A minimum setting of 2 is required to allow automatic tuning of stealthChop PWM_OFFS_AUTO. +#define TMC2209_TPOWERDOWN_SHIFT 0 // min.: 0, max.: 255, default: 0 +#define TMC2209_TPOWERDOWN_FIELD ((RegisterField) { TMC2209_TPOWERDOWN_MASK, TMC2209_TPOWERDOWN_SHIFT, TMC2209_TPOWERDOWN, false }) +#define TMC2209_TSTEP_MASK 0x0FFFFF // TSTEP // Actual measured time between two 1/256 microsteps derived from the step input frequency in units of 1/fCLK. Measured value is (2^20)-1 in case of overflow or stand still. The TSTEP related threshold uses a hysteresis of 1/16 of the compare value to compensate for jitter in the clock or the step frequency: (Txxx*15/16)-1 is the lower compare value for each TSTEP based comparison. This means, that the lower switching velocity equals the calculated setting, but the upper switching velocity is higher as defined by the hysteresis setting. +#define TMC2209_TSTEP_SHIFT 0 // min.: 0, max.: 1048575, default: 0 +#define TMC2209_TSTEP_FIELD ((RegisterField) { TMC2209_TSTEP_MASK, TMC2209_TSTEP_SHIFT, TMC2209_TSTEP, false }) +#define TMC2209_TPWMTHRS_MASK 0x0FFFFF // TPWMTHRS // Sets the upper velocity for stealthChop voltage PWM mode. For TSTEP = TPWMTHRS, stealthChop PWM mode is enabled, if configured. When the velocity exceeds the limit set by TPWMTHRS, the driver switches to spreadCycle. 0 = Disabled +#define TMC2209_TPWMTHRS_SHIFT 0 // min.: 0, max.: 1048575, default: 0 +#define TMC2209_TPWMTHRS_FIELD ((RegisterField) { TMC2209_TPWMTHRS_MASK, TMC2209_TPWMTHRS_SHIFT, TMC2209_TPWMTHRS, false }) +#define TMC2209_VACTUAL_MASK 0xFFFFFF // VACTUAL // VACTUAL allows moving the motor by UART control. It gives the motor velocity in +-(2^23)-1 [µsteps / t] 0: Normal operation. Driver reacts to STEP input. /=0: Motor moves with the velocity given by VACTUAL. Step pulses can be monitored via INDEX output. The motor direction is controlled by the sign of VACTUAL. +#define TMC2209_VACTUAL_SHIFT 0 // min.: -8388608, max.: 8388607, default: 0 +#define TMC2209_VACTUAL_FIELD ((RegisterField) { TMC2209_VACTUAL_MASK, TMC2209_VACTUAL_SHIFT, TMC2209_VACTUAL, true }) +#define TMC2209_SEMIN_MASK 0x0000000F +#define TMC2209_SEMIN_SHIFT 0 +#define TMC2209_SEMIN_FIELD ((RegisterField) { TMC2209_SEMIN_MASK, TMC2209_SEMIN_SHIFT, TMC2209_COOLCONF, false }) +#define TMC2209_SEUP_MASK 0x00000060 +#define TMC2209_SEUP_SHIFT 5 +#define TMC2209_SEUP_FIELD ((RegisterField) { TMC2209_SEUP_MASK, TMC2209_SEUP_SHIFT, TMC2209_COOLCONF, false }) +#define TMC2209_SEMAX_MASK 0x00000F00 +#define TMC2209_SEMAX_SHIFT 8 +#define TMC2209_SEMAX_FIELD ((RegisterField) { TMC2209_SEMAX_MASK, TMC2209_SEMAX_SHIFT, TMC2209_COOLCONF, false }) +#define TMC2209_SEDN_MASK 0x00006000 +#define TMC2209_SEDN_SHIFT 13 +#define TMC2209_SEDN_FIELD ((RegisterField) { TMC2209_SEDN_MASK, TMC2209_SEDN_SHIFT, TMC2209_COOLCONF, false }) +#define TMC2209_SEIMIN_MASK 0x00008000 +#define TMC2209_SEIMIN_SHIFT 15 +#define TMC2209_SEIMIN_FIELD ((RegisterField) { TMC2209_SEIMIN_MASK, TMC2209_SEIMIN_SHIFT, TMC2209_COOLCONF, false }) +#define TMC2209_MSCNT_MASK 0x03FF // MSCNT // Microstep counter. Indicates actual position in the microstep table for CUR_A. CUR_B uses an offset of 256 into the table. Reading out MSCNT allows determination of the motor position within the electrical wave. +#define TMC2209_MSCNT_SHIFT 0 // min.: 0, max.: 1023, default: 0 +#define TMC2209_MSCNT_FIELD ((RegisterField) { TMC2209_MSCNT_MASK, TMC2209_MSCNT_SHIFT, TMC2209_MSCNT, false }) +#define TMC2209_CUR_A_MASK 0x01FF // MSCURACT // (signed) Actual microstep current for motor phase A as read from the internal sine wave table (not scaled by current setting) +#define TMC2209_CUR_A_SHIFT 0 // min.: -255, max.: 255, default: 0 +#define TMC2209_CUR_A_FIELD ((RegisterField) { TMC2209_CUR_A_MASK, TMC2209_CUR_A_SHIFT, TMC2209_MSCURACT, true }) +#define TMC2209_CUR_B_MASK 0x01FF0000 // MSCURACT // (signed) Actual microstep current for motor phase B as read from the internal sine wave table (not scaled by current setting) +#define TMC2209_CUR_B_SHIFT 16 // min.: -255, max.: 255, default: 0 +#define TMC2209_CUR_B_FIELD ((RegisterField) { TMC2209_CUR_B_MASK, TMC2209_CUR_B_SHIFT, TMC2209_MSCURACT, true }) +#define TMC2209_TOFF_MASK 0x0F // CHOPCONF // chopper off time and driver enable, Off time setting controls duration of slow decay phase (Nclk = 12 + 32*Toff), %0000: Driver disable, all bridges off %0001: 1 - use only with TBL = 2 %0010 ... %1111: 2 - 15 (Default: OTP, resp. 3 in stealthChop mode) +#define TMC2209_TOFF_SHIFT 0 // min.: 0, max.: 7, default: 0 +#define TMC2209_TOFF_FIELD ((RegisterField) { TMC2209_TOFF_MASK, TMC2209_TOFF_SHIFT, TMC2209_CHOPCONF, false }) +#define TMC2209_HSTRT_MASK 0x70 // CHOPCONF // hysteresis start value added to HEND, %000 - %111: Add 1, 2, ..., 8 to hysteresis low value HEND (1/512 of this setting adds to current setting) Attention: Effective HEND+HSTRT <= 16. Hint: Hysteresis decrement is done each 16 clocks. (Default: OTP, resp. 0 in stealthChop mode) +#define TMC2209_HSTRT_SHIFT 4 // min.: 0, max.: 7, default: 0 +#define TMC2209_HSTRT_FIELD ((RegisterField) { TMC2209_HSTRT_MASK, TMC2209_HSTRT_SHIFT, TMC2209_CHOPCONF, false }) +#define TMC2209_HEND_MASK 0x0780 // CHOPCONF // hysteresis low value OFFSET sine wave offset, %0000 - %1111: Hysteresis is -3, -2, -1, 0, 1, ..., 12 (1/512 of this setting adds to current setting) This is the hysteresis value which becomes used for the hysteresis chopper. (Default: OTP, resp. 5 in stealthChop mode) +#define TMC2209_HEND_SHIFT 7 // min.: 0, max.: 255, default: 0 +#define TMC2209_HEND_FIELD ((RegisterField) { TMC2209_HEND_MASK, TMC2209_HEND_SHIFT, TMC2209_CHOPCONF, false }) +#define TMC2209_TBL_MASK 0x018000 // CHOPCONF // blank time select, %00 - %11: Set comparator blank time to 16, 24, 32 or 40 clocks Hint: %00 or %01 is recommended for most applications (Default: OTP) +#define TMC2209_TBL_SHIFT 15 // min.: 0, max.: 255, default: 0 +#define TMC2209_TBL_FIELD ((RegisterField) { TMC2209_TBL_MASK, TMC2209_TBL_SHIFT, TMC2209_CHOPCONF, false }) +#define TMC2209_VSENSE_MASK 0x020000 // CHOPCONF // sense resistor voltage based current scaling +#define TMC2209_VSENSE_SHIFT 17 // min.: 0, max.: 1, default: 0 +#define TMC2209_VSENSE_FIELD ((RegisterField) { TMC2209_VSENSE_MASK, TMC2209_VSENSE_SHIFT, TMC2209_CHOPCONF, false }) +#define TMC2209_MRES_MASK 0x0F000000 // CHOPCONF // MRES micro step resolution, %0000: Native 256 microstep setting. %0001 - %1000: 128, 64, 32, 16, 8, 4, 2, FULLSTEP: Reduced microstep resolution. The resolution gives the number of microstep entries per sine quarter wave. When choosing a lower microstep resolution, the driver automatically uses microstep positions which result in a symmetrical wave. Number of microsteps per step pulse = 2^MRES (Selection by pins unless disabled by GCONF. mstep_reg_select) +#define TMC2209_MRES_SHIFT 24 // min.: 0, max.: 255, default: 0 +#define TMC2209_MRES_FIELD ((RegisterField) { TMC2209_MRES_MASK, TMC2209_MRES_SHIFT, TMC2209_CHOPCONF, false }) +#define TMC2209_INTPOL_MASK 0x10000000 // CHOPCONF // interpolation to 256 microsteps +#define TMC2209_INTPOL_SHIFT 28 // min.: 0, max.: 1, default: 0 +#define TMC2209_INTPOL_FIELD ((RegisterField) { TMC2209_INTPOL_MASK, TMC2209_INTPOL_SHIFT, TMC2209_CHOPCONF, false }) +#define TMC2209_DEDGE_MASK 0x20000000 // CHOPCONF // enable double edge step pulses +#define TMC2209_DEDGE_SHIFT 29 // min.: 0, max.: 1, default: 0 +#define TMC2209_DEDGE_FIELD ((RegisterField) { TMC2209_DEDGE_MASK, TMC2209_DEDGE_SHIFT, TMC2209_CHOPCONF, false }) +#define TMC2209_DISS2G_MASK 0x40000000 // CHOPCONF // short to GND protection disable +#define TMC2209_DISS2G_SHIFT 30 // min.: 0, max.: 1, default: 0 +#define TMC2209_DISS2G_FIELD ((RegisterField) { TMC2209_DISS2G_MASK, TMC2209_DISS2G_SHIFT, TMC2209_CHOPCONF, false }) +#define TMC2209_DISS2VS_MASK 0x80000000 // CHOPCONF // Low side short protection disable +#define TMC2209_DISS2VS_SHIFT 31 // min.: 0, max.: 1, default: 0 +#define TMC2209_DISS2VS_FIELD ((RegisterField) { TMC2209_DISS2VS_MASK, TMC2209_DISS2VS_SHIFT, TMC2209_CHOPCONF, false }) +#define TMC2209_OTPW_MASK 0x01 // DRV_STATUS // overtemperature prewarning flag +#define TMC2209_OTPW_SHIFT 0 // min.: 0, max.: 1, default: 0 +#define TMC2209_OTPW_FIELD ((RegisterField) { TMC2209_OTPW_MASK, TMC2209_OTPW_SHIFT, TMC2209_DRV_STATUS, false }) +#define TMC2209_OT_MASK 0x02 // DRV_STATUS // overtemperature flag +#define TMC2209_OT_SHIFT 1 // min.: 0, max.: 1, default: 0 +#define TMC2209_OT_FIELD ((RegisterField) { TMC2209_OT_MASK, TMC2209_OT_SHIFT, TMC2209_DRV_STATUS, false }) +#define TMC2209_S2GA_MASK 0x04 // DRV_STATUS // short to ground indicator phase A +#define TMC2209_S2GA_SHIFT 2 // min.: 0, max.: 1, default: 0 +#define TMC2209_S2GA_FIELD ((RegisterField) { TMC2209_S2GA_MASK, TMC2209_S2GA_SHIFT, TMC2209_DRV_STATUS, false }) +#define TMC2209_S2GB_MASK 0x08 // DRV_STATUS // short to ground indicator phase B +#define TMC2209_S2GB_SHIFT 3 // min.: 0, max.: 1, default: 0 +#define TMC2209_S2GB_FIELD ((RegisterField) { TMC2209_S2GB_MASK, TMC2209_S2GB_SHIFT, TMC2209_DRV_STATUS, false }) +#define TMC2209_S2VSA_MASK 0x10 // DRV_STATUS // low side short indicator phase A +#define TMC2209_S2VSA_SHIFT 4 // min.: 0, max.: 1, default: 0 +#define TMC2209_S2VSA_FIELD ((RegisterField) { TMC2209_S2VSA_MASK, TMC2209_S2VSA_SHIFT, TMC2209_DRV_STATUS, false }) +#define TMC2209_S2VSB_MASK 0x20 // DRV_STATUS // low side short indicator phase B +#define TMC2209_S2VSB_SHIFT 5 // min.: 0, max.: 1, default: 0 +#define TMC2209_S2VSB_FIELD ((RegisterField) { TMC2209_S2VSB_MASK, TMC2209_S2VSB_SHIFT, TMC2209_DRV_STATUS, false }) +#define TMC2209_OLA_MASK 0x40 // DRV_STATUS // open load indicator phase A +#define TMC2209_OLA_SHIFT 6 // min.: 0, max.: 1, default: 0 +#define TMC2209_OLA_FIELD ((RegisterField) { TMC2209_OLA_MASK, TMC2209_OLA_SHIFT, TMC2209_DRV_STATUS, false }) +#define TMC2209_OLB_MASK 0x80 // DRV_STATUS // open load indicator phase B +#define TMC2209_OLB_SHIFT 7 // min.: 0, max.: 1, default: 0 +#define TMC2209_OLB_FIELD ((RegisterField) { TMC2209_OLB_MASK, TMC2209_OLB_SHIFT, TMC2209_DRV_STATUS, false }) +#define TMC2209_T120_MASK 0x0100 // DRV_STATUS // 120°C comparator +#define TMC2209_T120_SHIFT 8 // min.: 0, max.: 1, default: 0 +#define TMC2209_T120_FIELD ((RegisterField) { TMC2209_T120_MASK, TMC2209_T120_SHIFT, TMC2209_DRV_STATUS, false }) +#define TMC2209_T143_MASK 0x0200 // DRV_STATUS // 143°C comparator +#define TMC2209_T143_SHIFT 9 // min.: 0, max.: 1, default: 0 +#define TMC2209_T143_FIELD ((RegisterField) { TMC2209_T143_MASK, TMC2209_T143_SHIFT, TMC2209_DRV_STATUS, false }) +#define TMC2209_T150_MASK 0x0400 // DRV_STATUS // 150°C comparator +#define TMC2209_T150_SHIFT 10 // min.: 0, max.: 1, default: 0 +#define TMC2209_T150_FIELD ((RegisterField) { TMC2209_T150_MASK, TMC2209_T150_SHIFT, TMC2209_DRV_STATUS, false }) +#define TMC2209_T157_MASK 0x0800 // DRV_STATUS // 157°C comparator +#define TMC2209_T157_SHIFT 11 // min.: 0, max.: 1, default: 0 +#define TMC2209_T157_FIELD ((RegisterField) { TMC2209_T157_MASK, TMC2209_T157_SHIFT, TMC2209_DRV_STATUS, false }) +#define TMC2209_CS_ACTUAL_MASK 0x1F0000 // DRV_STATUS // actual motor current +#define TMC2209_CS_ACTUAL_SHIFT 16 // min.: 0, max.: 31, default: 0 +#define TMC2209_CS_ACTUAL_FIELD ((RegisterField) { TMC2209_CS_ACTUAL_MASK, TMC2209_CS_ACTUAL_SHIFT, TMC2209_DRV_STATUS, false }) +#define TMC2209_STEALTH_MASK 0x40000000 // DRV_STATUS // stealthChop indicator +#define TMC2209_STEALTH_SHIFT 30 // min.: 0, max.: 1, default: 0 +#define TMC2209_STEALTH_FIELD ((RegisterField) { TMC2209_STEALTH_MASK, TMC2209_STEALTH_SHIFT, TMC2209_DRV_STATUS, false }) +#define TMC2209_STST_MASK 0x80000000 // DRV_STATUS // standstill indicator +#define TMC2209_STST_SHIFT 31 // min.: 0, max.: 1, default: 0 +#define TMC2209_STST_FIELD ((RegisterField) { TMC2209_STST_MASK, TMC2209_STST_SHIFT, TMC2209_DRV_STATUS, false }) +#define TMC2209_PWM_OFS_MASK 0xFF // PWMCONF // User defined PWM amplitude offset (0-255) related to full motor current (CS_ACTUAL=31) in stand still. (Reset default=36) When using automatic scaling (pwm_autoscale=1) the value is used for initialization, only. The autoscale function starts with PWM_SCALE_AUTO=PWM_OFS and finds the required offset to yield the target current automatically. PWM_OFS = 0 will disable scaling down motor current below a motor specific lower measurement threshold. This setting should only be used under certain conditions, i.e. when the power supply voltage can vary up and down by a factor of two or more. It prevents the motor going out of regulation, but it also prevents power down below the regulation limit. PWM_OFS > 0 allows automatic scaling to low PWM duty cycles even below the lower regulation threshold. This allows low (standstill) current settings based on the actual (hold) current scale (register IHOLD_IRUN). +#define TMC2209_PWM_OFS_SHIFT 0 // min.: 0, max.: 255, default: 0 +#define TMC2209_PWM_OFS_FIELD ((RegisterField) { TMC2209_PWM_OFS_MASK, TMC2209_PWM_OFS_SHIFT, TMC2209_PWMCONF, false }) +#define TMC2209_PWM_GRAD_MASK 0xFF00 // PWMCONF // Velocity dependent gradient for PWM amplitude: PWM_GRAD * 256 / TSTEP This value is added to PWM_AMPL to compensate for the velocity-dependent motor back-EMF. With automatic scaling (pwm_autoscale=1) the value is used for first initialization, only. Set PWM_GRAD to the application specific value (it can be read out from PWM_GRAD_AUTO) to speed up the automatic tuning process. An approximate value can be stored to OTP by programming OTP_PWM_GRAD. +#define TMC2209_PWM_GRAD_SHIFT 8 // min.: 0, max.: 255, default: 0 +#define TMC2209_PWM_GRAD_FIELD ((RegisterField) { TMC2209_PWM_GRAD_MASK, TMC2209_PWM_GRAD_SHIFT, TMC2209_PWMCONF, false }) +#define TMC2209_PWM_FREQ_MASK 0x030000 // PWMCONF // %00: fPWM=2/1024 fCLK %01: fPWM=2/683 fCLK %10: fPWM=2/512 fCLK %11: fPWM=2/410 fCLK +#define TMC2209_PWM_FREQ_SHIFT 16 // min.: 0, max.: 3, default: 0 +#define TMC2209_PWM_FREQ_FIELD ((RegisterField) { TMC2209_PWM_FREQ_MASK, TMC2209_PWM_FREQ_SHIFT, TMC2209_PWMCONF, false }) +#define TMC2209_PWM_AUTOSCALE_MASK 0x040000 // PWMCONF // +#define TMC2209_PWM_AUTOSCALE_SHIFT 18 // min.: 0, max.: 1, default: 0 +#define TMC2209_PWM_AUTOSCALE_FIELD ((RegisterField) { TMC2209_PWM_AUTOSCALE_MASK, TMC2209_PWM_AUTOSCALE_SHIFT, TMC2209_PWMCONF, false }) +#define TMC2209_PWM_AUTOGRAD_MASK 0x080000 // PWMCONF // +#define TMC2209_PWM_AUTOGRAD_SHIFT 19 // min.: 0, max.: 1, default: 0 +#define TMC2209_PWM_AUTOGRAD_FIELD ((RegisterField) { TMC2209_PWM_AUTOGRAD_MASK, TMC2209_PWM_AUTOGRAD_SHIFT, TMC2209_PWMCONF, false }) +#define TMC2209_FREEWHEEL_MASK 0x300000 // PWMCONF // Stand still option when motor current setting is zero (I_HOLD=0). %00: Normal operation %01: Freewheeling %10: Coil shorted using LS drivers %11: Coil shorted using HS drivers +#define TMC2209_FREEWHEEL_SHIFT 20 // min.: 0, max.: 3, default: 0 +#define TMC2209_FREEWHEEL_FIELD ((RegisterField) { TMC2209_FREEWHEEL_MASK, TMC2209_FREEWHEEL_SHIFT, TMC2209_PWMCONF, false }) +#define TMC2209_PWM_REG_MASK 0x0F000000 // PWMCONF // User defined maximum PWM amplitude change per half wave when using pwm_autoscale=1. (1...15): 1: 0.5 increments (slowest regulation) 2: 1 increment (default with OTP2.1=1) 3: 1.5 increments 4: 2 increments ... 8: 4 increments (default with OTP2.1=0) ... 15: 7.5 increments (fastest regulation) +#define TMC2209_PWM_REG_SHIFT 24 // min.: 0, max.: 25, default: 0 +#define TMC2209_PWM_REG_FIELD ((RegisterField) { TMC2209_PWM_REG_MASK, TMC2209_PWM_REG_SHIFT, TMC2209_PWMCONF, false }) +#define TMC2209_PWM_LIM_MASK 0xF0000000 // PWMCONF // Limit for PWM_SCALE_AUTO when switching back from spreadCycle to stealthChop. This value defines the upper limit for bits 7 to 4 of the automatic current control when switching back. It can be set to reduce the current jerk during mode change back to stealthChop. It does not limit PWM_GRAD or PWM_GRAD_AUTO offset. (Default = 12) +#define TMC2209_PWM_LIM_SHIFT 28 // min.: 0, max.: 15, default: 0 +#define TMC2209_PWM_LIM_FIELD ((RegisterField) { TMC2209_PWM_LIM_MASK, TMC2209_PWM_LIM_SHIFT, TMC2209_PWMCONF, false }) +#define TMC2209_PWM_SCALE_SUM_MASK 0xFF // PWM_SCALE // Actual PWM duty cycle. This value is used for scaling the values CUR_A and CUR_B read from the sine wave table. +#define TMC2209_PWM_SCALE_SUM_SHIFT 0 // min.: 0, max.: 255, default: 0 +#define TMC2209_PWM_SCALE_SUM_FIELD ((RegisterField) { TMC2209_PWM_SCALE_SUM_MASK, TMC2209_PWM_SCALE_SUM_SHIFT, TMC2209_PWM_SCALE, false }) +#define TMC2209_PWM_SCALE_AUTO_MASK 0x01FF0000 // PWM_SCALE // 9 Bit signed offset added to the calculated PWM duty cycle. This is the result of the automatic amplitude regulation based on current measurement. +#define TMC2209_PWM_SCALE_AUTO_SHIFT 16 // min.: -255, max.: 255, default: 0 +#define TMC2209_PWM_SCALE_AUTO_FIELD ((RegisterField) { TMC2209_PWM_SCALE_AUTO_MASK, TMC2209_PWM_SCALE_AUTO_SHIFT, TMC2209_PWM_SCALE, true }) +#define TMC2209_PWM_OFS_AUTO_MASK 0xFF // PWM_AUTO // Automatically determined offset value +#define TMC2209_PWM_OFS_AUTO_SHIFT 0 // min.: 0, max.: 255, default: 0 +#define TMC2209_PWM_OFS_AUTO_FIELD ((RegisterField) { TMC2209_PWM_OFS_AUTO_MASK, TMC2209_PWM_OFS_AUTO_SHIFT, TMC2209_PWM_AUTO, false }) +#define TMC2209_PWM_GRAD_AUTO_MASK 0xFF0000 // PWM_AUTO // Automatically determined gradient value +#define TMC2209_PWM_GRAD_AUTO_SHIFT 16 // min.: 0, max.: 255, default: 0 +#define TMC2209_PWM_GRAD_AUTO_FIELD ((RegisterField) { TMC2209_PWM_GRAD_AUTO_MASK, TMC2209_PWM_GRAD_AUTO_SHIFT, TMC2209_PWM_AUTO, false }) + +#endif diff --git a/firmware/lib/tmc/ic/TMC2209/registercall_hierarchy_flowchart_UART.svg b/firmware/lib/tmc/ic/TMC2209/registercall_hierarchy_flowchart_UART.svg new file mode 100755 index 0000000..425f60a --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2209/registercall_hierarchy_flowchart_UART.svg @@ -0,0 +1,3 @@ + + +

HAL

HAL

APP (Eval)

APP (Eval)

API

API
Read a register
  •  Call tmcXXXX_readRegister function
Read a register...
Returns the register read value
Returns the register read value
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
tmcXXXX.c
tmcXXXX.c
UART.c
UART.c
tmcXXXX_eval.c
tmcXXXX_eval.c

 Implementation of UART_readWrite
  • Sends and receives bytes on the UART bus
Implementation of UART_readWrite...
Returns the raw reply data
Returns the raw reply data

Implementation of tmcXXXX_readWriteUART
  • Takes the array of data to write
  • Calls hardware function UART_readWrite
Implementation of tmcXXXX_readWriteUART...
Passes on the raw reply data to the API
Passes on the raw reply data to the API
Implementation of readRegisterUART
  • Constructs the datagram
  • Calls HAL wrapper function 
Implementation of readRegisterUART...
tmcXXXX_readWriteUART
tmcXXXX_readWriteUART
Parses the reply and returns the register value
Parses the reply and returns the register value
Implementation of tmcXXXX_readRegister 
  • Check which bus is active SPI/UART. (e.g. UART)
  • Calls bus-specific function (e.g. readRegisterUART)
 
Implementation of tmcXXXX_readRegister...
Returns the register read value
Returns the register read value
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC2209/uml-tmc-api.svg b/firmware/lib/tmc/ic/TMC2209/uml-tmc-api.svg new file mode 100755 index 0000000..5a5f8dd --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2209/uml-tmc-api.svg @@ -0,0 +1,3 @@ + + +

TMCXXXX_HW_Abstraction.h



TMCXXXX_HW_Abstraction.h...
// Constants
#define TMCXXXX_MOTORS              
                          
// Register definitions
#define TMCXXXX_GCONF        
                          ⋮
// Register fields definitions
#define TMCXXXX_GCONF_OTPW_FIELD
                     
// Constants...

TMCXXXX.h



TMCXXXX.h...
extern void tmcXXXX_readWriteSPI();
extern void tmcXXXX_readWriteUART();
extern TMCXXXXBusType tmcXXXX_getBusType();
extern uint8_t tmcXXXX_getNodeAddress();
                                  ⋮
tmcXXXX_readRegister();
tmcXXXX_writeRegister();
                                  ⋮
extern void tmcXXXX_readWriteSPI();...

TMCXXXX.c



TMCXXXX.c...
const uint8_t tmcCRCTable_Poly7Reflected[256] = {...};
int32_t tmcXXXX_readRegister(){
/* Call tmcXXXX_getBusType();
 * Based on bus type, call readRegisterSPI/UART() that
 * further calls tmcXXXX_readWriteSPI/UART();
 * For UART it also calls tmcXXXX_getNodeAddress();
                                           ⋮
}
                                           ⋮
const uint8_t tmcCRCTable_Poly7Reflected[256] = {.....
TMC-API
TMC-API

TMCXXXX_Simple_Rotation.h


TMCXXXX_Simple_Rotation.h...
void initAllMotors();
             ⋮
  
void initAllMotors()...

TMCXXXX_Simple_Rotation.c


TMCXXXX_Simple_Rotation.c...
void initAllMotors(){

// Configuring registers to enable motor drivers etc..
tmcXXXX_writeRegister();
                    ⋮
}
                    ⋮
void initAllMotors(){...
Examples
Examples
User Project
User Project

User_Project.h


User_Project.h

User_Project.c








User_Project.c...

void tmcXXXX_readWriteSPI(){
                           ⋮
}
void tmcXXXX_readWriteUART(){
                           ⋮
}
TMCXXXXBusType tmcXXXX_getBusType(){
                           ⋮
}
uint8_t tmcXXXX_getNodeAddress(){
                           ⋮
}

// User Code
                           ⋮
void tmcXXXX_readWriteSPI(){...
#include "TMCXXXX_HW_Abstraction.h"
#include "TMCXXXX.h"
#include "TMCXXXX_Simple_Rotation.h"
                                ⋮
TMCXXXXBusType bus = IC_BUS_SPI/UART;
uint8_t nodeAddress = <nodeAddress>;
                                ⋮
#include "TMCXXXX_HW_Abstraction.h"...
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC2224/README.md b/firmware/lib/tmc/ic/TMC2224/README.md new file mode 100755 index 0000000..972300c --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2224/README.md @@ -0,0 +1,52 @@ +# TMC2224 + + +## How to use + +To access the TMC2224's registers, the TMC-API offers two functions: **tmc2224_readRegister** and **tmc2224_writeRegister**. +Each of these functions takes in an **icID**, which is used to identify the IC when multiple ICs are connected. This identifier is passed down to the callback functions (see How to Integrate). + +## How to integrate: overview + +1. Include all the files of the TMC-API/ic/tmc/TMC2224 folder into the custom project. +2. Include the TMC2224.h file in the custom source code. +3. Implement the necessary callback functions (see below). +4. (optional): Take a look at the Examples subfolder for ready-made examples of the TMC-API usage. + +## Accessing the TMC2224 via UART +The following diagram depicts how to access the TMC2224 via UART using the TMC-API. + +![screenshot](registercall_hierarchy_flowchart_UART.svg) + +The description of the functions, in the above flowchart, are as follows: +- The functions tmc2224_readRegister and tmc2224_writeRegister are used to read and write the registers respectively. These functions check the current active bus and calls the bus-specific function i.e readRegisterUART or writeRegisterUART. +- These bus specific functions constructs the datagram and further calls the bus specific callback 'tmcXXXX_readWriteUART. +- This callback function further calls the hardware specific read/write function for UART and needs to be implemented externally. + +### How to integrate: Callback functions +To communicate with TMC2224 IC, implement the following callback functions to access the chip via UART: +1. **tmc2224_readWriteUART()**, which is a HAL wrapper function that provides the necessary hardware access. +2. **tmc2224_getNodeAddress()**, that returns the node/slave address. Node address could be set in NODECONF (0x3) register and the address could be incremented as defined by AD0, AD1 and AD2. (Node address + ADx) must be less than 255. For further details please consult the datasheet of TMC2224. + +### Sharing the CRC table with other TMC-API chips +The TMC2224 UART protocol uses an 8 bit CRC. For calculating this, a table-based algorithm is used. This table (tmcCRCTable_Poly7Reflected[256]) is 256 bytes big and identical across multiple different Trinamic chips (i.e. TMC2209). +If multiple Trinamic chips are being used in the same project, avoiding redundant copies of this table could save memory. It is possible to substitute this CRC table with another CRC table. + +### Option to use the cache logic for Write-Only registers +The chip features write-only registers that are unable to be read, necessitating the creation of a shadow copy to cache their contents. This copy is automatically updated whenever data is written to these registers. This cache logic could be enabled by setting the macro **TMC2224_CACHE** to **'1'** or disabled by setting to **'0'** respectively. If this feature is enabled then there comes another option to use **tmc2224_cache** function, which is already implemeted in the API, by defining **TMC2224_ENABLE_TMC_CACHE** macro to **'1** or one can implement their own function. + +The function **tmc2224_cache** works for both reading from and writing to the shadow array. It first checks whether the register has write-only access and data needs to be read from the shadow copy. On the basis of that, it returns **true** or **false**. The shadowRegisters on the premade cache implementation need to be one per chip. **TMC2224_IC_CACHE_COUNT** is set to '1' by default and is user-overwritable. If multiple chips are being used in the same project, increment its value to the number of chips connected. + +## Further info +### Dependency graph for the ICs with new register R/W mechanism +This graph illustrates the relationships between files within the TMC-API library, highlighting dependencies and identifying the files that are essential for integrating the library into the custom projects. + +![screenshot](uml-tmc-api.svg) + +### Example usage: TMC-Evalsystem +**For a reference usage of the TMC-API**, visit the [TMC-Evalsystem](https://github.com/analogdevicesinc/TMC-EvalSystem) + +## Migration status +The TMC2224 has been reworked to the access system described above. For more infos on the status of this and other ICs, check out the [migration page](https://github.com/analogdevicesinc/TMC-API/issues/53). + + diff --git a/firmware/lib/tmc/ic/TMC2224/TMC2224.c b/firmware/lib/tmc/ic/TMC2224/TMC2224.c new file mode 100755 index 0000000..0b1557d --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2224/TMC2224.c @@ -0,0 +1,210 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#include "TMC2224.h" + + +#ifdef TMC_API_EXTERNAL_CRC_TABLE +extern const uint8_t tmcCRCTable_Poly7Reflected[256]; +#else +const uint8_t tmcCRCTable_Poly7Reflected[256] = { + 0x00, 0x91, 0xE3, 0x72, 0x07, 0x96, 0xE4, 0x75, 0x0E, 0x9F, 0xED, 0x7C, 0x09, 0x98, 0xEA, 0x7B, + 0x1C, 0x8D, 0xFF, 0x6E, 0x1B, 0x8A, 0xF8, 0x69, 0x12, 0x83, 0xF1, 0x60, 0x15, 0x84, 0xF6, 0x67, + 0x38, 0xA9, 0xDB, 0x4A, 0x3F, 0xAE, 0xDC, 0x4D, 0x36, 0xA7, 0xD5, 0x44, 0x31, 0xA0, 0xD2, 0x43, + 0x24, 0xB5, 0xC7, 0x56, 0x23, 0xB2, 0xC0, 0x51, 0x2A, 0xBB, 0xC9, 0x58, 0x2D, 0xBC, 0xCE, 0x5F, + 0x70, 0xE1, 0x93, 0x02, 0x77, 0xE6, 0x94, 0x05, 0x7E, 0xEF, 0x9D, 0x0C, 0x79, 0xE8, 0x9A, 0x0B, + 0x6C, 0xFD, 0x8F, 0x1E, 0x6B, 0xFA, 0x88, 0x19, 0x62, 0xF3, 0x81, 0x10, 0x65, 0xF4, 0x86, 0x17, + 0x48, 0xD9, 0xAB, 0x3A, 0x4F, 0xDE, 0xAC, 0x3D, 0x46, 0xD7, 0xA5, 0x34, 0x41, 0xD0, 0xA2, 0x33, + 0x54, 0xC5, 0xB7, 0x26, 0x53, 0xC2, 0xB0, 0x21, 0x5A, 0xCB, 0xB9, 0x28, 0x5D, 0xCC, 0xBE, 0x2F, + 0xE0, 0x71, 0x03, 0x92, 0xE7, 0x76, 0x04, 0x95, 0xEE, 0x7F, 0x0D, 0x9C, 0xE9, 0x78, 0x0A, 0x9B, + 0xFC, 0x6D, 0x1F, 0x8E, 0xFB, 0x6A, 0x18, 0x89, 0xF2, 0x63, 0x11, 0x80, 0xF5, 0x64, 0x16, 0x87, + 0xD8, 0x49, 0x3B, 0xAA, 0xDF, 0x4E, 0x3C, 0xAD, 0xD6, 0x47, 0x35, 0xA4, 0xD1, 0x40, 0x32, 0xA3, + 0xC4, 0x55, 0x27, 0xB6, 0xC3, 0x52, 0x20, 0xB1, 0xCA, 0x5B, 0x29, 0xB8, 0xCD, 0x5C, 0x2E, 0xBF, + 0x90, 0x01, 0x73, 0xE2, 0x97, 0x06, 0x74, 0xE5, 0x9E, 0x0F, 0x7D, 0xEC, 0x99, 0x08, 0x7A, 0xEB, + 0x8C, 0x1D, 0x6F, 0xFE, 0x8B, 0x1A, 0x68, 0xF9, 0x82, 0x13, 0x61, 0xF0, 0x85, 0x14, 0x66, 0xF7, + 0xA8, 0x39, 0x4B, 0xDA, 0xAF, 0x3E, 0x4C, 0xDD, 0xA6, 0x37, 0x45, 0xD4, 0xA1, 0x30, 0x42, 0xD3, + 0xB4, 0x25, 0x57, 0xC6, 0xB3, 0x22, 0x50, 0xC1, 0xBA, 0x2B, 0x59, 0xC8, 0xBD, 0x2C, 0x5E, 0xCF, +}; +#endif + +/**************************************************************** Cache Implementation *************************************************************************/ + +#if TMC2224_CACHE == 0 +static inline bool tmc2224_cache(uint16_t icID, TMC2224CacheOp operation, uint8_t address, uint32_t *value) +{ + UNUSED(icID); + UNUSED(address); + UNUSED(operation); + return false; +} +#else +#if TMC2224_ENABLE_TMC_CACHE == 1 +uint8_t tmc2224_dirtyBits[TMC2224_IC_CACHE_COUNT][TMC2224_REGISTER_COUNT/8]= {0}; +int32_t tmc2224_shadowRegister[TMC2224_IC_CACHE_COUNT][TMC2224_REGISTER_COUNT]; + +void tmc2224_setDirtyBit(uint16_t icID, uint8_t index, bool value) +{ + if(index >= TMC2224_REGISTER_COUNT) + return; + + uint8_t *tmp = &tmc2224_dirtyBits[icID][index / 8]; + uint8_t shift = (index % 8); + uint8_t mask = 1 << shift; + *tmp = (((*tmp) & (~(mask))) | (((value) << (shift)) & (mask))); +} + +bool tmc2224_getDirtyBit(uint16_t icID, uint8_t index) +{ + if(index >= TMC2224_REGISTER_COUNT) + return false; + + uint8_t *tmp = &tmc2224_dirtyBits[icID][index / 8]; + uint8_t shift = (index % 8); + return ((*tmp) >> shift) & 1; +} + +/* + * This function is used to cache the value written to the Write-Only registers in the form of shadow array. + * The shadow copy is then used to read these kinds of registers. + */ +bool tmc2224_cache(uint16_t icID, TMC2224CacheOp operation, uint8_t address, uint32_t *value) +{ + if (operation == TMC2224_CACHE_READ) + { + // Check if the value should come from cache + + // Only supported chips have a cache + if (icID >= TMC2224_IC_CACHE_COUNT) + return false; + + // Only non-readable registers care about caching + // Note: This could also be used to cache i.e. RW config registers to reduce bus accesses + if (TMC2224_IS_READABLE(tmc2224_registerAccess[address])) + return false; + + // Grab the value from the cache + *value = tmc2224_shadowRegister[icID][address]; + return true; + } + else if (operation == TMC2224_CACHE_WRITE || operation == TMC2224_CACHE_FILL_DEFAULT) + { + // Fill the cache + + // only supported chips have a cache + if (icID >= TMC2224_IC_CACHE_COUNT) + return false; + + // Write to the shadow register and mark the register dirty + tmc2224_shadowRegister[icID][address] = *value; + if (operation == TMC2224_CACHE_WRITE) + { + tmc2224_setDirtyBit(icID, address, true); + } + return true; + } + return false; +} +#else +// User must implement their own cache +extern bool tmc2224_cache(uint16_t icID, TMC2224CacheOp operation, uint8_t address, uint32_t *value); +#endif +#endif + +/************************************************************** Register read / write Implementation ******************************************************************/ + +static int32_t readRegisterUART(uint16_t icID, uint8_t address); +static void writeRegisterUART(uint16_t icID ,uint8_t address, int32_t value); +static uint8_t CRC8(uint8_t *data, uint32_t bytes); + + +void tmc2224_writeRegister(uint16_t icID, uint8_t address, int32_t value) +{ + writeRegisterUART(icID, (uint8_t) address, value); +} + +int32_t tmc2224_readRegister(uint16_t icID, uint8_t address) +{ + uint32_t value; + + // Read from cache for registers with write-only access + if (tmc2224_cache(icID, TMC2224_CACHE_READ, address, &value)) + return value; + + return readRegisterUART(icID, (uint8_t) address); +} + +int32_t readRegisterUART(uint16_t icID, uint8_t address) +{ + uint8_t data[8] = { 0 }; + + address = address & TMC2224_ADDRESS_MASK; + data[0] = 0x05; + data[1] = tmc2224_getNodeAddress(icID); //targetAddressUart; + data[2] = address; + data[3] = CRC8(data, 3); + + if (!tmc2224_readWriteUART(icID, &data[0], 4, 8)) + return 0; + + // Byte 0: Sync nibble correct? + if (data[0] != 0x05) + return 0; + + // Byte 1: Master address correct? + if (data[1] != 0xFF) + return 0; + + // Byte 2: Address correct? + if (data[2] != address) + return 0; + + // Byte 7: CRC correct? + if (data[7] != CRC8(data, 7)) + return 0; + + return ((uint32_t)data[3] << 24) | ((uint32_t)data[4] << 16) | ((uint32_t)data[5] << 8) | data[6]; +} + +void writeRegisterUART(uint16_t icID, uint8_t address, int32_t value) +{ + uint8_t data[8]; + + data[0] = 0x05; + data[1] = (uint8_t)tmc2224_getNodeAddress(icID); //targetAddressUart; + data[2] = address | TMC2224_WRITE_BIT; + data[3] = (value >> 24) & 0xFF; + data[4] = (value >> 16) & 0xFF; + data[5] = (value >> 8 ) & 0xFF; + data[6] = (value ) & 0xFF; + data[7] = CRC8(data, 7); + + tmc2224_readWriteUART(icID, &data[0], 8, 0); + + //Cache the registers with write-only access + tmc2224_cache(icID, TMC2224_CACHE_WRITE, address, (uint32_t *)&value); +} + +static uint8_t CRC8(uint8_t *data, uint32_t bytes) +{ + uint8_t result = 0; + + while(bytes--) + result = tmcCRCTable_Poly7Reflected[result ^ *data++]; + + // Flip the result around + // swap odd and even bits + result = ((result >> 1) & 0x55) | ((result & 0x55) << 1); + // swap consecutive pairs + result = ((result >> 2) & 0x33) | ((result & 0x33) << 2); + // swap nibbles ... + result = ((result >> 4) & 0x0F) | ((result & 0x0F) << 4); + + return result; +} + diff --git a/firmware/lib/tmc/ic/TMC2224/TMC2224.h b/firmware/lib/tmc/ic/TMC2224/TMC2224.h new file mode 100755 index 0000000..0bc793c --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2224/TMC2224.h @@ -0,0 +1,176 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#ifndef TMC_IC_TMC2224_H_ +#define TMC_IC_TMC2224_H_ + +#include +#include +#include +#include "TMC2224_HW_Abstraction.h" + +/******************************************************************************* +* API Configuration Defines +* These control optional features of the TMC-API implementation. +* These can be commented in/out here or defined from the build system. +*******************************************************************************/ + +// Uncomment if you want to save space..... +// and put the table into your own .c file +//#define TMC_API_EXTERNAL_CRC_TABLE 1 + +#ifndef TMC2224_CACHE +#define TMC2224_CACHE 1 +//#define TMC2224_CACHE 0 +#endif + +// To use the caching mechanism already implemented by the TMC-API, set TMC2224_ENABLE_TMC_CACHE to '1'. +// Set TMC2224_ENABLE_TMC_CACHE to '0' if one wants to have their own cache implementation. +#ifndef TMC2224_ENABLE_TMC_CACHE +#define TMC2224_ENABLE_TMC_CACHE 1 +//#define TMC2224_ENABLE_TMC_CACHE 0 +#endif + +/******************************************************************************/ + +// => TMC-API wrapper +extern bool tmc2224_readWriteUART(uint16_t icID, uint8_t *data, size_t writeLength, size_t readLength); +extern uint8_t tmc2224_getNodeAddress(uint16_t icID); +// => TMC-API wrapper + +int32_t tmc2224_readRegister(uint16_t icID, uint8_t address); +void tmc2224_writeRegister(uint16_t icID, uint8_t address, int32_t value); + +typedef struct +{ + uint32_t mask; + uint8_t shift; + uint8_t address; + bool isSigned; +} RegisterField; + +static inline uint32_t tmc2224_fieldExtract(uint32_t data, RegisterField field) +{ + uint32_t value = (data & field.mask) >> field.shift; + + if (field.isSigned) + { + // Apply signedness conversion + uint32_t baseMask = field.mask >> field.shift; + uint32_t signMask = baseMask & (~baseMask >> 1); + value = (value ^ signMask) - signMask; + } + + return value; +} + +static inline uint32_t tmc2224_fieldRead(uint16_t icID, RegisterField field) +{ + uint32_t value = tmc2224_readRegister(icID, field.address); + + return tmc2224_fieldExtract(value, field); +} + +static inline uint32_t tmc2224_fieldUpdate(uint32_t data, RegisterField field, uint32_t value) +{ + return (data & (~field.mask)) | ((value << field.shift) & field.mask); +} + +static inline void tmc2224_fieldWrite(uint16_t icID, RegisterField field, uint32_t value) +{ + uint32_t regValue = tmc2224_readRegister(icID, field.address); + + regValue = tmc2224_fieldUpdate(regValue, field, value); + + tmc2224_writeRegister(icID, field.address, regValue); +} + +/**************************************************************** Cache Implementation *************************************************************************/ + +#if TMC2224_CACHE == 1 +#if TMC2224_ENABLE_TMC_CACHE == 1 + +// By default, support one IC in the cache +#ifndef TMC2224_IC_CACHE_COUNT +#define TMC2224_IC_CACHE_COUNT 1 +#endif + +typedef enum { + TMC2224_CACHE_READ, + TMC2224_CACHE_WRITE, + + // Special operation: Put content into the cache without marking the entry as dirty. + // Only used to initialize the cache with hardware defaults. This will allow reading + // from write-only registers that have a value inside them on reset. When using this + // operation, a restore will *not* rewrite that filled register! + TMC2224_CACHE_FILL_DEFAULT + +} TMC2224CacheOp; + +#define TMC2224_ACCESS_DIRTY 0x08 // Register has been written since reset -> shadow register is valid for restore +#define TMC2224_ACCESS_READ 0x01 +#define TMC2224_IS_READABLE(x) ((x) & TMC2224_ACCESS_READ) +#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) + +// Default Register values +#define R00 0x00000141 // GCONF +#define R10 0x00001F00 // IHOLD_IRUN +#define R11 0x00000014 // TPOWERDOWN +#define R6C 0x10000053 // CHOPCONF +#define R70 0xC10D0024 // PWMCONF + +/* Register access permissions: + * 0: none (reserved) + * 1: read + * 2: write + * 3: read/write + * 7: read^write (separate functions/values) + */ +static const uint8_t tmc2224_registerAccess[TMC2224_REGISTER_COUNT] = +{ +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 3, 3, 1, 2, 2, 1, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, // 0x00 - 0x0F + 2, 2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x10 - 0x1F + 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x20 - 0x2F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x30 - 0x3F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x40 - 0x4F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x50 - 0x5F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 3, 0, 0, 1, // 0x60 - 0x6F + 3, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // 0x70 - 0x7F +}; + +static const int32_t tmc2224_sampleRegisterPreset[TMC2224_REGISTER_COUNT] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + R00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x00 - 0x0F + R10, R11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x10 - 0x1F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x20 - 0x2F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x30 - 0x3F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x40 - 0x4F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x50 - 0x5F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, R6C, 0, 0, 0, // 0x60 - 0x6F + R70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // 0x70 - 0x7F +}; + +// Undefine the default register values. +// This prevents warnings in case multiple TMC-API chip headers are included at once +#undef R00 +#undef R10 +#undef R11 +#undef R6C +#undef R70 + +extern uint8_t tmc2224_dirtyBits[TMC2224_IC_CACHE_COUNT][TMC2224_REGISTER_COUNT/8]; +extern int32_t tmc2224_shadowRegister[TMC2224_IC_CACHE_COUNT][TMC2224_REGISTER_COUNT]; +void tmc2224_setDirtyBit(uint16_t icID, uint8_t index, bool value); +bool tmc2224_getDirtyBit(uint16_t icID, uint8_t index); +extern bool tmc2224_cache(uint16_t icID, TMC2224CacheOp operation, uint8_t address, uint32_t *value); +#endif +#endif + +#endif /* TMC_IC_TMC2224_H_ */ diff --git a/firmware/lib/tmc/ic/TMC2224/TMC2224_HW_Abstraction.h b/firmware/lib/tmc/ic/TMC2224/TMC2224_HW_Abstraction.h new file mode 100755 index 0000000..10792ec --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2224/TMC2224_HW_Abstraction.h @@ -0,0 +1,289 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#ifndef TMC2224_HW_ABSTRACTION +#define TMC2224_HW_ABSTRACTION + + +//constants + +#define TMC2224_MOTORS 1 +#define TMC2224_REGISTER_COUNT 128 +#define TMC2224_WRITE_BIT 0x80 +#define TMC2224_ADDRESS_MASK 0x7F +#define TMC2224_MAX_VELOCITY (int32_t) 2147483647 +#define TMC2224_MAX_ACCELERATION (int32_t) -2147483648 + +// ===== TMC2208 & 2202 & TMC2224 & 2220 & 2225 "Donkey Kong" family register set ===== + +#define TMC2224_GCONF 0x00 +#define TMC2224_GSTAT 0x01 +#define TMC2224_IFCNT 0x02 +#define TMC2224_SLAVECONF 0x03 +#define TMC2224_OTP_PROG 0x04 +#define TMC2224_OTP_READ 0x05 +#define TMC2224_IOIN 0x06 +#define TMC2224_FACTORY_CONF 0x07 + +#define TMC2224_IHOLD_IRUN 0x10 +#define TMC2224_TPOWERDOWN 0x11 +#define TMC2224_TSTEP 0x12 +#define TMC2224_TPWMTHRS 0x13 + +#define TMC2224_VACTUAL 0x22 + +#define TMC2224_MSCNT 0x6A +#define TMC2224_MSCURACT 0x6B +#define TMC2224_CHOPCONF 0x6C +#define TMC2224_DRVSTATUS 0x6F +#define TMC2224_PWMCONF 0x70 +#define TMC2224_PWM_SCALE 0x71 +#define TMC2224_PWM_AUTO 0x72 + +// FIELDS +#define TMC2224_I_SCALE_ANALOG_MASK 0x00000001 +#define TMC2224_I_SCALE_ANALOG_SHIFT 0 +#define TMC2224_I_SCALE_ANALOG_FIELD ((RegisterField) {TMC2224_I_SCALE_ANALOG_MASK, TMC2224_I_SCALE_ANALOG_SHIFT, TMC2224_GCONF, false}) +#define TMC2224_INTERNAL_RSENSE_MASK 0x00000002 +#define TMC2224_INTERNAL_RSENSE_SHIFT 1 +#define TMC2224_INTERNAL_RSENSE_FIELD ((RegisterField) {TMC2224_INTERNAL_RSENSE_MASK, TMC2224_INTERNAL_RSENSE_SHIFT, TMC2224_GCONF, false}) +#define TMC2224_EN_SPREADCYCLE_MASK 0x00000004 +#define TMC2224_EN_SPREADCYCLE_SHIFT 2 +#define TMC2224_EN_SPREADCYCLE_FIELD ((RegisterField) {TMC2224_EN_SPREADCYCLE_MASK, TMC2224_EN_SPREADCYCLE_SHIFT, TMC2224_GCONF, false}) +#define TMC2224_SHAFT_MASK 0x00000008 +#define TMC2224_SHAFT_SHIFT 3 +#define TMC2224_SHAFT_FIELD ((RegisterField) {TMC2224_SHAFT_MASK, TMC2224_SHAFT_SHIFT, TMC2224_GCONF, false}) +#define TMC2224_INDEX_OTPW_MASK 0x00000010 +#define TMC2224_INDEX_OTPW_SHIFT 4 +#define TMC2224_INDEX_OTPW_FIELD ((RegisterField) {TMC2224_INDEX_OTPW_MASK, TMC2224_INDEX_OTPW_SHIFT, TMC2224_GCONF, false}) +#define TMC2224_INDEX_STEP_MASK 0x00000020 +#define TMC2224_INDEX_STEP_SHIFT 5 +#define TMC2224_INDEX_STEP_FIELD ((RegisterField) {TMC2224_INDEX_STEP_MASK, TMC2224_INDEX_STEP_SHIFT, TMC2224_GCONF, false}) +#define TMC2224_PDN_DISABLE_MASK 0x00000040 +#define TMC2224_PDN_DISABLE_SHIFT 6 +#define TMC2224_PDN_DISABLE_FIELD ((RegisterField) {TMC2224_PDN_DISABLE_MASK, TMC2224_PDN_DISABLE_SHIFT, TMC2224_GCONF, false}) +#define TMC2224_MSTEP_REG_SELECT_MASK 0x00000080 +#define TMC2224_MSTEP_REG_SELECT_SHIFT 7 +#define TMC2224_MSTEP_REG_SELECT_FIELD ((RegisterField) {TMC2224_MSTEP_REG_SELECT_MASK, TMC2224_MSTEP_REG_SELECT_SHIFT, TMC2224_GCONF, false}) +#define TMC2224_MULTISTEP_FILT_MASK 0x00000100 +#define TMC2224_MULTISTEP_FILT_SHIFT 8 +#define TMC2224_MULTISTEP_FILT_FIELD ((RegisterField) {TMC2224_MULTISTEP_FILT_MASK, TMC2224_MULTISTEP_FILT_SHIFT, TMC2224_GCONF, false}) +#define TMC2224_TEST_MODE_MASK 0x00000200 +#define TMC2224_TEST_MODE_SHIFT 9 +#define TMC2224_TEST_MODE_FIELD ((RegisterField) {TMC2224_TEST_MODE_MASK, TMC2224_TEST_MODE_SHIFT, TMC2224_GCONF, false}) +#define TMC2224_RESET_MASK 0x00000001 +#define TMC2224_RESET_SHIFT 0 +#define TMC2224_RESET_FIELD ((RegisterField) {TMC2224_RESET_MASK, TMC2224_RESET_SHIFT, TMC2224_GSTAT, false}) +#define TMC2224_DRV_ERR_MASK 0x00000002 +#define TMC2224_DRV_ERR_SHIFT 1 +#define TMC2224_DRV_ERR_FIELD ((RegisterField) {TMC2224_DRV_ERR_MASK, TMC2224_DRV_ERR_SHIFT, TMC2224_GSTAT, false}) +#define TMC2224_UV_CP_MASK 0x00000004 +#define TMC2224_UV_CP_SHIFT 2 +#define TMC2224_UV_CP_FIELD ((RegisterField) {TMC2224_UV_CP_MASK, TMC2224_UV_CP_SHIFT, TMC2224_GSTAT, false}) +#define TMC2224_IFCNT_MASK 0x000000FF +#define TMC2224_IFCNT_SHIFT 0 +#define TMC2224_IFCNT_FIELD ((RegisterField) {TMC2224_IFCNT_MASK, TMC2224_IFCNT_SHIFT, TMC2224_IFCNT, false}) +#define TMC2224_SLAVECONF_MASK 0x00000F00 +#define TMC2224_SLAVECONF_SHIFT 8 +#define TMC2224_SLAVECONF_FIELD ((RegisterField) {TMC2224_SLAVECONF_MASK, TMC2224_SLAVECONF_SHIFT, TMC2224_SLAVECONF, false}) +#define TMC2224_OTPBIT_MASK 0x00000007 +#define TMC2224_OTPBIT_SHIFT 0 +#define TMC2224_OTPBIT_FIELD ((RegisterField) {TMC2224_OTPBIT_MASK, TMC2224_OTPBIT_SHIFT, TMC2224_OTP_PROG, false}) +#define TMC2224_OTPBYTE_MASK 0x00000030 +#define TMC2224_OTPBYTE_SHIFT 4 +#define TMC2224_OTPBYTE_FIELD ((RegisterField) {TMC2224_OTPBYTE_MASK, TMC2224_OTPBYTE_SHIFT, TMC2224_OTP_PROG, false}) +#define TMC2224_OTPMAGIC_MASK 0x0000FF00 +#define TMC2224_OTPMAGIC_SHIFT 8 +#define TMC2224_OTPMAGIC_FIELD ((RegisterField) {TMC2224_OTPMAGIC_MASK, TMC2224_OTPMAGIC_SHIFT, TMC2224_OTP_PROG, false}) +#define TMC2224_OTP0_BYTE_0_READ_DATA_MASK 0x000000FF +#define TMC2224_OTP0_BYTE_0_READ_DATA_SHIFT 0 +#define TMC2224_OTP0_BYTE_0_READ_DATA_FIELD ((RegisterField) {TMC2224_OTP0_BYTE_0_READ_DATA_MASK, TMC2224_OTP0_BYTE_0_READ_DATA_SHIFT, TMC2224_OTP_READ, false}) +#define TMC2224_OTP1_BYTE_1_READ_DATA_MASK 0x0000FF00 +#define TMC2224_OTP1_BYTE_1_READ_DATA_SHIFT 8 +#define TMC2224_OTP1_BYTE_1_READ_DATA_FIELD ((RegisterField) {TMC2224_OTP1_BYTE_1_READ_DATA_MASK, TMC2224_OTP1_BYTE_1_READ_DATA_SHIFT, TMC2224_OTP_READ, false}) +#define TMC2224_OTP2_BYTE_2_READ_DATA_MASK 0x00FF0000 +#define TMC2224_OTP2_BYTE_2_READ_DATA_SHIFT 16 +#define TMC2224_OTP2_BYTE_2_READ_DATA_FIELD ((RegisterField) {TMC2224_OTP2_BYTE_2_READ_DATA_MASK, TMC2224_OTP2_BYTE_2_READ_DATA_SHIFT, TMC2224_OTP_READ, false}) +#define TMC2224_PDN_UART_MASK 0x00000002 +#define TMC2224_PDN_UART_SHIFT 1 +#define TMC2224_PDN_UART_FIELD ((RegisterField) {TMC2224_PDN_UART_MASK, TMC2224_PDN_UART_SHIFT, TMC2224_IOIN, false}) +#define TMC2224_SPREAD_MASK 0x00000004 +#define TMC2224_SPREAD_SHIFT 2 +#define TMC2224_SPREAD_FIELD ((RegisterField) {TMC2224_SPREAD_MASK, TMC2224_SPREAD_SHIFT, TMC2224_IOIN, false}) +#define TMC2224_DIR_MASK 0x00000008 +#define TMC2224_DIR_SHIFT 3 +#define TMC2224_DIR_FIELD ((RegisterField) {TMC2224_DIR_MASK, TMC2224_DIR_SHIFT, TMC2224_IOIN, false}) +#define TMC2224_ENN_MASK 0x00000010 +#define TMC2224_ENN_SHIFT 4 +#define TMC2224_ENN_FIELD ((RegisterField) {TMC2224_ENN_MASK, TMC2224_ENN_SHIFT, TMC2224_IOIN, false}) +#define TMC2224_STEP_MASK 0x00000020 +#define TMC2224_STEP_SHIFT 5 +#define TMC2224_STEP_FIELD ((RegisterField) {TMC2224_STEP_MASK, TMC2224_STEP_SHIFT, TMC2224_IOIN, false}) +#define TMC2224_MS1_MASK 0x00000040 +#define TMC2224_MS1_SHIFT 6 +#define TMC2224_MS1_FIELD ((RegisterField) {TMC2224_MS1_MASK, TMC2224_MS1_SHIFT, TMC2224_IOIN, false}) +#define TMC2224_MS2_MASK 0x00000080 +#define TMC2224_MS2_SHIFT 7 +#define TMC2224_MS2_FIELD ((RegisterField) {TMC2224_MS2_MASK, TMC2224_MS2_SHIFT, TMC2224_IOIN, false}) +#define TMC2224_SEL_A_MASK 0x00000100 +#define TMC2224_SEL_A_SHIFT 8 +#define TMC2224_SEL_A_FIELD ((RegisterField) {TMC2224_SEL_A_MASK, TMC2224_SEL_A_SHIFT, TMC2224_IOIN, false}) +#define TMC2224_VERSION_MASK 0xFF000000 +#define TMC2224_VERSION_SHIFT 24 +#define TMC2224_VERSION_FIELD ((RegisterField) {TMC2224_VERSION_MASK, TMC2224_VERSION_SHIFT, TMC2224_IOIN, false}) +#define TMC2224_FCLKTRIM_MASK 0x0000001F +#define TMC2224_FCLKTRIM_SHIFT 0 +#define TMC2224_FCLKTRIM_FIELD ((RegisterField) {TMC2224_FCLKTRIM_MASK, TMC2224_FCLKTRIM_SHIFT, TMC2224_FACTORY_CONF, false}) +#define TMC2224_OTTRIM_MASK 0x00000300 +#define TMC2224_OTTRIM_SHIFT 8 +#define TMC2224_OTTRIM_FIELD ((RegisterField) {TMC2224_OTTRIM_MASK, TMC2224_OTTRIM_SHIFT, TMC2224_FACTORY_CONF, false}) +#define TMC2224_IHOLD_MASK 0x0000001F +#define TMC2224_IHOLD_SHIFT 0 +#define TMC2224_IHOLD_FIELD ((RegisterField) {TMC2224_IHOLD_MASK, TMC2224_IHOLD_SHIFT, TMC2224_IHOLD_IRUN, false}) +#define TMC2224_IRUN_MASK 0x00001F00 +#define TMC2224_IRUN_SHIFT 8 +#define TMC2224_IRUN_FIELD ((RegisterField) {TMC2224_IRUN_MASK, TMC2224_IRUN_SHIFT, TMC2224_IHOLD_IRUN, false}) +#define TMC2224_IHOLDDELAY_MASK 0x000F0000 +#define TMC2224_IHOLDDELAY_SHIFT 16 +#define TMC2224_IHOLDDELAY_FIELD ((RegisterField) {TMC2224_IHOLDDELAY_MASK, TMC2224_IHOLDDELAY_SHIFT, TMC2224_IHOLD_IRUN, false}) +#define TMC2224_TPOWERDOWN_MASK 0x000000FF +#define TMC2224_TPOWERDOWN_SHIFT 0 +#define TMC2224_TPOWERDOWN_FIELD ((RegisterField) {TMC2224_TPOWERDOWN_MASK, TMC2224_TPOWERDOWN_SHIFT, TMC2224_TPOWERDOWN, false}) +#define TMC2224_TSTEP_MASK 0x000FFFFF +#define TMC2224_TSTEP_SHIFT 0 +#define TMC2224_TSTEP_FIELD ((RegisterField) {TMC2224_TSTEP_MASK, TMC2224_TSTEP_SHIFT, TMC2224_TSTEP, false}) +#define TMC2224_TPWMTHRS_MASK 0x000FFFFF +#define TMC2224_TPWMTHRS_SHIFT 0 +#define TMC2224_TPWMTHRS_FIELD ((RegisterField) {TMC2224_TPWMTHRS_MASK, TMC2224_TPWMTHRS_SHIFT, TMC2224_TPWMTHRS, false}) +#define TMC2224_VACTUAL_MASK 0x00FFFFFF +#define TMC2224_VACTUAL_SHIFT 0 +#define TMC2224_VACTUAL_FIELD ((RegisterField) {TMC2224_VACTUAL_MASK, TMC2224_VACTUAL_SHIFT, TMC2224_VACTUAL, true}) +#define TMC2224_MSCNT_MASK 0x000003FF +#define TMC2224_MSCNT_SHIFT 0 +#define TMC2224_MSCNT_FIELD ((RegisterField) {TMC2224_MSCNT_MASK, TMC2224_MSCNT_SHIFT, TMC2224_MSCNT, false}) +#define TMC2224_CUR_A_MASK 0x000001FF +#define TMC2224_CUR_A_SHIFT 0 +#define TMC2224_CUR_A_FIELD ((RegisterField) {TMC2224_CUR_A_MASK, TMC2224_CUR_A_SHIFT, TMC2224_MSCURACT, true}) +#define TMC2224_CUR_B_MASK 0x01FF0000 +#define TMC2224_CUR_B_SHIFT 16 +#define TMC2224_CUR_B_FIELD ((RegisterField) {TMC2224_CUR_B_MASK, TMC2224_CUR_B_SHIFT, TMC2224_MSCURACT, true}) +#define TMC2224_TOFF_MASK 0x0000000F +#define TMC2224_TOFF_SHIFT 0 +#define TMC2224_TOFF_FIELD ((RegisterField) {TMC2224_TOFF_MASK, TMC2224_TOFF_SHIFT, TMC2224_CHOPCONF, false}) +#define TMC2224_HSTRT_MASK 0x00000070 +#define TMC2224_HSTRT_SHIFT 4 +#define TMC2224_HSTRT_FIELD ((RegisterField) {TMC2224_HSTRT_MASK, TMC2224_HSTRT_SHIFT, TMC2224_CHOPCONF, false}) +#define TMC2224_HEND_MASK 0x00000780 +#define TMC2224_HEND_SHIFT 7 +#define TMC2224_HEND_FIELD ((RegisterField) {TMC2224_HEND_MASK, TMC2224_HEND_SHIFT, TMC2224_CHOPCONF, false}) +#define TMC2224_TBL_MASK 0x00018000 +#define TMC2224_TBL_SHIFT 15 +#define TMC2224_TBL_FIELD ((RegisterField) {TMC2224_TBL_MASK, TMC2224_TBL_SHIFT, TMC2224_CHOPCONF, false}) +#define TMC2224_VSENSE_MASK 0x00020000 +#define TMC2224_VSENSE_SHIFT 17 +#define TMC2224_VSENSE_FIELD ((RegisterField) {TMC2224_VSENSE_MASK, TMC2224_VSENSE_SHIFT, TMC2224_CHOPCONF, false}) +#define TMC2224_MRES_MASK 0x0F000000 +#define TMC2224_MRES_SHIFT 24 +#define TMC2224_MRES_FIELD ((RegisterField) {TMC2224_MRES_MASK, TMC2224_MRES_SHIFT, TMC2224_CHOPCONF, false}) +#define TMC2224_INTPOL_MASK 0x10000000 +#define TMC2224_INTPOL_SHIFT 28 +#define TMC2224_INTPOL_FIELD ((RegisterField) {TMC2224_INTPOL_MASK, TMC2224_INTPOL_SHIFT, TMC2224_CHOPCONF, false}) +#define TMC2224_DEDGE_MASK 0x20000000 +#define TMC2224_DEDGE_SHIFT 29 +#define TMC2224_DEDGE_FIELD ((RegisterField) {TMC2224_DEDGE_MASK, TMC2224_DEDGE_SHIFT, TMC2224_CHOPCONF, false}) +#define TMC2224_DISS2G_MASK 0x40000000 +#define TMC2224_DISS2G_SHIFT 30 +#define TMC2224_DISS2G_FIELD ((RegisterField) {TMC2224_DISS2G_MASK, TMC2224_DISS2G_SHIFT, TMC2224_CHOPCONF, false}) +#define TMC2224_DISS2VS_MASK 0x80000000 +#define TMC2224_DISS2VS_SHIFT 31 +#define TMC2224_DISS2VS_FIELD ((RegisterField) {TMC2224_DISS2VS_MASK, TMC2224_DISS2VS_SHIFT, TMC2224_CHOPCONF, false}) +#define TMC2224_OTPW_MASK 0x00000001 +#define TMC2224_OTPW_SHIFT 0 +#define TMC2224_OTPW_FIELD ((RegisterField) {TMC2224_OTPW_MASK, TMC2224_OTPW_SHIFT, TMC2224_DRV_STATUS, false}) +#define TMC2224_OT_MASK 0x00000002 +#define TMC2224_OT_SHIFT 1 +#define TMC2224_OT_FIELD ((RegisterField) {TMC2224_OT_MASK, TMC2224_OT_SHIFT, TMC2224_DRV_STATUS, false}) +#define TMC2224_S2GA_MASK 0x00000004 +#define TMC2224_S2GA_SHIFT 2 +#define TMC2224_S2GA_FIELD ((RegisterField) {TMC2224_S2GA_MASK, TMC2224_S2GA_SHIFT, TMC2224_DRV_STATUS, false}) +#define TMC2224_S2GB_MASK 0x00000008 +#define TMC2224_S2GB_SHIFT 3 +#define TMC2224_S2GB_FIELD ((RegisterField) {TMC2224_S2GB_MASK, TMC2224_S2GB_SHIFT, TMC2224_DRV_STATUS, false}) +#define TMC2224_S2VSA_MASK 0x00000010 +#define TMC2224_S2VSA_SHIFT 4 +#define TMC2224_S2VSA_FIELD ((RegisterField) {TMC2224_S2VSA_MASK, TMC2224_S2VSA_SHIFT, TMC2224_DRV_STATUS, false}) +#define TMC2224_S2VSB_MASK 0x00000020 +#define TMC2224_S2VSB_SHIFT 5 +#define TMC2224_S2VSB_FIELD ((RegisterField) {TMC2224_S2VSB_MASK, TMC2224_S2VSB_SHIFT, TMC2224_DRV_STATUS, false}) +#define TMC2224_OLA_MASK 0x00000040 +#define TMC2224_OLA_SHIFT 6 +#define TMC2224_OLA_FIELD ((RegisterField) {TMC2224_OLA_MASK, TMC2224_OLA_SHIFT, TMC2224_DRV_STATUS, false}) +#define TMC2224_OLB_MASK 0x00000080 +#define TMC2224_OLB_SHIFT 7 +#define TMC2224_OLB_FIELD ((RegisterField) {TMC2224_OLB_MASK, TMC2224_OLB_SHIFT, TMC2224_DRV_STATUS, false}) +#define TMC2224_T120_MASK 0x00000100 +#define TMC2224_T120_SHIFT 8 +#define TMC2224_T120_FIELD ((RegisterField) {TMC2224_T120_MASK, TMC2224_T120_SHIFT, TMC2224_DRV_STATUS, false}) +#define TMC2224_T143_MASK 0x00000200 +#define TMC2224_T143_SHIFT 9 +#define TMC2224_T143_FIELD ((RegisterField) {TMC2224_T143_MASK, TMC2224_T143_SHIFT, TMC2224_DRV_STATUS, false}) +#define TMC2224_T150_MASK 0x00000400 +#define TMC2224_T150_SHIFT 10 +#define TMC2224_T150_FIELD ((RegisterField) {TMC2224_T150_MASK, TMC2224_T150_SHIFT, TMC2224_DRV_STATUS, false}) +#define TMC2224_T157_MASK 0x00000800 +#define TMC2224_T157_SHIFT 11 +#define TMC2224_T157_FIELD ((RegisterField) {TMC2224_T157_MASK, TMC2224_T157_SHIFT, TMC2224_DRV_STATUS, false}) +#define TMC2224_CS_ACTUAL_MASK 0x001F0000 +#define TMC2224_CS_ACTUAL_SHIFT 16 +#define TMC2224_CS_ACTUAL_FIELD ((RegisterField) {TMC2224_CS_ACTUAL_MASK, TMC2224_CS_ACTUAL_SHIFT, TMC2224_DRV_STATUS, false}) +#define TMC2224_STEALTH_MASK 0x40000000 +#define TMC2224_STEALTH_SHIFT 30 +#define TMC2224_STEALTH_FIELD ((RegisterField) {TMC2224_STEALTH_MASK, TMC2224_STEALTH_SHIFT, TMC2224_DRV_STATUS, false}) +#define TMC2224_STST_MASK 0x80000000 +#define TMC2224_STST_SHIFT 31 +#define TMC2224_STST_FIELD ((RegisterField) {TMC2224_STST_MASK, TMC2224_STST_SHIFT, TMC2224_DRV_STATUS, false}) +#define TMC2224_PWM_OFS_MASK 0x000000FF +#define TMC2224_PWM_OFS_SHIFT 0 +#define TMC2224_PWM_OFS_FIELD ((RegisterField) {TMC2224_PWM_OFS_MASK, TMC2224_PWM_OFS_SHIFT, TMC2224_PWMCONF, false}) +#define TMC2224_PWM_GRAD_MASK 0x0000FF00 +#define TMC2224_PWM_GRAD_SHIFT 8 +#define TMC2224_PWM_GRAD_FIELD ((RegisterField) {TMC2224_PWM_GRAD_MASK, TMC2224_PWM_GRAD_SHIFT, TMC2224_PWMCONF, false}) +#define TMC2224_PWM_FREQ_MASK 0x00030000 +#define TMC2224_PWM_FREQ_SHIFT 16 +#define TMC2224_PWM_FREQ_FIELD ((RegisterField) {TMC2224_PWM_FREQ_MASK, TMC2224_PWM_FREQ_SHIFT, TMC2224_PWMCONF, false}) +#define TMC2224_PWM_AUTOSCALE_MASK 0x00040000 +#define TMC2224_PWM_AUTOSCALE_SHIFT 18 +#define TMC2224_PWM_AUTOSCALE_FIELD ((RegisterField) {TMC2224_PWM_AUTOSCALE_MASK, TMC2224_PWM_AUTOSCALE_SHIFT, TMC2224_PWMCONF, false}) +#define TMC2224_PWM_AUTOGRAD_MASK 0x00080000 +#define TMC2224_PWM_AUTOGRAD_SHIFT 19 +#define TMC2224_PWM_AUTOGRAD_FIELD ((RegisterField) {TMC2224_PWM_AUTOGRAD_MASK, TMC2224_PWM_AUTOGRAD_SHIFT, TMC2224_PWMCONF, false}) +#define TMC2224_FREEWHEEL_MASK 0x00300000 +#define TMC2224_FREEWHEEL_SHIFT 20 +#define TMC2224_FREEWHEEL_FIELD ((RegisterField) {TMC2224_FREEWHEEL_MASK, TMC2224_FREEWHEEL_SHIFT, TMC2224_PWMCONF, false}) +#define TMC2224_PWM_REG_MASK 0x0F000000 +#define TMC2224_PWM_REG_SHIFT 24 +#define TMC2224_PWM_REG_FIELD ((RegisterField) {TMC2224_PWM_REG_MASK, TMC2224_PWM_REG_SHIFT, TMC2224_PWMCONF, false}) +#define TMC2224_PWM_LIM_MASK 0xF0000000 +#define TMC2224_PWM_LIM_SHIFT 28 +#define TMC2224_PWM_LIM_FIELD ((RegisterField) {TMC2224_PWM_LIM_MASK, TMC2224_PWM_LIM_SHIFT, TMC2224_PWMCONF, false}) +#define TMC2224_PWM_SCALE_SUM_MASK 0x000000FF +#define TMC2224_PWM_SCALE_SUM_SHIFT 0 +#define TMC2224_PWM_SCALE_SUM_FIELD ((RegisterField) {TMC2224_PWM_SCALE_SUM_MASK, TMC2224_PWM_SCALE_SUM_SHIFT, TMC2224_PWM_SCALE, false}) +#define TMC2224_PWM_SCALE_AUTO_MASK 0x01FF0000 +#define TMC2224_PWM_SCALE_AUTO_SHIFT 16 +#define TMC2224_PWM_SCALE_AUTO_FIELD ((RegisterField) {TMC2224_PWM_SCALE_AUTO_MASK, TMC2224_PWM_SCALE_AUTO_SHIFT, TMC2224_PWM_SCALE, true}) +#define TMC2224_PWM_OFS_AUTO_MASK 0x000000FF +#define TMC2224_PWM_OFS_AUTO_SHIFT 0 +#define TMC2224_PWM_OFS_AUTO_FIELD ((RegisterField) {TMC2224_PWM_OFS_AUTO_MASK, TMC2224_PWM_OFS_AUTO_SHIFT, TMC2224_PWM_AUTO, false}) +#define TMC2224_PWM_GRAD_AUTO_MASK 0x00FF0000 +#define TMC2224_PWM_GRAD_AUTO_SHIFT 16 +#define TMC2224_PWM_GRAD_AUTO_FIELD ((RegisterField) {TMC2224_PWM_GRAD_AUTO_MASK, TMC2224_PWM_GRAD_AUTO_SHIFT, TMC2224_PWM_AUTO, false}) + + +#endif /* TMC2224_HW_ABSTRACTION_H */ diff --git a/firmware/lib/tmc/ic/TMC2224/registercall_hierarchy_flowchart_UART.svg b/firmware/lib/tmc/ic/TMC2224/registercall_hierarchy_flowchart_UART.svg new file mode 100755 index 0000000..425f60a --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2224/registercall_hierarchy_flowchart_UART.svg @@ -0,0 +1,3 @@ + + +

HAL

HAL

APP (Eval)

APP (Eval)

API

API
Read a register
  •  Call tmcXXXX_readRegister function
Read a register...
Returns the register read value
Returns the register read value
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
tmcXXXX.c
tmcXXXX.c
UART.c
UART.c
tmcXXXX_eval.c
tmcXXXX_eval.c

 Implementation of UART_readWrite
  • Sends and receives bytes on the UART bus
Implementation of UART_readWrite...
Returns the raw reply data
Returns the raw reply data

Implementation of tmcXXXX_readWriteUART
  • Takes the array of data to write
  • Calls hardware function UART_readWrite
Implementation of tmcXXXX_readWriteUART...
Passes on the raw reply data to the API
Passes on the raw reply data to the API
Implementation of readRegisterUART
  • Constructs the datagram
  • Calls HAL wrapper function 
Implementation of readRegisterUART...
tmcXXXX_readWriteUART
tmcXXXX_readWriteUART
Parses the reply and returns the register value
Parses the reply and returns the register value
Implementation of tmcXXXX_readRegister 
  • Check which bus is active SPI/UART. (e.g. UART)
  • Calls bus-specific function (e.g. readRegisterUART)
 
Implementation of tmcXXXX_readRegister...
Returns the register read value
Returns the register read value
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC2224/uml-tmc-api.svg b/firmware/lib/tmc/ic/TMC2224/uml-tmc-api.svg new file mode 100755 index 0000000..5a5f8dd --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2224/uml-tmc-api.svg @@ -0,0 +1,3 @@ + + +

TMCXXXX_HW_Abstraction.h



TMCXXXX_HW_Abstraction.h...
// Constants
#define TMCXXXX_MOTORS              
                          
// Register definitions
#define TMCXXXX_GCONF        
                          ⋮
// Register fields definitions
#define TMCXXXX_GCONF_OTPW_FIELD
                     
// Constants...

TMCXXXX.h



TMCXXXX.h...
extern void tmcXXXX_readWriteSPI();
extern void tmcXXXX_readWriteUART();
extern TMCXXXXBusType tmcXXXX_getBusType();
extern uint8_t tmcXXXX_getNodeAddress();
                                  ⋮
tmcXXXX_readRegister();
tmcXXXX_writeRegister();
                                  ⋮
extern void tmcXXXX_readWriteSPI();...

TMCXXXX.c



TMCXXXX.c...
const uint8_t tmcCRCTable_Poly7Reflected[256] = {...};
int32_t tmcXXXX_readRegister(){
/* Call tmcXXXX_getBusType();
 * Based on bus type, call readRegisterSPI/UART() that
 * further calls tmcXXXX_readWriteSPI/UART();
 * For UART it also calls tmcXXXX_getNodeAddress();
                                           ⋮
}
                                           ⋮
const uint8_t tmcCRCTable_Poly7Reflected[256] = {.....
TMC-API
TMC-API

TMCXXXX_Simple_Rotation.h


TMCXXXX_Simple_Rotation.h...
void initAllMotors();
             ⋮
  
void initAllMotors()...

TMCXXXX_Simple_Rotation.c


TMCXXXX_Simple_Rotation.c...
void initAllMotors(){

// Configuring registers to enable motor drivers etc..
tmcXXXX_writeRegister();
                    ⋮
}
                    ⋮
void initAllMotors(){...
Examples
Examples
User Project
User Project

User_Project.h


User_Project.h

User_Project.c








User_Project.c...

void tmcXXXX_readWriteSPI(){
                           ⋮
}
void tmcXXXX_readWriteUART(){
                           ⋮
}
TMCXXXXBusType tmcXXXX_getBusType(){
                           ⋮
}
uint8_t tmcXXXX_getNodeAddress(){
                           ⋮
}

// User Code
                           ⋮
void tmcXXXX_readWriteSPI(){...
#include "TMCXXXX_HW_Abstraction.h"
#include "TMCXXXX.h"
#include "TMCXXXX_Simple_Rotation.h"
                                ⋮
TMCXXXXBusType bus = IC_BUS_SPI/UART;
uint8_t nodeAddress = <nodeAddress>;
                                ⋮
#include "TMCXXXX_HW_Abstraction.h"...
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC2225/README.md b/firmware/lib/tmc/ic/TMC2225/README.md new file mode 100755 index 0000000..29880a8 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2225/README.md @@ -0,0 +1,52 @@ +# TMC2225 + + +## How to use + +To access the TMC2225's registers, the TMC-API offers two functions: **tmc2225_readRegister** and **tmc2225_writeRegister**. +Each of these functions takes in an **icID**, which is used to identify the IC when multiple ICs are connected. This identifier is passed down to the callback functions (see How to Integrate). + +## How to integrate: overview + +1. Include all the files of the TMC-API/ic/tmc/TMC2225 folder into the custom project. +2. Include the TMC2225.h file in the custom source code. +3. Implement the necessary callback functions (see below). +4. (optional): Take a look at the Examples subfolder for ready-made examples of the TMC-API usage. + +## Accessing the TMC2225 via UART +The following diagram depicts how to access the TMC2225 via UART using the TMC-API. + +![screenshot](registercall_hierarchy_flowchart_UART.svg) + +The description of the functions, in the above flowchart, are as follows: +- The functions tmc2225_readRegister and tmc2225_writeRegister are used to read and write the registers respectively. These functions check the current active bus and calls the bus-specific function i.e readRegisterUART or writeRegisterUART. +- These bus specific functions constructs the datagram and further calls the bus specific callback 'tmcXXXX_readWriteUART. +- This callback function further calls the hardware specific read/write function for UART and needs to be implemented externally. + +### How to integrate: Callback functions +To communicate with TMC2225 IC, following callback functions needs to be implemented to access the chip via UART: +1. **tmc2225_readWriteUART()**, which is a HAL wrapper function that provides the necessary hardware access. +2. **tmc2225_getNodeAddress()**, that returns the node/slave address. Node address could be set in NODECONF (0x3) register and the address could be incremented as defined by AD0, AD1 and AD2. (Node address + ADx) must be less than 255. For further details please consult the datasheet of TMC2225. + +### Sharing the CRC table with other TMC-API chips +The TMC2225 UART protocol uses an 8 bit CRC. For calculating this, a table-based algorithm is used. This table (tmcCRCTable_Poly7Reflected[256]) is 256 bytes big and identical across multiple different Trinamic chips (i.e. TMC2209). +If multiple Trinamic chips are being used in the same project, avoiding redundant copies of this table could save memory. It is possible to substitute this CRC table with another CRC table. + +### Option to use the cache logic for Write-Only registers +The chip features write-only registers that are unable to be read, necessitating the creation of a shadow copy to cache their contents. This copy is automatically updated whenever data is written to these registers. This cache logic could be enabled by setting the macro **TMC2225_CACHE** to **'1'** or disabled by setting to **'0'** respectively. If this feature is enabled then there comes another option to use **tmc2225_cache** function, which is already implemeted in the API, by defining **TMC2225_ENABLE_TMC_CACHE** macro to **'1** or one can implement their own function. + +The function **tmc2225_cache** works for both reading from and writing to the shadow array. It first checks whether the register has write-only access and data needs to be read from the shadow copy. On the basis of that, it returns **true** or **false**. The shadowRegisters on the premade cache implementation need to be one per chip. **TMC2225_IC_CACHE_COUNT** is set to '1' by default and is user-overwritable. If multiple chips are being used in the same project, increment its value to the number of chips connected. + +## Further info +### Dependency graph for the ICs with new register R/W mechanism +This graph illustrates the relationships between files within the TMC-API library, highlighting dependencies and identifying the files that are essential for integrating the library into the custom projects. + +![screenshot](uml-tmc-api.svg) + +### Example usage: TMC-Evalsystem +**For a reference usage of the TMC-API**, visit the [TMC-Evalsystem](https://github.com/analogdevicesinc/TMC-EvalSystem) + +## Migration status +The TMC2225 has been reworked to the access system described above. For more infos on the status of this and other ICs, check out the [migration page](https://github.com/analogdevicesinc/TMC-API/issues/53). + + diff --git a/firmware/lib/tmc/ic/TMC2225/TMC2225.c b/firmware/lib/tmc/ic/TMC2225/TMC2225.c new file mode 100755 index 0000000..85da878 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2225/TMC2225.c @@ -0,0 +1,210 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#include "TMC2225.h" + + +#ifdef TMC_API_EXTERNAL_CRC_TABLE +extern const uint8_t tmcCRCTable_Poly7Reflected[256]; +#else +const uint8_t tmcCRCTable_Poly7Reflected[256] = { + 0x00, 0x91, 0xE3, 0x72, 0x07, 0x96, 0xE4, 0x75, 0x0E, 0x9F, 0xED, 0x7C, 0x09, 0x98, 0xEA, 0x7B, + 0x1C, 0x8D, 0xFF, 0x6E, 0x1B, 0x8A, 0xF8, 0x69, 0x12, 0x83, 0xF1, 0x60, 0x15, 0x84, 0xF6, 0x67, + 0x38, 0xA9, 0xDB, 0x4A, 0x3F, 0xAE, 0xDC, 0x4D, 0x36, 0xA7, 0xD5, 0x44, 0x31, 0xA0, 0xD2, 0x43, + 0x24, 0xB5, 0xC7, 0x56, 0x23, 0xB2, 0xC0, 0x51, 0x2A, 0xBB, 0xC9, 0x58, 0x2D, 0xBC, 0xCE, 0x5F, + 0x70, 0xE1, 0x93, 0x02, 0x77, 0xE6, 0x94, 0x05, 0x7E, 0xEF, 0x9D, 0x0C, 0x79, 0xE8, 0x9A, 0x0B, + 0x6C, 0xFD, 0x8F, 0x1E, 0x6B, 0xFA, 0x88, 0x19, 0x62, 0xF3, 0x81, 0x10, 0x65, 0xF4, 0x86, 0x17, + 0x48, 0xD9, 0xAB, 0x3A, 0x4F, 0xDE, 0xAC, 0x3D, 0x46, 0xD7, 0xA5, 0x34, 0x41, 0xD0, 0xA2, 0x33, + 0x54, 0xC5, 0xB7, 0x26, 0x53, 0xC2, 0xB0, 0x21, 0x5A, 0xCB, 0xB9, 0x28, 0x5D, 0xCC, 0xBE, 0x2F, + 0xE0, 0x71, 0x03, 0x92, 0xE7, 0x76, 0x04, 0x95, 0xEE, 0x7F, 0x0D, 0x9C, 0xE9, 0x78, 0x0A, 0x9B, + 0xFC, 0x6D, 0x1F, 0x8E, 0xFB, 0x6A, 0x18, 0x89, 0xF2, 0x63, 0x11, 0x80, 0xF5, 0x64, 0x16, 0x87, + 0xD8, 0x49, 0x3B, 0xAA, 0xDF, 0x4E, 0x3C, 0xAD, 0xD6, 0x47, 0x35, 0xA4, 0xD1, 0x40, 0x32, 0xA3, + 0xC4, 0x55, 0x27, 0xB6, 0xC3, 0x52, 0x20, 0xB1, 0xCA, 0x5B, 0x29, 0xB8, 0xCD, 0x5C, 0x2E, 0xBF, + 0x90, 0x01, 0x73, 0xE2, 0x97, 0x06, 0x74, 0xE5, 0x9E, 0x0F, 0x7D, 0xEC, 0x99, 0x08, 0x7A, 0xEB, + 0x8C, 0x1D, 0x6F, 0xFE, 0x8B, 0x1A, 0x68, 0xF9, 0x82, 0x13, 0x61, 0xF0, 0x85, 0x14, 0x66, 0xF7, + 0xA8, 0x39, 0x4B, 0xDA, 0xAF, 0x3E, 0x4C, 0xDD, 0xA6, 0x37, 0x45, 0xD4, 0xA1, 0x30, 0x42, 0xD3, + 0xB4, 0x25, 0x57, 0xC6, 0xB3, 0x22, 0x50, 0xC1, 0xBA, 0x2B, 0x59, 0xC8, 0xBD, 0x2C, 0x5E, 0xCF, +}; +#endif +/**************************************************************** Cache Implementation *************************************************************************/ +#if TMC2225_CACHE == 0 +static inline bool tmc2225_cache(uint16_t icID, TMC2225CacheOp operation, uint8_t address, uint32_t *value) +{ + UNUSED(icID); + UNUSED(address); + UNUSED(operation); + return false; +} +#else +#if TMC2225_ENABLE_TMC_CACHE == 1 +uint8_t tmc2225_dirtyBits[TMC2225_IC_CACHE_COUNT][TMC2225_REGISTER_COUNT/8]= {0}; +int32_t tmc2225_shadowRegister[TMC2225_IC_CACHE_COUNT][TMC2225_REGISTER_COUNT]; + +void tmc2225_setDirtyBit(uint16_t icID, uint8_t index, bool value) +{ + if(index >= TMC2225_REGISTER_COUNT) + return; + + uint8_t *tmp = &tmc2225_dirtyBits[icID][index / 8]; + uint8_t shift = (index % 8); + uint8_t mask = 1 << shift; + *tmp = (((*tmp) & (~(mask))) | (((value) << (shift)) & (mask))); +} + +bool tmc2225_getDirtyBit(uint16_t icID, uint8_t index) +{ + if(index >= TMC2225_REGISTER_COUNT) + return false; + + uint8_t *tmp = &tmc2225_dirtyBits[icID][index / 8]; + uint8_t shift = (index % 8); + return ((*tmp) >> shift) & 1; + } + +/* + * This function is used to cache the value written to the Write-Only registers in the form of shadow array. + * The shadow copy is then used to read these kinds of registers. + */ +bool tmc2225_cache(uint16_t icID, TMC2225CacheOp operation, uint8_t address, uint32_t *value) +{ + if (operation == TMC2225_CACHE_READ) + { + // Check if the value should come from cache + + // Only supported chips have a cache + if (icID >= TMC2225_IC_CACHE_COUNT) + return false; + + // Only non-readable registers care about caching + // Note: This could also be used to cache i.e. RW config registers to reduce bus accesses + if (TMC2225_IS_READABLE(tmc2225_registerAccess[address])) + return false; + + // Grab the value from the cache + *value = tmc2225_shadowRegister[icID][address]; + return true; + } + else if (operation == TMC2225_CACHE_WRITE || operation == TMC2225_CACHE_FILL_DEFAULT) + { + // Fill the cache + + // only supported chips have a cache + if (icID >= TMC2225_IC_CACHE_COUNT) + return false; + + // Write to the shadow register and mark the register dirty + tmc2225_shadowRegister[icID][address] = *value; + + if (operation == TMC2225_CACHE_WRITE) + { + tmc2225_setDirtyBit(icID, address, true); + } + + return true; + } + return false; +} + +#else +// User must implement their own cache +extern bool tmc2225_cache(uint16_t icID, TMC2225CacheOp operation, uint8_t address, uint32_t *value); +#endif +#endif + +/************************************************************** Register read / write Implementation ******************************************************************/ +static int32_t readRegisterUART(uint16_t icID, uint8_t registerAddress); +static void writeRegisterUART(uint16_t icID, uint8_t registerAddress, int32_t value); +static uint8_t CRC8(uint8_t *data, uint32_t bytes); + + +int32_t tmc2225_readRegister(uint16_t icID, uint8_t address) +{ + uint32_t value; + + // Read from cache for registers with write-only access + if (tmc2225_cache(icID, TMC2225_CACHE_READ, address, &value)) + return value; + + return readRegisterUART(icID, address); + + // ToDo: Error handling +} + +void tmc2225_writeRegister(uint16_t icID, uint8_t address, int32_t value) +{ + writeRegisterUART(icID, address, value); +} + +int32_t readRegisterUART(uint16_t icID, uint8_t registerAddress) +{ + uint8_t data[8] = {0}; + + registerAddress = registerAddress & TMC2225_ADDRESS_MASK; + + data[0] = 0x05; + data[1] = tmc2225_getNodeAddress(icID); + data[2] = registerAddress; + data[3] = CRC8(data, 3); + + if (!tmc2225_readWriteUART(icID, &data[0], 4, 8)) + return 0; + + // Byte 0: Sync nibble correct? + if (data[0] != 0x05) + return 0; + + // Byte 1: Master address correct? + if (data[1] != 0xFF) + return 0; + + // Byte 2: Address correct? + if (data[2] != registerAddress) + return 0; + + // Byte 7: CRC correct? + if (data[7] != CRC8(data, 7)) + return 0; + + return ((uint32_t) data[3] << 24) | ((uint32_t) data[4] << 16) | ((uint32_t) data[5] << 8) | data[6]; +} + +void writeRegisterUART(uint16_t icID, uint8_t registerAddress, int32_t value) +{ + uint8_t data[8]; + + data[0] = 0x05; + data[1] = tmc2225_getNodeAddress(icID); + data[2] = registerAddress | TMC2225_WRITE_BIT; + data[3] = (value >> 24) & 0xFF; + data[4] = (value >> 16) & 0xFF; + data[5] = (value >> 8) & 0xFF; + data[6] = (value) & 0xFF; + data[7] = CRC8(data, 7); + + tmc2225_readWriteUART(icID, &data[0], 8, 0); + + //Cache the registers with write-only access + tmc2225_cache(icID, TMC2225_CACHE_WRITE, registerAddress, (uint32_t *)&value); +} + +static uint8_t CRC8(uint8_t *data, uint32_t bytes) +{ + uint8_t result = 0; + while (bytes--) result = tmcCRCTable_Poly7Reflected[result ^ *data++]; + + // Flip the result around + // swap odd and even bits + result = ((result >> 1) & 0x55) | ((result & 0x55) << 1); + // swap consecutive pairs + result = ((result >> 2) & 0x33) | ((result & 0x33) << 2); + // swap nibbles ... + result = ((result >> 4) & 0x0F) | ((result & 0x0F) << 4); + + return result; +} diff --git a/firmware/lib/tmc/ic/TMC2225/TMC2225.h b/firmware/lib/tmc/ic/TMC2225/TMC2225.h new file mode 100755 index 0000000..b365771 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2225/TMC2225.h @@ -0,0 +1,182 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#ifndef TMC_IC_TMC2225_H_ +#define TMC_IC_TMC2225_H_ + + +#include +#include +#include +#include "TMC2225_HW_Abstraction.h" + +/******************************************************************************* +* API Configuration Defines +* These control optional features of the TMC-API implementation. +* These can be commented in/out here or defined from the build system. +*******************************************************************************/ + +// Uncomment if you want to save space..... +// and put the table into your own .c file +//#define TMC_API_EXTERNAL_CRC_TABLE 1 + +#ifndef TMC2225_CACHE +#define TMC2225_CACHE 1 +//#define TMC2225_CACHE 0 +#endif + +// To use the caching mechanism already implemented by the TMC-API, set TMC2225_ENABLE_TMC_CACHE to '1'. +// Set TMC2225_ENABLE_TMC_CACHE to '0' if one wants to have their own cache implementation. +#ifndef TMC2225_ENABLE_TMC_CACHE +#define TMC2225_ENABLE_TMC_CACHE 1 +//#define TMC2225_ENABLE_TMC_CACHE 0 +#endif + +/******************************************************************************/ + +typedef struct +{ + uint32_t mask; + uint8_t shift; + uint8_t address; + bool isSigned; +} RegisterField; + +// => TMC-API wrapper +extern bool tmc2225_readWriteUART(uint16_t icID, uint8_t *data, size_t writeLength, size_t readLength); +extern uint8_t tmc2225_getNodeAddress(uint16_t icID); +// => TMC-API wrapper + +int32_t tmc2225_readRegister(uint16_t icID, uint8_t address); +void tmc2225_writeRegister(uint16_t icID, uint8_t address, int32_t value); + + +static inline uint32_t tmc2225_fieldExtract(uint32_t data, RegisterField field) +{ + uint32_t value = (data & field.mask) >> field.shift; + + if (field.isSigned) + { + // Apply signedness conversion + uint32_t baseMask = field.mask >> field.shift; + uint32_t signMask = baseMask & (~baseMask >> 1); + value = (value ^ signMask) - signMask; + } + + return value; +} + +static inline uint32_t tmc2225_fieldRead(uint16_t icID, RegisterField field) +{ + uint32_t value = tmc2225_readRegister(icID, field.address); + + return tmc2225_fieldExtract(value, field); +} + +static inline uint32_t tmc2225_fieldUpdate(uint32_t data, RegisterField field, uint32_t value) +{ + return (data & (~field.mask)) | ((value << field.shift) & field.mask); +} + +static inline void tmc2225_fieldWrite(uint16_t icID, RegisterField field, uint32_t value) +{ + uint32_t regValue = tmc2225_readRegister(icID, field.address); + + regValue = tmc2225_fieldUpdate(regValue, field, value); + + tmc2225_writeRegister(icID, field.address, regValue); +} + +/**************************************************************** Cache Implementation *************************************************************************/ + +#if TMC2225_CACHE == 1 +#if TMC2225_ENABLE_TMC_CACHE == 1 + +// By default, support one IC in the cache +#ifndef TMC2225_IC_CACHE_COUNT +#define TMC2225_IC_CACHE_COUNT 1 +#endif + +typedef enum { + TMC2225_CACHE_READ, + TMC2225_CACHE_WRITE, + + // Special operation: Put content into the cache without marking the entry as dirty. + // Only used to initialize the cache with hardware defaults. This will allow reading + // from write-only registers that have a value inside them on reset. When using this + // operation, a restore will *not* rewrite that filled register! + TMC2225_CACHE_FILL_DEFAULT +} TMC2225CacheOp; + +#define TMC2225_ACCESS_DIRTY 0x08 // Register has been written since reset -> shadow register is valid for restore +#define TMC2225_ACCESS_READ 0x01 +#define TMC2225_IS_READABLE(x) ((x) & TMC2225_ACCESS_READ) +#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) +#define ____ 0x00 + +// Default Register values +#define R00 0x000000C1 // GCONF +#define R10 0x00071703 // IHOLD_IRUN +#define R11 0x00000014 // TPOWERDOWN +#define R6C 0x10000053 // CHOPCONF +#define R70 0xC00D0024 // PWMCONF + +// Register access permissions: +// 0x00: none (reserved) +// 0x01: read +// 0x02: write +// 0x03: read/write +// 0x13: read/write, separate functions/values for reading or writing +// 0x21: read, flag register (read to clear) +// 0x42: write, has hardware presets on reset +static const uint8_t tmc2225_registerAccess[TMC2225_REGISTER_COUNT] = +{ +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0x03, 0x23, 0x01, 0x02, 0x02, 0x01, 0x01, 0x03, ____, ____, ____, ____, ____, ____, ____, ____, // 0x00 - 0x0F + 0x02, 0x02, 0x01, 0x02, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x10 - 0x1F + ____, ____, 0x02, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x20 - 0x2F + ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x30 - 0x3F + 0x02, 0x01, 0x02, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x40 - 0x4F + ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x50 - 0x5F + ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, 0x01, 0x01, 0x03, ____, ____, 0x01, // 0x60 - 0x6F + 0x03, 0x01, 0x01, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____ // 0x70 - 0x7F +}; + +static const int32_t tmc2225_sampleRegisterPreset[TMC2225_REGISTER_COUNT] = +{ +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + R00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x00 - 0x0F + R10, R11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x10 - 0x1F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x20 - 0x2F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x30 - 0x3F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x40 - 0x4F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x50 - 0x5F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, R6C, 0, 0, 0, // 0x60 - 0x6F + R70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // 0x70 - 0x7F +}; + +// Undefine the default register values. +// This prevents warnings in case multiple TMC-API chip headers are included at once +#undef R00 +#undef R10 +#undef R11 +#undef R6C +#undef R70 + +extern uint8_t tmc2225_dirtyBits[TMC2225_IC_CACHE_COUNT][TMC2225_REGISTER_COUNT/8]; +extern int32_t tmc2225_shadowRegister[TMC2225_IC_CACHE_COUNT][TMC2225_REGISTER_COUNT]; +void tmc2225_setDirtyBit(uint16_t icID, uint8_t index, bool value); +bool tmc2225_getDirtyBit(uint16_t icID, uint8_t index); +extern bool tmc2225_cache(uint16_t icID, TMC2225CacheOp operation, uint8_t address, uint32_t *value); +#endif +#endif + +/***************************************************************************************************************************************************/ + +#endif /* TMC_IC_TMC2225_H_ */ diff --git a/firmware/lib/tmc/ic/TMC2225/TMC2225_HW_Abstraction.h b/firmware/lib/tmc/ic/TMC2225/TMC2225_HW_Abstraction.h new file mode 100755 index 0000000..9465ed1 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2225/TMC2225_HW_Abstraction.h @@ -0,0 +1,291 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + +#ifndef TMC5272_HW_ABSTRACTION +#define TMC5272_HW_ABSTRACTION + + +// Constants + +#define TMC2225_MOTORS 1 +#define TMC2225_REGISTER_COUNT 128 // Default register count +#define TMC2225_WRITE_BIT 0x80 +#define TMC2225_ADDRESS_MASK 0x7F +#define TMC2225_MAX_VELOCITY (int32_t) 2147483647 +#define TMC2225_MAX_ACCELERATION (uint32_t) 16777215uL + +//Register +// ===== TMC2208 & 2202 & TMC2208 & 2220 & 2225 "Donkey Kong" family register set ===== + +#define TMC2225_GCONF 0x00 +#define TMC2225_GSTAT 0x01 +#define TMC2225_IFCNT 0x02 +#define TMC2225_SLAVECONF 0x03 +#define TMC2225_OTP_PROG 0x04 +#define TMC2225_OTP_READ 0x05 +#define TMC2225_IOIN 0x06 +#define TMC2225_FACTORY_CONF 0x07 + +#define TMC2225_IHOLD_IRUN 0x10 +#define TMC2225_TPOWERDOWN 0x11 +#define TMC2225_TSTEP 0x12 +#define TMC2225_TPWMTHRS 0x13 + +#define TMC2225_VACTUAL 0x22 + +#define TMC2225_MSCNT 0x6A +#define TMC2225_MSCURACT 0x6B +#define TMC2225_CHOPCONF 0x6C +#define TMC2225_DRVSTATUS 0x6F +#define TMC2225_PWMCONF 0x70 +#define TMC2225_PWM_SCALE 0x71 +#define TMC2225_PWM_AUTO 0x72 + + +// Register fields + +#define TMC2225_I_SCALE_ANALOG_MASK 0x00000001 +#define TMC2225_I_SCALE_ANALOG_SHIFT 0 +#define TMC2225_I_SCALE_ANALOG_FIELD ((RegisterField) {TMC2225_I_SCALE_ANALOG_MASK, TMC2225_I_SCALE_ANALOG_SHIFT, TMC2225_GCONF, false}) +#define TMC2225_INTERNAL_RSENSE_MASK 0x00000002 +#define TMC2225_INTERNAL_RSENSE_SHIFT 1 +#define TMC2225_INTERNAL_RSENSE_FIELD ((RegisterField) {TMC2225_INTERNAL_RSENSE_MASK, TMC2225_INTERNAL_RSENSE_SHIFT, TMC2225_GCONF, false}) +#define TMC2225_EN_SPREADCYCLE_MASK 0x00000004 +#define TMC2225_EN_SPREADCYCLE_SHIFT 2 +#define TMC2225_EN_SPREADCYCLE_FIELD ((RegisterField) {TMC2225_EN_SPREADCYCLE_MASK, TMC2225_EN_SPREADCYCLE_SHIFT, TMC2225_GCONF, false}) +#define TMC2225_SHAFT_MASK 0x00000008 +#define TMC2225_SHAFT_SHIFT 3 +#define TMC2225_SHAFT_FIELD ((RegisterField) {TMC2225_SHAFT_MASK, TMC2225_SHAFT_SHIFT, TMC2225_GCONF, false}) +#define TMC2225_INDEX_OTPW_MASK 0x00000010 +#define TMC2225_INDEX_OTPW_SHIFT 4 +#define TMC2225_INDEX_OTPW_FIELD ((RegisterField) {TMC2225_INDEX_OTPW_MASK, TMC2225_INDEX_OTPW_SHIFT, TMC2225_GCONF, false}) +#define TMC2225_INDEX_STEP_MASK 0x00000020 +#define TMC2225_INDEX_STEP_SHIFT 5 +#define TMC2225_INDEX_STEP_FIELD ((RegisterField) {TMC2225_INDEX_STEP_MASK, TMC2225_INDEX_STEP_SHIFT, TMC2225_GCONF, false}) +#define TMC2225_PDN_DISABLE_MASK 0x00000040 +#define TMC2225_PDN_DISABLE_SHIFT 6 +#define TMC2225_PDN_DISABLE_FIELD ((RegisterField) {TMC2225_PDN_DISABLE_MASK, TMC2225_PDN_DISABLE_SHIFT, TMC2225_GCONF, false}) +#define TMC2225_MSTEP_REG_SELECT_MASK 0x00000080 +#define TMC2225_MSTEP_REG_SELECT_SHIFT 7 +#define TMC2225_MSTEP_REG_SELECT_FIELD ((RegisterField) {TMC2225_MSTEP_REG_SELECT_MASK, TMC2225_MSTEP_REG_SELECT_SHIFT, TMC2225_GCONF, false}) +#define TMC2225_MULTISTEP_FILT_MASK 0x00000100 +#define TMC2225_MULTISTEP_FILT_SHIFT 8 +#define TMC2225_MULTISTEP_FILT_FIELD ((RegisterField) {TMC2225_MULTISTEP_FILT_MASK, TMC2225_MULTISTEP_FILT_SHIFT, TMC2225_GCONF, false}) +#define TMC2225_TEST_MODE_MASK 0x00000200 +#define TMC2225_TEST_MODE_SHIFT 9 +#define TMC2225_TEST_MODE_FIELD ((RegisterField) {TMC2225_TEST_MODE_MASK, TMC2225_TEST_MODE_SHIFT, TMC2225_GCONF, false}) +#define TMC2225_RESET_MASK 0x00000001 +#define TMC2225_RESET_SHIFT 0 +#define TMC2225_RESET_FIELD ((RegisterField) {TMC2225_RESET_MASK, TMC2225_RESET_SHIFT, TMC2225_GSTAT, false}) +#define TMC2225_DRV_ERR_MASK 0x00000002 +#define TMC2225_DRV_ERR_SHIFT 1 +#define TMC2225_DRV_ERR_FIELD ((RegisterField) {TMC2225_DRV_ERR_MASK, TMC2225_DRV_ERR_SHIFT, TMC2225_GSTAT, false}) +#define TMC2225_UV_CP_MASK 0x00000004 +#define TMC2225_UV_CP_SHIFT 2 +#define TMC2225_UV_CP_FIELD ((RegisterField) {TMC2225_UV_CP_MASK, TMC2225_UV_CP_SHIFT, TMC2225_GSTAT, false}) +#define TMC2225_IFCNT_MASK 0x000000FF +#define TMC2225_IFCNT_SHIFT 0 +#define TMC2225_IFCNT_FIELD ((RegisterField) {TMC2225_IFCNT_MASK, TMC2225_IFCNT_SHIFT, TMC2225_IFCNT, false}) +#define TMC2225_SLAVECONF_MASK 0x00000F00 +#define TMC2225_SLAVECONF_SHIFT 8 +#define TMC2225_SLAVECONF_FIELD ((RegisterField) {TMC2225_SLAVECONF_MASK, TMC2225_SLAVECONF_SHIFT, TMC2225_SLAVECONF, false}) +#define TMC2225_OTPBIT_MASK 0x00000007 +#define TMC2225_OTPBIT_SHIFT 0 +#define TMC2225_OTPBIT_FIELD ((RegisterField) {TMC2225_OTPBIT_MASK, TMC2225_OTPBIT_SHIFT, TMC2225_OTP_PROG, false}) +#define TMC2225_OTPBYTE_MASK 0x00000030 +#define TMC2225_OTPBYTE_SHIFT 4 +#define TMC2225_OTPBYTE_FIELD ((RegisterField) {TMC2225_OTPBYTE_MASK, TMC2225_OTPBYTE_SHIFT, TMC2225_OTP_PROG, false}) +#define TMC2225_OTPMAGIC_MASK 0x0000FF00 +#define TMC2225_OTPMAGIC_SHIFT 8 +#define TMC2225_OTPMAGIC_FIELD ((RegisterField) {TMC2225_OTPMAGIC_MASK, TMC2225_OTPMAGIC_SHIFT, TMC2225_OTP_PROG, false}) +#define TMC2225_OTP0_BYTE_0_READ_DATA_MASK 0x000000FF +#define TMC2225_OTP0_BYTE_0_READ_DATA_SHIFT 0 +#define TMC2225_OTP0_BYTE_0_READ_DATA_FIELD ((RegisterField) {TMC2225_OTP0_BYTE_0_READ_DATA_MASK, TMC2225_OTP0_BYTE_0_READ_DATA_SHIFT, TMC2225_OTP_READ, false}) +#define TMC2225_OTP1_BYTE_1_READ_DATA_MASK 0x0000FF00 +#define TMC2225_OTP1_BYTE_1_READ_DATA_SHIFT 8 +#define TMC2225_OTP1_BYTE_1_READ_DATA_FIELD ((RegisterField) {TMC2225_OTP1_BYTE_1_READ_DATA_MASK, TMC2225_OTP1_BYTE_1_READ_DATA_SHIFT, TMC2225_OTP_READ, false}) +#define TMC2225_OTP2_BYTE_2_READ_DATA_MASK 0x00FF0000 +#define TMC2225_OTP2_BYTE_2_READ_DATA_SHIFT 16 +#define TMC2225_OTP2_BYTE_2_READ_DATA_FIELD ((RegisterField) {TMC2225_OTP2_BYTE_2_READ_DATA_MASK, TMC2225_OTP2_BYTE_2_READ_DATA_SHIFT, TMC2225_OTP_READ, false}) +#define TMC2225_ENN_MASK 0x00000001 +#define TMC2225_ENN_SHIFT 0 +#define TMC2225_ENN_FIELD ((RegisterField) {TMC2225_ENN_MASK, TMC2225_ENN_SHIFT, TMC2225_IOIN, false}) +#define TMC2225_MS1_MASK 0x00000004 +#define TMC2225_MS1_SHIFT 2 +#define TMC2225_MS1_FIELD ((RegisterField) {TMC2225_MS1_MASK, TMC2225_MS1_SHIFT, TMC2225_IOIN, false}) +#define TMC2225_MS2_MASK 0x00000008 +#define TMC2225_MS2_SHIFT 3 +#define TMC2225_MS2_FIELD ((RegisterField) {TMC2225_MS2_MASK, TMC2225_MS2_SHIFT, TMC2225_IOIN, false}) +#define TMC2225_DIAG_MASK 0x00000010 +#define TMC2225_DIAG_SHIFT 4 +#define TMC2225_DIAG_FIELD ((RegisterField) {TMC2225_DIAG_MASK, TMC2225_DIAG_SHIFT, TMC2225_IOIN, false}) +#define TMC2225_PDN_UART_MASK 0x00000040 +#define TMC2225_PDN_UART_SHIFT 6 +#define TMC2225_PDN_UART_FIELD ((RegisterField) {TMC2225_PDN_UART_MASK, TMC2225_PDN_UART_SHIFT, TMC2225_IOIN, false}) +#define TMC2225_STEP_MASK 0x00000080 +#define TMC2225_STEP_SHIFT 7 +#define TMC2225_STEP_FIELD ((RegisterField) {TMC2225_STEP_MASK, TMC2225_STEP_SHIFT, TMC2225_IOIN, false}) +#define TMC2225_SEL_A_MASK 0x00000100 +#define TMC2225_SEL_A_SHIFT 8 +#define TMC2225_SEL_A_FIELD ((RegisterField) {TMC2225_SEL_A_MASK, TMC2225_SEL_A_SHIFT, TMC2225_IOIN, false}) +#define TMC2225_DIR_MASK 0x00000200 +#define TMC2225_DIR_SHIFT 9 +#define TMC2225_DIR_FIELD ((RegisterField) {TMC2225_DIR_MASK, TMC2225_DIR_SHIFT, TMC2225_IOIN, false}) +#define TMC2225_VERSION_MASK 0xFF000000 +#define TMC2225_VERSION_SHIFT 24 +#define TMC2225_VERSION_FIELD ((RegisterField) {TMC2225_VERSION_MASK, TMC2225_VERSION_SHIFT, TMC2225_IOIN, false}) +#define TMC2225_FCLKTRIM_MASK 0x0000001F +#define TMC2225_FCLKTRIM_SHIFT 0 +#define TMC2225_FCLKTRIM_FIELD ((RegisterField) {TMC2225_FCLKTRIM_MASK, TMC2225_FCLKTRIM_SHIFT, TMC2225_FACTORY_CONF, false}) +#define TMC2225_OTTRIM_MASK 0x00000300 +#define TMC2225_OTTRIM_SHIFT 8 +#define TMC2225_OTTRIM_FIELD ((RegisterField) {TMC2225_OTTRIM_MASK, TMC2225_OTTRIM_SHIFT, TMC2225_FACTORY_CONF, false}) +#define TMC2225_IHOLD_MASK 0x0000001F +#define TMC2225_IHOLD_SHIFT 0 +#define TMC2225_IHOLD_FIELD ((RegisterField) {TMC2225_IHOLD_MASK, TMC2225_IHOLD_SHIFT, TMC2225_IHOLD_IRUN, false}) +#define TMC2225_IRUN_MASK 0x00001F00 +#define TMC2225_IRUN_SHIFT 8 +#define TMC2225_IRUN_FIELD ((RegisterField) {TMC2225_IRUN_MASK, TMC2225_IRUN_SHIFT, TMC2225_IHOLD_IRUN, false}) +#define TMC2225_IHOLDDELAY_MASK 0x000F0000 +#define TMC2225_IHOLDDELAY_SHIFT 16 +#define TMC2225_IHOLDDELAY_FIELD ((RegisterField) {TMC2225_IHOLDDELAY_MASK, TMC2225_IHOLDDELAY_SHIFT, TMC2225_IHOLD_IRUN, false}) +#define TMC2225_TPOWERDOWN_MASK 0x000000FF +#define TMC2225_TPOWERDOWN_SHIFT 0 +#define TMC2225_TPOWERDOWN_FIELD ((RegisterField) {TMC2225_TPOWERDOWN_MASK, TMC2225_TPOWERDOWN_SHIFT, TMC2225_TPOWERDOWN, false}) +#define TMC2225_TSTEP_MASK 0x000FFFFF +#define TMC2225_TSTEP_SHIFT 0 +#define TMC2225_TSTEP_FIELD ((RegisterField) {TMC2225_TSTEP_MASK, TMC2225_TSTEP_SHIFT, TMC2225_TSTEP, false}) +#define TMC2225_TPWMTHRS_MASK 0x000FFFFF +#define TMC2225_TPWMTHRS_SHIFT 0 +#define TMC2225_TPWMTHRS_FIELD ((RegisterField) {TMC2225_TPWMTHRS_MASK, TMC2225_TPWMTHRS_SHIFT, TMC2225_TPWMTHRS, false}) +#define TMC2225_VACTUAL_MASK 0x00FFFFFF +#define TMC2225_VACTUAL_SHIFT 0 +#define TMC2225_VACTUAL_FIELD ((RegisterField) {TMC2225_VACTUAL_MASK, TMC2225_VACTUAL_SHIFT, TMC2225_VACTUAL, true}) +#define TMC2225_MSCNT_MASK 0x000003FF +#define TMC2225_MSCNT_SHIFT 0 +#define TMC2225_MSCNT_FIELD ((RegisterField) {TMC2225_MSCNT_MASK, TMC2225_MSCNT_SHIFT, TMC2225_MSCNT, false}) +#define TMC2225_CUR_A_MASK 0x000001FF +#define TMC2225_CUR_A_SHIFT 0 +#define TMC2225_CUR_A_FIELD ((RegisterField) {TMC2225_CUR_A_MASK, TMC2225_CUR_A_SHIFT, TMC2225_MSCURACT, true}) +#define TMC2225_CUR_B_MASK 0x01FF0000 +#define TMC2225_CUR_B_SHIFT 16 +#define TMC2225_CUR_B_FIELD ((RegisterField) {TMC2225_CUR_B_MASK, TMC2225_CUR_B_SHIFT, TMC2225_MSCURACT, true}) +#define TMC2225_TOFF_MASK 0x0000000F +#define TMC2225_TOFF_SHIFT 0 +#define TMC2225_TOFF_FIELD ((RegisterField) {TMC2225_TOFF_MASK, TMC2225_TOFF_SHIFT, TMC2225_CHOPCONF, false}) +#define TMC2225_HSTRT_MASK 0x00000070 +#define TMC2225_HSTRT_SHIFT 4 +#define TMC2225_HSTRT_FIELD ((RegisterField) {TMC2225_HSTRT_MASK, TMC2225_HSTRT_SHIFT, TMC2225_CHOPCONF, false}) +#define TMC2225_HEND_MASK 0x00000780 +#define TMC2225_HEND_SHIFT 7 +#define TMC2225_HEND_FIELD ((RegisterField) {TMC2225_HEND_MASK, TMC2225_HEND_SHIFT, TMC2225_CHOPCONF, false}) +#define TMC2225_TBL_MASK 0x00018000 +#define TMC2225_TBL_SHIFT 15 +#define TMC2225_TBL_FIELD ((RegisterField) {TMC2225_TBL_MASK, TMC2225_TBL_SHIFT, TMC2225_CHOPCONF, false}) +#define TMC2225_VSENSE_MASK 0x00020000 +#define TMC2225_VSENSE_SHIFT 17 +#define TMC2225_VSENSE_FIELD ((RegisterField) {TMC2225_VSENSE_MASK, TMC2225_VSENSE_SHIFT, TMC2225_CHOPCONF, false}) +#define TMC2225_MRES_MASK 0x0F000000 +#define TMC2225_MRES_SHIFT 24 +#define TMC2225_MRES_FIELD ((RegisterField) {TMC2225_MRES_MASK, TMC2225_MRES_SHIFT, TMC2225_CHOPCONF, false}) +#define TMC2225_INTPOL_MASK 0x10000000 +#define TMC2225_INTPOL_SHIFT 28 +#define TMC2225_INTPOL_FIELD ((RegisterField) {TMC2225_INTPOL_MASK, TMC2225_INTPOL_SHIFT, TMC2225_CHOPCONF, false}) +#define TMC2225_DEDGE_MASK 0x20000000 +#define TMC2225_DEDGE_SHIFT 29 +#define TMC2225_DEDGE_FIELD ((RegisterField) {TMC2225_DEDGE_MASK, TMC2225_DEDGE_SHIFT, TMC2225_CHOPCONF, false}) +#define TMC2225_DISS2G_MASK 0x40000000 +#define TMC2225_DISS2G_SHIFT 30 +#define TMC2225_DISS2G_FIELD ((RegisterField) {TMC2225_DISS2G_MASK, TMC2225_DISS2G_SHIFT, TMC2225_CHOPCONF, false}) +#define TMC2225_DISS2VS_MASK 0x80000000 +#define TMC2225_DISS2VS_SHIFT 31 +#define TMC2225_DISS2VS_FIELD ((RegisterField) {TMC2225_DISS2VS_MASK, TMC2225_DISS2VS_SHIFT, TMC2225_CHOPCONF, false}) +#define TMC2225_OTPW_MASK 0x00000001 +#define TMC2225_OTPW_SHIFT 0 +#define TMC2225_OTPW_FIELD ((RegisterField) {TMC2225_OTPW_MASK, TMC2225_OTPW_SHIFT, TMC2225_DRVSTATUS, false}) +#define TMC2225_OT_MASK 0x00000002 +#define TMC2225_OT_SHIFT 1 +#define TMC2225_OT_FIELD ((RegisterField) {TMC2225_OT_MASK, TMC2225_OT_SHIFT, TMC2225_DRVSTATUS, false}) +#define TMC2225_S2GA_MASK 0x00000004 +#define TMC2225_S2GA_SHIFT 2 +#define TMC2225_S2GA_FIELD ((RegisterField) {TMC2225_S2GA_MASK, TMC2225_S2GA_SHIFT, TMC2225_DRVSTATUS, false}) +#define TMC2225_S2GB_MASK 0x00000008 +#define TMC2225_S2GB_SHIFT 3 +#define TMC2225_S2GB_FIELD ((RegisterField) {TMC2225_S2GB_MASK, TMC2225_S2GB_SHIFT, TMC2225_DRVSTATUS, false}) +#define TMC2225_S2VSA_MASK 0x00000010 +#define TMC2225_S2VSA_SHIFT 4 +#define TMC2225_S2VSA_FIELD ((RegisterField) {TMC2225_S2VSA_MASK, TMC2225_S2VSA_SHIFT, TMC2225_DRVSTATUS, false}) +#define TMC2225_S2VSB_MASK 0x00000020 +#define TMC2225_S2VSB_SHIFT 5 +#define TMC2225_S2VSB_FIELD ((RegisterField) {TMC2225_S2VSB_MASK, TMC2225_S2VSB_SHIFT, TMC2225_DRVSTATUS, false}) +#define TMC2225_OLA_MASK 0x00000040 +#define TMC2225_OLA_SHIFT 6 +#define TMC2225_OLA_FIELD ((RegisterField) {TMC2225_OLA_MASK, TMC2225_OLA_SHIFT, TMC2225_DRVSTATUS, false}) +#define TMC2225_OLB_MASK 0x00000080 +#define TMC2225_OLB_SHIFT 7 +#define TMC2225_OLB_FIELD ((RegisterField) {TMC2225_OLB_MASK, TMC2225_OLB_SHIFT, TMC2225_DRVSTATUS, false}) +#define TMC2225_T120_MASK 0x00000100 +#define TMC2225_T120_SHIFT 8 +#define TMC2225_T120_FIELD ((RegisterField) {TMC2225_T120_MASK, TMC2225_T120_SHIFT, TMC2225_DRVSTATUS, false}) +#define TMC2225_T143_MASK 0x00000200 +#define TMC2225_T143_SHIFT 9 +#define TMC2225_T143_FIELD ((RegisterField) {TMC2225_T143_MASK, TMC2225_T143_SHIFT, TMC2225_DRVSTATUS, false}) +#define TMC2225_T150_MASK 0x00000400 +#define TMC2225_T150_SHIFT 10 +#define TMC2225_T150_FIELD ((RegisterField) {TMC2225_T150_MASK, TMC2225_T150_SHIFT, TMC2225_DRVSTATUS, false}) +#define TMC2225_T157_MASK 0x00000800 +#define TMC2225_T157_SHIFT 11 +#define TMC2225_T157_FIELD ((RegisterField) {TMC2225_T157_MASK, TMC2225_T157_SHIFT, TMC2225_DRVSTATUS, false}) +#define TMC2225_CS_ACTUAL_MASK 0x001F0000 +#define TMC2225_CS_ACTUAL_SHIFT 16 +#define TMC2225_CS_ACTUAL_FIELD ((RegisterField) {TMC2225_CS_ACTUAL_MASK, TMC2225_CS_ACTUAL_SHIFT, TMC2225_DRVSTATUS, false}) +#define TMC2225_STEALTH_MASK 0x40000000 +#define TMC2225_STEALTH_SHIFT 30 +#define TMC2225_STEALTH_FIELD ((RegisterField) {TMC2225_STEALTH_MASK, TMC2225_STEALTH_SHIFT, TMC2225_DRVSTATUS, false}) +#define TMC2225_STST_MASK 0x80000000 +#define TMC2225_STST_SHIFT 31 +#define TMC2225_STST_FIELD ((RegisterField) {TMC2225_STST_MASK, TMC2225_STST_SHIFT, TMC2225_DRVSTATUS, false}) +#define TMC2225_PWM_OFS_MASK 0x000000FF +#define TMC2225_PWM_OFS_SHIFT 0 +#define TMC2225_PWM_OFS_FIELD ((RegisterField) {TMC2225_PWM_OFS_MASK, TMC2225_PWM_OFS_SHIFT, TMC2225_PWMCONF, false}) +#define TMC2225_PWM_GRAD_MASK 0x0000FF00 +#define TMC2225_PWM_GRAD_SHIFT 8 +#define TMC2225_PWM_GRAD_FIELD ((RegisterField) {TMC2225_PWM_GRAD_MASK, TMC2225_PWM_GRAD_SHIFT, TMC2225_PWMCONF, false}) +#define TMC2225_PWM_FREQ_MASK 0x00030000 +#define TMC2225_PWM_FREQ_SHIFT 16 +#define TMC2225_PWM_FREQ_FIELD ((RegisterField) {TMC2225_PWM_FREQ_MASK, TMC2225_PWM_FREQ_SHIFT, TMC2225_PWMCONF, false}) +#define TMC2225_PWM_AUTOSCALE_MASK 0x00040000 +#define TMC2225_PWM_AUTOSCALE_SHIFT 18 +#define TMC2225_PWM_AUTOSCALE_FIELD ((RegisterField) {TMC2225_PWM_AUTOSCALE_MASK, TMC2225_PWM_AUTOSCALE_SHIFT, TMC2225_PWMCONF, false}) +#define TMC2225_PWM_AUTOGRAD_MASK 0x00080000 +#define TMC2225_PWM_AUTOGRAD_SHIFT 19 +#define TMC2225_PWM_AUTOGRAD_FIELD ((RegisterField) {TMC2225_PWM_AUTOGRAD_MASK, TMC2225_PWM_AUTOGRAD_SHIFT, TMC2225_PWMCONF, false}) +#define TMC2225_FREEWHEEL_MASK 0x00300000 +#define TMC2225_FREEWHEEL_SHIFT 20 +#define TMC2225_FREEWHEEL_FIELD ((RegisterField) {TMC2225_FREEWHEEL_MASK, TMC2225_FREEWHEEL_SHIFT, TMC2225_PWMCONF, false}) +#define TMC2225_PWM_REG_MASK 0x0F000000 +#define TMC2225_PWM_REG_SHIFT 24 +#define TMC2225_PWM_REG_FIELD ((RegisterField) {TMC2225_PWM_REG_MASK, TMC2225_PWM_REG_SHIFT, TMC2225_PWMCONF, false}) +#define TMC2225_PWM_LIM_MASK 0xF0000000 +#define TMC2225_PWM_LIM_SHIFT 28 +#define TMC2225_PWM_LIM_FIELD ((RegisterField) {TMC2225_PWM_LIM_MASK, TMC2225_PWM_LIM_SHIFT, TMC2225_PWMCONF, false}) +#define TMC2225_PWM_SCALE_SUM_MASK 0x000000FF +#define TMC2225_PWM_SCALE_SUM_SHIFT 0 +#define TMC2225_PWM_SCALE_SUM_FIELD ((RegisterField) {TMC2225_PWM_SCALE_SUM_MASK, TMC2225_PWM_SCALE_SUM_SHIFT, TMC2225_PWM_SCALE, false}) +#define TMC2225_PWM_SCALE_AUTO_MASK 0x01FF0000 +#define TMC2225_PWM_SCALE_AUTO_SHIFT 16 +#define TMC2225_PWM_SCALE_AUTO_FIELD ((RegisterField) {TMC2225_PWM_SCALE_AUTO_MASK, TMC2225_PWM_SCALE_AUTO_SHIFT, TMC2225_PWM_SCALE, true}) +#define TMC2225_PWM_OFS_AUTO_MASK 0x000000FF +#define TMC2225_PWM_OFS_AUTO_SHIFT 0 +#define TMC2225_PWM_OFS_AUTO_FIELD ((RegisterField) {TMC2225_PWM_OFS_AUTO_MASK, TMC2225_PWM_OFS_AUTO_SHIFT, TMC2225_PWM_AUTO, false}) +#define TMC2225_PWM_GRAD_AUTO_MASK 0x00FF0000 +#define TMC2225_PWM_GRAD_AUTO_SHIFT 16 +#define TMC2225_PWM_GRAD_AUTO_FIELD ((RegisterField) {TMC2225_PWM_GRAD_AUTO_MASK, TMC2225_PWM_GRAD_AUTO_SHIFT, TMC2225_PWM_AUTO, false}) + +#endif + diff --git a/firmware/lib/tmc/ic/TMC2225/registercall_hierarchy_flowchart_UART.svg b/firmware/lib/tmc/ic/TMC2225/registercall_hierarchy_flowchart_UART.svg new file mode 100755 index 0000000..425f60a --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2225/registercall_hierarchy_flowchart_UART.svg @@ -0,0 +1,3 @@ + + +

HAL

HAL

APP (Eval)

APP (Eval)

API

API
Read a register
  •  Call tmcXXXX_readRegister function
Read a register...
Returns the register read value
Returns the register read value
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
tmcXXXX.c
tmcXXXX.c
UART.c
UART.c
tmcXXXX_eval.c
tmcXXXX_eval.c

 Implementation of UART_readWrite
  • Sends and receives bytes on the UART bus
Implementation of UART_readWrite...
Returns the raw reply data
Returns the raw reply data

Implementation of tmcXXXX_readWriteUART
  • Takes the array of data to write
  • Calls hardware function UART_readWrite
Implementation of tmcXXXX_readWriteUART...
Passes on the raw reply data to the API
Passes on the raw reply data to the API
Implementation of readRegisterUART
  • Constructs the datagram
  • Calls HAL wrapper function 
Implementation of readRegisterUART...
tmcXXXX_readWriteUART
tmcXXXX_readWriteUART
Parses the reply and returns the register value
Parses the reply and returns the register value
Implementation of tmcXXXX_readRegister 
  • Check which bus is active SPI/UART. (e.g. UART)
  • Calls bus-specific function (e.g. readRegisterUART)
 
Implementation of tmcXXXX_readRegister...
Returns the register read value
Returns the register read value
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC2225/uml-tmc-api.svg b/firmware/lib/tmc/ic/TMC2225/uml-tmc-api.svg new file mode 100755 index 0000000..5a5f8dd --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2225/uml-tmc-api.svg @@ -0,0 +1,3 @@ + + +

TMCXXXX_HW_Abstraction.h



TMCXXXX_HW_Abstraction.h...
// Constants
#define TMCXXXX_MOTORS              
                          
// Register definitions
#define TMCXXXX_GCONF        
                          ⋮
// Register fields definitions
#define TMCXXXX_GCONF_OTPW_FIELD
                     
// Constants...

TMCXXXX.h



TMCXXXX.h...
extern void tmcXXXX_readWriteSPI();
extern void tmcXXXX_readWriteUART();
extern TMCXXXXBusType tmcXXXX_getBusType();
extern uint8_t tmcXXXX_getNodeAddress();
                                  ⋮
tmcXXXX_readRegister();
tmcXXXX_writeRegister();
                                  ⋮
extern void tmcXXXX_readWriteSPI();...

TMCXXXX.c



TMCXXXX.c...
const uint8_t tmcCRCTable_Poly7Reflected[256] = {...};
int32_t tmcXXXX_readRegister(){
/* Call tmcXXXX_getBusType();
 * Based on bus type, call readRegisterSPI/UART() that
 * further calls tmcXXXX_readWriteSPI/UART();
 * For UART it also calls tmcXXXX_getNodeAddress();
                                           ⋮
}
                                           ⋮
const uint8_t tmcCRCTable_Poly7Reflected[256] = {.....
TMC-API
TMC-API

TMCXXXX_Simple_Rotation.h


TMCXXXX_Simple_Rotation.h...
void initAllMotors();
             ⋮
  
void initAllMotors()...

TMCXXXX_Simple_Rotation.c


TMCXXXX_Simple_Rotation.c...
void initAllMotors(){

// Configuring registers to enable motor drivers etc..
tmcXXXX_writeRegister();
                    ⋮
}
                    ⋮
void initAllMotors(){...
Examples
Examples
User Project
User Project

User_Project.h


User_Project.h

User_Project.c








User_Project.c...

void tmcXXXX_readWriteSPI(){
                           ⋮
}
void tmcXXXX_readWriteUART(){
                           ⋮
}
TMCXXXXBusType tmcXXXX_getBusType(){
                           ⋮
}
uint8_t tmcXXXX_getNodeAddress(){
                           ⋮
}

// User Code
                           ⋮
void tmcXXXX_readWriteSPI(){...
#include "TMCXXXX_HW_Abstraction.h"
#include "TMCXXXX.h"
#include "TMCXXXX_Simple_Rotation.h"
                                ⋮
TMCXXXXBusType bus = IC_BUS_SPI/UART;
uint8_t nodeAddress = <nodeAddress>;
                                ⋮
#include "TMCXXXX_HW_Abstraction.h"...
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC2226/README.md b/firmware/lib/tmc/ic/TMC2226/README.md new file mode 100755 index 0000000..2608370 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2226/README.md @@ -0,0 +1,52 @@ +# TMC2226 + + +## How to use + +To access the TMC2226's registers, the TMC-API offers two functions: **tmc2226_readRegister** and **tmc2226_writeRegister**. +Each of these functions takes in an **icID**, which is used to identify the IC when multiple ICs are connected. This identifier is passed down to the callback functions (see How to Integrate). + +## How to integrate: overview + +1. Include all the files of the TMC-API/ic/tmc/TMC2226 folder into the custom project. +2. Include the TMC2226.h file in the custom source code. +3. Implement the necessary callback functions (see below). +4. (optional): Take a look at the Examples subfolder for ready-made examples of the TMC-API usage. + +## Accessing the TMC2226 via UART +The following diagram depicts how to access the TMC2226 via UART using the TMC-API. + +![screenshot](registercall_hierarchy_flowchart_UART.svg) + +The description of the functions, in the above flowchart, are as follows: +- The functions tmc2226_readRegister and tmc2226_writeRegister are used to read and write the registers respectively. These functions check the current active bus and calls the bus-specific function i.e readRegisterUART or writeRegisterUART. +- These bus specific functions constructs the datagram and further calls the bus specific callback 'tmcXXXX_readWriteUART. +- This callback function further calls the hardware specific read/write function for UART and needs to be implemented externally. + +### How to integrate: Callback functions +Implement the following callback functions to access the chip via UART: +1. **tmc2226_readWriteUART()**, which is a HAL wrapper function that provides the necessary hardware access. +2. **tmc2226_getNodeAddress()**, that returns the node/slave address. Node address could be set in NODECONF (0x3) register and the address could be incremented as defined by AD0, AD1 and AD2. (Node address + ADx) must be less than 255. For further details please consult the datasheet of TMC2226. + +### Sharing the CRC table with other TMC-API chips +The TMC2226 UART protocol uses an 8 bit CRC. For calculating this, a table-based algorithm is used. This table (tmcCRCTable_Poly7Reflected[256]) is 256 bytes big and identical across multiple different Trinamic chips (i.e. TMC2209). +If multiple Trinamic chips are being used in the same project, avoiding redundant copies of this table could save memory. It is possible to substitute this CRC table with another CRC table. + +### Option to use the cache logic for Write-Only registers +The chip features write-only registers that are unable to be read, necessitating the creation of a shadow copy to cache their contents. This copy is automatically updated whenever data is written to these registers. This cache logic could be enabled by setting the macro **TMC2226_CACHE** to **'1'** or disabled by setting to **'0'** respectively. If this feature is enabled then there comes another option to use **tmc2226_cache** function, which is already implemeted in the API, by defining **TMC2226_ENABLE_TMC_CACHE** macro to **'1** or one can implement their own function. + +The function **tmc2226_cache** works for both reading from and writing to the shadow array. It first checks whether the register has write-only access and data needs to be read from the shadow copy. On the basis of that, it returns **true** or **false**. The shadowRegisters on the premade cache implementation need to be one per chip. **TMC2226_IC_CACHE_COUNT** is set to '1' by default and is user-overwritable. If multiple chips are being used in the same project, increment its value to the number of chips connected. + +## Further info +### Dependency graph for the ICs with new register R/W mechanism +This graph illustrates the relationships between files within the TMC-API library, highlighting dependencies and identifying the files that are essential for integrating the library into the custom projects. + +![screenshot](uml-tmc-api.svg) + +### Example usage: TMC-Evalsystem +**For a reference usage of the TMC-API**, visit the [TMC-Evalsystem](https://github.com/analogdevicesinc/TMC-EvalSystem) + +## Migration status +The TMC2226 has been reworked to the access system described above. For more infos on the status of this and other ICs, check out the [migration page](https://github.com/analogdevicesinc/TMC-API/issues/53). + + diff --git a/firmware/lib/tmc/ic/TMC2226/TMC2226.c b/firmware/lib/tmc/ic/TMC2226/TMC2226.c new file mode 100755 index 0000000..66a4740 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2226/TMC2226.c @@ -0,0 +1,210 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#include "TMC2226.h" + + +#ifdef TMC_API_EXTERNAL_CRC_TABLE +extern const uint8_t tmcCRCTable_Poly7Reflected[256]; +#else +const uint8_t tmcCRCTable_Poly7Reflected[256] = { + 0x00, 0x91, 0xE3, 0x72, 0x07, 0x96, 0xE4, 0x75, 0x0E, 0x9F, 0xED, 0x7C, 0x09, 0x98, 0xEA, 0x7B, + 0x1C, 0x8D, 0xFF, 0x6E, 0x1B, 0x8A, 0xF8, 0x69, 0x12, 0x83, 0xF1, 0x60, 0x15, 0x84, 0xF6, 0x67, + 0x38, 0xA9, 0xDB, 0x4A, 0x3F, 0xAE, 0xDC, 0x4D, 0x36, 0xA7, 0xD5, 0x44, 0x31, 0xA0, 0xD2, 0x43, + 0x24, 0xB5, 0xC7, 0x56, 0x23, 0xB2, 0xC0, 0x51, 0x2A, 0xBB, 0xC9, 0x58, 0x2D, 0xBC, 0xCE, 0x5F, + 0x70, 0xE1, 0x93, 0x02, 0x77, 0xE6, 0x94, 0x05, 0x7E, 0xEF, 0x9D, 0x0C, 0x79, 0xE8, 0x9A, 0x0B, + 0x6C, 0xFD, 0x8F, 0x1E, 0x6B, 0xFA, 0x88, 0x19, 0x62, 0xF3, 0x81, 0x10, 0x65, 0xF4, 0x86, 0x17, + 0x48, 0xD9, 0xAB, 0x3A, 0x4F, 0xDE, 0xAC, 0x3D, 0x46, 0xD7, 0xA5, 0x34, 0x41, 0xD0, 0xA2, 0x33, + 0x54, 0xC5, 0xB7, 0x26, 0x53, 0xC2, 0xB0, 0x21, 0x5A, 0xCB, 0xB9, 0x28, 0x5D, 0xCC, 0xBE, 0x2F, + 0xE0, 0x71, 0x03, 0x92, 0xE7, 0x76, 0x04, 0x95, 0xEE, 0x7F, 0x0D, 0x9C, 0xE9, 0x78, 0x0A, 0x9B, + 0xFC, 0x6D, 0x1F, 0x8E, 0xFB, 0x6A, 0x18, 0x89, 0xF2, 0x63, 0x11, 0x80, 0xF5, 0x64, 0x16, 0x87, + 0xD8, 0x49, 0x3B, 0xAA, 0xDF, 0x4E, 0x3C, 0xAD, 0xD6, 0x47, 0x35, 0xA4, 0xD1, 0x40, 0x32, 0xA3, + 0xC4, 0x55, 0x27, 0xB6, 0xC3, 0x52, 0x20, 0xB1, 0xCA, 0x5B, 0x29, 0xB8, 0xCD, 0x5C, 0x2E, 0xBF, + 0x90, 0x01, 0x73, 0xE2, 0x97, 0x06, 0x74, 0xE5, 0x9E, 0x0F, 0x7D, 0xEC, 0x99, 0x08, 0x7A, 0xEB, + 0x8C, 0x1D, 0x6F, 0xFE, 0x8B, 0x1A, 0x68, 0xF9, 0x82, 0x13, 0x61, 0xF0, 0x85, 0x14, 0x66, 0xF7, + 0xA8, 0x39, 0x4B, 0xDA, 0xAF, 0x3E, 0x4C, 0xDD, 0xA6, 0x37, 0x45, 0xD4, 0xA1, 0x30, 0x42, 0xD3, + 0xB4, 0x25, 0x57, 0xC6, 0xB3, 0x22, 0x50, 0xC1, 0xBA, 0x2B, 0x59, 0xC8, 0xBD, 0x2C, 0x5E, 0xCF, +}; +#endif + +/**************************************************************** Cache Implementation *************************************************************************/ + +#if TMC2226_CACHE == 0 +static inline bool tmc2226_cache(uint16_t icID, TMC2226CacheOp operation, uint8_t address, uint32_t *value) +{ + UNUSED(icID); + UNUSED(address); + UNUSED(operation); + return false; +} +#else +#if TMC2226_ENABLE_TMC_CACHE == 1 +uint8_t tmc2226_dirtyBits[TMC2226_IC_CACHE_COUNT][TMC2226_REGISTER_COUNT/8]= {0}; +int32_t tmc2226_shadowRegister[TMC2226_IC_CACHE_COUNT][TMC2226_REGISTER_COUNT]; + +void tmc2226_setDirtyBit(uint16_t icID, uint8_t index, bool value) +{ + if(index >= TMC2226_REGISTER_COUNT) + return; + + uint8_t *tmp = &tmc2226_dirtyBits[icID][index / 8]; + uint8_t shift = (index % 8); + uint8_t mask = 1 << shift; + *tmp = (((*tmp) & (~(mask))) | (((value) << (shift)) & (mask))); +} + +bool tmc2226_getDirtyBit(uint16_t icID, uint8_t index) +{ + if(index >= TMC2226_REGISTER_COUNT) + return false; + + uint8_t *tmp = &tmc2226_dirtyBits[icID][index / 8]; + uint8_t shift = (index % 8); + return ((*tmp) >> shift) & 1; +} + +/* + * This function is used to cache the value written to the Write-Only registers in the form of shadow array. + * The shadow copy is then used to read these kinds of registers. + */ +bool tmc2226_cache(uint16_t icID, TMC2226CacheOp operation, uint8_t address, uint32_t *value) +{ + if (operation == TMC2226_CACHE_READ) + { + // Check if the value should come from cache + + // Only supported chips have a cache + if (icID >= TMC2226_IC_CACHE_COUNT) + return false; + + // Only non-readable registers care about caching + // Note: This could also be used to cache i.e. RW config registers to reduce bus accesses + if (TMC2226_IS_READABLE(tmc2226_registerAccess[address])) + return false; + + // Grab the value from the cache + *value = tmc2226_shadowRegister[icID][address]; + return true; + } + else if (operation == TMC2226_CACHE_WRITE || operation == TMC2226_CACHE_FILL_DEFAULT) + { + // Fill the cache + + // only supported chips have a cache + if (icID >= TMC2226_IC_CACHE_COUNT) + return false; + + // Write to the shadow register and mark the register dirty + tmc2226_shadowRegister[icID][address] = *value; + if (operation == TMC2226_CACHE_WRITE) + { + tmc2226_setDirtyBit(icID, address, true); + } + return true; + } + return false; +} + +#else +// User must implement their own cache +extern bool tmc2226_cache(uint16_t icID, TMC2226CacheOp operation, uint8_t address, uint32_t *value); +#endif +#endif + +/************************************************************** Register read / write Implementation ******************************************************************/ + +static int32_t readRegisterUART(uint16_t icID, uint8_t registerAddress); +static void writeRegisterUART(uint16_t icID, uint8_t registerAddress, int32_t value); +static uint8_t CRC8(uint8_t *data, uint32_t bytes); + + +int32_t tmc2226_readRegister(uint16_t icID, uint8_t address) +{ + uint32_t value; + + // Read from cache for registers with write-only access + if (tmc2226_cache(icID, TMC2226_CACHE_READ, address, &value)) + return value; + + return readRegisterUART(icID, address); + + // ToDo: Error handling +} +void tmc2226_writeRegister(uint16_t icID, uint8_t address, int32_t value) +{ + writeRegisterUART(icID, address, value); +} + +int32_t readRegisterUART(uint16_t icID, uint8_t registerAddress) +{ + uint8_t data[8] = {0}; + + registerAddress = registerAddress & TMC2226_ADDRESS_MASK; + + data[0] = 0x05; + data[1] = tmc2226_getNodeAddress(icID); + data[2] = registerAddress; + data[3] = CRC8(data, 3); + + if (!tmc2226_readWriteUART(icID, &data[0], 4, 8)) + return 0; + + // Byte 0: Sync nibble correct? + if (data[0] != 0x05) + return 0; + + // Byte 1: Master address correct? + if (data[1] != 0xFF) + return 0; + + // Byte 2: Address correct? + if (data[2] != registerAddress) + return 0; + + // Byte 7: CRC correct? + if (data[7] != CRC8(data, 7)) + return 0; + + return ((uint32_t) data[3] << 24) | ((uint32_t) data[4] << 16) | ((uint32_t) data[5] << 8) | data[6]; +} + +void writeRegisterUART(uint16_t icID, uint8_t registerAddress, int32_t value) +{ + uint8_t data[8]; + + data[0] = 0x05; + data[1] = tmc2226_getNodeAddress(icID); + data[2] = registerAddress | TMC2226_WRITE_BIT; + data[3] = (value >> 24) & 0xFF; + data[4] = (value >> 16) & 0xFF; + data[5] = (value >> 8) & 0xFF; + data[6] = (value) & 0xFF; + data[7] = CRC8(data, 7); + + tmc2226_readWriteUART(icID, &data[0], 8, 0); + + //Cache the registers with write-only access + tmc2226_cache(icID, TMC2226_CACHE_WRITE, registerAddress, (uint32_t *)&value); +} + +static uint8_t CRC8(uint8_t *data, uint32_t bytes) +{ + uint8_t result = 0; + while (bytes--) result = tmcCRCTable_Poly7Reflected[result ^ *data++]; + + // Flip the result around + // swap odd and even bits + result = ((result >> 1) & 0x55) | ((result & 0x55) << 1); + // swap consecutive pairs + result = ((result >> 2) & 0x33) | ((result & 0x33) << 2); + // swap nibbles ... + result = ((result >> 4) & 0x0F) | ((result & 0x0F) << 4); + + return result; +} diff --git a/firmware/lib/tmc/ic/TMC2226/TMC2226.h b/firmware/lib/tmc/ic/TMC2226/TMC2226.h new file mode 100755 index 0000000..0cd6a48 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2226/TMC2226.h @@ -0,0 +1,199 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#ifndef TMC_IC_TMC2226_H_ +#define TMC_IC_TMC2226_H_ + + +#include +#include +#include +#include "TMC2226_HW_Abstraction.h" + +/******************************************************************************* +* API Configuration Defines +* These control optional features of the TMC-API implementation. +* These can be commented in/out here or defined from the build system. +*******************************************************************************/ + +// Uncomment if you want to save space..... +// and put the table into your own .c file +//#define TMC_API_EXTERNAL_CRC_TABLE 1 + +#ifndef TMC2226_CACHE +#define TMC2226_CACHE 1 +//#define TMC2226_CACHE 0 +#endif + +// To use the caching mechanism already implemented by the TMC-API, set TMC2226_ENABLE_TMC_CACHE to '1'. +// Set TMC2226_ENABLE_TMC_CACHE to '0' if one wants to have their own cache implementation. +#ifndef TMC2226_ENABLE_TMC_CACHE +#define TMC2226_ENABLE_TMC_CACHE 1 +//#define TMC2226_ENABLE_TMC_CACHE 0 +#endif + +/******************************************************************************/ + +typedef struct +{ + uint32_t mask; + uint8_t shift; + uint8_t address; + bool isSigned; +} RegisterField; + +// => TMC-API wrapper +extern bool tmc2226_readWriteUART(uint16_t icID, uint8_t *data, size_t writeLength, size_t readLength); +extern uint8_t tmc2226_getNodeAddress(uint16_t icID); +// => TMC-API wrapper + +int32_t tmc2226_readRegister(uint16_t icID, uint8_t address); +void tmc2226_writeRegister(uint16_t icID, uint8_t address, int32_t value); + + +static inline uint32_t tmc2226_fieldExtract(uint32_t data, RegisterField field) +{ + uint32_t value = (data & field.mask) >> field.shift; + + if (field.isSigned) + { + // Apply signedness conversion + uint32_t baseMask = field.mask >> field.shift; + uint32_t signMask = baseMask & (~baseMask >> 1); + value = (value ^ signMask) - signMask; + } + + return value; +} + +static inline uint32_t tmc2226_fieldRead(uint16_t icID, RegisterField field) +{ + uint32_t value = tmc2226_readRegister(icID, field.address); + + return tmc2226_fieldExtract(value, field); +} + +static inline uint32_t tmc2226_fieldUpdate(uint32_t data, RegisterField field, uint32_t value) +{ + return (data & (~field.mask)) | ((value << field.shift) & field.mask); +} + +static inline void tmc2226_fieldWrite(uint16_t icID, RegisterField field, uint32_t value) +{ + uint32_t regValue = tmc2226_readRegister(icID, field.address); + + regValue = tmc2226_fieldUpdate(regValue, field, value); + + tmc2226_writeRegister(icID, field.address, regValue); +} + +/**************************************************************** Cache Implementation *************************************************************************/ + +#if TMC2226_CACHE == 1 +#if TMC2226_ENABLE_TMC_CACHE == 1 + +// By default, support one IC in the cache +#ifndef TMC2226_IC_CACHE_COUNT +#define TMC2226_IC_CACHE_COUNT 1 +#endif + +typedef enum +{ + TMC2226_CACHE_READ, + TMC2226_CACHE_WRITE, + + // Special operation: Put content into the cache without marking the entry as dirty. + // Only used to initialize the cache with hardware defaults. This will allow reading + // from write-only registers that have a value inside them on reset. When using this + // operation, a restore will *not* rewrite that filled register! + TMC2226_CACHE_FILL_DEFAULT + +} TMC2226CacheOp; + +typedef struct +{ + uint8_t address; + uint32_t value; +} TMC2226RegisterConstants; + +#define TMC2226_ACCESS_DIRTY 0x08 // Register has been written since reset -> shadow register is valid for restore +#define TMC2226_ACCESS_READ 0x01 +#define TMC2226_IS_READABLE(x) ((x) & TMC2226_ACCESS_READ) +#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) +#define ____ 0x00 + +// Default Register values +#define R00 0x000001C1 // GCONF +#define R10 0x00071703 // IHOLD_IRUN +#define R6C 0x10000053 // CHOPCONF +#define R70 0xC10D0024 // PWMCONF + +// Register access permissions: +// 0x00: none (reserved) +// 0x01: read +// 0x02: write +// 0x03: read/write +// 0x13: read/write, separate functions/values for reading or writing +// 0x23: read/write, flag register (write to clear) +// 0x42: write, has hardware presets on reset +// 0x42: read/write, has hardware presets on reset +static const uint8_t tmc2226_registerAccess[TMC2226_REGISTER_COUNT] = +{ +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0x03, 0x23, 0x01, 0x02, 0x02, 0x01, 0x01, 0x43, ____, ____, ____, ____, ____, ____, ____, ____, // 0x00 - 0x0F + 0x02, 0x42, 0x01, 0x42, 0x02, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x10 - 0x1F + ____, ____, 0x02, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x20 - 0x2F + ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x30 - 0x3F + 0x02, 0x01, 0x02, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x40 - 0x4F + ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x50 - 0x5F + ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, 0x01, 0x01, 0x43, ____, ____, 0x01, // 0x60 - 0x6F + 0x03, 0x01, 0x01, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____ // 0x70 - 0x7F +}; + +static const int32_t tmc2226_sampleRegisterPreset[TMC2226_REGISTER_COUNT] = +{ +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + R00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x00 - 0x0F + R10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x10 - 0x1F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x20 - 0x2F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x30 - 0x3F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x40 - 0x4F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x50 - 0x5F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, R6C, 0, 0, 0, // 0x60 - 0x6F + R70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // 0x70 - 0x7F +}; + +// Undefine the default register values. +// This prevents warnings in case multiple TMC-API chip headers are included at once +#undef R00 +#undef R10 +#undef R6C +#undef R70 + +// Register constants (only required for 0x42 registers, since we do not have +// any way to find out the content but want to hold the actual value in the +// shadow register so an application (i.e. the TMCL IDE) can still display +// the values. This only works when the register content is constant. +static const TMC2226RegisterConstants tmc2226_RegisterConstants[] = +{ // Use ascending addresses! + { 0x11, 0x00000014 }, // TPOWERDOWN +}; + + +extern uint8_t tmc2226_dirtyBits[TMC2226_IC_CACHE_COUNT][TMC2226_REGISTER_COUNT/8]; +extern int32_t tmc2226_shadowRegister[TMC2226_IC_CACHE_COUNT][TMC2226_REGISTER_COUNT]; +void tmc2226_setDirtyBit(uint16_t icID, uint8_t index, bool value); +bool tmc2226_getDirtyBit(uint16_t icID, uint8_t index); +extern bool tmc2226_cache(uint16_t icID, TMC2226CacheOp operation, uint8_t address, uint32_t *value); +#endif +#endif + +/***************************************************************************************************************************************************/ + +#endif /* TMC_IC_TMC2226_H_ */ diff --git a/firmware/lib/tmc/ic/TMC2226/TMC2226_HW_Abstraction.h b/firmware/lib/tmc/ic/TMC2226/TMC2226_HW_Abstraction.h new file mode 100755 index 0000000..e3b048a --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2226/TMC2226_HW_Abstraction.h @@ -0,0 +1,326 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + +#ifndef TMC2226_HW_ABSTRACTION +#define TMC2226_HW_ABSTRACTION + + +// Constants + +#define TMC2226_MOTORS 1 +#define TMC2226_REGISTER_COUNT 128 // Default register count +#define TMC2226_WRITE_BIT 0x80 +#define TMC2226_ADDRESS_MASK 0x7F +#define TMC2226_MAX_VELOCITY (int32_t) 2147483647 +#define TMC2226_MAX_ACCELERATION (uint32_t) 16777215uL + +// Register +// ===== TMC2226 & 2202 & TMC2226 & 2220 & 2225 "Donkey Kong" family register set ===== + +#define TMC2226_GCONF 0x00 +#define TMC2226_GSTAT 0x01 +#define TMC2226_IFCNT 0x02 +#define TMC2226_SLAVECONF 0x03 +#define TMC2226_OTP_PROG 0x04 +#define TMC2226_OTP_READ 0x05 +#define TMC2226_IOIN 0x06 +#define TMC2226_FACTORY_CONF 0x07 + +#define TMC2226_IHOLD_IRUN 0x10 +#define TMC2226_TPOWERDOWN 0x11 +#define TMC2226_TSTEP 0x12 +#define TMC2226_TPWMTHRS 0x13 +#define TMC2226_TCOOLTHRS 0x14 + +#define TMC2226_VACTUAL 0x22 + +#define TMC2226_SGTHRS 0x40 +#define TMC2226_SG_RESULT 0x41 +#define TMC2226_COOLCONF 0x42 + +#define TMC2226_MSCNT 0x6A +#define TMC2226_MSCURACT 0x6B +#define TMC2226_CHOPCONF 0x6C + +#define TMC2226_DRVSTATUS 0x6F + +#define TMC2226_PWMCONF 0x70 +#define TMC2226_PWM_SCALE 0x71 +#define TMC2226_PWM_AUTO 0x72 + +// Register fields + +#define TMC2226_I_SCALE_ANALOG_MASK 0x00000001 +#define TMC2226_I_SCALE_ANALOG_SHIFT 0 +#define TMC2226_I_SCALE_ANALOG_FIELD ((RegisterField) {TMC2226_I_SCALE_ANALOG_MASK, TMC2226_I_SCALE_ANALOG_SHIFT, TMC2226_GCONF, false}) +#define TMC2226_INTERNAL_RSENSE_MASK 0x00000002 +#define TMC2226_INTERNAL_RSENSE_SHIFT 1 +#define TMC2226_INTERNAL_RSENSE_FIELD ((RegisterField) {TMC2226_INTERNAL_RSENSE_MASK, TMC2226_INTERNAL_RSENSE_SHIFT, TMC2226_GCONF, false}) +#define TMC2226_EN_SPREADCYCLE_MASK 0x00000004 +#define TMC2226_EN_SPREADCYCLE_SHIFT 2 +#define TMC2226_EN_SPREADCYCLE_FIELD ((RegisterField) {TMC2226_EN_SPREADCYCLE_MASK, TMC2226_EN_SPREADCYCLE_SHIFT, TMC2226_GCONF, false}) +#define TMC2226_SHAFT_MASK 0x00000008 +#define TMC2226_SHAFT_SHIFT 3 +#define TMC2226_SHAFT_FIELD ((RegisterField) {TMC2226_SHAFT_MASK, TMC2226_SHAFT_SHIFT, TMC2226_GCONF, false}) +#define TMC2226_INDEX_OTPW_MASK 0x00000010 +#define TMC2226_INDEX_OTPW_SHIFT 4 +#define TMC2226_INDEX_OTPW_FIELD ((RegisterField) {TMC2226_INDEX_OTPW_MASK, TMC2226_INDEX_OTPW_SHIFT, TMC2226_GCONF, false}) +#define TMC2226_INDEX_STEP_MASK 0x00000020 +#define TMC2226_INDEX_STEP_SHIFT 5 +#define TMC2226_INDEX_STEP_FIELD ((RegisterField) {TMC2226_INDEX_STEP_MASK, TMC2226_INDEX_STEP_SHIFT, TMC2226_GCONF, false}) +#define TMC2226_PDN_DISABLE_MASK 0x00000040 +#define TMC2226_PDN_DISABLE_SHIFT 6 +#define TMC2226_PDN_DISABLE_FIELD ((RegisterField) {TMC2226_PDN_DISABLE_MASK, TMC2226_PDN_DISABLE_SHIFT, TMC2226_GCONF, false}) +#define TMC2226_MSTEP_REG_SELECT_MASK 0x00000080 +#define TMC2226_MSTEP_REG_SELECT_SHIFT 7 +#define TMC2226_MSTEP_REG_SELECT_FIELD ((RegisterField) {TMC2226_MSTEP_REG_SELECT_MASK, TMC2226_MSTEP_REG_SELECT_SHIFT, TMC2226_GCONF, false}) +#define TMC2226_MULTISTEP_FILT_MASK 0x00000100 +#define TMC2226_MULTISTEP_FILT_SHIFT 8 +#define TMC2226_MULTISTEP_FILT_FIELD ((RegisterField) {TMC2226_MULTISTEP_FILT_MASK, TMC2226_MULTISTEP_FILT_SHIFT, TMC2226_GCONF, false}) +#define TMC2226_TEST_MODE_MASK 0x00000200 +#define TMC2226_TEST_MODE_SHIFT 9 +#define TMC2226_TEST_MODE_FIELD ((RegisterField) {TMC2226_TEST_MODE_MASK, TMC2226_TEST_MODE_SHIFT, TMC2226_GCONF, false}) +#define TMC2226_RESET_MASK 0x00000001 +#define TMC2226_RESET_SHIFT 0 +#define TMC2226_RESET_FIELD ((RegisterField) {TMC2226_RESET_MASK, TMC2226_RESET_SHIFT, TMC2226_GSTAT, false}) +#define TMC2226_DRV_ERR_MASK 0x00000002 +#define TMC2226_DRV_ERR_SHIFT 1 +#define TMC2226_DRV_ERR_FIELD ((RegisterField) {TMC2226_DRV_ERR_MASK, TMC2226_DRV_ERR_SHIFT, TMC2226_GSTAT, false}) +#define TMC2226_UV_CP_MASK 0x00000004 +#define TMC2226_UV_CP_SHIFT 2 +#define TMC2226_UV_CP_FIELD ((RegisterField) {TMC2226_UV_CP_MASK, TMC2226_UV_CP_SHIFT, TMC2226_GSTAT, false}) +#define TMC2226_IFCNT_MASK 0x000000FF +#define TMC2226_IFCNT_SHIFT 0 +#define TMC2226_IFCNT_FIELD ((RegisterField) {TMC2226_IFCNT_MASK, TMC2226_IFCNT_SHIFT, TMC2226_IFCNT, false}) +#define TMC2226_SLAVECONF_MASK 0x00000F00 +#define TMC2226_SLAVECONF_SHIFT 8 +#define TMC2226_SLAVECONF_FIELD ((RegisterField) {TMC2226_SLAVECONF_MASK, TMC2226_SLAVECONF_SHIFT, TMC2226_SLAVECONF, false}) +#define TMC2226_OTPBIT_MASK 0x00000007 +#define TMC2226_OTPBIT_SHIFT 0 +#define TMC2226_OTPBIT_FIELD ((RegisterField) {TMC2226_OTPBIT_MASK, TMC2226_OTPBIT_SHIFT, TMC2226_OTP_PROG, false}) +#define TMC2226_OTPBYTE_MASK 0x00000030 +#define TMC2226_OTPBYTE_SHIFT 4 +#define TMC2226_OTPBYTE_FIELD ((RegisterField) {TMC2226_OTPBYTE_MASK, TMC2226_OTPBYTE_SHIFT, TMC2226_OTP_PROG, false}) +#define TMC2226_OTPMAGIC_MASK 0x0000FF00 +#define TMC2226_OTPMAGIC_SHIFT 8 +#define TMC2226_OTPMAGIC_FIELD ((RegisterField) {TMC2226_OTPMAGIC_MASK, TMC2226_OTPMAGIC_SHIFT, TMC2226_OTP_PROG, false}) +#define TMC2226_OTP0_BYTE_0_READ_DATA_MASK 0x000000FF +#define TMC2226_OTP0_BYTE_0_READ_DATA_SHIFT 0 +#define TMC2226_OTP0_BYTE_0_READ_DATA_FIELD ((RegisterField) {TMC2226_OTP0_BYTE_0_READ_DATA_MASK, TMC2226_OTP0_BYTE_0_READ_DATA_SHIFT, TMC2226_OTP_READ, false}) +#define TMC2226_OTP1_BYTE_1_READ_DATA_MASK 0x0000FF00 +#define TMC2226_OTP1_BYTE_1_READ_DATA_SHIFT 8 +#define TMC2226_OTP1_BYTE_1_READ_DATA_FIELD ((RegisterField) {TMC2226_OTP1_BYTE_1_READ_DATA_MASK, TMC2226_OTP1_BYTE_1_READ_DATA_SHIFT, TMC2226_OTP_READ, false}) +#define TMC2226_OTP2_BYTE_2_READ_DATA_MASK 0x00FF0000 +#define TMC2226_OTP2_BYTE_2_READ_DATA_SHIFT 16 +#define TMC2226_OTP2_BYTE_2_READ_DATA_FIELD ((RegisterField) {TMC2226_OTP2_BYTE_2_READ_DATA_MASK, TMC2226_OTP2_BYTE_2_READ_DATA_SHIFT, TMC2226_OTP_READ, false}) +#define TMC2226_ENN_MASK 0x00000001 +#define TMC2226_ENN_SHIFT 0 +#define TMC2226_ENN_FIELD ((RegisterField) {TMC2226_ENN_MASK, TMC2226_ENN_SHIFT, TMC2226_IOIN, false}) +#define TMC2226_UNUSED_MASK 0x00000002 +#define TMC2226_UNUSED_SHIFT 1 +#define TMC2226_UNUSED_FIELD ((RegisterField) {TMC2226_UNUSED_MASK, TMC2226_UNUSED_SHIFT, TMC2226_IOIN, false}) +#define TMC2226_MS1_MASK 0x00000004 +#define TMC2226_MS1_SHIFT 2 +#define TMC2226_MS1_FIELD ((RegisterField) {TMC2226_MS1_MASK, TMC2226_MS1_SHIFT, TMC2226_IOIN, false}) +#define TMC2226_MS2_MASK 0x00000008 +#define TMC2226_MS2_SHIFT 3 +#define TMC2226_MS2_FIELD ((RegisterField) {TMC2226_MS2_MASK, TMC2226_MS2_SHIFT, TMC2226_IOIN, false}) +#define TMC2226_DIAG_MASK 0x00000010 +#define TMC2226_DIAG_SHIFT 4 +#define TMC2226_DIAG_FIELD ((RegisterField) {TMC2226_DIAG_MASK, TMC2226_DIAG_SHIFT, TMC2226_IOIN, false}) +//#define TMC2226_UNUSED_MASK 0x00000020 +//#define TMC2226_UNUSED_SHIFT 5 +//#define TMC2226_UNUSED_FIELD ((RegisterField) {TMC2226_UNUSED_MASK, TMC2226_UNUSED_SHIFT, TMC2226_IOIN, false}) +#define TMC2226_PDN_UART_MASK 0x00000040 +#define TMC2226_PDN_UART_SHIFT 6 +#define TMC2226_PDN_UART_FIELD ((RegisterField) {TMC2226_PDN_UART_MASK, TMC2226_PDN_UART_SHIFT, TMC2226_IOIN, false}) +#define TMC2226_STEP_MASK 0x00000080 +#define TMC2226_STEP_SHIFT 7 +#define TMC2226_STEP_FIELD ((RegisterField) {TMC2226_STEP_MASK, TMC2226_STEP_SHIFT, TMC2226_IOIN, false}) +#define TMC2226_SPREAD_EN_MASK 0x00000100 +#define TMC2226_SPREAD_EN_SHIFT 8 +#define TMC2226_SPREAD_EN_FIELD ((RegisterField) {TMC2226_SPREAD_EN_MASK, TMC2226_SPREAD_EN_SHIFT, TMC2226_IOIN, false}) +#define TMC2226_DIR_MASK 0x00000200 +#define TMC2226_DIR_SHIFT 9 +#define TMC2226_DIR_FIELD ((RegisterField) {TMC2226_DIR_MASK, TMC2226_DIR_SHIFT, TMC2226_IOIN, false}) +#define TMC2226_VERSION_MASK 0xFF000000 +#define TMC2226_VERSION_SHIFT 24 +#define TMC2226_VERSION_FIELD ((RegisterField) {TMC2226_VERSION_MASK, TMC2226_VERSION_SHIFT, TMC2226_IOIN, false}) +#define TMC2226_FCLKTRIM_MASK 0x0000001F +#define TMC2226_FCLKTRIM_SHIFT 0 +#define TMC2226_FCLKTRIM_FIELD ((RegisterField) {TMC2226_FCLKTRIM_MASK, TMC2226_FCLKTRIM_SHIFT, TMC2226_FACTORY_CONF, false}) +#define TMC2226_OTTRIM_MASK 0x00000300 +#define TMC2226_OTTRIM_SHIFT 8 +#define TMC2226_OTTRIM_FIELD ((RegisterField) {TMC2226_OTTRIM_MASK, TMC2226_OTTRIM_SHIFT, TMC2226_FACTORY_CONF, false}) +#define TMC2226_IHOLD_MASK 0x0000001F +#define TMC2226_IHOLD_SHIFT 0 +#define TMC2226_IHOLD_FIELD ((RegisterField) {TMC2226_IHOLD_MASK, TMC2226_IHOLD_SHIFT, TMC2226_IHOLD_IRUN, false}) +#define TMC2226_IRUN_MASK 0x00001F00 +#define TMC2226_IRUN_SHIFT 8 +#define TMC2226_IRUN_FIELD ((RegisterField) {TMC2226_IRUN_MASK, TMC2226_IRUN_SHIFT, TMC2226_IHOLD_IRUN, false}) +#define TMC2226_IHOLDDELAY_MASK 0x000F0000 +#define TMC2226_IHOLDDELAY_SHIFT 16 +#define TMC2226_IHOLDDELAY_FIELD ((RegisterField) {TMC2226_IHOLDDELAY_MASK, TMC2226_IHOLDDELAY_SHIFT, TMC2226_IHOLD_IRUN, false}) +#define TMC2226_TPOWERDOWN_MASK 0x000000FF +#define TMC2226_TPOWERDOWN_SHIFT 0 +#define TMC2226_TPOWERDOWN_FIELD ((RegisterField) {TMC2226_TPOWERDOWN_MASK, TMC2226_TPOWERDOWN_SHIFT, TMC2226_TPOWERDOWN, false}) +#define TMC2226_TSTEP_MASK 0x000FFFFF +#define TMC2226_TSTEP_SHIFT 0 +#define TMC2226_TSTEP_FIELD ((RegisterField) {TMC2226_TSTEP_MASK, TMC2226_TSTEP_SHIFT, TMC2226_TSTEP, false}) +#define TMC2226_TPWMTHRS_MASK 0x000FFFFF +#define TMC2226_TPWMTHRS_SHIFT 0 +#define TMC2226_TPWMTHRS_FIELD ((RegisterField) {TMC2226_TPWMTHRS_MASK, TMC2226_TPWMTHRS_SHIFT, TMC2226_TPWMTHRS, false}) +#define TMC2226_TCOOLTHRS_MASK 0x000FFFFF +#define TMC2226_TCOOLTHRS_SHIFT 0 +#define TMC2226_TCOOLTHRS_FIELD ((RegisterField) {TMC2226_TCOOLTHRS_MASK, TMC2226_TCOOLTHRS_SHIFT, TMC2226_TCOOLTHRS, false}) +#define TMC2226_VACTUAL_MASK 0x00FFFFFF +#define TMC2226_VACTUAL_SHIFT 0 +#define TMC2226_VACTUAL_FIELD ((RegisterField) {TMC2226_VACTUAL_MASK, TMC2226_VACTUAL_SHIFT, TMC2226_VACTUAL, true}) +#define TMC2226_SGTHRS_MASK 0x000000FF +#define TMC2226_SGTHRS_SHIFT 0 +#define TMC2226_SGTHRS_FIELD ((RegisterField) {TMC2226_SGTHRS_MASK, TMC2226_SGTHRS_SHIFT, TMC2226_SGTHRS, false}) +#define TMC2226_SG_RESULT_MASK 0x000003FF +#define TMC2226_SG_RESULT_SHIFT 0 +#define TMC2226_SG_RESULT_FIELD ((RegisterField) {TMC2226_SG_RESULT_MASK, TMC2226_SG_RESULT_SHIFT, TMC2226_SG_RESULT, false}) +#define TMC2226_SEMIN_MASK 0x0000000F +#define TMC2226_SEMIN_SHIFT 0 +#define TMC2226_SEMIN_FIELD ((RegisterField) {TMC2226_SEMIN_MASK, TMC2226_SEMIN_SHIFT, TMC2226_COOLCONF, false}) +#define TMC2226_SEUP_MASK 0x00000060 +#define TMC2226_SEUP_SHIFT 5 +#define TMC2226_SEUP_FIELD ((RegisterField) {TMC2226_SEUP_MASK, TMC2226_SEUP_SHIFT, TMC2226_COOLCONF, false}) +#define TMC2226_SEMAX_MASK 0x00000F00 +#define TMC2226_SEMAX_SHIFT 8 +#define TMC2226_SEMAX_FIELD ((RegisterField) {TMC2226_SEMAX_MASK, TMC2226_SEMAX_SHIFT, TMC2226_COOLCONF, false}) +#define TMC2226_SEDN_MASK 0x00006000 +#define TMC2226_SEDN_SHIFT 13 +#define TMC2226_SEDN_FIELD ((RegisterField) {TMC2226_SEDN_MASK, TMC2226_SEDN_SHIFT, TMC2226_COOLCONF, false}) +#define TMC2226_SEIMIN_MASK 0x00008000 +#define TMC2226_SEIMIN_SHIFT 15 +#define TMC2226_SEIMIN_FIELD ((RegisterField) {TMC2226_SEIMIN_MASK, TMC2226_SEIMIN_SHIFT, TMC2226_COOLCONF, false}) +#define TMC2226_MSCNT_MASK 0x000003FF +#define TMC2226_MSCNT_SHIFT 0 +#define TMC2226_MSCNT_FIELD ((RegisterField) {TMC2226_MSCNT_MASK, TMC2226_MSCNT_SHIFT, TMC2226_MSCNT, false}) +#define TMC2226_CUR_A_MASK 0x000001FF +#define TMC2226_CUR_A_SHIFT 0 +#define TMC2226_CUR_A_FIELD ((RegisterField) {TMC2226_CUR_A_MASK, TMC2226_CUR_A_SHIFT, TMC2226_MSCURACT, true}) +#define TMC2226_CUR_B_MASK 0x01FF0000 +#define TMC2226_CUR_B_SHIFT 16 +#define TMC2226_CUR_B_FIELD ((RegisterField) {TMC2226_CUR_B_MASK, TMC2226_CUR_B_SHIFT, TMC2226_MSCURACT, true}) +#define TMC2226_TOFF_MASK 0x0000000F +#define TMC2226_TOFF_SHIFT 0 +#define TMC2226_TOFF_FIELD ((RegisterField) {TMC2226_TOFF_MASK, TMC2226_TOFF_SHIFT, TMC2226_CHOPCONF, false}) +#define TMC2226_HSTRT_MASK 0x00000070 +#define TMC2226_HSTRT_SHIFT 4 +#define TMC2226_HSTRT_FIELD ((RegisterField) {TMC2226_HSTRT_MASK, TMC2226_HSTRT_SHIFT, TMC2226_CHOPCONF, false}) +#define TMC2226_HEND_MASK 0x00000780 +#define TMC2226_HEND_SHIFT 7 +#define TMC2226_HEND_FIELD ((RegisterField) {TMC2226_HEND_MASK, TMC2226_HEND_SHIFT, TMC2226_CHOPCONF, false}) +#define TMC2226_TBL_MASK 0x00018000 +#define TMC2226_TBL_SHIFT 15 +#define TMC2226_TBL_FIELD ((RegisterField) {TMC2226_TBL_MASK, TMC2226_TBL_SHIFT, TMC2226_CHOPCONF, false}) +#define TMC2226_VSENSE_MASK 0x00020000 +#define TMC2226_VSENSE_SHIFT 17 +#define TMC2226_VSENSE_FIELD ((RegisterField) {TMC2226_VSENSE_MASK, TMC2226_VSENSE_SHIFT, TMC2226_CHOPCONF, false}) +#define TMC2226_MRES_MASK 0x0F000000 +#define TMC2226_MRES_SHIFT 24 +#define TMC2226_MRES_FIELD ((RegisterField) {TMC2226_MRES_MASK, TMC2226_MRES_SHIFT, TMC2226_CHOPCONF, false}) +#define TMC2226_INTPOL_MASK 0x10000000 +#define TMC2226_INTPOL_SHIFT 28 +#define TMC2226_INTPOL_FIELD ((RegisterField) {TMC2226_INTPOL_MASK, TMC2226_INTPOL_SHIFT, TMC2226_CHOPCONF, false}) +#define TMC2226_DEDGE_MASK 0x20000000 +#define TMC2226_DEDGE_SHIFT 29 +#define TMC2226_DEDGE_FIELD ((RegisterField) {TMC2226_DEDGE_MASK, TMC2226_DEDGE_SHIFT, TMC2226_CHOPCONF, false}) +#define TMC2226_DISS2G_MASK 0x40000000 +#define TMC2226_DISS2G_SHIFT 30 +#define TMC2226_DISS2G_FIELD ((RegisterField) {TMC2226_DISS2G_MASK, TMC2226_DISS2G_SHIFT, TMC2226_CHOPCONF, false}) +#define TMC2226_DISS2VS_MASK 0x80000000 +#define TMC2226_DISS2VS_SHIFT 31 +#define TMC2226_DISS2VS_FIELD ((RegisterField) {TMC2226_DISS2VS_MASK, TMC2226_DISS2VS_SHIFT, TMC2226_CHOPCONF, false}) +#define TMC2226_OTPW_MASK 0x00000001 +#define TMC2226_OTPW_SHIFT 0 +#define TMC2226_OTPW_FIELD ((RegisterField) {TMC2226_OTPW_MASK, TMC2226_OTPW_SHIFT, TMC2226_DRVSTATUS, false}) +#define TMC2226_OT_MASK 0x00000002 +#define TMC2226_OT_SHIFT 1 +#define TMC2226_OT_FIELD ((RegisterField) {TMC2226_OT_MASK, TMC2226_OT_SHIFT, TMC2226_DRVSTATUS, false}) +#define TMC2226_S2GA_MASK 0x00000004 +#define TMC2226_S2GA_SHIFT 2 +#define TMC2226_S2GA_FIELD ((RegisterField) {TMC2226_S2GA_MASK, TMC2226_S2GA_SHIFT, TMC2226_DRVSTATUS, false}) +#define TMC2226_S2GB_MASK 0x00000008 +#define TMC2226_S2GB_SHIFT 3 +#define TMC2226_S2GB_FIELD ((RegisterField) {TMC2226_S2GB_MASK, TMC2226_S2GB_SHIFT, TMC2226_DRVSTATUS, false}) +#define TMC2226_S2VSA_MASK 0x00000010 +#define TMC2226_S2VSA_SHIFT 4 +#define TMC2226_S2VSA_FIELD ((RegisterField) {TMC2226_S2VSA_MASK, TMC2226_S2VSA_SHIFT, TMC2226_DRVSTATUS, false}) +#define TMC2226_S2VSB_MASK 0x00000020 +#define TMC2226_S2VSB_SHIFT 5 +#define TMC2226_S2VSB_FIELD ((RegisterField) {TMC2226_S2VSB_MASK, TMC2226_S2VSB_SHIFT, TMC2226_DRVSTATUS, false}) +#define TMC2226_OLA_MASK 0x00000040 +#define TMC2226_OLA_SHIFT 6 +#define TMC2226_OLA_FIELD ((RegisterField) {TMC2226_OLA_MASK, TMC2226_OLA_SHIFT, TMC2226_DRVSTATUS, false}) +#define TMC2226_OLB_MASK 0x00000080 +#define TMC2226_OLB_SHIFT 7 +#define TMC2226_OLB_FIELD ((RegisterField) {TMC2226_OLB_MASK, TMC2226_OLB_SHIFT, TMC2226_DRVSTATUS, false}) +#define TMC2226_T120_MASK 0x00000100 +#define TMC2226_T120_SHIFT 8 +#define TMC2226_T120_FIELD ((RegisterField) {TMC2226_T120_MASK, TMC2226_T120_SHIFT, TMC2226_DRVSTATUS, false}) +#define TMC2226_T143_MASK 0x00000200 +#define TMC2226_T143_SHIFT 9 +#define TMC2226_T143_FIELD ((RegisterField) {TMC2226_T143_MASK, TMC2226_T143_SHIFT, TMC2226_DRVSTATUS, false}) +#define TMC2226_T150_MASK 0x00000400 +#define TMC2226_T150_SHIFT 10 +#define TMC2226_T150_FIELD ((RegisterField) {TMC2226_T150_MASK, TMC2226_T150_SHIFT, TMC2226_DRVSTATUS, false}) +#define TMC2226_T157_MASK 0x00000800 +#define TMC2226_T157_SHIFT 11 +#define TMC2226_T157_FIELD ((RegisterField) {TMC2226_T157_MASK, TMC2226_T157_SHIFT, TMC2226_DRVSTATUS, false}) +#define TMC2226_CS_ACTUAL_MASK 0x001F0000 +#define TMC2226_CS_ACTUAL_SHIFT 16 +#define TMC2226_CS_ACTUAL_FIELD ((RegisterField) {TMC2226_CS_ACTUAL_MASK, TMC2226_CS_ACTUAL_SHIFT, TMC2226_DRVSTATUS, false}) +#define TMC2226_STEALTH_MASK 0x40000000 +#define TMC2226_STEALTH_SHIFT 30 +#define TMC2226_STEALTH_FIELD ((RegisterField) {TMC2226_STEALTH_MASK, TMC2226_STEALTH_SHIFT, TMC2226_DRVSTATUS, false}) +#define TMC2226_STST_MASK 0x80000000 +#define TMC2226_STST_SHIFT 31 +#define TMC2226_STST_FIELD ((RegisterField) {TMC2226_STST_MASK, TMC2226_STST_SHIFT, TMC2226_DRVSTATUS, false}) +#define TMC2226_PWM_OFS_MASK 0x000000FF +#define TMC2226_PWM_OFS_SHIFT 0 +#define TMC2226_PWM_OFS_FIELD ((RegisterField) {TMC2226_PWM_OFS_MASK, TMC2226_PWM_OFS_SHIFT, TMC2226_PWMCONF, false}) +#define TMC2226_PWM_GRAD_MASK 0x0000FF00 +#define TMC2226_PWM_GRAD_SHIFT 8 +#define TMC2226_PWM_GRAD_FIELD ((RegisterField) {TMC2226_PWM_GRAD_MASK, TMC2226_PWM_GRAD_SHIFT, TMC2226_PWMCONF, false}) +#define TMC2226_PWM_FREQ_MASK 0x00030000 +#define TMC2226_PWM_FREQ_SHIFT 16 +#define TMC2226_PWM_FREQ_FIELD ((RegisterField) {TMC2226_PWM_FREQ_MASK, TMC2226_PWM_FREQ_SHIFT, TMC2226_PWMCONF, false}) +#define TMC2226_PWM_AUTOSCALE_MASK 0x00040000 +#define TMC2226_PWM_AUTOSCALE_SHIFT 18 +#define TMC2226_PWM_AUTOSCALE_FIELD ((RegisterField) {TMC2226_PWM_AUTOSCALE_MASK, TMC2226_PWM_AUTOSCALE_SHIFT, TMC2226_PWMCONF, false}) +#define TMC2226_PWM_AUTOGRAD_MASK 0x00080000 +#define TMC2226_PWM_AUTOGRAD_SHIFT 19 +#define TMC2226_PWM_AUTOGRAD_FIELD ((RegisterField) {TMC2226_PWM_AUTOGRAD_MASK, TMC2226_PWM_AUTOGRAD_SHIFT, TMC2226_PWMCONF, false}) +#define TMC2226_FREEWHEEL_MASK 0x00300000 +#define TMC2226_FREEWHEEL_SHIFT 20 +#define TMC2226_FREEWHEEL_FIELD ((RegisterField) {TMC2226_FREEWHEEL_MASK, TMC2226_FREEWHEEL_SHIFT, TMC2226_PWMCONF, false}) +#define TMC2226_PWM_REG_MASK 0x0F000000 +#define TMC2226_PWM_REG_SHIFT 24 +#define TMC2226_PWM_REG_FIELD ((RegisterField) {TMC2226_PWM_REG_MASK, TMC2226_PWM_REG_SHIFT, TMC2226_PWMCONF, false}) +#define TMC2226_PWM_LIM_MASK 0xF0000000 +#define TMC2226_PWM_LIM_SHIFT 28 +#define TMC2226_PWM_LIM_FIELD ((RegisterField) {TMC2226_PWM_LIM_MASK, TMC2226_PWM_LIM_SHIFT, TMC2226_PWMCONF, false}) +#define TMC2226_PWM_SCALE_SUM_MASK 0x000000FF +#define TMC2226_PWM_SCALE_SUM_SHIFT 0 +#define TMC2226_PWM_SCALE_SUM_FIELD ((RegisterField) {TMC2226_PWM_SCALE_SUM_MASK, TMC2226_PWM_SCALE_SUM_SHIFT, TMC2226_PWM_SCALE, false}) +#define TMC2226_PWM_SCALE_AUTO_MASK 0x01FF0000 +#define TMC2226_PWM_SCALE_AUTO_SHIFT 16 +#define TMC2226_PWM_SCALE_AUTO_FIELD ((RegisterField) {TMC2226_PWM_SCALE_AUTO_MASK, TMC2226_PWM_SCALE_AUTO_SHIFT, TMC2226_PWM_SCALE, true}) +#define TMC2226_PWM_OFS_AUTO_MASK 0x000000FF +#define TMC2226_PWM_OFS_AUTO_SHIFT 0 +#define TMC2226_PWM_OFS_AUTO_FIELD ((RegisterField) {TMC2226_PWM_OFS_AUTO_MASK, TMC2226_PWM_OFS_AUTO_SHIFT, TMC2226_PWM_AUTO, false}) +#define TMC2226_PWM_GRAD_AUTO_MASK 0x00FF0000 +#define TMC2226_PWM_GRAD_AUTO_SHIFT 16 +#define TMC2226_PWM_GRAD_AUTO_FIELD ((RegisterField) {TMC2226_PWM_GRAD_AUTO_MASK, TMC2226_PWM_GRAD_AUTO_SHIFT, TMC2226_PWM_AUTO, false}) + +#endif diff --git a/firmware/lib/tmc/ic/TMC2226/registercall_hierarchy_flowchart_UART.svg b/firmware/lib/tmc/ic/TMC2226/registercall_hierarchy_flowchart_UART.svg new file mode 100755 index 0000000..425f60a --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2226/registercall_hierarchy_flowchart_UART.svg @@ -0,0 +1,3 @@ + + +

HAL

HAL

APP (Eval)

APP (Eval)

API

API
Read a register
  •  Call tmcXXXX_readRegister function
Read a register...
Returns the register read value
Returns the register read value
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
tmcXXXX.c
tmcXXXX.c
UART.c
UART.c
tmcXXXX_eval.c
tmcXXXX_eval.c

 Implementation of UART_readWrite
  • Sends and receives bytes on the UART bus
Implementation of UART_readWrite...
Returns the raw reply data
Returns the raw reply data

Implementation of tmcXXXX_readWriteUART
  • Takes the array of data to write
  • Calls hardware function UART_readWrite
Implementation of tmcXXXX_readWriteUART...
Passes on the raw reply data to the API
Passes on the raw reply data to the API
Implementation of readRegisterUART
  • Constructs the datagram
  • Calls HAL wrapper function 
Implementation of readRegisterUART...
tmcXXXX_readWriteUART
tmcXXXX_readWriteUART
Parses the reply and returns the register value
Parses the reply and returns the register value
Implementation of tmcXXXX_readRegister 
  • Check which bus is active SPI/UART. (e.g. UART)
  • Calls bus-specific function (e.g. readRegisterUART)
 
Implementation of tmcXXXX_readRegister...
Returns the register read value
Returns the register read value
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC2226/uml-tmc-api.svg b/firmware/lib/tmc/ic/TMC2226/uml-tmc-api.svg new file mode 100755 index 0000000..5a5f8dd --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2226/uml-tmc-api.svg @@ -0,0 +1,3 @@ + + +

TMCXXXX_HW_Abstraction.h



TMCXXXX_HW_Abstraction.h...
// Constants
#define TMCXXXX_MOTORS              
                          
// Register definitions
#define TMCXXXX_GCONF        
                          ⋮
// Register fields definitions
#define TMCXXXX_GCONF_OTPW_FIELD
                     
// Constants...

TMCXXXX.h



TMCXXXX.h...
extern void tmcXXXX_readWriteSPI();
extern void tmcXXXX_readWriteUART();
extern TMCXXXXBusType tmcXXXX_getBusType();
extern uint8_t tmcXXXX_getNodeAddress();
                                  ⋮
tmcXXXX_readRegister();
tmcXXXX_writeRegister();
                                  ⋮
extern void tmcXXXX_readWriteSPI();...

TMCXXXX.c



TMCXXXX.c...
const uint8_t tmcCRCTable_Poly7Reflected[256] = {...};
int32_t tmcXXXX_readRegister(){
/* Call tmcXXXX_getBusType();
 * Based on bus type, call readRegisterSPI/UART() that
 * further calls tmcXXXX_readWriteSPI/UART();
 * For UART it also calls tmcXXXX_getNodeAddress();
                                           ⋮
}
                                           ⋮
const uint8_t tmcCRCTable_Poly7Reflected[256] = {.....
TMC-API
TMC-API

TMCXXXX_Simple_Rotation.h


TMCXXXX_Simple_Rotation.h...
void initAllMotors();
             ⋮
  
void initAllMotors()...

TMCXXXX_Simple_Rotation.c


TMCXXXX_Simple_Rotation.c...
void initAllMotors(){

// Configuring registers to enable motor drivers etc..
tmcXXXX_writeRegister();
                    ⋮
}
                    ⋮
void initAllMotors(){...
Examples
Examples
User Project
User Project

User_Project.h


User_Project.h

User_Project.c








User_Project.c...

void tmcXXXX_readWriteSPI(){
                           ⋮
}
void tmcXXXX_readWriteUART(){
                           ⋮
}
TMCXXXXBusType tmcXXXX_getBusType(){
                           ⋮
}
uint8_t tmcXXXX_getNodeAddress(){
                           ⋮
}

// User Code
                           ⋮
void tmcXXXX_readWriteSPI(){...
#include "TMCXXXX_HW_Abstraction.h"
#include "TMCXXXX.h"
#include "TMCXXXX_Simple_Rotation.h"
                                ⋮
TMCXXXXBusType bus = IC_BUS_SPI/UART;
uint8_t nodeAddress = <nodeAddress>;
                                ⋮
#include "TMCXXXX_HW_Abstraction.h"...
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC2240/README.md b/firmware/lib/tmc/ic/TMC2240/README.md new file mode 100755 index 0000000..9b17b48 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2240/README.md @@ -0,0 +1,62 @@ +# TMC2240 + + +## How to use + +To access the TMC2240's registers, the TMC-API offers two functions: **tmc2240_readRegister** and **tmc2240_writeRegister**. +Each of these functions takes in an **icID**, which is used to identify the IC when multiple ICs are connected. This identifier is passed down to the callback functions (see How to Integrate). + +## How to integrate: overview + +1. Include all the files of the TMC-API/ic/tmc/TMC2240 folder into the custom project. +2. Include the TMC2240.h file in the custom source code. +3. Implement the necessary callback functions (see below). +4. (optional): Take a look at the Examples subfolder for ready-made examples of the TMC-API usage. + +## Accessing the TMC2240 via SPI +The following diagram depicts how to access the TMC2240 via SPI using the TMC-API. + +![screenshot](registercall_hierarchy_flowchart_SPI.svg) + +The description of the functions, in the above flowchart, are as follows: +- The functions tmc2240_readRegister and tmc2240_writeRegister are used to read and write the registers respectively. These functions check the current active bus and calls the bus-specific function i.e readRegisterSPI or writeRegisterSPI. +- These bus specific functions constructs the datagram and further calls the bus specific callback 'tmcXXXX_readWriteSPI. +- This callback function further calls the hardware specific read/write function for SPI and needs to be implemented externally. + +## Accessing the TMC2240 via UART +The following diagram depicts how to access the TMC2240 via UART using the TMC-API. + +![screenshot](registercall_hierarchy_flowchart_UART.svg) + +The description of the functions, in the above flowchart, are as follows: +- The functions tmc2240_readRegister and tmc2240_writeRegister are used to read and write the registers respectively. These functions check the current active bus and calls the bus-specific function i.e readRegisterUART or writeRegisterUART. +- These bus specific functions constructs the datagram and further calls the bus specific callback 'tmcXXXX_readWriteUART. +- This callback function further calls the hardware specific read/write function for UART and needs to be implemented externally. + +### How to integrate: Callback functions +To communicate with TMC2240 IC, the TMC-API library needs to know which bus (UART, SPI) it shall use. For that, the callback function **'tmc2240_getBusType()'** needs to be implemented. +Additionally, implement the following callback functions to access the chip via SPI: +1. **tmc2240_readWriteSPI()**, which is a HAL wrapper function that provides the necessary hardware access. This function should also set the chip select pin CSN to low before starting the data transfer and set to high upon completion. Please refer to the datasheet of the IC for further details. + +Implement the following callback functions to access the chip via UART: +1. **tmc2240_readWriteUART()**, which is a HAL wrapper function that provides the necessary hardware access. +2. **tmc2240_getNodeAddress()**, that returns the node/slave address. Node address could be set in NODECONF (0x3) register and the address could be incremented as defined by AD0, AD1 and AD2. (Node address + ADx) must be less than 255. For further details please consult the datasheet of TMC2240. + +### Sharing the CRC table with other TMC-API chips +The TMC2240 UART protocol uses an 8 bit CRC. For calculating this, a table-based algorithm is used. This table (tmcCRCTable_Poly7Reflected[256]) is 256 bytes big and identical across multiple different Trinamic chips (i.e. TMC2209). +If multiple Trinamic chips are being used in the same project, avoiding redundant copies of this table could save memory. It is possible to substitute this CRC table with another CRC table. + +### Option to use the cache logic for Write-Only registers +The chip features write-only registers that are unable to be read, necessitating the creation of a shadow copy to cache their contents. This copy is automatically updated whenever data is written to these registers. This cache logic could be enabled by setting the macro **TMC2240_CACHE** to **'1'** or disabled by setting to **'0'** respectively. If this feature is enabled then there comes another option to use **tmc2240_cache** function, which is already implemeted in the API, by defining **TMC2240_ENABLE_TMC_CACHE** macro to **'1** or one can implement their own function. The function **tmc2240_cache** works for both reading from and writing to the shadow array. It first checks whether the register has write-only access and data needs to be read from the hadow copy. On the basis of that, it returns **true** or **false**. The shadowRegisters on the premade cache implementation need to be one per chip. **TMC2240_IC_CACHE_COUNT** is set to '1' by default and is user-overwritable. If multiple chips are being used in the same project, increment its value to the number of chips connected. + +## Further info +### Dependency graph for the ICs with new register R/W mechanism +This graph illustrates the relationships between files within the TMC-API library, highlighting dependencies and identifying the files that are essential for integrating the library into the custom projects. + +![screenshot](uml-tmc-api.svg) + +### Example usage: TMC-Evalsystem +**For a reference usage of the TMC-API**, visit the [TMC-Evalsystem](https://github.com/analogdevicesinc/TMC-EvalSystem) + +## Migration status +The TMC2240 has been reworked to the access system described above. For more infos on the status of this and other ICs, check out the [migration page](https://github.com/analogdevicesinc/TMC-API/issues/53). \ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC2240/TMC2240.c b/firmware/lib/tmc/ic/TMC2240/TMC2240.c new file mode 100755 index 0000000..6b20c80 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2240/TMC2240.c @@ -0,0 +1,306 @@ +/******************************************************************************* +* Copyright © 2017 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#include "TMC2240.h" + +#ifdef TMC_API_EXTERNAL_CRC_TABLE +extern const uint8_t tmcCRCTable_Poly7Reflected[256]; +#else +const uint8_t tmcCRCTable_Poly7Reflected[256] = { + 0x00, 0x91, 0xE3, 0x72, 0x07, 0x96, 0xE4, 0x75, 0x0E, 0x9F, 0xED, 0x7C, 0x09, 0x98, 0xEA, 0x7B, + 0x38, 0xA9, 0xDB, 0x4A, 0x3F, 0xAE, 0xDC, 0x4D, 0x36, 0xA7, 0xD5, 0x44, 0x31, 0xA0, 0xD2, 0x43, + 0x24, 0xB5, 0xC7, 0x56, 0x23, 0xB2, 0xC0, 0x51, 0x2A, 0xBB, 0xC9, 0x58, 0x2D, 0xBC, 0xCE, 0x5F, + 0x70, 0xE1, 0x93, 0x02, 0x77, 0xE6, 0x94, 0x05, 0x7E, 0xEF, 0x9D, 0x0C, 0x79, 0xE8, 0x9A, 0x0B, + 0x6C, 0xFD, 0x8F, 0x1E, 0x6B, 0xFA, 0x88, 0x19, 0x62, 0xF3, 0x81, 0x10, 0x65, 0xF4, 0x86, 0x17, + 0x48, 0xD9, 0xAB, 0x3A, 0x4F, 0xDE, 0xAC, 0x3D, 0x46, 0xD7, 0xA5, 0x34, 0x41, 0xD0, 0xA2, 0x33, + 0x54, 0xC5, 0xB7, 0x26, 0x53, 0xC2, 0xB0, 0x21, 0x5A, 0xCB, 0xB9, 0x28, 0x5D, 0xCC, 0xBE, 0x2F, + 0xE0, 0x71, 0x03, 0x92, 0xE7, 0x76, 0x04, 0x95, 0xEE, 0x7F, 0x0D, 0x9C, 0xE9, 0x78, 0x0A, 0x9B, + 0xFC, 0x6D, 0x1F, 0x8E, 0xFB, 0x6A, 0x18, 0x89, 0xF2, 0x63, 0x11, 0x80, 0xF5, 0x64, 0x16, 0x87, + 0xD8, 0x49, 0x3B, 0xAA, 0xDF, 0x4E, 0x3C, 0xAD, 0xD6, 0x47, 0x35, 0xA4, 0xD1, 0x40, 0x32, 0xA3, + 0xC4, 0x55, 0x27, 0xB6, 0xC3, 0x52, 0x20, 0xB1, 0xCA, 0x5B, 0x29, 0xB8, 0xCD, 0x5C, 0x2E, 0xBF, + 0x90, 0x01, 0x73, 0xE2, 0x97, 0x06, 0x74, 0xE5, 0x9E, 0x0F, 0x7D, 0xEC, 0x99, 0x08, 0x7A, 0xEB, + 0x8C, 0x1D, 0x6F, 0xFE, 0x8B, 0x1A, 0x68, 0xF9, 0x82, 0x13, 0x61, 0xF0, 0x85, 0x14, 0x66, 0xF7, + 0xA8, 0x39, 0x4B, 0xDA, 0xAF, 0x3E, 0x4C, 0xDD, 0xA6, 0x37, 0x45, 0xD4, 0xA1, 0x30, 0x42, 0xD3, + 0xB4, 0x25, 0x57, 0xC6, 0xB3, 0x22, 0x50, 0xC1, 0xBA, 0x2B, 0x59, 0xC8, 0xBD, 0x2C, 0x5E, 0xCF, +}; +#endif + +/**************************************************************** Cache Implementation *************************************************************************/ + +#if TMC2240_CACHE == 0 +static inline bool tmc2240_cache(uint16_t icID, TMC2240CacheOp operation, uint8_t address, uint32_t *value) +{ + UNUSED(icID); + UNUSED(address); + UNUSED(operation); + return false; +} +#else +#if TMC2240_ENABLE_TMC_CACHE == 1 + +uint8_t tmc2240_dirtyBits[TMC2240_IC_CACHE_COUNT][TMC2240_REGISTER_COUNT/8]= {0}; +int32_t tmc2240_shadowRegister[TMC2240_IC_CACHE_COUNT][TMC2240_REGISTER_COUNT]; + +void tmc2240_setDirtyBit(uint16_t icID, uint8_t index, bool value) +{ + if(index >= TMC2240_REGISTER_COUNT) + return; + + uint8_t *tmp = &tmc2240_dirtyBits[icID][index / 8]; + uint8_t shift = (index % 8); + uint8_t mask = 1 << shift; + *tmp = (((*tmp) & (~(mask))) | (((value) << (shift)) & (mask))); +} + +bool tmc2240_getDirtyBit(uint16_t icID, uint8_t index) +{ + if(index >= TMC2240_REGISTER_COUNT) + return false; + + uint8_t *tmp = &tmc2240_dirtyBits[icID][index / 8]; + uint8_t shift = (index % 8); + return ((*tmp) >> shift) & 1; +} +/* + * This function is used to cache the value written to the Write-Only registers in the form of shadow array. + * The shadow copy is then used to read these kinds of registers. + */ + +bool tmc2240_cache(uint16_t icID, TMC2240CacheOp operation, uint8_t address, uint32_t *value) +{ + if (operation == TMC2240_CACHE_READ) + { + // Check if the value should come from cache + + // Only supported chips have a cache + if (icID >= TMC2240_IC_CACHE_COUNT) + return false; + + // Only non-readable registers care about caching + // Note: This could also be used to cache i.e. RW config registers to reduce bus accesses + if (TMC2240_IS_READABLE(tmc2240_registerAccess[address])) + return false; + + // Grab the value from the cache + *value = tmc2240_shadowRegister[icID][address]; + return true; + } + else if (operation == TMC2240_CACHE_WRITE || operation == TMC2240_CACHE_FILL_DEFAULT) + { + // Fill the cache + + // only supported chips have a cache + if (icID >= TMC2240_IC_CACHE_COUNT) + return false; + + // Write to the shadow register. + tmc2240_shadowRegister[icID][address] = *value; + // For write operations, mark the register dirty + if (operation == TMC2240_CACHE_WRITE) + { + tmc2240_setDirtyBit(icID, address, true); + } + + return true; + } + return false; +} + +void tmc2240_initCache() +{ + // Check if we have constants defined + if(ARRAY_SIZE(tmc2240_RegisterConstants) == 0) + return; + + size_t i, j, id; + + for(i = 0, j = 0; i < TMC2240_REGISTER_COUNT; i++) + { + // We only need to worry about hardware preset, write-only registers + // that have not yet been written (no dirty bit) here. + if(tmc2240_registerAccess[i] != TMC2240_ACCESS_W_PRESET) + continue; + + // Search the constant list for the current address. With the constant + // list being sorted in ascended order, we can walk through the list + // until the entry with an address equal or greater than i + while(j < ARRAY_SIZE(tmc2240_RegisterConstants) && (tmc2240_RegisterConstants[j].address < i)) + j++; + + // Abort when we reach the end of the constant list + if (j == ARRAY_SIZE(tmc2240_RegisterConstants)) + break; + + // If we have an entry for our current address, write the constant + if(tmc2240_RegisterConstants[j].address == i) + { + for (id = 0; id < TMC2240_IC_CACHE_COUNT; id++) + { + uint32_t temp = tmc2240_RegisterConstants[j].value; + tmc2240_cache(id, TMC2240_CACHE_FILL_DEFAULT, i, &temp); + } + } + } +} +#else +// User must implement their own cache +extern bool tmc2240_cache(uint16_t icID, TMC2240CacheOp operation, uint8_t address, uint32_t *value); +#endif +#endif + +/************************************************************* read / write Implementation *********************************************************************/ + + +static int32_t readRegisterSPI(uint16_t icID, uint8_t address); +static void writeRegisterSPI(uint16_t icID, uint8_t address, int32_t value); +static int32_t readRegisterUART(uint16_t icID, uint8_t registerAddress); +static void writeRegisterUART(uint16_t icID, uint8_t registerAddress, int32_t value); +static uint8_t CRC8(uint8_t *data, uint32_t bytes); + + + +int32_t tmc2240_readRegister(uint16_t icID, uint8_t address) +{ + uint32_t value; + + // Read from cache for registers with write-only access + if (tmc2240_cache(icID, TMC2240_CACHE_READ, address, &value)) + return value; + + TMC2240BusType bus = tmc2240_getBusType(icID); + + if(bus == IC_BUS_SPI) + { + return readRegisterSPI(icID, address); + } + else if (bus == IC_BUS_UART) + { + return readRegisterUART(icID, address); + } + + // ToDo: Error handling + return -1; +} +void tmc2240_writeRegister(uint16_t icID, uint8_t address, int32_t value) +{ + TMC2240BusType bus = tmc2240_getBusType(icID); + + if(bus == IC_BUS_SPI) + { + writeRegisterSPI(icID, address, value); + } + else if(bus == IC_BUS_UART) + { + writeRegisterUART(icID, address, value); + } + //Cache the registers with write-only access + tmc2240_cache(icID, TMC2240_CACHE_WRITE, address, (uint32_t *)&value); +} + +int32_t readRegisterSPI(uint16_t icID, uint8_t address) +{ + uint8_t data[5] = { 0 }; + + // clear write bit + data[0] = address & TMC2240_ADDRESS_MASK; + + // Send the read request + tmc2240_readWriteSPI(icID, &data[0], sizeof(data)); + + // Rewrite address and clear write bit + data[0] = address & TMC2240_ADDRESS_MASK; + + // Send another request to receive the read reply + tmc2240_readWriteSPI(icID, &data[0], sizeof(data)); + + return ((int32_t)data[1] << 24) | ((int32_t) data[2] << 16) | ((int32_t) data[3] << 8) | ((int32_t) data[4]); +} + +void writeRegisterSPI(uint16_t icID, uint8_t address, int32_t value) +{ + uint8_t data[5] = { 0 }; + + data[0] = address | TMC2240_WRITE_BIT; + data[1] = 0xFF & (value>>24); + data[2] = 0xFF & (value>>16); + data[3] = 0xFF & (value>>8); + data[4] = 0xFF & (value>>0); + + // Send the write request + tmc2240_readWriteSPI(icID, &data[0], sizeof(data)); +} + +int32_t readRegisterUART(uint16_t icID, uint8_t registerAddress) +{ + uint8_t data[8] = { 0 }; + + registerAddress = registerAddress & TMC2240_ADDRESS_MASK; + + data[0] = 0x05; + data[1] = tmc2240_getNodeAddress(icID); + data[2] = registerAddress; + data[3] = CRC8(data, 3); + + if (!tmc2240_readWriteUART(icID, &data[0], 4, 8)) + return 0; + + // Byte 0: Sync nibble correct? + if (data[0] != 0x05) + return 0; + + // Byte 1: Master address correct? + if (data[1] != 0xFF) + return 0; + + // Byte 2: Address correct? + if (data[2] != registerAddress) + return 0; + + // Byte 7: CRC correct? + if (data[7] != CRC8(data, 7)) + return 0; + + return ((uint32_t)data[3] << 24) | ((uint32_t)data[4] << 16) | (data[5] << 8) | data[6]; +} + +void writeRegisterUART(uint16_t icID, uint8_t registerAddress, int32_t value) +{ + uint8_t data[8]; + + data[0] = 0x05; + data[1] = tmc2240_getNodeAddress(icID); + data[2] = registerAddress | TMC2240_WRITE_BIT; + data[3] = (value >> 24) & 0xFF; + data[4] = (value >> 16) & 0xFF; + data[5] = (value >> 8 ) & 0xFF; + data[6] = (value ) & 0xFF; + data[7] = CRC8(data, 7); + + tmc2240_readWriteUART(icID, &data[0], 8, 0); +} + +static uint8_t CRC8(uint8_t *data, uint32_t bytes) +{ + uint8_t result = 0; + + while(bytes--) + result = tmcCRCTable_Poly7Reflected[result ^ *data++]; + + // Flip the result around + // swap odd and even bits + result = ((result >> 1) & 0x55) | ((result & 0x55) << 1); + // swap consecutive pairs + result = ((result >> 2) & 0x33) | ((result & 0x33) << 2); + // swap nibbles ... + result = ((result >> 4) & 0x0F) | ((result & 0x0F) << 4); + + return result; +} + +/***************************************************************************************************************************************************************/ diff --git a/firmware/lib/tmc/ic/TMC2240/TMC2240.h b/firmware/lib/tmc/ic/TMC2240/TMC2240.h new file mode 100755 index 0000000..9965c23 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2240/TMC2240.h @@ -0,0 +1,224 @@ +/******************************************************************************* +* Copyright © 2017 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#ifndef TMC_IC_TMC2240_H_ + +#include +#include +#include +#include "TMC2240_HW_Abstraction.h" + + +/******************************************************************************* +* API Configuration Defines +* These control optional features of the TMC-API implementation. +* These can be commented in/out here or defined from the build system. +*******************************************************************************/ + +// Uncomment if you want to save space..... +// and put the table into your own .c file +//#define TMC_API_EXTERNAL_CRC_TABLE 1 + +// To enable the cache mechanism in order to keep the copy of all registers, set TMC2240_CACHE to '1'. +// With this mechanism the value of write-only registers could be read from their shadow copies. +#ifndef TMC2240_CACHE +#define TMC2240_CACHE 1 +//#define TMC2240_CACHE 0 +#endif + +// To use the caching mechanism already implemented by the TMC-API, set TMC2240_ENABLE_TMC_CACHE to '1'. +// Set TMC2240_ENABLE_TMC_CACHE to '0' if one wants to have their own cache implementation. +#ifndef TMC2240_ENABLE_TMC_CACHE +#define TMC2240_ENABLE_TMC_CACHE 1 +//#define TMC2240_ENABLE_TMC_CACHE 0 +#endif + +/******************************************************************************/ + + +typedef enum { + IC_BUS_SPI, + IC_BUS_UART, + IC_BUS_WLAN, +} TMC2240BusType; + +// => TMC-API wrapper +extern void tmc2240_readWriteSPI(uint16_t icID, uint8_t *data, size_t dataLength); +extern bool tmc2240_readWriteUART(uint16_t icID, uint8_t *data, size_t writeLength, size_t readLength); +extern TMC2240BusType tmc2240_getBusType(uint16_t icID); +extern uint8_t tmc2240_getNodeAddress(uint16_t icID); +// => TMC-API wrapper + +int32_t tmc2240_readRegister(uint16_t icID, uint8_t address); +void tmc2240_writeRegister(uint16_t icID, uint8_t address, int32_t value); + +typedef struct +{ + uint32_t mask; + uint8_t shift; + uint8_t address; + bool isSigned; +} RegisterField; + + +static inline uint32_t tmc2240_fieldExtract(uint32_t data, RegisterField field) +{ + uint32_t value = (data & field.mask) >> field.shift; + + if (field.isSigned) + { + // Apply signedness conversion + uint32_t baseMask = field.mask >> field.shift; + uint32_t signMask = baseMask & (~baseMask >> 1); + value = (value ^ signMask) - signMask; + } + + return value; +} + +static inline uint32_t tmc2240_fieldRead(uint16_t icID, RegisterField field) +{ + uint32_t value = tmc2240_readRegister(icID, field.address); + + return tmc2240_fieldExtract(value, field); +} + +static inline uint32_t tmc2240_fieldUpdate(uint32_t data, RegisterField field, uint32_t value) +{ + return (data & (~field.mask)) | ((value << field.shift) & field.mask); +} + +static inline void tmc2240_fieldWrite(uint16_t icID, RegisterField field, uint32_t value) +{ + uint32_t regValue = tmc2240_readRegister(icID, field.address); + + regValue = tmc2240_fieldUpdate(regValue, field, value); + + tmc2240_writeRegister(icID, field.address, regValue); +} + +/**************************************************************** Cache Implementation *************************************************************************/ +#if TMC2240_CACHE == 1 +#ifdef TMC2240_ENABLE_TMC_CACHE + +// By default, support one IC in the cache +#ifndef TMC2240_IC_CACHE_COUNT +#define TMC2240_IC_CACHE_COUNT 1 +#endif + +typedef enum { + TMC2240_CACHE_READ, + TMC2240_CACHE_WRITE, + // Special operation: Put content into the cache without marking the entry as dirty. + // Only used to initialize the cache with hardware defaults. This will allow reading + // from write-only registers that have a value inside them on reset. When using this + // operation, a restore will *not* rewrite that filled register! + TMC2240_CACHE_FILL_DEFAULT, +} TMC2240CacheOp; + +typedef struct{ + uint8_t address; + uint32_t value; +} TMC2240RegisterConstants; + +#define TMC2240_ACCESS_DIRTY 0x08 // Register has been written since reset -> shadow register is valid for restore +#define TMC2240_ACCESS_READ 0x01 +#define TMC2240_ACCESS_W_PRESET 0x42 +#define TMC2240_IS_READABLE(x) ((x) & TMC2240_ACCESS_READ) +#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) + +// Helper define: +// Most register permission arrays are initialized with 128 values. +// In those fields its quite hard to have an easy overview of available +// registers. For that, ____ is defined to 0, since 4 underscores are +// very easy to distinguish from the 2-digit hexadecimal values. +// This way, the used registers (permission != ACCESS_NONE) are easily spotted +// amongst unused (permission == ACCESS_NONE) registers. +#define ____ 0x00 + +// Helper define: +// Default reset values are not used if the corresponding register has a +// hardware preset. Since this is not directly visible in the default +// register reset values array, N_A is used as an indicator for a preset +// value, where any value will be ignored anyways (N_A: not available). +#define N_A 0 + +// Default Register values +#define R00 0x00002108 // GCONF +#define R0A 0x00000020 // DRVCONF +#define R10 0x00070A03 // IHOLD_IRUN +#define R11 0x0000000A // TPOWERDOWN +#define R2B 0x00000001 // VSTOP +#define R3A 0x00010000 // ENC_CONST +#define R52 0x0B920F25 // OTW_OV_VTH +#define R6C 0x14410153 // CHOPCONF +#define R70 0xC44C001E // PWMCONF + +// Register access permissions: +// 0x00: none (reserved) +// 0x01: read +// 0x02: write +// 0x03: read/write +// 0x13: read/write, separate functions/values for reading or writing +// 0x23: read/write, flag register (write to clear) +// 0x42: write, has hardware presets on reset +static const uint8_t tmc2240_registerAccess[TMC2240_REGISTER_COUNT] = +{ + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0x03, 0x23, 0x01, 0x03, 0x03, ____, ____, ____, ____, ____, 0x03, 0x03, ____, ____, ____, ____, // 0x00 - 0x0F + 0x03, 0x03, 0x01, 0x03, 0x03, 0x03, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x10 - 0x1F + ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, 0x03, ____, ____, // 0x20 - 0x2F + ____, ____, ____, ____, ____, ____, ____, ____, 0x03, 0x03, 0x03, 0x23, 0x01, ____, ____, ____, // 0x30 - 0x3F + ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x40 - 0x4F + 0x01, 0x01, 0x03, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x50 - 0x5F + 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x01, 0x01, 0x03, 0x03, ____, 0x01, // 0x60 - 0x6F + 0x03, 0x01, 0x01, ____, 0x03, 0x01, 0x01, ____, ____, ____, ____, ____, ____, ____, ____, ____ // 0x70 - 0x7F +}; +static const int32_t tmc2240_sampleRegisterPreset[TMC2240_REGISTER_COUNT] = +{ + // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F + R00, 0, 0, 0, 0, 0, 0, 0, 0, 0, R0A, 0, 0, 0, 0, 0, // 0x00 - 0x0F + R10, R11, 0, 0, 0, 0, 0, 0, 0, 0, 0, R2B, 0, 0, 0, 0, // 0x10 - 0x1F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x20 - 0x2F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, R3A, 0, 0, 0, 0, 0, // 0x30 - 0x3F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x40 - 0x4F + 0, 0, R52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x50 - 0x5F + N_A, N_A, N_A, N_A, N_A, N_A, N_A, N_A, N_A, N_A, 0, 0, R6C, 0, 0, 0, // 0x60 - 0x6F + R70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x70 - 0x7F +}; + + +// Register constants (only required for 0x42 registers, since we do not have +// any way to find out the content but want to hold the actual value in the +// shadow register so an application (i.e. the TMCL IDE) can still display +// the values. This only works when the register content is constant. +static const TMC2240RegisterConstants tmc2240_RegisterConstants[] = +{ // Use ascending addresses! + { 0x60, 0xAAAAB554 }, // MSLUT[0] + { 0x61, 0x4A9554AA }, // MSLUT[1] + { 0x62, 0x24492929 }, // MSLUT[2] + { 0x63, 0x10104222 }, // MSLUT[3] + { 0x64, 0xFBFFFFFF }, // MSLUT[4] + { 0x65, 0xB5BB777D }, // MSLUT[5] + { 0x66, 0x49295556 }, // MSLUT[6] + { 0x67, 0x00404222 }, // MSLUT[7] + { 0x68, 0xFFFF8056 }, // MSLUTSEL + { 0x69, 0x00F70000 } // MSLUTSTART +}; + +extern uint8_t tmc2240_dirtyBits[TMC2240_IC_CACHE_COUNT][TMC2240_REGISTER_COUNT/8]; +extern int32_t tmc2240_shadowRegister[TMC2240_IC_CACHE_COUNT][TMC2240_REGISTER_COUNT]; +bool tmc2240_cache(uint16_t icID, TMC2240CacheOp operation, uint8_t address, uint32_t *value); +void tmc2240_initCache(void); +void tmc2240_setDirtyBit(uint16_t icID, uint8_t index, bool value); +bool tmc2240_getDirtyBit(uint16_t icID, uint8_t index); +#endif +#endif +/***************************************************************************************************************************************************/ +#endif /* TMC_IC_TMC2240_H_ */ diff --git a/firmware/lib/tmc/ic/TMC2240/TMC2240_HW_Abstraction.h b/firmware/lib/tmc/ic/TMC2240/TMC2240_HW_Abstraction.h new file mode 100755 index 0000000..e64922b --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2240/TMC2240_HW_Abstraction.h @@ -0,0 +1,567 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#ifndef TMC_IC_TMC2240_H_ +#define TMC_IC_TMC2240_H_ + +// Constants +#define TMC2240_REGISTER_COUNT 128 +#define TMC2240_MOTORS 1 +#define TMC2240_WRITE_BIT 0x80 +#define TMC2240_ADDRESS_MASK 0x7F +#define TMC2240_MAX_VELOCITY 8388096 +#define TMC2240_MAX_ACCELERATION (uint16_t) 65535 + +// ramp modes (Register TMC2240_RAMPMODE) +#define TMC2240_MODE_POSITION 0 +#define TMC2240_MODE_VELPOS 1 +#define TMC2240_MODE_VELNEG 2 +#define TMC2240_MODE_HOLD 3 + +// limit switch mode bits (Register TMC2240_SWMODE) +#define TMC2240_SW_STOPL_ENABLE 0x0001 +#define TMC2240_SW_STOPR_ENABLE 0x0002 +#define TMC2240_SW_STOPL_POLARITY 0x0004 +#define TMC2240_SW_STOPR_POLARITY 0x0008 +#define TMC2240_SW_SWAP_LR 0x0010 +#define TMC2240_SW_LATCH_L_ACT 0x0020 +#define TMC2240_SW_LATCH_L_INACT 0x0040 +#define TMC2240_SW_LATCH_R_ACT 0x0080 +#define TMC2240_SW_LATCH_R_INACT 0x0100 +#define TMC2240_SW_LATCH_ENC 0x0200 +#define TMC2240_SW_SG_STOP 0x0400 +#define TMC2240_SW_SOFTSTOP 0x0800 + +// Status bits (Register TMC2240_RAMPSTAT) +#define TMC2240_RS_STOPL 0x0001 +#define TMC2240_RS_STOPR 0x0002 +#define TMC2240_RS_LATCHL 0x0004 +#define TMC2240_RS_LATCHR 0x0008 +#define TMC2240_RS_EV_STOPL 0x0010 +#define TMC2240_RS_EV_STOPR 0x0020 +#define TMC2240_RS_EV_STOP_SG 0x0040 +#define TMC2240_RS_EV_POSREACHED 0x0080 +#define TMC2240_RS_VELREACHED 0x0100 +#define TMC2240_RS_POSREACHED 0x0200 +#define TMC2240_RS_VZERO 0x0400 +#define TMC2240_RS_ZEROWAIT 0x0800 +#define TMC2240_RS_SECONDMOVE 0x1000 +#define TMC2240_RS_SG 0x2000 + +// Encoderbits (Register TMC2240_ENCMODE) +#define TMC2240_EM_DECIMAL 0x0400 +#define TMC2240_EM_LATCH_XACT 0x0200 +#define TMC2240_EM_CLR_XENC 0x0100 +#define TMC2240_EM_NEG_EDGE 0x0080 +#define TMC2240_EM_POS_EDGE 0x0040 +#define TMC2240_EM_CLR_ONCE 0x0020 +#define TMC2240_EM_CLR_CONT 0x0010 +#define TMC2240_EM_IGNORE_AB 0x0008 +#define TMC2240_EM_POL_N 0x0004 +#define TMC2240_EM_POL_B 0x0002 +#define TMC2240_EM_POL_A 0x0001 + + +// Registers +#define TMC2240_GCONF 0x00 +#define TMC2240_GSTAT 0x01 +#define TMC2240_IFCNT 0x02 +#define TMC2240_SLAVECONF 0x03 +#define TMC2240_IOIN 0x04 +#define TMC2240_DRV_CONF 0x0A +#define TMC2240_GLOBAL_SCALER 0x0B + +#define TMC2240_IHOLD_IRUN 0x10 +#define TMC2240_TPOWERDOWN 0x11 +#define TMC2240_TSTEP 0x12 +#define TMC2240_TPWMTHRS 0x13 +#define TMC2240_TCOOLTHRS 0x14 +#define TMC2240_THIGH 0x15 + +#define TMC2240_DIRECT_MODE 0x2D + +#define TMC2240_ENCMODE 0x38 +#define TMC2240_XENC 0x39 +#define TMC2240_ENC_CONST 0x3A +#define TMC2240_ENC_STATUS 0x3B +#define TMC2240_ENC_LATCH 0x3C + +#define TMC2240_ADC_VSUPPLY_AIN 0x50 +#define TMC2240_ADC_TEMP 0x51 +#define TMC2240_OTW_OV_VTH 0x52 + +#define TMC2240_MSLUT0 0x60 +#define TMC2240_MSLUT1 0x61 +#define TMC2240_MSLUT2 0x62 +#define TMC2240_MSLUT3 0x63 +#define TMC2240_MSLUT4 0x64 +#define TMC2240_MSLUT5 0x65 +#define TMC2240_MSLUT6 0x66 +#define TMC2240_MSLUT7 0x67 +#define TMC2240_MSLUTSEL 0x68 +#define TMC2240_MSLUTSTART 0x69 +#define TMC2240_MSCNT 0x6A +#define TMC2240_MSCURACT 0x6B +#define TMC2240_CHOPCONF 0x6C +#define TMC2240_COOLCONF 0x6D +#define TMC2240_DCCTRL 0x6E +#define TMC2240_DRVSTATUS 0x6F + +#define TMC2240_PWMCONF 0x70 +#define TMC2240_PWM_SCALE 0x71 +#define TMC2240_PWM_AUTO 0x72 +#define TMC2240_SG4_THRS 0x74 +#define TMC2240_SG4_RESULT 0x75 +#define TMC2240_SG4_IND 0x76 + + +// Register fields +#define TMC2240_FAST_STANDSTILL_MASK 0x00000002 +#define TMC2240_FAST_STANDSTILL_SHIFT 1 +#define TMC2240_FAST_STANDSTILL_FIELD ((RegisterField) {TMC2240_FAST_STANDSTILL_MASK, TMC2240_FAST_STANDSTILL_SHIFT, TMC2240_GCONF, false}) +#define TMC2240_EN_PWM_MODE_MASK 0x00000004 +#define TMC2240_EN_PWM_MODE_SHIFT 2 +#define TMC2240_EN_PWM_MODE_FIELD ((RegisterField) {TMC2240_EN_PWM_MODE_MASK, TMC2240_EN_PWM_MODE_SHIFT, TMC2240_GCONF, false}) +#define TMC2240_MULTISTEP_FILT_MASK 0x00000008 +#define TMC2240_MULTISTEP_FILT_SHIFT 3 +#define TMC2240_MULTISTEP_FILT_FIELD ((RegisterField) {TMC2240_MULTISTEP_FILT_MASK, TMC2240_MULTISTEP_FILT_SHIFT, TMC2240_GCONF, false}) +#define TMC2240_SHAFT_MASK 0x00000010 +#define TMC2240_SHAFT_SHIFT 4 +#define TMC2240_SHAFT_FIELD ((RegisterField) {TMC2240_SHAFT_MASK, TMC2240_SHAFT_SHIFT, TMC2240_GCONF, false}) +#define TMC2240_DIAG0_ERROR_MASK 0x00000020 +#define TMC2240_DIAG0_ERROR_SHIFT 5 +#define TMC2240_DIAG0_ERROR_FIELD ((RegisterField) {TMC2240_DIAG0_ERROR_MASK, TMC2240_DIAG0_ERROR_SHIFT, TMC2240_GCONF, false}) +#define TMC2240_DIAG0_OTPW_MASK 0x00000040 +#define TMC2240_DIAG0_OTPW_SHIFT 6 +#define TMC2240_DIAG0_OTPW_FIELD ((RegisterField) {TMC2240_DIAG0_OTPW_MASK, TMC2240_DIAG0_OTPW_SHIFT, TMC2240_GCONF, false}) +#define TMC2240_DIAG0_STALL_MASK 0x00000080 +#define TMC2240_DIAG0_STALL_SHIFT 7 +#define TMC2240_DIAG0_STALL_FIELD ((RegisterField) {TMC2240_DIAG0_STALL_MASK, TMC2240_DIAG0_STALL_SHIFT, TMC2240_GCONF, false}) +#define TMC2240_DIAG1_STALL_MASK 0x00000100 +#define TMC2240_DIAG1_STALL_SHIFT 8 +#define TMC2240_DIAG1_STALL_FIELD ((RegisterField) {TMC2240_DIAG1_STALL_MASK, TMC2240_DIAG1_STALL_SHIFT, TMC2240_GCONF, false}) +#define TMC2240_DIAG1_INDEX_MASK 0x00000200 +#define TMC2240_DIAG1_INDEX_SHIFT 9 +#define TMC2240_DIAG1_INDEX_FIELD ((RegisterField) {TMC2240_DIAG1_INDEX_MASK, TMC2240_DIAG1_INDEX_SHIFT, TMC2240_GCONF, false}) +#define TMC2240_DIAG1_ONSTATE_MASK 0x00000400 +#define TMC2240_DIAG1_ONSTATE_SHIFT 10 +#define TMC2240_DIAG1_ONSTATE_FIELD ((RegisterField) {TMC2240_DIAG1_ONSTATE_MASK, TMC2240_DIAG1_ONSTATE_SHIFT, TMC2240_GCONF, false}) +#define TMC2240_DIAG0_PUSHPULL_MASK 0x00001000 +#define TMC2240_DIAG0_PUSHPULL_SHIFT 12 +#define TMC2240_DIAG0_PUSHPULL_FIELD ((RegisterField) {TMC2240_DIAG0_PUSHPULL_MASK, TMC2240_DIAG0_PUSHPULL_SHIFT, TMC2240_GCONF, false}) +#define TMC2240_DIAG1_PUSHPULL_MASK 0x00002000 +#define TMC2240_DIAG1_PUSHPULL_SHIFT 13 +#define TMC2240_DIAG1_PUSHPULL_FIELD ((RegisterField) {TMC2240_DIAG1_PUSHPULL_MASK, TMC2240_DIAG1_PUSHPULL_SHIFT, TMC2240_GCONF, false}) +#define TMC2240_SMALL_HYSTERESIS_MASK 0x00004000 +#define TMC2240_SMALL_HYSTERESIS_SHIFT 14 +#define TMC2240_SMALL_HYSTERESIS_FIELD ((RegisterField) {TMC2240_SMALL_HYSTERESIS_MASK, TMC2240_SMALL_HYSTERESIS_SHIFT, TMC2240_GCONF, false}) +#define TMC2240_STOP_ENABLE_MASK 0x00008000 +#define TMC2240_STOP_ENABLE_SHIFT 15 +#define TMC2240_STOP_ENABLE_FIELD ((RegisterField) {TMC2240_STOP_ENABLE_MASK, TMC2240_STOP_ENABLE_SHIFT, TMC2240_GCONF, false}) +#define TMC2240_DIRECT_MODE_MASK 0x00010000 +#define TMC2240_DIRECT_MODE_SHIFT 16 +#define TMC2240_DIRECT_MODE_FIELD ((RegisterField) {TMC2240_DIRECT_MODE_MASK, TMC2240_DIRECT_MODE_SHIFT, TMC2240_GCONF, false}) +#define TMC2240_RESET_MASK 0x00000001 +#define TMC2240_RESET_SHIFT 0 +#define TMC2240_RESET_FIELD ((RegisterField) {TMC2240_RESET_MASK, TMC2240_RESET_SHIFT, TMC2240_GSTAT, false}) +#define TMC2240_DRV_ERR_MASK 0x00000002 +#define TMC2240_DRV_ERR_SHIFT 1 +#define TMC2240_DRV_ERR_FIELD ((RegisterField) {TMC2240_DRV_ERR_MASK, TMC2240_DRV_ERR_SHIFT, TMC2240_GSTAT, false}) +#define TMC2240_UV_CP_MASK 0x00000004 +#define TMC2240_UV_CP_SHIFT 2 +#define TMC2240_UV_CP_FIELD ((RegisterField) {TMC2240_UV_CP_MASK, TMC2240_UV_CP_SHIFT, TMC2240_GSTAT, false}) +#define TMC2240_REGISTER_RESET_MASK 0x00000008 +#define TMC2240_REGISTER_RESET_SHIFT 3 +#define TMC2240_REGISTER_RESET_FIELD ((RegisterField) {TMC2240_REGISTER_RESET_MASK, TMC2240_REGISTER_RESET_SHIFT, TMC2240_GSTAT, false}) +#define TMC2240_VM_UVLO_MASK 0x00000010 +#define TMC2240_VM_UVLO_SHIFT 4 +#define TMC2240_VM_UVLO_FIELD ((RegisterField) {TMC2240_VM_UVLO_MASK, TMC2240_VM_UVLO_SHIFT, TMC2240_GSTAT, false}) +#define TMC2240_IFCNT_MASK 0x000000FF +#define TMC2240_IFCNT_SHIFT 0 +#define TMC2240_IFCNT_FIELD ((RegisterField) {TMC2240_IFCNT_MASK, TMC2240_IFCNT_SHIFT, TMC2240_IFCNT, false}) +#define TMC2240_SLAVEADDR_MASK 0x000000FF +#define TMC2240_SLAVEADDR_SHIFT 0 +#define TMC2240_SLAVEADDR_FIELD ((RegisterField) {TMC2240_SLAVEADDR_MASK, TMC2240_SLAVEADDR_SHIFT, TMC2240_SLAVECONF, false}) +#define TMC2240_SENDDELAY_MASK 0x00000F00 +#define TMC2240_SENDDELAY_SHIFT 8 +#define TMC2240_SENDDELAY_FIELD ((RegisterField) {TMC2240_SENDDELAY_MASK, TMC2240_SENDDELAY_SHIFT, TMC2240_SLAVECONF, false}) +#define TMC2240_STEP_MASK 0x00000001 +#define TMC2240_STEP_SHIFT 0 +#define TMC2240_STEP_FIELD ((RegisterField) {TMC2240_STEP_MASK, TMC2TMC2240_GCONF240_STEP_SHIFT, TMC2240_IOIN, false}) +#define TMC2240_DIR_MASK 0x00000002 +#define TMC2240_DIR_SHIFT 1 +#define TMC2240_DIR_FIELD ((RegisterField) {TMC2240_DIR_MASK, TMC2240_DIR_SHIFT, TMC2240_IOIN, false}) +#define TMC2240_ENCB_MASK 0x00000004 +#define TMC2240_ENCB_SHIFT 2 +#define TMC2240_ENCB_FIELD ((RegisterField) {TMC2240_ENCB_MASK, TMC2240_ENCB_SHIFT, TMC2240_IOIN, false}) +#define TMC2240_ENCA_MASK 0x00000008 +#define TMC2240_ENCA_SHIFT 3 +#define TMC2240_ENCA_FIELD ((RegisterField) {TMC2240_ENCA_MASK, TMC2240_ENCA_SHIFT, TMC2240_IOIN, false}) +#define TMC2240_DRV_ENN_MASK 0x00000010 +#define TMC2240_DRV_ENN_SHIFT 4 +#define TMC2240_DRV_ENN_FIELD ((RegisterField) {TMC2240_DRV_ENN_MASK, TMC2240_DRV_ENN_SHIFT, TMC2240_IOIN, false}) +#define TMC2240_ENCN_MASK 0x00000020 +#define TMC2240_ENCN_SHIFT 5 +#define TMC2240_ENCN_FIELD ((RegisterField) {TMC2240_ENCN_MASK, TMC2240_ENCN_SHIFT, TMC2240_IOIN, false}) +#define TMC2240_UART_EN_MASK 0x00000040 +#define TMC2240_UART_EN_SHIFT 6 +#define TMC2240_UART_EN_FIELD ((RegisterField) {TMC2240_UART_EN_MASK, TMC2240_UART_EN_SHIFT, TMC2240_IOIN, false}) +#define TMC2240_RESERVED_MASK 0x00000080 +#define TMC2240_RESERVED_SHIFT 7 +#define TMC2240_RESERVED_FIELD ((RegisterField) {TMC2240_RESERVED_MASK, TMC2240_RESERVED_SHIFT, TMC2240_IOIN, false}) +#define TMC2240_COMP_A_MASK 0x00000100 +#define TMC2240_COMP_A_SHIFT 8 +#define TMC2240_COMP_A_FIELD ((RegisterField) {TMC2240_COMP_A_MASK, TMC2240_COMP_A_SHIFT, TMC2240_IOIN, false}) +#define TMC2240_COMP_B_MASK 0x00000200 +#define TMC2240_COMP_B_SHIFT 9 +#define TMC2240_COMP_B_FIELD ((RegisterField) {TMC2240_COMP_B_MASK, TMC2240_COMP_B_SHIFT, TMC2240_IOIN, false}) +#define TMC2240_COMP_A1_A2_MASK 0x00000400 +#define TMC2240_COMP_A1_A2_SHIFT 10 +#define TMC2240_COMP_A1_A2_FIELD ((RegisterField) {TMC2240_COMP_A1_A2_MASK, TMC2240_COMP_A1_A2_SHIFT, TMC2240_IOIN, false}) +#define TMC2240_COMP_B1_B2_MASK 0x00000800 +#define TMC2240_COMP_B1_B2_SHIFT 11 +#define TMC2240_COMP_B1_B2_FIELD ((RegisterField) {TMC2240_COMP_B1_B2_MASK, TMC2240_COMP_B1_B2_SHIFT, TMC2240_IOIN, false}) +#define TMC2240_OUTPUT_MASK 0x00001000 +#define TMC2240_OUTPUT_SHIFT 12 +#define TMC2240_OUTPUT_FIELD ((RegisterField) {TMC2240_OUTPUT_MASK, TMC2240_OUTPUT_SHIFT, TMC2240_IOIN, false}) +#define TMC2240_EXT_RES_DET_MASK 0x00002000 +#define TMC2240_EXT_RES_DET_SHIFT 13 +#define TMC2240_EXT_RES_DET_FIELD ((RegisterField) {TMC2240_EXT_RES_DET_MASK, TMC2240_EXT_RES_DET_SHIFT, TMC2240_IOIN, false}) +#define TMC2240_EXT_CLK_MASK 0x00004000 +#define TMC2240_EXT_CLK_SHIFT 14 +#define TMC2240_EXT_CLK_FIELD ((RegisterField) {TMC2240_EXT_CLK_MASK, TMC2240_EXT_CLK_SHIFT, TMC2240_IOIN, false}) +#define TMC2240_ADC_ERR_MASK 0x00008000 +#define TMC2240_ADC_ERR_SHIFT 15 +#define TMC2240_ADC_ERR_FIELD ((RegisterField) {TMC2240_ADC_ERR_MASK, TMC2240_ADC_ERR_SHIFT, TMC2240_IOIN, false}) +#define TMC2240_SILICON_RV_MASK 0x00070000 +#define TMC2240_SILICON_RV_SHIFT 16 +#define TMC2240_SILICON_RV_FIELD ((RegisterField) {TMC2240_SILICON_RV_MASK, TMC2240_SILICON_RV_SHIFT, TMC2240_IOIN, false}) +#define TMC2240_VERSION_MASK 0xFF000000 +#define TMC2240_VERSION_SHIFT 24 +#define TMC2240_VERSION_FIELD ((RegisterField) {TMC2240_VERSION_MASK, TMC2240_VERSION_SHIFT, TMC2240_IOIN, false}) +#define TMC2240_CURRENT_RANGE_MASK 0x00000003 +#define TMC2240_CURRENT_RANGE_SHIFT 0 +#define TMC2240_CURRENT_RANGE_FIELD ((RegisterField) {TMC2240_CURRENT_RANGE_MASK, TMC2240_CURRENT_RANGE_SHIFT, TMC2240_DRV_CONF, false}) +#define TMC2240_SLOPE_CONTROL_MASK 0x00000030 +#define TMC2240_SLOPE_CONTROL_SHIFT 4 +#define TMC2240_SLOPE_CONTROL_FIELD ((RegisterField) {TMC2240_SLOPE_CONTROL_MASK, TMC2240_SLOPE_CONTROL_SHIFT, TMC2240_DRV_CONF, false}) +#define TMC2240_GLOBALSCALER_MASK 0x000000FF +#define TMC2240_GLOBALSCALER_SHIFT 0 +#define TMC2240_GLOBALSCALER_FIELD ((RegisterField) {TMC2240_GLOBALSCALER_MASK, TMC2240_GLOBALSCALER_SHIFT, TMC2240_GLOBAL_SCALER, false}) +#define TMC2240_IHOLD_MASK 0x0000001F +#define TMC2240_IHOLD_SHIFT 0 +#define TMC2240_IHOLD_FIELD ((RegisterField) {TMC2240_IHOLD_MASK, TMC2240_IHOLD_SHIFT, TMC2240_IHOLD_IRUN, false}) +#define TMC2240_IRUN_MASK 0x00001F00 +#define TMC2240_IRUN_SHIFT 8 +#define TMC2240_IRUN_FIELD ((RegisterField) {TMC2240_IRUN_MASK, TMC2240_IRUN_SHIFT, TMC2240_IHOLD_IRUN, false}) +#define TMC2240_IHOLDDELAY_MASK 0x000F0000 +#define TMC2240_IHOLDDELAY_SHIFT 16 +#define TMC2240_IHOLDDELAY_FIELD ((RegisterField) {TMC2240_IHOLDDELAY_MASK, TMC2240_IHOLDDELAY_SHIFT, TMC2240_IHOLD_IRUN, false}) +#define TMC2240_IRUNDELAY_MASK 0x0F000000 +#define TMC2240_IRUNDELAY_SHIFT 24 +#define TMC2240_IRUNDELAY_FIELD ((RegisterField) {TMC2240_IRUNDELAY_MASK, TMC2240_IRUNDELAY_SHIFT, TMC2240_IHOLD_IRUN, false}) +#define TMC2240_TPOWERDOWN_MASK 0x000000FF +#define TMC2240_TPOWERDOWN_SHIFT 0 +#define TMC2240_TPOWERDOWN_FIELD ((RegisterField) {TMC2240_TPOWERDOWN_MASK, TMC2240_TPOWERDOWN_SHIFT, TMC2240_TPOWERDOWN, false}) +#define TMC2240_TSTEP_MASK 0x000FFFFF +#define TMC2240_TSTEP_SHIFT 0 +#define TMC2240_TSTEP_FIELD ((RegisterField) {TMC2240_TSTEP_MASK, TMC2240_TSTEP_SHIFT, TMC2240_TSTEP, false}) +#define TMC2240_TPWMTHRS_MASK 0x000FFFFF +#define TMC2240_TPWMTHRS_SHIFT 0 +#define TMC2240_TPWMTHRS_FIELD ((RegisterField) {TMC2240_TPWMTHRS_MASK, TMC2240_TPWMTHRS_SHIFT, TMC2240_TPWMTHRS, false}) +#define TMC2240_TCOOLTHRS_MASK 0x000FFFFF +#define TMC2240_TCOOLTHRS_SHIFT 0 +#define TMC2240_TCOOLTHRS_FIELD ((RegisterField) {TMC2240_TCOOLTHRS_MASK, TMC2240_TCOOLTHRS_SHIFT, TMC2240_TCOOLTHRS, false}) +#define TMC2240_THIGH_MASK 0x000FFFFF +#define TMC2240_THIGH_SHIFT 0 +#define TMC2240_THIGH_FIELD ((RegisterField) {TMC2240_THIGH_MASK, TMC2240_THIGH_SHIFT, TMC2240_THIGH, false}) +#define TMC2240_DIRECT_COIL_A_MASK 0x000001FF +#define TMC2240_DIRECT_COIL_A_SHIFT 0 +#define TMC2240_DIRECT_COIL_A_FIELD ((RegisterField) {TMC2240_DIRECT_COIL_A_MASK, TMC2240_DIRECT_COIL_A_SHIFT, TMC2240_DIRECT_MODE, true}) +#define TMC2240_DIRECT_COIL_B_MASK 0x01FF0000 +#define TMC2240_DIRECT_COIL_B_SHIFT 16 +#define TMC2240_DIRECT_COIL_B_FIELD ((RegisterField) {TMC2240_DIRECT_COIL_B_MASK, TMC2240_DIRECT_COIL_B_SHIFT, TMC2240_DIRECT_MODE, true}) +#define TMC2240_POL_A_MASK 0x00000001 +#define TMC2240_POL_A_SHIFT 0 +#define TMC2240_POL_A_FIELD ((RegisterField) {TMC2240_POL_A_MASK, TMC2240_POL_A_SHIFT, TMC2240_ENCMODE, false}) +#define TMC2240_POL_B_MASK 0x00000002 +#define TMC2240_POL_B_SHIFT 1 +#define TMC2240_POL_B_FIELD ((RegisterField) {TMC2240_POL_B_MASK, TMC2240_POL_B_SHIFT, TMC2240_ENCMODE, false}) +#define TMC2240_POL_N_MASK 0x00000004 +#define TMC2240_POL_N_SHIFT 2 +#define TMC2240_POL_N_FIELD ((RegisterField) {TMC2240_POL_N_MASK, TMC2240_POL_N_SHIFT, TMC2240_ENCMODE, false}) +#define TMC2240_IGNORE_AB_MASK 0x00000008 +#define TMC2240_IGNORE_AB_SHIFT 3 +#define TMC2240_IGNORE_AB_FIELD ((RegisterField) {TMC2240_IGNORE_AB_MASK, TMC2240_IGNORE_AB_SHIFT, TMC2240_ENCMODE, false}) +#define TMC2240_CLR_CONT_MASK 0x00000010 +#define TMC2240_CLR_CONT_SHIFT 4 +#define TMC2240_CLR_CONT_FIELD ((RegisterField) {TMC2240_CLR_CONT_MASK, TMC2240_CLR_CONT_SHIFT, TMC2240_ENCMODE, false}) +#define TMC2240_CLR_ONCE_MASK 0x00000020 +#define TMC2240_CLR_ONCE_SHIFT 5 +#define TMC2240_CLR_ONCE_FIELD ((RegisterField) {TMC2240_CLR_ONCE_MASK, TMC2240_CLR_ONCE_SHIFT, TMC2240_ENCMODE, false}) +#define TMC2240_POS_NEG_EDGE_MASK 0x000000C0 +#define TMC2240_POS_NEG_EDGE_SHIFT 6 +#define TMC2240_POS_NEG_EDGE_FIELD ((RegisterField) {TMC2240_POS_NEG_EDGE_MASK, TMC2240_POS_NEG_EDGE_SHIFT, TMC2240_ENCMODE, false}) +#define TMC2240_CLR_ENC_X_MASK 0x00000100 +#define TMC2240_CLR_ENC_X_SHIFT 8 +#define TMC2240_CLR_ENC_X_FIELD ((RegisterField) {TMC2240_CLR_ENC_X_MASK, TMC2240_CLR_ENC_X_SHIFT, TMC2240_ENCMODE, false}) +#define TMC2240_LATCH_X_ACT_MASK 0x00000200 +#define TMC2240_LATCH_X_ACT_SHIFT 9 +#define TMC2240_LATCH_X_ACT_FIELD ((RegisterField) {TMC2240_LATCH_X_ACT_MASK, TMC2240_LATCH_X_ACT_SHIFT, TMC2240_ENCMODE, false}) +#define TMC2240_ENC_SEL_DECIMAL_MASK 0x00000400 +#define TMC2240_ENC_SEL_DECIMAL_SHIFT 10 +#define TMC2240_ENC_SEL_DECIMAL_FIELD ((RegisterField) {TMC2240_ENC_SEL_DECIMAL_MASK, TMC2240_ENC_SEL_DECIMAL_SHIFT, TMC2240_ENCMODE, false}) +#define TMC2240_X_ENC_MASK 0xFFFFFFFF +#define TMC2240_X_ENC_SHIFT 0 +#define TMC2240_X_ENC_FIELD ((RegisterField) {TMC2240_X_ENC_MASK, TMC2240_X_ENC_SHIFT, TMC2240_X_ENC, true}) +#define TMC2240_ENC_CONST_MASK 0xFFFFFFFF +#define TMC2240_ENC_CONST_SHIFT 0 +#define TMC2240_ENC_CONST_FIELD ((RegisterField) {TMC2240_ENC_CONST_MASK, TMC2240_ENC_CONST_SHIFT, TMC2240_ENC_CONST, true}) +#define TMC2240_N_EVENT_MASK 0x00000001 +#define TMC2240_N_EVENT_SHIFT 0 +#define TMC2240_N_EVENT_FIELD ((RegisterField) {TMC2240_N_EVENT_MASK, TMC2240_N_EVENT_SHIFT, TMC2240_ENC_STATUS, false}) +#define TMC2240_DEVIATION_WARN_MASK 0x00000002 +#define TMC2240_DEVIATION_WARN_SHIFT 1 +#define TMC2240_DEVIATION_WARN_FIELD ((RegisterField) {TMC2240_DEVIATION_WARN_MASK, TMC2240_DEVIATION_WARN_SHIFT, TMC2240_ENC_STATUS, false}) +#define TMC2240_ENC_LATCH_MASK 0xFFFFFFFF +#define TMC2240_ENC_LATCH_SHIFT 0 +#define TMC2240_ENC_LATCH_FIELD ((RegisterField) {TMC2240_ENC_LATCH_MASK, TMC2240_ENC_LATCH_SHIFT, TMC2240_ENC_LATCH, false}) +#define TMC2240_ADC_VSUPPLY_MASK 0x00001FFF +#define TMC2240_ADC_VSUPPLY_SHIFT 0 +#define TMC2240_ADC_VSUPPLY_FIELD ((RegisterField) {TMC2240_ADC_VSUPPLY_MASK, TMC2240_ADC_VSUPPLY_SHIFT, TMC2240_ADC_VSUPPLY_AIN, true}) +#define TMC2240_ADC_AIN_MASK 0x1FFF0000 +#define TMC2240_ADC_AIN_SHIFT 16 +#define TMC2240_ADC_AIN_FIELD ((RegisterField) {TMC2240_ADC_AIN_MASK, TMC2240_ADC_AIN_SHIFT, TMC2240_ADC_VSUPPLY_AIN, true}) +#define TMC2240_ADC_TEMP_MASK 0x00001FFF +#define TMC2240_ADC_TEMP_SHIFT 0 +#define TMC2240_ADC_TEMP_FIELD ((RegisterField) {TMC2240_ADC_TEMP_MASK, TMC2240_ADC_TEMP_SHIFT, TMC2240_ADC_TEMP, true}) +#define TMC2240_OVERVOLTAGE_VTH_MASK 0x00001FFF +#define TMC2240_OVERVOLTAGE_VTH_SHIFT 0 +#define TMC2240_OVERVOLTAGE_VTH_FIELD ((RegisterField) {TMC2240_OVERVOLTAGE_VTH_MASK, TMC2240_OVERVOLTAGE_VTH_SHIFT, TMC2240_OTW_OV_VTH, false}) +#define TMC2240_OVERTEMPPREWARNING_VTH_MASK 0x1FFF0000 +#define TMC2240_OVERTEMPPREWARNING_VTH_SHIFT 16 +#define TMC2240_OVERTEMPPREWARNING_VTH_FIELD ((RegisterField) {TMC2240_OVERTEMPPREWARNING_VTH_MASK, TMC2240_OVERTEMPPREWARNING_VTH_SHIFT, TMC2240_OTW_OV_VTH, false}) +#define TMC2240_MSLUT___MASK 0xFFFFFFFF +#define TMC2240_MSLUT___SHIFT 0 +#define TMC2240_MSLUT___FIELD ((RegisterField) {TMC2240_MSLUT___MASK, TMC2240_MSLUT___SHIFT, TMC2240_MSLUT[0], false}) +#define TMC2240_W0_MASK 0x00000003 +#define TMC2240_W0_SHIFT 0 +#define TMC2240_W0_FIELD ((RegisterField) {TMC2240_W0_MASK, TMC2240_W0_SHIFT, TMC2240_MSLUTSEL, false}) +#define TMC2240_W1_MASK 0x0000000C +#define TMC2240_W1_SHIFT 2 +#define TMC2240_W1_FIELD ((RegisterField) {TMC2240_W1_MASK, TMC2240_W1_SHIFT, TMC2240_MSLUTSEL, false}) +#define TMC2240_W2_MASK 0x00000030 +#define TMC2240_W2_SHIFT 4 +#define TMC2240_W2_FIELD ((RegisterField) {TMC2240_W2_MASK, TMC2240_W2_SHIFT, TMC2240_MSLUTSEL, false}) +#define TMC2240_W3_MASK 0x000000C0 +#define TMC2240_W3_SHIFT 6 +#define TMC2240_W3_FIELD ((RegisterField) {TMC2240_W3_MASK, TMC2240_W3_SHIFT, TMC2240_MSLUTSEL, false}) +#define TMC2240_X1_MASK 0x0000FF00 +#define TMC2240_X1_SHIFT 8 +#define TMC2240_X1_FIELD ((RegisterField) {TMC2240_X1_MASK, TMC2240_X1_SHIFT, TMC2240_MSLUTSEL, false}) +#define TMC2240_X2_MASK 0x00FF0000 +#define TMC2240_X2_SHIFT 16 +#define TMC2240_X2_FIELD ((RegisterField) {TMC2240_X2_MASK, TMC2240_X2_SHIFT, TMC2240_MSLUTSEL, false}) +#define TMC2240_X3_MASK 0xFF000000 +#define TMC2240_X3_SHIFT 24 +#define TMC2240_X3_FIELD ((RegisterField) {TMC2240_X3_MASK, TMC2240_X3_SHIFT, TMC2240_MSLUTSEL, false}) +#define TMC2240_START_SIN_MASK 0x000000FF +#define TMC2240_START_SIN_SHIFT 0 +#define TMC2240_START_SIN_FIELD ((RegisterField) {TMC2240_START_SIN_MASK, TMC2240_START_SIN_SHIFT, TMC2240_MSLUTSTART, false}) +#define TMC2240_START_SIN90_MASK 0x00FF0000 +#define TMC2240_START_SIN90_SHIFT 16 +#define TMC2240_START_SIN90_FIELD ((RegisterField) {TMC2240_START_SIN90_MASK, TMC2240_START_SIN90_SHIFT, TMC2240_MSLUTSTART, false}) +#define TMC2240_OFFSET_SIN90_MASK 0xFF000000 +#define TMC2240_OFFSET_SIN90_SHIFT 24 +#define TMC2240_OFFSET_SIN90_FIELD ((RegisterField) {TMC2240_OFFSET_SIN90_MASK, TMC2240_OFFSET_SIN90_SHIFT, TMC2240_MSLUTSTART, false}) +#define TMC2240_MSCNT_MASK 0x000003FF +#define TMC2240_MSCNT_SHIFT 0 +#define TMC2240_MSCNT_FIELD ((RegisterField) {TMC2240_MSCNT_MASK, TMC2240_MSCNT_SHIFT, TMC2240_MSCNT, false}) +#define TMC2240_CUR_B_MASK 0x000001FF +#define TMC2240_CUR_B_SHIFT 0 +#define TMC2240_CUR_B_FIELD ((RegisterField) {TMC2240_CUR_B_MASK, TMC2240_CUR_B_SHIFT, TMC2240_MSCURACT, true}) +#define TMC2240_CUR_A_MASK 0x01FF0000 +#define TMC2240_CUR_A_SHIFT 16 +#define TMC2240_CUR_A_FIELD ((RegisterField) {TMC2240_CUR_A_MASK, TMC2240_CUR_A_SHIFT, TMC2240_MSCURACT, true}) +#define TMC2240_TOFF_MASK 0x0000000F +#define TMC2240_TOFF_SHIFT 0 +#define TMC2240_TOFF_FIELD ((RegisterField) {TMC2240_TOFF_MASK, TMC2240_TOFF_SHIFT, TMC2240_CHOPCONF, false}) +#define TMC2240_HSTRT_TFD210_MASK 0x00000070 +#define TMC2240_HSTRT_TFD210_SHIFT 4 +#define TMC2240_HSTRT_TFD210_FIELD ((RegisterField) {TMC2240_HSTRT_TFD210_MASK, TMC2240_HSTRT_TFD210_SHIFT, TMC2240_CHOPCONF, false}) +#define TMC2240_HEND_OFFSET_MASK 0x00000780 +#define TMC2240_HEND_OFFSET_SHIFT 7 +#define TMC2240_HEND_OFFSET_FIELD ((RegisterField) {TMC2240_HEND_OFFSET_MASK, TMC2240_HEND_OFFSET_SHIFT, TMC2240_CHOPCONF, false}) +#define TMC2240_FD3_MASK 0x00000800 +#define TMC2240_FD3_SHIFT 11 +#define TMC2240_FD3_FIELD ((RegisterField) {TMC2240_FD3_MASK, TMC2240_FD3_SHIFT, TMC2240_CHOPCONF, false}) +#define TMC2240_DISFDCC_MASK 0x00001000 +#define TMC2240_DISFDCC_SHIFT 12 +#define TMC2240_DISFDCC_FIELD ((RegisterField) {TMC2240_DISFDCC_MASK, TMC2240_DISFDCC_SHIFT, TMC2240_CHOPCONF, false}) +#define TMC2240_CHM_MASK 0x00004000 +#define TMC2240_CHM_SHIFT 14 +#define TMC2240_CHM_FIELD ((RegisterField) {TMC2240_CHM_MASK, TMC2240_CHM_SHIFT, TMC2240_CHOPCONF, false}) +#define TMC2240_TBL_MASK 0x00018000 +#define TMC2240_TBL_SHIFT 15 +#define TMC2240_TBL_FIELD ((RegisterField) {TMC2240_TBL_MASK, TMC2240_TBL_SHIFT, TMC2240_CHOPCONF, false}) +#define TMC2240_VHIGHFS_MASK 0x00040000 +#define TMC2240_VHIGHFS_SHIFT 18 +#define TMC2240_VHIGHFS_FIELD ((RegisterField) {TMC2240_VHIGHFS_MASK, TMC2240_VHIGHFS_SHIFT, TMC2240_CHOPCONF, false}) +#define TMC2240_VHIGHCHM_MASK 0x00080000 +#define TMC2240_VHIGHCHM_SHIFT 19 +#define TMC2240_VHIGHCHM_FIELD ((RegisterField) {TMC2240_VHIGHCHM_MASK, TMC2240_VHIGHCHM_SHIFT, TMC2240_CHOPCONF, false}) +#define TMC2240_TPFD_MASK 0x00F00000 +#define TMC2240_TPFD_SHIFT 20 +#define TMC2240_TPFD_FIELD ((RegisterField) {TMC2240_TPFD_MASK, TMC2240_TPFD_SHIFT, TMC2240_CHOPCONF, false}) +#define TMC2240_MRES_MASK 0x0F000000 +#define TMC2240_MRES_SHIFT 24 +#define TMC2240_MRES_FIELD ((RegisterField) {TMC2240_MRES_MASK, TMC2240_MRES_SHIFT, TMC2240_CHOPCONF, false}) +#define TMC2240_INTPOL_MASK 0x10000000 +#define TMC2240_INTPOL_SHIFT 28 +#define TMC2240_INTPOL_FIELD ((RegisterField) {TMC2240_INTPOL_MASK, TMC2240_INTPOL_SHIFT, TMC2240_CHOPCONF, false}) +#define TMC2240_DEDGE_MASK 0x20000000 +#define TMC2240_DEDGE_SHIFT 29 +#define TMC2240_DEDGE_FIELD ((RegisterField) {TMC2240_DEDGE_MASK, TMC2240_DEDGE_SHIFT, TMC2240_CHOPCONF, false}) +#define TMC2240_DISS2G_MASK 0x40000000 +#define TMC2240_DISS2G_SHIFT 30 +#define TMC2240_DISS2G_FIELD ((RegisterField) {TMC2240_DISS2G_MASK, TMC2240_DISS2G_SHIFT, TMC2240_CHOPCONF, false}) +#define TMC2240_DISS2VS_MASK 0x80000000 +#define TMC2240_DISS2VS_SHIFT 31 +#define TMC2240_DISS2VS_FIELD ((RegisterField) {TMC2240_DISS2VS_MASK, TMC2240_DISS2VS_SHIFT, TMC2240_CHOPCONF, false}) +#define TMC2240_SEMIN_MASK 0x0000000F +#define TMC2240_SEMIN_SHIFT 0 +#define TMC2240_SEMIN_FIELD ((RegisterField) {TMC2240_SEMIN_MASK, TMC2240_SEMIN_SHIFT, TMC2240_COOLCONF, false}) +#define TMC2240_SEUP_MASK 0x00000060 +#define TMC2240_SEUP_SHIFT 5 +#define TMC2240_SEUP_FIELD ((RegisterField) {TMC2240_SEUP_MASK, TMC2240_SEUP_SHIFT, TMC2240_COOLCONF, false}) +#define TMC2240_SEMAX_MASK 0x00000F00 +#define TMC2240_SEMAX_SHIFT 8 +#define TMC2240_SEMAX_FIELD ((RegisterField) {TMC2240_SEMAX_MASK, TMC2240_SEMAX_SHIFT, TMC2240_COOLCONF, false}) +#define TMC2240_SEDN_MASK 0x00006000 +#define TMC2240_SEDN_SHIFT 13 +#define TMC2240_SEDN_FIELD ((RegisterField) {TMC2240_SEDN_MASK, TMC2240_SEDN_SHIFT, TMC2240_COOLCONF, false}) +#define TMC2240_SEIMIN_MASK 0x00008000 +#define TMC2240_SEIMIN_SHIFT 15 +#define TMC2240_SEIMIN_FIELD ((RegisterField) {TMC2240_SEIMIN_MASK, TMC2240_SEIMIN_SHIFT, TMC2240_COOLCONF, false}) +#define TMC2240_SGT_MASK 0x007F0000 +#define TMC2240_SGT_SHIFT 16 +#define TMC2240_SGT_FIELD ((RegisterField) {TMC2240_SGT_MASK, TMC2240_SGT_SHIFT, TMC2240_COOLCONF, false}) +#define TMC2240_SFILT_MASK 0x01000000 +#define TMC2240_SFILT_SHIFT 24 +#define TMC2240_SFILT_FIELD ((RegisterField) {TMC2240_SFILT_MASK, TMC2240_SFILT_SHIFT, TMC2240_COOLCONF, false}) +#define TMC2240_SG_RESULT_MASK 0x000003FF +#define TMC2240_SG_RESULT_SHIFT 0 +#define TMC2240_SG_RESULT_FIELD ((RegisterField) {TMC2240_SG_RESULT_MASK, TMC2240_SG_RESULT_SHIFT, TMC2240_DRVSTATUS, false}) +#define TMC2240_S2VSA_MASK 0x00001000 +#define TMC2240_S2VSA_SHIFT 12 +#define TMC2240_S2VSA_FIELD ((RegisterField) {TMC2240_S2VSA_MASK, TMC2240_S2VSA_SHIFT, TMC2240_DRVSTATUS, false}) +#define TMC2240_S2VSB_MASK 0x00002000 +#define TMC2240_S2VSB_SHIFT 13 +#define TMC2240_S2VSB_FIELD ((RegisterField) {TMC2240_S2VSB_MASK, TMC2240_S2VSB_SHIFT, TMC2240_DRVSTATUS, false}) +#define TMC2240_STEALTH_MASK 0x00004000 +#define TMC2240_STEALTH_SHIFT 14 +#define TMC2240_STEALTH_FIELD ((RegisterField) {TMC2240_STEALTH_MASK, TMC2240_STEALTH_SHIFT, TMC2240_DRVSTATUS, false}) +#define TMC2240_FSACTIVE_MASK 0x00008000 +#define TMC2240_FSACTIVE_SHIFT 15 +#define TMC2240_FSACTIVE_FIELD ((RegisterField) {TMC2240_FSACTIVE_MASK, TMC2240_FSACTIVE_SHIFT, TMC2240_DRVSTATUS, false}) +#define TMC2240_CS_ACTUAL_MASK 0x001F0000 +#define TMC2240_CS_ACTUAL_SHIFT 16 +#define TMC2240_CS_ACTUAL_FIELD ((RegisterField) {TMC2240_CS_ACTUAL_MASK, TMC2240_CS_ACTUAL_SHIFT, TMC2240_DRVSTATUS, false}) +#define TMC2240_STALLGUARD_MASK 0x01000000 +#define TMC2240_STALLGUARD_SHIFT 24 +#define TMC2240_STALLGUARD_FIELD ((RegisterField) {TMC2240_STALLGUARD_MASK, TMC2240_STALLGUARD_SHIFT, TMC2240_DRVSTATUS, false}) +#define TMC2240_OT_MASK 0x02000000 +#define TMC2240_OT_SHIFT 25 +#define TMC2240_OT_FIELD ((RegisterField) {TMC2240_OT_MASK, TMC2240_OT_SHIFT, TMC2240_DRVSTATUS, false}) +#define TMC2240_OTPW_MASK 0x04000000 +#define TMC2240_OTPW_SHIFT 26 +#define TMC2240_OTPW_FIELD ((RegisterField) {TMC2240_OTPW_MASK, TMC2240_OTPW_SHIFT, TMC2240_DRVSTATUS, false}) +#define TMC2240_S2GA_MASK 0x08000000 +#define TMC2240_S2GA_SHIFT 27 +#define TMC2240_S2GA_FIELD ((RegisterField) {TMC2240_S2GA_MASK, TMC2240_S2GA_SHIFT, TMC2240_DRVSTATUS, false}) +#define TMC2240_S2GB_MASK 0x10000000 +#define TMC2240_S2GB_SHIFT 28 +#define TMC2240_S2GB_FIELD ((RegisterField) {TMC2240_S2GB_MASK, TMC2240_S2GB_SHIFT, TMC2240_DRVSTATUS, false}) +#define TMC2240_OLA_MASK 0x20000000 +#define TMC2240_OLA_SHIFT 29 +#define TMC2240_OLA_FIELD ((RegisterField) {TMC2240_OLA_MASK, TMC2240_OLA_SHIFT, TMC2240_DRVSTATUS, false}) +#define TMC2240_OLB_MASK 0x40000000 +#define TMC2240_OLB_SHIFT 30 +#define TMC2240_OLB_FIELD ((RegisterField) {TMC2240_OLB_MASK, TMC2240_OLB_SHIFT, TMC2240_DRVSTATUS, false}) +#define TMC2240_STST_MASK 0x80000000 +#define TMC2240_STST_SHIFT 31 +#define TMC2240_STST_FIELD ((RegisterField) {TMC2240_STST_MASK, TMC2240_STST_SHIFT, TMC2240_DRVSTATUS, false}) +#define TMC2240_PWM_OFS_MASK 0x000000FF +#define TMC2240_PWM_OFS_SHIFT 0 +#define TMC2240_PWM_OFS_FIELD ((RegisterField) {TMC2240_PWM_OFS_MASK, TMC2240_PWM_OFS_SHIFT, TMC2240_PWMCONF, false}) +#define TMC2240_PWM_GRAD_MASK 0x0000FF00 +#define TMC2240_PWM_GRAD_SHIFT 8 +#define TMC2240_PWM_GRAD_FIELD ((RegisterField) {TMC2240_PWM_GRAD_MASK, TMC2240_PWM_GRAD_SHIFT, TMC2240_PWMCONF, false}) +#define TMC2240_PWM_FREQ_MASK 0x00030000 +#define TMC2240_PWM_FREQ_SHIFT 16 +#define TMC2240_PWM_FREQ_FIELD ((RegisterField) {TMC2240_PWM_FREQ_MASK, TMC2240_PWM_FREQ_SHIFT, TMC2240_PWMCONF, false}) +#define TMC2240_PWM_AUTOSCALE_MASK 0x00040000 +#define TMC2240_PWM_AUTOSCALE_SHIFT 18 +#define TMC2240_PWM_AUTOSCALE_FIELD ((RegisterField) {TMC2240_PWM_AUTOSCALE_MASK, TMC2240_PWM_AUTOSCALE_SHIFT, TMC2240_PWMCONF, false}) +#define TMC2240_PWM_AUTOGRAD_MASK 0x00080000 +#define TMC2240_PWM_AUTOGRAD_SHIFT 19 +#define TMC2240_PWM_AUTOGRAD_FIELD ((RegisterField) {TMC2240_PWM_AUTOGRAD_MASK, TMC2240_PWM_AUTOGRAD_SHIFT, TMC2240_PWMCONF, false}) +#define TMC2240_FREEWHEEL_MASK 0x00300000 +#define TMC2240_FREEWHEEL_SHIFT 20 +#define TMC2240_FREEWHEEL_FIELD ((RegisterField) {TMC2240_FREEWHEEL_MASK, TMC2240_FREEWHEEL_SHIFT, TMC2240_PWMCONF, false}) +#define TMC2240_PWM_MEAS_SD_ENABLE_MASK 0x00400000 +#define TMC2240_PWM_MEAS_SD_ENABLE_SHIFT 22 +#define TMC2240_PWM_MEAS_SD_ENABLE_FIELD ((RegisterField) {TMC2240_PWM_MEAS_SD_ENABLE_MASK, TMC2240_PWM_MEAS_SD_ENABLE_SHIFT, TMC2240_PWMCONF, false}) +#define TMC2240_PWM_DIS_REG_STST_MASK 0x00800000 +#define TMC2240_PWM_DIS_REG_STST_SHIFT 23 +#define TMC2240_PWM_DIS_REG_STST_FIELD ((RegisterField) {TMC2240_PWM_DIS_REG_STST_MASK, TMC2240_PWM_DIS_REG_STST_SHIFT, TMC2240_PWMCONF, false}) +#define TMC2240_PWM_REG_MASK 0x0F000000 +#define TMC2240_PWM_REG_SHIFT 24 +#define TMC2240_PWM_REG_FIELD ((RegisterField) {TMC2240_PWM_REG_MASK, TMC2240_PWM_REG_SHIFT, TMC2240_PWMCONF, false}) +#define TMC2240_PWM_LIM_MASK 0xF0000000 +#define TMC2240_PWM_LIM_SHIFT 28 +#define TMC2240_PWM_LIM_FIELD ((RegisterField) {TMC2240_PWM_LIM_MASK, TMC2240_PWM_LIM_SHIFT, TMC2240_PWMCONF, false}) +#define TMC2240_PWM_SCALE_SUM_MASK 0x000003FF +#define TMC2240_PWM_SCALE_SUM_SHIFT 0 +#define TMC2240_PWM_SCALE_SUM_FIELD ((RegisterField) {TMC2240_PWM_SCALE_SUM_MASK, TMC2240_PWM_SCALE_SUM_SHIFT, TMC2240_PWM_SCALE, false}) +#define TMC2240_PWM_SCALE_AUTO_MASK 0x01FF0000 +#define TMC2240_PWM_SCALE_AUTO_SHIFT 16 +#define TMC2240_PWM_SCALE_AUTO_FIELD ((RegisterField) {TMC2240_PWM_SCALE_AUTO_MASK, TMC2240_PWM_SCALE_AUTO_SHIFT, TMC2240_PWM_SCALE, false}) +#define TMC2240_PWM_OFS_AUTO_MASK 0x000000FF +#define TMC2240_PWM_OFS_AUTO_SHIFT 0 +#define TMC2240_PWM_OFS_AUTO_FIELD ((RegisterField) {TMC2240_PWM_OFS_AUTO_MASK, TMC2240_PWM_OFS_AUTO_SHIFT, TMC2240_PWM_AUTO, false}) +#define TMC2240_PWM_GRAD_AUTO_MASK 0x00FF0000 +#define TMC2240_PWM_GRAD_AUTO_SHIFT 16 +#define TMC2240_PWM_GRAD_AUTO_FIELD ((RegisterField) {TMC2240_PWM_GRAD_AUTO_MASK, TMC2240_PWM_GRAD_AUTO_SHIFT, TMC2240_PWM_AUTO, false}) +#define TMC2240_SG4_THRS_MASK 0x000000FF +#define TMC2240_SG4_THRS_SHIFT 0 +#define TMC2240_SG4_THRS_FIELD ((RegisterField) {TMC2240_SG4_THRS_MASK, TMC2240_SG4_THRS_SHIFT, TMC2240_SG4_THRS, false}) +#define TMC2240_SG4_FILT_EN_MASK 0x00000100 +#define TMC2240_SG4_FILT_EN_SHIFT 8 +#define TMC2240_SG4_FILT_EN_FIELD ((RegisterField) {TMC2240_SG4_FILT_EN_MASK, TMC2240_SG4_FILT_EN_SHIFT, TMC2240_SG4_THRS, false}) +#define TMC2240_SG_ANGLE_OFFSET_MASK 0x00000200 +#define TMC2240_SG_ANGLE_OFFSET_SHIFT 9 +#define TMC2240_SG_ANGLE_OFFSET_FIELD ((RegisterField) {TMC2240_SG_ANGLE_OFFSET_MASK, TMC2240_SG_ANGLE_OFFSET_SHIFT, TMC2240_SG4_THRS, false}) +#define TMC2240_SG4_RESULT_MASK 0x000003FF +#define TMC2240_SG4_RESULT_SHIFT 0 +#define TMC2240_SG4_RESULT_FIELD ((RegisterField) {TMC2240_SG4_RESULT_MASK, TMC2240_SG4_RESULT_SHIFT, TMC2240_SG4_RESULT, false}) +#define TMC2240_SG4_IND_0_MASK 0x000000FF +#define TMC2240_SG4_IND_0_SHIFT 0 +#define TMC2240_SG4_IND_0_FIELD ((RegisterField) {TMC2240_SG4_IND_0_MASK, TMC2240_SG4_IND_0_SHIFT, TMC2240_SG4_IND, false}) +#define TMC2240_SG4_IND_1_MASK 0x0000FF00 +#define TMC2240_SG4_IND_1_SHIFT 8 +#define TMC2240_SG4_IND_1_FIELD ((RegisterField) {TMC2240_SG4_IND_1_MASK, TMC2240_SG4_IND_1_SHIFT, TMC2240_SG4_IND, false}) +#define TMC2240_SG4_IND_2_MASK 0x00FF0000 +#define TMC2240_SG4_IND_2_SHIFT 16 +#define TMC2240_SG4_IND_2_FIELD ((RegisterField) {TMC2240_SG4_IND_2_MASK, TMC2240_SG4_IND_2_SHIFT, TMC2240_SG4_IND, false}) +#define TMC2240_SG4_IND_3_MASK 0xFF000000 +#define TMC2240_SG4_IND_3_SHIFT 24 +#define TMC2240_SG4_IND_3_FIELD ((RegisterField) {TMC2240_SG4_IND_3_MASK, TMC2240_SG4_IND_3_SHIFT, TMC2240_SG4_IND, false}) + +#endif diff --git a/firmware/lib/tmc/ic/TMC2240/registercall_hierarchy_flowchart_SPI.svg b/firmware/lib/tmc/ic/TMC2240/registercall_hierarchy_flowchart_SPI.svg new file mode 100755 index 0000000..cbad58f --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2240/registercall_hierarchy_flowchart_SPI.svg @@ -0,0 +1,3 @@ + + +

HAL

HAL

APP (Eval)

APP (Eval)

API

API
Read a register
  •  Call tmcXXXX_readRegister function
Read a register...
Returns the register read value
Returns the register read value
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
tmcXXXX.c
tmcXXXX.c
SPI.c
SPI.c
tmcXXXX_eval.c
tmcXXXX_eval.c

 Implementation of SPI_readWrite
  • Sends and receives bytes on the SPI bus
Implementation of SPI_readWrite...
Returns the raw reply data
Returns the raw reply data

Implementation of tmcXXXX_readWriteSPI
  • Sets the CSN pin to LOW
  • Takes the array of data to write
  • Calls hardware function SPI_readWrite
  • Upon completion of data transfer,
    sets CSN to 
    HIGH
Implementation of tmcXXXX_readWriteSPI...
Passes on the raw reply data to the API
Passes on the raw reply data to the API
Implementation of readRegisterSPI
  • Constructs the datagram
  • Calls HAL wrapper function 
Implementation of readRegisterSPI...
tmcXXXX_readWriteSPI
tmcXXXX_readWriteSPI
Parses the reply and returns the register value
Parses the reply and returns the register value
Implementation of tmcXXXX_readRegister 
  • Check which bus is active SPI/UART. (e.g. SPI)
  • Calls bus-specific function (e.g. readRegisterSPI)
 
Implementation of tmcXXXX_readRegister...
Returns the register read value
Returns the register read value
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC2240/registercall_hierarchy_flowchart_UART.svg b/firmware/lib/tmc/ic/TMC2240/registercall_hierarchy_flowchart_UART.svg new file mode 100755 index 0000000..425f60a --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2240/registercall_hierarchy_flowchart_UART.svg @@ -0,0 +1,3 @@ + + +

HAL

HAL

APP (Eval)

APP (Eval)

API

API
Read a register
  •  Call tmcXXXX_readRegister function
Read a register...
Returns the register read value
Returns the register read value
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
tmcXXXX.c
tmcXXXX.c
UART.c
UART.c
tmcXXXX_eval.c
tmcXXXX_eval.c

 Implementation of UART_readWrite
  • Sends and receives bytes on the UART bus
Implementation of UART_readWrite...
Returns the raw reply data
Returns the raw reply data

Implementation of tmcXXXX_readWriteUART
  • Takes the array of data to write
  • Calls hardware function UART_readWrite
Implementation of tmcXXXX_readWriteUART...
Passes on the raw reply data to the API
Passes on the raw reply data to the API
Implementation of readRegisterUART
  • Constructs the datagram
  • Calls HAL wrapper function 
Implementation of readRegisterUART...
tmcXXXX_readWriteUART
tmcXXXX_readWriteUART
Parses the reply and returns the register value
Parses the reply and returns the register value
Implementation of tmcXXXX_readRegister 
  • Check which bus is active SPI/UART. (e.g. UART)
  • Calls bus-specific function (e.g. readRegisterUART)
 
Implementation of tmcXXXX_readRegister...
Returns the register read value
Returns the register read value
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC2240/uml-tmc-api.svg b/firmware/lib/tmc/ic/TMC2240/uml-tmc-api.svg new file mode 100755 index 0000000..5a5f8dd --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2240/uml-tmc-api.svg @@ -0,0 +1,3 @@ + + +

TMCXXXX_HW_Abstraction.h



TMCXXXX_HW_Abstraction.h...
// Constants
#define TMCXXXX_MOTORS              
                          
// Register definitions
#define TMCXXXX_GCONF        
                          ⋮
// Register fields definitions
#define TMCXXXX_GCONF_OTPW_FIELD
                     
// Constants...

TMCXXXX.h



TMCXXXX.h...
extern void tmcXXXX_readWriteSPI();
extern void tmcXXXX_readWriteUART();
extern TMCXXXXBusType tmcXXXX_getBusType();
extern uint8_t tmcXXXX_getNodeAddress();
                                  ⋮
tmcXXXX_readRegister();
tmcXXXX_writeRegister();
                                  ⋮
extern void tmcXXXX_readWriteSPI();...

TMCXXXX.c



TMCXXXX.c...
const uint8_t tmcCRCTable_Poly7Reflected[256] = {...};
int32_t tmcXXXX_readRegister(){
/* Call tmcXXXX_getBusType();
 * Based on bus type, call readRegisterSPI/UART() that
 * further calls tmcXXXX_readWriteSPI/UART();
 * For UART it also calls tmcXXXX_getNodeAddress();
                                           ⋮
}
                                           ⋮
const uint8_t tmcCRCTable_Poly7Reflected[256] = {.....
TMC-API
TMC-API

TMCXXXX_Simple_Rotation.h


TMCXXXX_Simple_Rotation.h...
void initAllMotors();
             ⋮
  
void initAllMotors()...

TMCXXXX_Simple_Rotation.c


TMCXXXX_Simple_Rotation.c...
void initAllMotors(){

// Configuring registers to enable motor drivers etc..
tmcXXXX_writeRegister();
                    ⋮
}
                    ⋮
void initAllMotors(){...
Examples
Examples
User Project
User Project

User_Project.h


User_Project.h

User_Project.c








User_Project.c...

void tmcXXXX_readWriteSPI(){
                           ⋮
}
void tmcXXXX_readWriteUART(){
                           ⋮
}
TMCXXXXBusType tmcXXXX_getBusType(){
                           ⋮
}
uint8_t tmcXXXX_getNodeAddress(){
                           ⋮
}

// User Code
                           ⋮
void tmcXXXX_readWriteSPI(){...
#include "TMCXXXX_HW_Abstraction.h"
#include "TMCXXXX.h"
#include "TMCXXXX_Simple_Rotation.h"
                                ⋮
TMCXXXXBusType bus = IC_BUS_SPI/UART;
uint8_t nodeAddress = <nodeAddress>;
                                ⋮
#include "TMCXXXX_HW_Abstraction.h"...
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC2241/README.md b/firmware/lib/tmc/ic/TMC2241/README.md new file mode 100755 index 0000000..0130903 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2241/README.md @@ -0,0 +1,64 @@ +# TMC2241 + + +## How to use + +To access the TMC2241's registers, the TMC-API offers two functions: **tmc2241_readRegister** and **tmc2241_writeRegister**. +Each of these functions takes in an **icID**, which is used to identify the IC when multiple ICs are connected. This identifier is passed down to the callback functions (see How to Integrate). + +## How to integrate: overview + +1. Include all the files of the TMC-API/ic/tmc/TMC2241 folder into the custom project. +2. Include the TMC2241.h file in the custom source code. +3. Implement the necessary callback functions (see below). +4. (optional): Take a look at the Examples subfolder for ready-made examples of the TMC-API usage. + +## Accessing the TMC2241 via SPI +The following diagram depicts how to access the TMC2241 via SPI using the TMC-API. + +![screenshot](registercall_hierarchy_flowchart_SPI.svg) + +The description of the functions, in the above flowchart, are as follows: +- The functions tmc2241_readRegister and tmc2241_writeRegister are used to read and write the registers respectively. These functions check the current active bus and calls the bus-specific function i.e readRegisterSPI or writeRegisterSPI. +- These bus specific functions constructs the datagram and further calls the bus specific callback 'tmcXXXX_readWriteSPI. +- This callback function further calls the hardware specific read/write function for SPI and needs to be implemented externally. + +### How to integrate: Callback functions +To communicate with TMC2241 IC, the TMC-API library needs to know which bus (UART, SPI) it shall use. For that, the callback function **'tmc2241_getBusType()'** needs to be implemented. +Additionally, implement the following callback functions to access the chip via SPI: +1. **tmc2241_readWriteSPI()**, which is a HAL wrapper function that provides the necessary hardware access. This function should also set the chip select pin CSN to low before starting the data transfer and set to high upon completion. Please refer to the datasheet of the IC for further details. + +## Accessing the TMC2241 via UART +The following diagram depicts how to access the TMC2241 via UART using the TMC-API. + +![screenshot](registercall_hierarchy_flowchart_UART.svg) + +The description of the functions, in the above flowchart, are as follows: +- The functions tmc2241_readRegister and tmc2241_writeRegister are used to read and write the registers respectively. These functions check the current active bus and calls the bus-specific function i.e readRegisterUART or writeRegisterUART. +- These bus specific functions constructs the datagram and further calls the bus specific callback 'tmcXXXX_readWriteUART. +- This callback function further calls the hardware specific read/write function for UART and needs to be implemented externally. + +### How to integrate: Callback functions +To communicate with TMC2241 IC, the TMC-API library needs to know which bus (UART, SPI) it shall use. For that, the callback function **'tmc2241_getBusType()'** needs to be implemented. +Additionally, implement the following callback functions to access the chip via UART: +1. **tmc2241_readWriteUART()**, which is a HAL wrapper function that provides the necessary hardware access. +2. **tmc2241_getNodeAddress()**, that returns the node/slave address. Node address could be set in NODECONF (0x3) register and the address could be incremented as defined by AD0, AD1 and AD2. (Node address + ADx) must be less than 255. For further details please consult the datasheet of TMC2241. + +### Sharing the CRC table with other TMC-API chips +The TMC2241 UART protocol uses an 8 bit CRC. For calculating this, a table-based algorithm is used. This table (tmcCRCTable_Poly7Reflected[256]) is 256 bytes big and identical across multiple different Trinamic chips (i.e. TMC2241). +If multiple Trinamic chips are being used in the same project, avoiding redundant copies of this table could save memory. It is possible to substitute this CRC table with another CRC table. + +### Option to use the cache logic for Write-Only registers +The chip features write-only registers that are unable to be read, necessitating the creation of a shadow copy to cache their contents. This copy is automatically updated whenever data is written to these registers. This cache logic could be enabled by setting the macro **TMC2241_CACHE** to **'1'** or disabled by setting to **'0'** respectively. If this feature is enabled then there comes another option to use **tmc2241_cache** function, which is already implemeted in the API, by defining **TMC2241_ENABLE_TMC_CACHE** macro to **'1** or one can implement their own function. The function **tmc2241_cache** works for both reading from and writing to the shadow array. It first checks whether the register has write-only access and data needs to be read from the hadow copy. On the basis of that, it returns **true** or **false**. The shadowRegisters on the premade cache implementation need to be one per chip. **TMC2241_IC_CACHE_COUNT** is set to '1' by default and is user-overwritable. If multiple chips are being used in the same project, increment its value to the number of chips connected. + +## Further info +### Dependency graph for the ICs with new register R/W mechanism +This graph illustrates the relationships between files within the TMC-API library, highlighting dependencies and identifying the files that are essential for integrating the library into the custom projects. + +![screenshot](uml-tmc-api.svg) + +### Example usage: TMC-Evalsystem +**For a reference usage of the TMC-API**, visit the [TMC-Evalsystem](https://github.com/analogdevicesinc/TMC-EvalSystem) + +## Migration status +The TMC2241 has been reworked to the access system described above. For more infos on the status of this and other ICs, check out the [migration page](https://github.com/analogdevicesinc/TMC-API/issues/53). \ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC2241/TMC2241.c b/firmware/lib/tmc/ic/TMC2241/TMC2241.c new file mode 100755 index 0000000..9423a7c --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2241/TMC2241.c @@ -0,0 +1,303 @@ +/******************************************************************************* +* Copyright © 2025 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#include "TMC2241.h" + +#ifdef TMC_API_EXTERNAL_CRC_TABLE +extern const uint8_t tmcCRCTable_Poly7Reflected[256]; +#else +const uint8_t tmcCRCTable_Poly7Reflected[256] = { + 0x00, 0x91, 0xE3, 0x72, 0x07, 0x96, 0xE4, 0x75, 0x0E, 0x9F, 0xED, 0x7C, 0x09, 0x98, 0xEA, 0x7B, + 0x38, 0xA9, 0xDB, 0x4A, 0x3F, 0xAE, 0xDC, 0x4D, 0x36, 0xA7, 0xD5, 0x44, 0x31, 0xA0, 0xD2, 0x43, + 0x24, 0xB5, 0xC7, 0x56, 0x23, 0xB2, 0xC0, 0x51, 0x2A, 0xBB, 0xC9, 0x58, 0x2D, 0xBC, 0xCE, 0x5F, + 0x70, 0xE1, 0x93, 0x02, 0x77, 0xE6, 0x94, 0x05, 0x7E, 0xEF, 0x9D, 0x0C, 0x79, 0xE8, 0x9A, 0x0B, + 0x6C, 0xFD, 0x8F, 0x1E, 0x6B, 0xFA, 0x88, 0x19, 0x62, 0xF3, 0x81, 0x10, 0x65, 0xF4, 0x86, 0x17, + 0x48, 0xD9, 0xAB, 0x3A, 0x4F, 0xDE, 0xAC, 0x3D, 0x46, 0xD7, 0xA5, 0x34, 0x41, 0xD0, 0xA2, 0x33, + 0x54, 0xC5, 0xB7, 0x26, 0x53, 0xC2, 0xB0, 0x21, 0x5A, 0xCB, 0xB9, 0x28, 0x5D, 0xCC, 0xBE, 0x2F, + 0xE0, 0x71, 0x03, 0x92, 0xE7, 0x76, 0x04, 0x95, 0xEE, 0x7F, 0x0D, 0x9C, 0xE9, 0x78, 0x0A, 0x9B, + 0xFC, 0x6D, 0x1F, 0x8E, 0xFB, 0x6A, 0x18, 0x89, 0xF2, 0x63, 0x11, 0x80, 0xF5, 0x64, 0x16, 0x87, + 0xD8, 0x49, 0x3B, 0xAA, 0xDF, 0x4E, 0x3C, 0xAD, 0xD6, 0x47, 0x35, 0xA4, 0xD1, 0x40, 0x32, 0xA3, + 0xC4, 0x55, 0x27, 0xB6, 0xC3, 0x52, 0x20, 0xB1, 0xCA, 0x5B, 0x29, 0xB8, 0xCD, 0x5C, 0x2E, 0xBF, + 0x90, 0x01, 0x73, 0xE2, 0x97, 0x06, 0x74, 0xE5, 0x9E, 0x0F, 0x7D, 0xEC, 0x99, 0x08, 0x7A, 0xEB, + 0x8C, 0x1D, 0x6F, 0xFE, 0x8B, 0x1A, 0x68, 0xF9, 0x82, 0x13, 0x61, 0xF0, 0x85, 0x14, 0x66, 0xF7, + 0xA8, 0x39, 0x4B, 0xDA, 0xAF, 0x3E, 0x4C, 0xDD, 0xA6, 0x37, 0x45, 0xD4, 0xA1, 0x30, 0x42, 0xD3, + 0xB4, 0x25, 0x57, 0xC6, 0xB3, 0x22, 0x50, 0xC1, 0xBA, 0x2B, 0x59, 0xC8, 0xBD, 0x2C, 0x5E, 0xCF, +}; +#endif + +/**************************************************************** Cache Implementation *************************************************************************/ + +#if TMC2241_CACHE == 0 +static inline bool tmc2241_cache(uint16_t icID, TMC2241CacheOp operation, uint8_t address, uint32_t *value) +{ + UNUSED(icID); + UNUSED(address); + UNUSED(operation); + return false; +} +#else +#if TMC2241_ENABLE_TMC_CACHE == 1 + +uint8_t tmc2241_dirtyBits[TMC2241_IC_CACHE_COUNT][TMC2241_REGISTER_COUNT/8]= {0}; +int32_t tmc2241_shadowRegister[TMC2241_IC_CACHE_COUNT][TMC2241_REGISTER_COUNT]; + +void tmc2241_setDirtyBit(uint16_t icID, uint8_t index, bool value) +{ + if(index >= TMC2241_REGISTER_COUNT) + return; + + uint8_t *tmp = &tmc2241_dirtyBits[icID][index / 8]; + uint8_t shift = (index % 8); + uint8_t mask = 1 << shift; + *tmp = (((*tmp) & (~(mask))) | (((value) << (shift)) & (mask))); +} + +bool tmc2241_getDirtyBit(uint16_t icID, uint8_t index) +{ + if(index >= TMC2241_REGISTER_COUNT) + return false; + + uint8_t *tmp = &tmc2241_dirtyBits[icID][index / 8]; + uint8_t shift = (index % 8); + return ((*tmp) >> shift) & 1; +} +/* + * This function is used to cache the value written to the Write-Only registers in the form of shadow array. + * The shadow copy is then used to read these kinds of registers. + */ + +bool tmc2241_cache(uint16_t icID, TMC2241CacheOp operation, uint8_t address, uint32_t *value) +{ + if (operation == TMC2241_CACHE_READ) + { + // Check if the value should come from cache + + // Only supported chips have a cache + if (icID >= TMC2241_IC_CACHE_COUNT) + return false; + + // Only non-readable registers care about caching + // Note: This could also be used to cache i.e. RW config registers to reduce bus accesses + if (TMC2241_IS_READABLE(tmc2241_registerAccess[address])) + return false; + + // Grab the value from the cache + *value = tmc2241_shadowRegister[icID][address]; + return true; + } + else if (operation == TMC2241_CACHE_WRITE || operation == TMC2241_CACHE_FILL_DEFAULT) + { + // Fill the cache + + // only supported chips have a cache + if (icID >= TMC2241_IC_CACHE_COUNT) + return false; + + // Write to the shadow register. + tmc2241_shadowRegister[icID][address] = *value; + // For write operations, mark the register dirty + if (operation == TMC2241_CACHE_WRITE) + { + tmc2241_setDirtyBit(icID, address, true); + } + + return true; + } + return false; +} + +void tmc2241_initCache() +{ + // Check if we have constants defined + if(ARRAY_SIZE(tmc2241_RegisterConstants) == 0) + return; + + size_t i, j, id; + + for(i = 0, j = 0; i < TMC2241_REGISTER_COUNT; i++) + { + // We only need to worry about hardware preset, write-only registers + // that have not yet been written (no dirty bit) here. + if(tmc2241_registerAccess[i] != TMC2241_ACCESS_W_PRESET) + continue; + + // Search the constant list for the current address. With the constant + // list being sorted in ascended order, we can walk through the list + // until the entry with an address equal or greater than i + while(j < ARRAY_SIZE(tmc2241_RegisterConstants) && (tmc2241_RegisterConstants[j].address < i)) + j++; + + // Abort when we reach the end of the constant list + if (j == ARRAY_SIZE(tmc2241_RegisterConstants)) + break; + + // If we have an entry for our current address, write the constant + if(tmc2241_RegisterConstants[j].address == i) + { + for (id = 0; id < TMC2241_IC_CACHE_COUNT; id++) + { + uint32_t temp = tmc2241_RegisterConstants[j].value; + tmc2241_cache(id, TMC2241_CACHE_FILL_DEFAULT, i, &temp); + } + } + } +} +#else +// User must implement their own cache +extern bool tmc2241_cache(uint16_t icID, TMC2241CacheOp operation, uint8_t address, uint32_t *value); +#endif +#endif + +/************************************************************* read / write Implementation *********************************************************************/ + + +static int32_t readRegisterSPI(uint16_t icID, uint8_t address); +static void writeRegisterSPI(uint16_t icID, uint8_t address, int32_t value); +static int32_t readRegisterUART(uint16_t icID, uint8_t registerAddress); +static void writeRegisterUART(uint16_t icID, uint8_t registerAddress, int32_t value); +static uint8_t CRC8(uint8_t *data, uint32_t bytes); + + + +int32_t tmc2241_readRegister(uint16_t icID, uint8_t address) +{ + uint32_t value; + + // Read from cache for registers with write-only access + if (tmc2241_cache(icID, TMC2241_CACHE_READ, address, &value)) + return value; + + TMC2241BusType bus = tmc2241_getBusType(icID); + + if(bus == IC_BUS_SPI) + { + return readRegisterSPI(icID, address); + } + else if (bus == IC_BUS_UART) + { + return readRegisterUART(icID, address); + } + + // ToDo: Error handling + return -1; +} +void tmc2241_writeRegister(uint16_t icID, uint8_t address, int32_t value) +{ + TMC2241BusType bus = tmc2241_getBusType(icID); + + if(bus == IC_BUS_SPI) + { + writeRegisterSPI(icID, address, value); + } + else if(bus == IC_BUS_UART) + { + writeRegisterUART(icID, address, value); + } + //Cache the registers with write-only access + tmc2241_cache(icID, TMC2241_CACHE_WRITE, address, (uint32_t *)&value); +} + +int32_t readRegisterSPI(uint16_t icID, uint8_t address) +{ + uint8_t data[5] = { 0 }; + + // clear write bit + data[0] = address & TMC2241_ADDRESS_MASK; + + // Send the read request + tmc2241_readWriteSPI(icID, &data[0], sizeof(data)); + + // Rewrite address and clear write bit + data[0] = address & TMC2241_ADDRESS_MASK; + + // Send another request to receive the read reply + tmc2241_readWriteSPI(icID, &data[0], sizeof(data)); + + return ((int32_t)data[1] << 24) | ((int32_t) data[2] << 16) | ((int32_t) data[3] << 8) | ((int32_t) data[4]); +} + +void writeRegisterSPI(uint16_t icID, uint8_t address, int32_t value) +{ + uint8_t data[5] = { 0 }; + + data[0] = address | TMC2241_WRITE_BIT; + data[1] = 0xFF & (value>>24); + data[2] = 0xFF & (value>>16); + data[3] = 0xFF & (value>>8); + data[4] = 0xFF & (value>>0); + + // Send the write request + tmc2241_readWriteSPI(icID, &data[0], sizeof(data)); +} + +int32_t readRegisterUART(uint16_t icID, uint8_t registerAddress) +{ + uint8_t data[8] = { 0 }; + + registerAddress = registerAddress & TMC2241_ADDRESS_MASK; + + data[0] = 0x05; + data[1] = tmc2241_getNodeAddress(icID); + data[2] = registerAddress; + data[3] = CRC8(data, 3); + + if (!tmc2241_readWriteUART(icID, &data[0], 4, 8)) + return 0; + + // Byte 0: Sync nibble correct? + if (data[0] != 0x05) + return 0; + + // Byte 1: Master address correct? + if (data[1] != 0xFF) + return 0; + + // Byte 2: Address correct? + if (data[2] != registerAddress) + return 0; + + // Byte 7: CRC correct? + if (data[7] != CRC8(data, 7)) + return 0; + + return ((uint32_t)data[3] << 24) | ((uint32_t)data[4] << 16) | (data[5] << 8) | data[6]; +} + +void writeRegisterUART(uint16_t icID, uint8_t registerAddress, int32_t value) +{ + uint8_t data[8]; + + data[0] = 0x05; + data[1] = tmc2241_getNodeAddress(icID); + data[2] = registerAddress | TMC2241_WRITE_BIT; + data[3] = (value >> 24) & 0xFF; + data[4] = (value >> 16) & 0xFF; + data[5] = (value >> 8 ) & 0xFF; + data[6] = (value ) & 0xFF; + data[7] = CRC8(data, 7); + + tmc2241_readWriteUART(icID, &data[0], 8, 0); +} + +static uint8_t CRC8(uint8_t *data, uint32_t bytes) +{ + uint8_t result = 0; + + while(bytes--) + result = tmcCRCTable_Poly7Reflected[result ^ *data++]; + + // Flip the result around + // swap odd and even bits + result = ((result >> 1) & 0x55) | ((result & 0x55) << 1); + // swap consecutive pairs + result = ((result >> 2) & 0x33) | ((result & 0x33) << 2); + // swap nibbles ... + result = ((result >> 4) & 0x0F) | ((result & 0x0F) << 4); + + return result; +} + +/***************************************************************************************************************************************************************/ diff --git a/firmware/lib/tmc/ic/TMC2241/TMC2241.h b/firmware/lib/tmc/ic/TMC2241/TMC2241.h new file mode 100755 index 0000000..bb43d03 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2241/TMC2241.h @@ -0,0 +1,221 @@ +/******************************************************************************* +* Copyright © 2025 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#ifndef TMC_IC_TMC2241_H_ + +#include +#include +#include +#include "TMC2241_HW_Abstraction.h" + + +/******************************************************************************* +* API Configuration Defines +* These control optional features of the TMC-API implementation. +* These can be commented in/out here or defined from the build system. +*******************************************************************************/ + +// Uncomment if you want to save space..... +// and put the table into your own .c file +//#define TMC_API_EXTERNAL_CRC_TABLE 1 + +// To enable the cache mechanism in order to keep the copy of all registers, set TMC2241_CACHE to '1'. +// With this mechanism the value of write-only registers could be read from their shadow copies. +#ifndef TMC2241_CACHE +#define TMC2241_CACHE 1 +//#define TMC2241_CACHE 0 +#endif + +// To use the caching mechanism already implemented by the TMC-API, set TMC2241_ENABLE_TMC_CACHE to '1'. +// Set TMC2241_ENABLE_TMC_CACHE to '0' if one wants to have their own cache implementation. +#ifndef TMC2241_ENABLE_TMC_CACHE +#define TMC2241_ENABLE_TMC_CACHE 1 +//#define TMC2241_ENABLE_TMC_CACHE 0 +#endif + +/******************************************************************************/ + + +typedef enum { + IC_BUS_SPI, + IC_BUS_UART, + IC_BUS_WLAN, +} TMC2241BusType; + +// => TMC-API wrapper +extern void tmc2241_readWriteSPI(uint16_t icID, uint8_t *data, size_t dataLength); +extern bool tmc2241_readWriteUART(uint16_t icID, uint8_t *data, size_t writeLength, size_t readLength); +extern TMC2241BusType tmc2241_getBusType(uint16_t icID); +extern uint8_t tmc2241_getNodeAddress(uint16_t icID); +// => TMC-API wrapper + +int32_t tmc2241_readRegister(uint16_t icID, uint8_t address); +void tmc2241_writeRegister(uint16_t icID, uint8_t address, int32_t value); + +typedef struct +{ + uint32_t mask; + uint8_t shift; + uint8_t address; + bool isSigned; +} RegisterField; + + +static inline uint32_t tmc2241_fieldExtract(uint32_t data, RegisterField field) +{ + uint32_t value = (data & field.mask) >> field.shift; + + if (field.isSigned) + { + // Apply signedness conversion + uint32_t baseMask = field.mask >> field.shift; + uint32_t signMask = baseMask & (~baseMask >> 1); + value = (value ^ signMask) - signMask; + } + + return value; +} + +static inline uint32_t tmc2241_fieldRead(uint16_t icID, RegisterField field) +{ + uint32_t value = tmc2241_readRegister(icID, field.address); + + return tmc2241_fieldExtract(value, field); +} + +static inline uint32_t tmc2241_fieldUpdate(uint32_t data, RegisterField field, uint32_t value) +{ + return (data & (~field.mask)) | ((value << field.shift) & field.mask); +} + +static inline void tmc2241_fieldWrite(uint16_t icID, RegisterField field, uint32_t value) +{ + uint32_t regValue = tmc2241_readRegister(icID, field.address); + + regValue = tmc2241_fieldUpdate(regValue, field, value); + + tmc2241_writeRegister(icID, field.address, regValue); +} + +/**************************************************************** Cache Implementation *************************************************************************/ +#if TMC2241_CACHE == 1 +#ifdef TMC2241_ENABLE_TMC_CACHE + +// By default, support one IC in the cache +#ifndef TMC2241_IC_CACHE_COUNT +#define TMC2241_IC_CACHE_COUNT 1 +#endif + +typedef enum { + TMC2241_CACHE_READ, + TMC2241_CACHE_WRITE, + // Special operation: Put content into the cache without marking the entry as dirty. + // Only used to initialize the cache with hardware defaults. This will allow reading + // from write-only registers that have a value inside them on reset. When using this + // operation, a restore will *not* rewrite that filled register! + TMC2241_CACHE_FILL_DEFAULT, +} TMC2241CacheOp; + +typedef struct{ + uint8_t address; + uint32_t value; +} TMC2241RegisterConstants; + +#define TMC2241_ACCESS_DIRTY 0x08 // Register has been written since reset -> shadow register is valid for restore +#define TMC2241_ACCESS_READ 0x01 +#define TMC2241_ACCESS_W_PRESET 0x42 +#define TMC2241_IS_READABLE(x) ((x) & TMC2241_ACCESS_READ) +#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) + +// Helper define: +// Most register permission arrays are initialized with 128 values. +// In those fields its quite hard to have an easy overview of available +// registers. For that, ____ is defined to 0, since 4 underscores are +// very easy to distinguish from the 2-digit hexadecimal values. +// This way, the used registers (permission != ACCESS_NONE) are easily spotted +// amongst unused (permission == ACCESS_NONE) registers. +#define ____ 0x00 + +// Helper define: +// Default reset values are not used if the corresponding register has a +// hardware preset. Since this is not directly visible in the default +// register reset values array, N_A is used as an indicator for a preset +// value, where any value will be ignored anyways (N_A: not available). +#define N_A 0 + +// Default Register values +#define R00 0x00002108 // GCONF +#define R0A 0x00000020 // DRVCONF +#define R10 0x00070A03 // IHOLD_IRUN +#define R11 0x0000000A // TPOWERDOWN +#define R2B 0x00000001 // VSTOP +#define R3A 0x00010000 // ENC_CONST +#define R52 0x0B920F25 // OTW_OV_VTH +#define R6C 0x14410153 // CHOPCONF +#define R70 0xC44C001E // PWMCONF + +// Register access permissions: +// 0x00: none (reserved) +// 0x01: read +// 0x02: write +// 0x03: read/write +// 0x13: read/write, separate functions/values for reading or writing +// 0x23: read/write, flag register (write to clear) +// 0x42: write, has hardware presets on reset +static const uint8_t tmc2241_registerAccess[TMC2241_REGISTER_COUNT] = +{ + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0x03, 0x23, 0x01, 0x03, 0x03, ____, ____, ____, ____, ____, 0x03, 0x03, ____, ____, ____, ____, // 0x00 - 0x0F + 0x03, 0x03, 0x01, 0x03, 0x03, 0x03, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x10 - 0x1F + ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, 0x03, ____, ____, // 0x20 - 0x2F + ____, ____, ____, ____, ____, ____, ____, ____, 0x03, 0x03, 0x03, 0x23, 0x01, ____, ____, ____, // 0x30 - 0x3F + ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x40 - 0x4F + 0x01, 0x01, 0x03, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x50 - 0x5F + 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x01, 0x01, 0x03, 0x03, ____, 0x01, // 0x60 - 0x6F + 0x03, 0x01, 0x01, ____, 0x03, 0x01, 0x01, ____, ____, ____, ____, ____, ____, ____, ____, ____ // 0x70 - 0x7F +}; +static const int32_t tmc2241_sampleRegisterPreset[TMC2241_REGISTER_COUNT] = +{ + // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F + R00, 0, 0, 0, 0, 0, 0, 0, 0, 0, R0A, 0, 0, 0, 0, 0, // 0x00 - 0x0F + R10, R11, 0, 0, 0, 0, 0, 0, 0, 0, 0, R2B, 0, 0, 0, 0, // 0x10 - 0x1F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x20 - 0x2F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, R3A, 0, 0, 0, 0, 0, // 0x30 - 0x3F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x40 - 0x4F + 0, 0, R52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x50 - 0x5F + N_A, N_A, N_A, N_A, N_A, N_A, N_A, N_A, N_A, N_A, 0, 0, R6C, 0, 0, 0, // 0x60 - 0x6F + R70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x70 - 0x7F +}; + + +// Register constants (only required for 0x42 registers, since we do not have +// any way to find out the content but want to hold the actual value in the +// shadow register so an application (i.e. the TMCL IDE) can still display +// the values. This only works when the register content is constant. +static const TMC2241RegisterConstants tmc2241_RegisterConstants[] = +{ // Use ascending addresses! + { 0x60, 0xAAAAB554 }, // MSLUT[0] + { 0x61, 0x4A9554AA }, // MSLUT[1] + { 0x62, 0x24492929 }, // MSLUT[2] + { 0x63, 0x10104222 }, // MSLUT[3] + { 0x64, 0xFBFFFFFF }, // MSLUT[4] + { 0x65, 0xB5BB777D }, // MSLUT[5] + { 0x66, 0x49295556 }, // MSLUT[6] + { 0x67, 0x00404222 }, // MSLUT[7] + { 0x68, 0xFFFF8056 }, // MSLUTSEL + { 0x69, 0x00F70000 } // MSLUTSTART +}; + +extern uint8_t tmc2241_dirtyBits[TMC2241_IC_CACHE_COUNT][TMC2241_REGISTER_COUNT/8]; +extern int32_t tmc2241_shadowRegister[TMC2241_IC_CACHE_COUNT][TMC2241_REGISTER_COUNT]; +bool tmc2241_cache(uint16_t icID, TMC2241CacheOp operation, uint8_t address, uint32_t *value); +void tmc2241_initCache(void); +void tmc2241_setDirtyBit(uint16_t icID, uint8_t index, bool value); +bool tmc2241_getDirtyBit(uint16_t icID, uint8_t index); +#endif +#endif +/***************************************************************************************************************************************************/ +#endif /* TMC_IC_TMC2241_H_ */ diff --git a/firmware/lib/tmc/ic/TMC2241/TMC2241_HW_Abstraction.h b/firmware/lib/tmc/ic/TMC2241/TMC2241_HW_Abstraction.h new file mode 100755 index 0000000..f2349ff --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2241/TMC2241_HW_Abstraction.h @@ -0,0 +1,610 @@ +/******************************************************************************* +* Copyright © 2025 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#ifndef TMC_IC_TMC2241_H_ +#define TMC_IC_TMC2241_H_ + +// Constants +#define TMC2241_REGISTER_COUNT 128 +#define TMC2241_MOTORS 1 +#define TMC2241_WRITE_BIT 0x80 +#define TMC2241_ADDRESS_MASK 0x7F +#define TMC2241_MAX_VELOCITY 8388096 +#define TMC2241_MAX_ACCELERATION (uint16_t) 65535 + +// ramp modes (Register TMC2241_RAMPMODE) +#define TMC2241_MODE_POSITION 0 +#define TMC2241_MODE_VELPOS 1 +#define TMC2241_MODE_VELNEG 2 +#define TMC2241_MODE_HOLD 3 + +// limit switch mode bits (Register TMC2241_SWMODE) +#define TMC2241_SW_STOPL_ENABLE 0x0001 +#define TMC2241_SW_STOPR_ENABLE 0x0002 +#define TMC2241_SW_STOPL_POLARITY 0x0004 +#define TMC2241_SW_STOPR_POLARITY 0x0008 +#define TMC2241_SW_SWAP_LR 0x0010 +#define TMC2241_SW_LATCH_L_ACT 0x0020 +#define TMC2241_SW_LATCH_L_INACT 0x0040 +#define TMC2241_SW_LATCH_R_ACT 0x0080 +#define TMC2241_SW_LATCH_R_INACT 0x0100 +#define TMC2241_SW_LATCH_ENC 0x0200 +#define TMC2241_SW_SG_STOP 0x0400 +#define TMC2241_SW_SOFTSTOP 0x0800 + +// Status bits (Register TMC2241_RAMPSTAT) +#define TMC2241_RS_STOPL 0x0001 +#define TMC2241_RS_STOPR 0x0002 +#define TMC2241_RS_LATCHL 0x0004 +#define TMC2241_RS_LATCHR 0x0008 +#define TMC2241_RS_EV_STOPL 0x0010 +#define TMC2241_RS_EV_STOPR 0x0020 +#define TMC2241_RS_EV_STOP_SG 0x0040 +#define TMC2241_RS_EV_POSREACHED 0x0080 +#define TMC2241_RS_VELREACHED 0x0100 +#define TMC2241_RS_POSREACHED 0x0200 +#define TMC2241_RS_VZERO 0x0400 +#define TMC2241_RS_ZEROWAIT 0x0800 +#define TMC2241_RS_SECONDMOVE 0x1000 +#define TMC2241_RS_SG 0x2000 + +// Encoderbits (Register TMC2241_ENCMODE) +#define TMC2241_EM_DECIMAL 0x0400 +#define TMC2241_EM_LATCH_XACT 0x0200 +#define TMC2241_EM_CLR_XENC 0x0100 +#define TMC2241_EM_NEG_EDGE 0x0080 +#define TMC2241_EM_POS_EDGE 0x0040 +#define TMC2241_EM_CLR_ONCE 0x0020 +#define TMC2241_EM_CLR_CONT 0x0010 +#define TMC2241_EM_IGNORE_AB 0x0008 +#define TMC2241_EM_POL_N 0x0004 +#define TMC2241_EM_POL_B 0x0002 +#define TMC2241_EM_POL_A 0x0001 + + +// Registers +#define TMC2241_GCONF 0x00 +#define TMC2241_GSTAT 0x01 +#define TMC2241_IFCNT 0x02 +#define TMC2241_NODECONF 0x03 +#define TMC2241_IOIN 0x04 +#define TMC2241_DIAG_GCONF 0x07 +#define TMC2241_DRV_CONF 0x0A +#define TMC2241_GLOBAL_SCALER 0x0B +#define TMC2241_IHOLD_IRUN 0x10 +#define TMC2241_TPOWERDOWN 0x11 +#define TMC2241_TSTEP 0x12 +#define TMC2241_TPWMTHRS 0x13 +#define TMC2241_TCOOLTHRS 0x14 +#define TMC2241_THIGH 0x15 +#define TMC2241_DIRECT_MODE 0x2D +#define TMC2241_ENCMODE 0x38 +#define TMC2241_X_ENC 0x39 +#define TMC2241_ENC_CONST 0x3A +#define TMC2241_ENC_STATUS 0x3B +#define TMC2241_ENC_LATCH 0x3C +#define TMC2241_ADC_VSUPPLY_AIN 0x50 +#define TMC2241_ADC_TEMP 0x51 +#define TMC2241_OTW_OV_VTH 0x52 +#define TMC2241_MSLUT_0 0x60 +#define TMC2241_MSLUT_1 0x61 +#define TMC2241_MSLUT_2 0x62 +#define TMC2241_MSLUT_3 0x63 +#define TMC2241_MSLUT_4 0x64 +#define TMC2241_MSLUT_5 0x65 +#define TMC2241_MSLUT_6 0x66 +#define TMC2241_MSLUT_7 0x67 +#define TMC2241_MSLUTSEL 0x68 +#define TMC2241_MSLUTSTART 0x69 +#define TMC2241_MSCNT 0x6A +#define TMC2241_MSCURACT 0x6B +#define TMC2241_CHOPCONF 0x6C +#define TMC2241_COOLCONF 0x6D +#define TMC2241_DRV_STATUS 0x6F +#define TMC2241_PWMCONF 0x70 +#define TMC2241_PWM_SCALE 0x71 +#define TMC2241_PWM_AUTO 0x72 +#define TMC2241_SG4_CONF 0x74 +#define TMC2241_SG4_RESULT 0x75 +#define TMC2241_SG4_IND 0x76 + +// Register fields +#define TMC2241_FAST_STANDSTILL_MASK 0x00000002 +#define TMC2241_FAST_STANDSTILL_SHIFT 1 +#define TMC2241_FAST_STANDSTILL_FIELD ((RegisterField) {TMC2241_FAST_STANDSTILL_MASK, TMC2241_FAST_STANDSTILL_SHIFT, TMC2241_GCONF, false}) +#define TMC2241_EN_PWM_MODE_MASK 0x00000004 +#define TMC2241_EN_PWM_MODE_SHIFT 2 +#define TMC2241_EN_PWM_MODE_FIELD ((RegisterField) {TMC2241_EN_PWM_MODE_MASK, TMC2241_EN_PWM_MODE_SHIFT, TMC2241_GCONF, false}) +#define TMC2241_MULTISTEP_FILT_MASK 0x00000008 +#define TMC2241_MULTISTEP_FILT_SHIFT 3 +#define TMC2241_MULTISTEP_FILT_FIELD ((RegisterField) {TMC2241_MULTISTEP_FILT_MASK, TMC2241_MULTISTEP_FILT_SHIFT, TMC2241_GCONF, false}) +#define TMC2241_SHAFT_MASK 0x00000010 +#define TMC2241_SHAFT_SHIFT 4 +#define TMC2241_SHAFT_FIELD ((RegisterField) {TMC2241_SHAFT_MASK, TMC2241_SHAFT_SHIFT, TMC2241_GCONF, false}) +#define TMC2241_DIAG0_ERROR_MASK 0x00000020 +#define TMC2241_DIAG0_ERROR_SHIFT 5 +#define TMC2241_DIAG0_ERROR_FIELD ((RegisterField) {TMC2241_DIAG0_ERROR_MASK, TMC2241_DIAG0_ERROR_SHIFT, TMC2241_GCONF, false}) +#define TMC2241_DIAG0_OTPW_MASK 0x00000040 +#define TMC2241_DIAG0_OTPW_SHIFT 6 +#define TMC2241_DIAG0_OTPW_FIELD ((RegisterField) {TMC2241_DIAG0_OTPW_MASK, TMC2241_DIAG0_OTPW_SHIFT, TMC2241_GCONF, false}) +#define TMC2241_DIAG0_STALL_MASK 0x00000080 +#define TMC2241_DIAG0_STALL_SHIFT 7 +#define TMC2241_DIAG0_STALL_FIELD ((RegisterField) {TMC2241_DIAG0_STALL_MASK, TMC2241_DIAG0_STALL_SHIFT, TMC2241_GCONF, false}) +#define TMC2241_DIAG1_STALL_MASK 0x00000100 +#define TMC2241_DIAG1_STALL_SHIFT 8 +#define TMC2241_DIAG1_STALL_FIELD ((RegisterField) {TMC2241_DIAG1_STALL_MASK, TMC2241_DIAG1_STALL_SHIFT, TMC2241_GCONF, false}) +#define TMC2241_DIAG1_INDEX_MASK 0x00000200 +#define TMC2241_DIAG1_INDEX_SHIFT 9 +#define TMC2241_DIAG1_INDEX_FIELD ((RegisterField) {TMC2241_DIAG1_INDEX_MASK, TMC2241_DIAG1_INDEX_SHIFT, TMC2241_GCONF, false}) +#define TMC2241_DIAG1_ONSTATE_MASK 0x00000400 +#define TMC2241_DIAG1_ONSTATE_SHIFT 10 +#define TMC2241_DIAG1_ONSTATE_FIELD ((RegisterField) {TMC2241_DIAG1_ONSTATE_MASK, TMC2241_DIAG1_ONSTATE_SHIFT, TMC2241_GCONF, false}) +#define TMC2241_DIAG0_PUSHPULL_MASK 0x00001000 +#define TMC2241_DIAG0_PUSHPULL_SHIFT 12 +#define TMC2241_DIAG0_PUSHPULL_FIELD ((RegisterField) {TMC2241_DIAG0_PUSHPULL_MASK, TMC2241_DIAG0_PUSHPULL_SHIFT, TMC2241_GCONF, false}) +#define TMC2241_DIAG1_PUSHPULL_MASK 0x00002000 +#define TMC2241_DIAG1_PUSHPULL_SHIFT 13 +#define TMC2241_DIAG1_PUSHPULL_FIELD ((RegisterField) {TMC2241_DIAG1_PUSHPULL_MASK, TMC2241_DIAG1_PUSHPULL_SHIFT, TMC2241_GCONF, false}) +#define TMC2241_SMALL_HYSTERESIS_MASK 0x00004000 +#define TMC2241_SMALL_HYSTERESIS_SHIFT 14 +#define TMC2241_SMALL_HYSTERESIS_FIELD ((RegisterField) {TMC2241_SMALL_HYSTERESIS_MASK, TMC2241_SMALL_HYSTERESIS_SHIFT, TMC2241_GCONF, false}) +#define TMC2241_STOP_ENABLE_MASK 0x00008000 +#define TMC2241_STOP_ENABLE_SHIFT 15 +#define TMC2241_STOP_ENABLE_FIELD ((RegisterField) {TMC2241_STOP_ENABLE_MASK, TMC2241_STOP_ENABLE_SHIFT, TMC2241_GCONF, false}) +#define TMC2241_DIRECT_MODE_MASK 0x00010000 +#define TMC2241_DIRECT_MODE_SHIFT 16 +#define TMC2241_DIRECT_MODE_FIELD ((RegisterField) {TMC2241_DIRECT_MODE_MASK, TMC2241_DIRECT_MODE_SHIFT, TMC2241_GCONF, false}) +#define TMC2241_RESET_MASK 0x00000001 +#define TMC2241_RESET_SHIFT 0 +#define TMC2241_RESET_FIELD ((RegisterField) {TMC2241_RESET_MASK, TMC2241_RESET_SHIFT, TMC2241_GSTAT, false}) +#define TMC2241_DRV_ERR_MASK 0x00000002 +#define TMC2241_DRV_ERR_SHIFT 1 +#define TMC2241_DRV_ERR_FIELD ((RegisterField) {TMC2241_DRV_ERR_MASK, TMC2241_DRV_ERR_SHIFT, TMC2241_GSTAT, false}) +#define TMC2241_UV_CP_MASK 0x00000004 +#define TMC2241_UV_CP_SHIFT 2 +#define TMC2241_UV_CP_FIELD ((RegisterField) {TMC2241_UV_CP_MASK, TMC2241_UV_CP_SHIFT, TMC2241_GSTAT, false}) +#define TMC2241_REGISTER_RESET_MASK 0x00000008 +#define TMC2241_REGISTER_RESET_SHIFT 3 +#define TMC2241_REGISTER_RESET_FIELD ((RegisterField) {TMC2241_REGISTER_RESET_MASK, TMC2241_REGISTER_RESET_SHIFT, TMC2241_GSTAT, false}) +#define TMC2241_VM_UVLO_MASK 0x00000010 +#define TMC2241_VM_UVLO_SHIFT 4 +#define TMC2241_VM_UVLO_FIELD ((RegisterField) {TMC2241_VM_UVLO_MASK, TMC2241_VM_UVLO_SHIFT, TMC2241_GSTAT, false}) +#define TMC2241_IFCNT_MASK 0x000000FF +#define TMC2241_IFCNT_SHIFT 0 +#define TMC2241_IFCNT_FIELD ((RegisterField) {TMC2241_IFCNT_MASK, TMC2241_IFCNT_SHIFT, TMC2241_IFCNT, false}) +#define TMC2241_NODEADDR_MASK 0x000000FF +#define TMC2241_NODEADDR_SHIFT 0 +#define TMC2241_NODEADDR_FIELD ((RegisterField) {TMC2241_NODEADDR_MASK, TMC2241_NODEADDR_SHIFT, TMC2241_NODECONF, false}) +#define TMC2241_SENDDELAY_MASK 0x00000F00 +#define TMC2241_SENDDELAY_SHIFT 8 +#define TMC2241_SENDDELAY_FIELD ((RegisterField) {TMC2241_SENDDELAY_MASK, TMC2241_SENDDELAY_SHIFT, TMC2241_NODECONF, false}) +#define TMC2241_STEP_MASK 0x00000001 +#define TMC2241_STEP_SHIFT 0 +#define TMC2241_STEP_FIELD ((RegisterField) {TMC2241_STEP_MASK, TMC2241_STEP_SHIFT, TMC2241_IOIN, false}) +#define TMC2241_DIR_MASK 0x00000002 +#define TMC2241_DIR_SHIFT 1 +#define TMC2241_DIR_FIELD ((RegisterField) {TMC2241_DIR_MASK, TMC2241_DIR_SHIFT, TMC2241_IOIN, false}) +#define TMC2241_ENCB_MASK 0x00000004 +#define TMC2241_ENCB_SHIFT 2 +#define TMC2241_ENCB_FIELD ((RegisterField) {TMC2241_ENCB_MASK, TMC2241_ENCB_SHIFT, TMC2241_IOIN, false}) +#define TMC2241_ENCA_MASK 0x00000008 +#define TMC2241_ENCA_SHIFT 3 +#define TMC2241_ENCA_FIELD ((RegisterField) {TMC2241_ENCA_MASK, TMC2241_ENCA_SHIFT, TMC2241_IOIN, false}) +#define TMC2241_DRV_ENN_MASK 0x00000010 +#define TMC2241_DRV_ENN_SHIFT 4 +#define TMC2241_DRV_ENN_FIELD ((RegisterField) {TMC2241_DRV_ENN_MASK, TMC2241_DRV_ENN_SHIFT, TMC2241_IOIN, false}) +#define TMC2241_ENCN_MASK 0x00000020 +#define TMC2241_ENCN_SHIFT 5 +#define TMC2241_ENCN_FIELD ((RegisterField) {TMC2241_ENCN_MASK, TMC2241_ENCN_SHIFT, TMC2241_IOIN, false}) +#define TMC2241_UART_EN_MASK 0x00000040 +#define TMC2241_UART_EN_SHIFT 6 +#define TMC2241_UART_EN_FIELD ((RegisterField) {TMC2241_UART_EN_MASK, TMC2241_UART_EN_SHIFT, TMC2241_IOIN, false}) +#define TMC2241_RESERVED_MASK 0x00000080 +#define TMC2241_RESERVED_SHIFT 7 +#define TMC2241_RESERVED_FIELD ((RegisterField) {TMC2241_RESERVED_MASK, TMC2241_RESERVED_SHIFT, TMC2241_IOIN, false}) +#define TMC2241_COMP_A_MASK 0x00000100 +#define TMC2241_COMP_A_SHIFT 8 +#define TMC2241_COMP_A_FIELD ((RegisterField) {TMC2241_COMP_A_MASK, TMC2241_COMP_A_SHIFT, TMC2241_IOIN, false}) +#define TMC2241_COMP_B_MASK 0x00000200 +#define TMC2241_COMP_B_SHIFT 9 +#define TMC2241_COMP_B_FIELD ((RegisterField) {TMC2241_COMP_B_MASK, TMC2241_COMP_B_SHIFT, TMC2241_IOIN, false}) +#define TMC2241_COMP_A1_A2_MASK 0x00000400 +#define TMC2241_COMP_A1_A2_SHIFT 10 +#define TMC2241_COMP_A1_A2_FIELD ((RegisterField) {TMC2241_COMP_A1_A2_MASK, TMC2241_COMP_A1_A2_SHIFT, TMC2241_IOIN, false}) +#define TMC2241_COMP_B1_B2_MASK 0x00000800 +#define TMC2241_COMP_B1_B2_SHIFT 11 +#define TMC2241_COMP_B1_B2_FIELD ((RegisterField) {TMC2241_COMP_B1_B2_MASK, TMC2241_COMP_B1_B2_SHIFT, TMC2241_IOIN, false}) +#define TMC2241_OUTPUT_MASK 0x00001000 +#define TMC2241_OUTPUT_SHIFT 12 +#define TMC2241_OUTPUT_FIELD ((RegisterField) {TMC2241_OUTPUT_MASK, TMC2241_OUTPUT_SHIFT, TMC2241_IOIN, false}) +#define TMC2241_EXT_RES_DET_MASK 0x00002000 +#define TMC2241_EXT_RES_DET_SHIFT 13 +#define TMC2241_EXT_RES_DET_FIELD ((RegisterField) {TMC2241_EXT_RES_DET_MASK, TMC2241_EXT_RES_DET_SHIFT, TMC2241_IOIN, false}) +#define TMC2241_EXT_CLK_MASK 0x00004000 +#define TMC2241_EXT_CLK_SHIFT 14 +#define TMC2241_EXT_CLK_FIELD ((RegisterField) {TMC2241_EXT_CLK_MASK, TMC2241_EXT_CLK_SHIFT, TMC2241_IOIN, false}) +#define TMC2241_ADC_ERR_MASK 0x00008000 +#define TMC2241_ADC_ERR_SHIFT 15 +#define TMC2241_ADC_ERR_FIELD ((RegisterField) {TMC2241_ADC_ERR_MASK, TMC2241_ADC_ERR_SHIFT, TMC2241_IOIN, false}) +#define TMC2241_SILICON_RV_MASK 0x00070000 +#define TMC2241_SILICON_RV_SHIFT 16 +#define TMC2241_SILICON_RV_FIELD ((RegisterField) {TMC2241_SILICON_RV_MASK, TMC2241_SILICON_RV_SHIFT, TMC2241_IOIN, false}) +//#define TMC2241_DIAG0_ERROR_MASK 0x00000001 +//#define TMC2241_DIAG0_ERROR_SHIFT 0 +//#define TMC2241_DIAG0_ERROR_FIELD ((RegisterField) {TMC2241_DIAG0_ERROR_MASK, TMC2241_DIAG0_ERROR_SHIFT, TMC2241_DIAG_GCONF, false}) +//#define TMC2241_DIAG0_OTPW_MASK 0x00000002 +//#define TMC2241_DIAG0_OTPW_SHIFT 1 +//#define TMC2241_DIAG0_OTPW_FIELD ((RegisterField) {TMC2241_DIAG0_OTPW_MASK, TMC2241_DIAG0_OTPW_SHIFT, TMC2241_DIAG_GCONF, false}) +//#define TMC2241_DIAG0_STALL_MASK 0x00000004 +//#define TMC2241_DIAG0_STALL_SHIFT 2 +//#define TMC2241_DIAG0_STALL_FIELD ((RegisterField) {TMC2241_DIAG0_STALL_MASK, TMC2241_DIAG0_STALL_SHIFT, TMC2241_DIAG_GCONF, false}) +#define TMC2241_DIAG0_INDEX_MASK 0x00000008 +#define TMC2241_DIAG0_INDEX_SHIFT 3 +#define TMC2241_DIAG0_INDEX_FIELD ((RegisterField) {TMC2241_DIAG0_INDEX_MASK, TMC2241_DIAG0_INDEX_SHIFT, TMC2241_DIAG_GCONF, false}) +#define TMC2241_DIAG0_EV_N_DEVIATION_MASK 0x00000400 +#define TMC2241_DIAG0_EV_N_DEVIATION_SHIFT 10 +#define TMC2241_DIAG0_EV_N_DEVIATION_FIELD ((RegisterField) {TMC2241_DIAG0_EV_N_DEVIATION_MASK, TMC2241_DIAG0_EV_N_DEVIATION_SHIFT, TMC2241_DIAG_GCONF, false}) +#define TMC2241_DIAG0_OVERVOLTAGE_MASK 0x00000800 +#define TMC2241_DIAG0_OVERVOLTAGE_SHIFT 11 +#define TMC2241_DIAG0_OVERVOLTAGE_FIELD ((RegisterField) {TMC2241_DIAG0_OVERVOLTAGE_MASK, TMC2241_DIAG0_OVERVOLTAGE_SHIFT, TMC2241_DIAG_GCONF, false}) +#define TMC2241_DIAG1_ERROR_MASK 0x00010000 +#define TMC2241_DIAG1_ERROR_SHIFT 16 +#define TMC2241_DIAG1_ERROR_FIELD ((RegisterField) {TMC2241_DIAG1_ERROR_MASK, TMC2241_DIAG1_ERROR_SHIFT, TMC2241_DIAG_GCONF, false}) +#define TMC2241_DIAG1_OTPW_MASK 0x00020000 +#define TMC2241_DIAG1_OTPW_SHIFT 17 +#define TMC2241_DIAG1_OTPW_FIELD ((RegisterField) {TMC2241_DIAG1_OTPW_MASK, TMC2241_DIAG1_OTPW_SHIFT, TMC2241_DIAG_GCONF, false}) +//#define TMC2241_DIAG1_STALL_MASK 0x00040000 +//#define TMC2241_DIAG1_STALL_SHIFT 18 +//#define TMC2241_DIAG1_STALL_FIELD ((RegisterField) {TMC2241_DIAG1_STALL_MASK, TMC2241_DIAG1_STALL_SHIFT, TMC2241_DIAG_GCONF, false}) +//#define TMC2241_DIAG1_INDEX_MASK 0x00080000 +//#define TMC2241_DIAG1_INDEX_SHIFT 19 +//#define TMC2241_DIAG1_INDEX_FIELD ((RegisterField) {TMC2241_DIAG1_INDEX_MASK, TMC2241_DIAG1_INDEX_SHIFT, TMC2241_DIAG_GCONF, false}) +#define TMC2241_DIAG1_EV_N_DEVIATION_MASK 0x04000000 +#define TMC2241_DIAG1_EV_N_DEVIATION_SHIFT 26 +#define TMC2241_DIAG1_EV_N_DEVIATION_FIELD ((RegisterField) {TMC2241_DIAG1_EV_N_DEVIATION_MASK, TMC2241_DIAG1_EV_N_DEVIATION_SHIFT, TMC2241_DIAG_GCONF, false}) +#define TMC2241_DIAG1_OVERVOLTAGE_MASK 0x08000000 +#define TMC2241_DIAG1_OVERVOLTAGE_SHIFT 27 +#define TMC2241_DIAG1_OVERVOLTAGE_FIELD ((RegisterField) {TMC2241_DIAG1_OVERVOLTAGE_MASK, TMC2241_DIAG1_OVERVOLTAGE_SHIFT, TMC2241_DIAG_GCONF, false}) +#define TMC2241_CURRENT_RANGE_MASK 0x00000003 +#define TMC2241_CURRENT_RANGE_SHIFT 0 +#define TMC2241_CURRENT_RANGE_FIELD ((RegisterField) {TMC2241_CURRENT_RANGE_MASK, TMC2241_CURRENT_RANGE_SHIFT, TMC2241_DRV_CONF, false}) +#define TMC2241_SLOPE_CONTROL_MASK 0x00000030 +#define TMC2241_SLOPE_CONTROL_SHIFT 4 +#define TMC2241_SLOPE_CONTROL_FIELD ((RegisterField) {TMC2241_SLOPE_CONTROL_MASK, TMC2241_SLOPE_CONTROL_SHIFT, TMC2241_DRV_CONF, false}) +#define TMC2241_GLOBAL_SCALER_MASK 0x000000FF +#define TMC2241_GLOBAL_SCALER_SHIFT 0 +#define TMC2241_GLOBAL_SCALER_FIELD ((RegisterField) {TMC2241_GLOBAL_SCALER_MASK, TMC2241_GLOBAL_SCALER_SHIFT, TMC2241_GLOBAL_SCALER, false}) +#define TMC2241_IHOLD_MASK 0x0000001F +#define TMC2241_IHOLD_SHIFT 0 +#define TMC2241_IHOLD_FIELD ((RegisterField) {TMC2241_IHOLD_MASK, TMC2241_IHOLD_SHIFT, TMC2241_IHOLD_IRUN, false}) +#define TMC2241_IRUN_MASK 0x00001F00 +#define TMC2241_IRUN_SHIFT 8 +#define TMC2241_IRUN_FIELD ((RegisterField) {TMC2241_IRUN_MASK, TMC2241_IRUN_SHIFT, TMC2241_IHOLD_IRUN, false}) +#define TMC2241_IHOLDDELAY_MASK 0x000F0000 +#define TMC2241_IHOLDDELAY_SHIFT 16 +#define TMC2241_IHOLDDELAY_FIELD ((RegisterField) {TMC2241_IHOLDDELAY_MASK, TMC2241_IHOLDDELAY_SHIFT, TMC2241_IHOLD_IRUN, false}) +#define TMC2241_IRUNDELAY_MASK 0x0F000000 +#define TMC2241_IRUNDELAY_SHIFT 24 +#define TMC2241_IRUNDELAY_FIELD ((RegisterField) {TMC2241_IRUNDELAY_MASK, TMC2241_IRUNDELAY_SHIFT, TMC2241_IHOLD_IRUN, false}) +#define TMC2241_TPOWERDOWN_MASK 0x000000FF +#define TMC2241_TPOWERDOWN_SHIFT 0 +#define TMC2241_TPOWERDOWN_FIELD ((RegisterField) {TMC2241_TPOWERDOWN_MASK, TMC2241_TPOWERDOWN_SHIFT, TMC2241_TPOWERDOWN, false}) +#define TMC2241_TSTEP_MASK 0x000FFFFF +#define TMC2241_TSTEP_SHIFT 0 +#define TMC2241_TSTEP_FIELD ((RegisterField) {TMC2241_TSTEP_MASK, TMC2241_TSTEP_SHIFT, TMC2241_TSTEP, false}) +#define TMC2241_TPWMTHRS_MASK 0x000FFFFF +#define TMC2241_TPWMTHRS_SHIFT 0 +#define TMC2241_TPWMTHRS_FIELD ((RegisterField) {TMC2241_TPWMTHRS_MASK, TMC2241_TPWMTHRS_SHIFT, TMC2241_TPWMTHRS, false}) +#define TMC2241_TCOOLTHRS_MASK 0x000FFFFF +#define TMC2241_TCOOLTHRS_SHIFT 0 +#define TMC2241_TCOOLTHRS_FIELD ((RegisterField) {TMC2241_TCOOLTHRS_MASK, TMC2241_TCOOLTHRS_SHIFT, TMC2241_TCOOLTHRS, false}) +#define TMC2241_THIGH_MASK 0x000FFFFF +#define TMC2241_THIGH_SHIFT 0 +#define TMC2241_THIGH_FIELD ((RegisterField) {TMC2241_THIGH_MASK, TMC2241_THIGH_SHIFT, TMC2241_THIGH, false}) +#define TMC2241_DIRECT_COIL_A_MASK 0x000001FF +#define TMC2241_DIRECT_COIL_A_SHIFT 0 +#define TMC2241_DIRECT_COIL_A_FIELD ((RegisterField) {TMC2241_DIRECT_COIL_A_MASK, TMC2241_DIRECT_COIL_A_SHIFT, TMC2241_DIRECT_MODE, true}) +#define TMC2241_DIRECT_COIL_B_MASK 0x01FF0000 +#define TMC2241_DIRECT_COIL_B_SHIFT 16 +#define TMC2241_DIRECT_COIL_B_FIELD ((RegisterField) {TMC2241_DIRECT_COIL_B_MASK, TMC2241_DIRECT_COIL_B_SHIFT, TMC2241_DIRECT_MODE, true}) +#define TMC2241_POL_A_MASK 0x00000001 +#define TMC2241_POL_A_SHIFT 0 +#define TMC2241_POL_A_FIELD ((RegisterField) {TMC2241_POL_A_MASK, TMC2241_POL_A_SHIFT, TMC2241_ENCMODE, false}) +#define TMC2241_POL_B_MASK 0x00000002 +#define TMC2241_POL_B_SHIFT 1 +#define TMC2241_POL_B_FIELD ((RegisterField) {TMC2241_POL_B_MASK, TMC2241_POL_B_SHIFT, TMC2241_ENCMODE, false}) +#define TMC2241_POL_N_MASK 0x00000004 +#define TMC2241_POL_N_SHIFT 2 +#define TMC2241_POL_N_FIELD ((RegisterField) {TMC2241_POL_N_MASK, TMC2241_POL_N_SHIFT, TMC2241_ENCMODE, false}) +#define TMC2241_IGNORE_AB_MASK 0x00000008 +#define TMC2241_IGNORE_AB_SHIFT 3 +#define TMC2241_IGNORE_AB_FIELD ((RegisterField) {TMC2241_IGNORE_AB_MASK, TMC2241_IGNORE_AB_SHIFT, TMC2241_ENCMODE, false}) +#define TMC2241_CLR_CONT_MASK 0x00000010 +#define TMC2241_CLR_CONT_SHIFT 4 +#define TMC2241_CLR_CONT_FIELD ((RegisterField) {TMC2241_CLR_CONT_MASK, TMC2241_CLR_CONT_SHIFT, TMC2241_ENCMODE, false}) +#define TMC2241_CLR_ONCE_MASK 0x00000020 +#define TMC2241_CLR_ONCE_SHIFT 5 +#define TMC2241_CLR_ONCE_FIELD ((RegisterField) {TMC2241_CLR_ONCE_MASK, TMC2241_CLR_ONCE_SHIFT, TMC2241_ENCMODE, false}) +#define TMC2241_POS_NEG_EDGE_MASK 0x000000C0 +#define TMC2241_POS_NEG_EDGE_SHIFT 6 +#define TMC2241_POS_NEG_EDGE_FIELD ((RegisterField) {TMC2241_POS_NEG_EDGE_MASK, TMC2241_POS_NEG_EDGE_SHIFT, TMC2241_ENCMODE, false}) +#define TMC2241_CLR_ENC_X_MASK 0x00000100 +#define TMC2241_CLR_ENC_X_SHIFT 8 +#define TMC2241_CLR_ENC_X_FIELD ((RegisterField) {TMC2241_CLR_ENC_X_MASK, TMC2241_CLR_ENC_X_SHIFT, TMC2241_ENCMODE, false}) +#define TMC2241_LATCH_X_ACT_MASK 0x00000200 +#define TMC2241_LATCH_X_ACT_SHIFT 9 +#define TMC2241_LATCH_X_ACT_FIELD ((RegisterField) {TMC2241_LATCH_X_ACT_MASK, TMC2241_LATCH_X_ACT_SHIFT, TMC2241_ENCMODE, false}) +#define TMC2241_ENC_SEL_DECIMAL_MASK 0x00000400 +#define TMC2241_ENC_SEL_DECIMAL_SHIFT 10 +#define TMC2241_ENC_SEL_DECIMAL_FIELD ((RegisterField) {TMC2241_ENC_SEL_DECIMAL_MASK, TMC2241_ENC_SEL_DECIMAL_SHIFT, TMC2241_ENCMODE, false}) +#define TMC2241_X_ENC_MASK 0xFFFFFFFF +#define TMC2241_X_ENC_SHIFT 0 +#define TMC2241_X_ENC_FIELD ((RegisterField) {TMC2241_X_ENC_MASK, TMC2241_X_ENC_SHIFT, TMC2241_X_ENC, true}) +#define TMC2241_ENC_CONST_MASK 0xFFFFFFFF +#define TMC2241_ENC_CONST_SHIFT 0 +#define TMC2241_ENC_CONST_FIELD ((RegisterField) {TMC2241_ENC_CONST_MASK, TMC2241_ENC_CONST_SHIFT, TMC2241_ENC_CONST, true}) +#define TMC2241_N_EVENT_MASK 0x00000001 +#define TMC2241_N_EVENT_SHIFT 0 +#define TMC2241_N_EVENT_FIELD ((RegisterField) {TMC2241_N_EVENT_MASK, TMC2241_N_EVENT_SHIFT, TMC2241_ENC_STATUS, false}) +#define TMC2241_ENC_LATCH_MASK 0xFFFFFFFF +#define TMC2241_ENC_LATCH_SHIFT 0 +#define TMC2241_ENC_LATCH_FIELD ((RegisterField) {TMC2241_ENC_LATCH_MASK, TMC2241_ENC_LATCH_SHIFT, TMC2241_ENC_LATCH, false}) +#define TMC2241_ADC_VSUPPLY_MASK 0x00001FFF +#define TMC2241_ADC_VSUPPLY_SHIFT 0 +#define TMC2241_ADC_VSUPPLY_FIELD ((RegisterField) {TMC2241_ADC_VSUPPLY_MASK, TMC2241_ADC_VSUPPLY_SHIFT, TMC2241_ADC_VSUPPLY_AIN, true}) +#define TMC2241_ADC_AIN_MASK 0x1FFF0000 +#define TMC2241_ADC_AIN_SHIFT 16 +#define TMC2241_ADC_AIN_FIELD ((RegisterField) {TMC2241_ADC_AIN_MASK, TMC2241_ADC_AIN_SHIFT, TMC2241_ADC_VSUPPLY_AIN, true}) +#define TMC2241_ADC_TEMP_MASK 0x00001FFF +#define TMC2241_ADC_TEMP_SHIFT 0 +#define TMC2241_ADC_TEMP_FIELD ((RegisterField) {TMC2241_ADC_TEMP_MASK, TMC2241_ADC_TEMP_SHIFT, TMC2241_ADC_TEMP, true}) +//#define TMC2241_RESERVED_MASK 0x1FFF0000 +//#define TMC2241_RESERVED_SHIFT 16 +//#define TMC2241_RESERVED_FIELD ((RegisterField) {TMC2241_RESERVED_MASK, TMC2241_RESERVED_SHIFT, TMC2241_ADC_TEMP, false}) +#define TMC2241_OVERVOLTAGE_VTH_MASK 0x00001FFF +#define TMC2241_OVERVOLTAGE_VTH_SHIFT 0 +#define TMC2241_OVERVOLTAGE_VTH_FIELD ((RegisterField) {TMC2241_OVERVOLTAGE_VTH_MASK, TMC2241_OVERVOLTAGE_VTH_SHIFT, TMC2241_OTW_OV_VTH, false}) +#define TMC2241_OVERTEMPPREWARNING_VTH_MASK 0x1FFF0000 +#define TMC2241_OVERTEMPPREWARNING_VTH_SHIFT 16 +#define TMC2241_OVERTEMPPREWARNING_VTH_FIELD ((RegisterField) {TMC2241_OVERTEMPPREWARNING_VTH_MASK, TMC2241_OVERTEMPPREWARNING_VTH_SHIFT, TMC2241_OTW_OV_VTH, false}) +#define TMC2241_MSLUT_0_MASK 0xFFFFFFFF +#define TMC2241_MSLUT_0_SHIFT 0 +#define TMC2241_MSLUT_0_FIELD ((RegisterField) {TMC2241_MSLUT_0_MASK, TMC2241_MSLUT_0_SHIFT, TMC2241_MSLUT_0, false}) +#define TMC2241_MSLUT_1_MASK 0xFFFFFFFF +#define TMC2241_MSLUT_1_SHIFT 0 +#define TMC2241_MSLUT_1_FIELD ((RegisterField) {TMC2241_MSLUT_1_MASK, TMC2241_MSLUT_1_SHIFT, TMC2241_MSLUT_1, false}) +#define TMC2241_MSLUT_2_MASK 0xFFFFFFFF +#define TMC2241_MSLUT_2_SHIFT 0 +#define TMC2241_MSLUT_2_FIELD ((RegisterField) {TMC2241_MSLUT_2_MASK, TMC2241_MSLUT_2_SHIFT, TMC2241_MSLUT_2, false}) +#define TMC2241_MSLUT_3_MASK 0xFFFFFFFF +#define TMC2241_MSLUT_3_SHIFT 0 +#define TMC2241_MSLUT_3_FIELD ((RegisterField) {TMC2241_MSLUT_3_MASK, TMC2241_MSLUT_3_SHIFT, TMC2241_MSLUT_3, false}) +#define TMC2241_MSLUT_4_MASK 0xFFFFFFFF +#define TMC2241_MSLUT_4_SHIFT 0 +#define TMC2241_MSLUT_4_FIELD ((RegisterField) {TMC2241_MSLUT_4_MASK, TMC2241_MSLUT_4_SHIFT, TMC2241_MSLUT_4, false}) +#define TMC2241_MSLUT_5_MASK 0xFFFFFFFF +#define TMC2241_MSLUT_5_SHIFT 0 +#define TMC2241_MSLUT_5_FIELD ((RegisterField) {TMC2241_MSLUT_5_MASK, TMC2241_MSLUT_5_SHIFT, TMC2241_MSLUT_5, false}) +#define TMC2241_MSLUT_6_MASK 0xFFFFFFFF +#define TMC2241_MSLUT_6_SHIFT 0 +#define TMC2241_MSLUT_6_FIELD ((RegisterField) {TMC2241_MSLUT_6_MASK, TMC2241_MSLUT_6_SHIFT, TMC2241_MSLUT_6, false}) +#define TMC2241_MSLUT_7_MASK 0xFFFFFFFF +#define TMC2241_MSLUT_7_SHIFT 0 +#define TMC2241_MSLUT_7_FIELD ((RegisterField) {TMC2241_MSLUT_7_MASK, TMC2241_MSLUT_7_SHIFT, TMC2241_MSLUT_7, false}) +#define TMC2241_W0_MASK 0x00000003 +#define TMC2241_W0_SHIFT 0 +#define TMC2241_W0_FIELD ((RegisterField) {TMC2241_W0_MASK, TMC2241_W0_SHIFT, TMC2241_MSLUTSEL, false}) +#define TMC2241_W1_MASK 0x0000000C +#define TMC2241_W1_SHIFT 2 +#define TMC2241_W1_FIELD ((RegisterField) {TMC2241_W1_MASK, TMC2241_W1_SHIFT, TMC2241_MSLUTSEL, false}) +#define TMC2241_W2_MASK 0x00000030 +#define TMC2241_W2_SHIFT 4 +#define TMC2241_W2_FIELD ((RegisterField) {TMC2241_W2_MASK, TMC2241_W2_SHIFT, TMC2241_MSLUTSEL, false}) +#define TMC2241_W3_MASK 0x000000C0 +#define TMC2241_W3_SHIFT 6 +#define TMC2241_W3_FIELD ((RegisterField) {TMC2241_W3_MASK, TMC2241_W3_SHIFT, TMC2241_MSLUTSEL, false}) +#define TMC2241_X1_MASK 0x0000FF00 +#define TMC2241_X1_SHIFT 8 +#define TMC2241_X1_FIELD ((RegisterField) {TMC2241_X1_MASK, TMC2241_X1_SHIFT, TMC2241_MSLUTSEL, false}) +#define TMC2241_X2_MASK 0x00FF0000 +#define TMC2241_X2_SHIFT 16 +#define TMC2241_X2_FIELD ((RegisterField) {TMC2241_X2_MASK, TMC2241_X2_SHIFT, TMC2241_MSLUTSEL, false}) +#define TMC2241_X3_MASK 0xFF000000 +#define TMC2241_X3_SHIFT 24 +#define TMC2241_X3_FIELD ((RegisterField) {TMC2241_X3_MASK, TMC2241_X3_SHIFT, TMC2241_MSLUTSEL, false}) +#define TMC2241_START_SIN_MASK 0x000000FF +#define TMC2241_START_SIN_SHIFT 0 +#define TMC2241_START_SIN_FIELD ((RegisterField) {TMC2241_START_SIN_MASK, TMC2241_START_SIN_SHIFT, TMC2241_MSLUTSTART, false}) +#define TMC2241_START_SIN90_MASK 0x00FF0000 +#define TMC2241_START_SIN90_SHIFT 16 +#define TMC2241_START_SIN90_FIELD ((RegisterField) {TMC2241_START_SIN90_MASK, TMC2241_START_SIN90_SHIFT, TMC2241_MSLUTSTART, false}) +#define TMC2241_OFFSET_SIN90_MASK 0xFF000000 +#define TMC2241_OFFSET_SIN90_SHIFT 24 +#define TMC2241_OFFSET_SIN90_FIELD ((RegisterField) {TMC2241_OFFSET_SIN90_MASK, TMC2241_OFFSET_SIN90_SHIFT, TMC2241_MSLUTSTART, false}) +#define TMC2241_MSCNT_MASK 0x000003FF +#define TMC2241_MSCNT_SHIFT 0 +#define TMC2241_MSCNT_FIELD ((RegisterField) {TMC2241_MSCNT_MASK, TMC2241_MSCNT_SHIFT, TMC2241_MSCNT, false}) +#define TMC2241_CUR_B_MASK 0x000001FF +#define TMC2241_CUR_B_SHIFT 0 +#define TMC2241_CUR_B_FIELD ((RegisterField) {TMC2241_CUR_B_MASK, TMC2241_CUR_B_SHIFT, TMC2241_MSCURACT, true}) +#define TMC2241_CUR_A_MASK 0x01FF0000 +#define TMC2241_CUR_A_SHIFT 16 +#define TMC2241_CUR_A_FIELD ((RegisterField) {TMC2241_CUR_A_MASK, TMC2241_CUR_A_SHIFT, TMC2241_MSCURACT, true}) +#define TMC2241_TOFF_MASK 0x0000000F +#define TMC2241_TOFF_SHIFT 0 +#define TMC2241_TOFF_FIELD ((RegisterField) {TMC2241_TOFF_MASK, TMC2241_TOFF_SHIFT, TMC2241_CHOPCONF, false}) +#define TMC2241_HSTRT_TFD210_MASK 0x00000070 +#define TMC2241_HSTRT_TFD210_SHIFT 4 +#define TMC2241_HSTRT_TFD210_FIELD ((RegisterField) {TMC2241_HSTRT_TFD210_MASK, TMC2241_HSTRT_TFD210_SHIFT, TMC2241_CHOPCONF, false}) +#define TMC2241_HEND_OFFSET_MASK 0x00000780 +#define TMC2241_HEND_OFFSET_SHIFT 7 +#define TMC2241_HEND_OFFSET_FIELD ((RegisterField) {TMC2241_HEND_OFFSET_MASK, TMC2241_HEND_OFFSET_SHIFT, TMC2241_CHOPCONF, false}) +#define TMC2241_FD3_MASK 0x00000800 +#define TMC2241_FD3_SHIFT 11 +#define TMC2241_FD3_FIELD ((RegisterField) {TMC2241_FD3_MASK, TMC2241_FD3_SHIFT, TMC2241_CHOPCONF, false}) +#define TMC2241_DISFDCC_MASK 0x00001000 +#define TMC2241_DISFDCC_SHIFT 12 +#define TMC2241_DISFDCC_FIELD ((RegisterField) {TMC2241_DISFDCC_MASK, TMC2241_DISFDCC_SHIFT, TMC2241_CHOPCONF, false}) +#define TMC2241_CHM_MASK 0x00004000 +#define TMC2241_CHM_SHIFT 14 +#define TMC2241_CHM_FIELD ((RegisterField) {TMC2241_CHM_MASK, TMC2241_CHM_SHIFT, TMC2241_CHOPCONF, false}) +#define TMC2241_TBL_MASK 0x00018000 +#define TMC2241_TBL_SHIFT 15 +#define TMC2241_TBL_FIELD ((RegisterField) {TMC2241_TBL_MASK, TMC2241_TBL_SHIFT, TMC2241_CHOPCONF, false}) +#define TMC2241_VHIGHFS_MASK 0x00040000 +#define TMC2241_VHIGHFS_SHIFT 18 +#define TMC2241_VHIGHFS_FIELD ((RegisterField) {TMC2241_VHIGHFS_MASK, TMC2241_VHIGHFS_SHIFT, TMC2241_CHOPCONF, false}) +#define TMC2241_VHIGHCHM_MASK 0x00080000 +#define TMC2241_VHIGHCHM_SHIFT 19 +#define TMC2241_VHIGHCHM_FIELD ((RegisterField) {TMC2241_VHIGHCHM_MASK, TMC2241_VHIGHCHM_SHIFT, TMC2241_CHOPCONF, false}) +#define TMC2241_TPFD_MASK 0x00F00000 +#define TMC2241_TPFD_SHIFT 20 +#define TMC2241_TPFD_FIELD ((RegisterField) {TMC2241_TPFD_MASK, TMC2241_TPFD_SHIFT, TMC2241_CHOPCONF, false}) +#define TMC2241_MRES_MASK 0x0F000000 +#define TMC2241_MRES_SHIFT 24 +#define TMC2241_MRES_FIELD ((RegisterField) {TMC2241_MRES_MASK, TMC2241_MRES_SHIFT, TMC2241_CHOPCONF, false}) +#define TMC2241_INTPOL_MASK 0x10000000 +#define TMC2241_INTPOL_SHIFT 28 +#define TMC2241_INTPOL_FIELD ((RegisterField) {TMC2241_INTPOL_MASK, TMC2241_INTPOL_SHIFT, TMC2241_CHOPCONF, false}) +#define TMC2241_DEDGE_MASK 0x20000000 +#define TMC2241_DEDGE_SHIFT 29 +#define TMC2241_DEDGE_FIELD ((RegisterField) {TMC2241_DEDGE_MASK, TMC2241_DEDGE_SHIFT, TMC2241_CHOPCONF, false}) +#define TMC2241_DISS2G_MASK 0x40000000 +#define TMC2241_DISS2G_SHIFT 30 +#define TMC2241_DISS2G_FIELD ((RegisterField) {TMC2241_DISS2G_MASK, TMC2241_DISS2G_SHIFT, TMC2241_CHOPCONF, false}) +#define TMC2241_DISS2VS_MASK 0x80000000 +#define TMC2241_DISS2VS_SHIFT 31 +#define TMC2241_DISS2VS_FIELD ((RegisterField) {TMC2241_DISS2VS_MASK, TMC2241_DISS2VS_SHIFT, TMC2241_CHOPCONF, false}) +#define TMC2241_SEMIN_MASK 0x0000000F +#define TMC2241_SEMIN_SHIFT 0 +#define TMC2241_SEMIN_FIELD ((RegisterField) {TMC2241_SEMIN_MASK, TMC2241_SEMIN_SHIFT, TMC2241_COOLCONF, false}) +#define TMC2241_SEUP_MASK 0x00000060 +#define TMC2241_SEUP_SHIFT 5 +#define TMC2241_SEUP_FIELD ((RegisterField) {TMC2241_SEUP_MASK, TMC2241_SEUP_SHIFT, TMC2241_COOLCONF, false}) +#define TMC2241_SEMAX_MASK 0x00000F00 +#define TMC2241_SEMAX_SHIFT 8 +#define TMC2241_SEMAX_FIELD ((RegisterField) {TMC2241_SEMAX_MASK, TMC2241_SEMAX_SHIFT, TMC2241_COOLCONF, false}) +#define TMC2241_SEDN_MASK 0x00006000 +#define TMC2241_SEDN_SHIFT 13 +#define TMC2241_SEDN_FIELD ((RegisterField) {TMC2241_SEDN_MASK, TMC2241_SEDN_SHIFT, TMC2241_COOLCONF, false}) +#define TMC2241_SEIMIN_MASK 0x00008000 +#define TMC2241_SEIMIN_SHIFT 15 +#define TMC2241_SEIMIN_FIELD ((RegisterField) {TMC2241_SEIMIN_MASK, TMC2241_SEIMIN_SHIFT, TMC2241_COOLCONF, false}) +#define TMC2241_SGT_MASK 0x007F0000 +#define TMC2241_SGT_SHIFT 16 +#define TMC2241_SGT_FIELD ((RegisterField) {TMC2241_SGT_MASK, TMC2241_SGT_SHIFT, TMC2241_COOLCONF, true}) +#define TMC2241_SFILT_MASK 0x01000000 +#define TMC2241_SFILT_SHIFT 24 +#define TMC2241_SFILT_FIELD ((RegisterField) {TMC2241_SFILT_MASK, TMC2241_SFILT_SHIFT, TMC2241_COOLCONF, false}) +#define TMC2241_SG_RESULT_MASK 0x000003FF +#define TMC2241_SG_RESULT_SHIFT 0 +#define TMC2241_SG_RESULT_FIELD ((RegisterField) {TMC2241_SG_RESULT_MASK, TMC2241_SG_RESULT_SHIFT, TMC2241_DRV_STATUS, false}) +#define TMC2241_S2VSA_MASK 0x00001000 +#define TMC2241_S2VSA_SHIFT 12 +#define TMC2241_S2VSA_FIELD ((RegisterField) {TMC2241_S2VSA_MASK, TMC2241_S2VSA_SHIFT, TMC2241_DRV_STATUS, false}) +#define TMC2241_S2VSB_MASK 0x00002000 +#define TMC2241_S2VSB_SHIFT 13 +#define TMC2241_S2VSB_FIELD ((RegisterField) {TMC2241_S2VSB_MASK, TMC2241_S2VSB_SHIFT, TMC2241_DRV_STATUS, false}) +#define TMC2241_STEALTH_MASK 0x00004000 +#define TMC2241_STEALTH_SHIFT 14 +#define TMC2241_STEALTH_FIELD ((RegisterField) {TMC2241_STEALTH_MASK, TMC2241_STEALTH_SHIFT, TMC2241_DRV_STATUS, false}) +#define TMC2241_FSACTIVE_MASK 0x00008000 +#define TMC2241_FSACTIVE_SHIFT 15 +#define TMC2241_FSACTIVE_FIELD ((RegisterField) {TMC2241_FSACTIVE_MASK, TMC2241_FSACTIVE_SHIFT, TMC2241_DRV_STATUS, false}) +#define TMC2241_CS_ACTUAL_MASK 0x001F0000 +#define TMC2241_CS_ACTUAL_SHIFT 16 +#define TMC2241_CS_ACTUAL_FIELD ((RegisterField) {TMC2241_CS_ACTUAL_MASK, TMC2241_CS_ACTUAL_SHIFT, TMC2241_DRV_STATUS, false}) +#define TMC2241_STALLGUARD_MASK 0x01000000 +#define TMC2241_STALLGUARD_SHIFT 24 +#define TMC2241_STALLGUARD_FIELD ((RegisterField) {TMC2241_STALLGUARD_MASK, TMC2241_STALLGUARD_SHIFT, TMC2241_DRV_STATUS, false}) +#define TMC2241_OT_MASK 0x02000000 +#define TMC2241_OT_SHIFT 25 +#define TMC2241_OT_FIELD ((RegisterField) {TMC2241_OT_MASK, TMC2241_OT_SHIFT, TMC2241_DRV_STATUS, false}) +#define TMC2241_OTPW_MASK 0x04000000 +#define TMC2241_OTPW_SHIFT 26 +#define TMC2241_OTPW_FIELD ((RegisterField) {TMC2241_OTPW_MASK, TMC2241_OTPW_SHIFT, TMC2241_DRV_STATUS, false}) +#define TMC2241_S2GA_MASK 0x08000000 +#define TMC2241_S2GA_SHIFT 27 +#define TMC2241_S2GA_FIELD ((RegisterField) {TMC2241_S2GA_MASK, TMC2241_S2GA_SHIFT, TMC2241_DRV_STATUS, false}) +#define TMC2241_S2GB_MASK 0x10000000 +#define TMC2241_S2GB_SHIFT 28 +#define TMC2241_S2GB_FIELD ((RegisterField) {TMC2241_S2GB_MASK, TMC2241_S2GB_SHIFT, TMC2241_DRV_STATUS, false}) +#define TMC2241_OLA_MASK 0x20000000 +#define TMC2241_OLA_SHIFT 29 +#define TMC2241_OLA_FIELD ((RegisterField) {TMC2241_OLA_MASK, TMC2241_OLA_SHIFT, TMC2241_DRV_STATUS, false}) +#define TMC2241_OLB_MASK 0x40000000 +#define TMC2241_OLB_SHIFT 30 +#define TMC2241_OLB_FIELD ((RegisterField) {TMC2241_OLB_MASK, TMC2241_OLB_SHIFT, TMC2241_DRV_STATUS, false}) +#define TMC2241_STST_MASK 0x80000000 +#define TMC2241_STST_SHIFT 31 +#define TMC2241_STST_FIELD ((RegisterField) {TMC2241_STST_MASK, TMC2241_STST_SHIFT, TMC2241_DRV_STATUS, false}) +#define TMC2241_PWM_OFS_MASK 0x000000FF +#define TMC2241_PWM_OFS_SHIFT 0 +#define TMC2241_PWM_OFS_FIELD ((RegisterField) {TMC2241_PWM_OFS_MASK, TMC2241_PWM_OFS_SHIFT, TMC2241_PWMCONF, false}) +#define TMC2241_PWM_GRAD_MASK 0x0000FF00 +#define TMC2241_PWM_GRAD_SHIFT 8 +#define TMC2241_PWM_GRAD_FIELD ((RegisterField) {TMC2241_PWM_GRAD_MASK, TMC2241_PWM_GRAD_SHIFT, TMC2241_PWMCONF, false}) +#define TMC2241_PWM_FREQ_MASK 0x00030000 +#define TMC2241_PWM_FREQ_SHIFT 16 +#define TMC2241_PWM_FREQ_FIELD ((RegisterField) {TMC2241_PWM_FREQ_MASK, TMC2241_PWM_FREQ_SHIFT, TMC2241_PWMCONF, false}) +#define TMC2241_PWM_AUTOSCALE_MASK 0x00040000 +#define TMC2241_PWM_AUTOSCALE_SHIFT 18 +#define TMC2241_PWM_AUTOSCALE_FIELD ((RegisterField) {TMC2241_PWM_AUTOSCALE_MASK, TMC2241_PWM_AUTOSCALE_SHIFT, TMC2241_PWMCONF, false}) +#define TMC2241_PWM_AUTOGRAD_MASK 0x00080000 +#define TMC2241_PWM_AUTOGRAD_SHIFT 19 +#define TMC2241_PWM_AUTOGRAD_FIELD ((RegisterField) {TMC2241_PWM_AUTOGRAD_MASK, TMC2241_PWM_AUTOGRAD_SHIFT, TMC2241_PWMCONF, false}) +#define TMC2241_FREEWHEEL_MASK 0x00300000 +#define TMC2241_FREEWHEEL_SHIFT 20 +#define TMC2241_FREEWHEEL_FIELD ((RegisterField) {TMC2241_FREEWHEEL_MASK, TMC2241_FREEWHEEL_SHIFT, TMC2241_PWMCONF, false}) +#define TMC2241_PWM_MEAS_SD_ENABLE_MASK 0x00400000 +#define TMC2241_PWM_MEAS_SD_ENABLE_SHIFT 22 +#define TMC2241_PWM_MEAS_SD_ENABLE_FIELD ((RegisterField) {TMC2241_PWM_MEAS_SD_ENABLE_MASK, TMC2241_PWM_MEAS_SD_ENABLE_SHIFT, TMC2241_PWMCONF, false}) +#define TMC2241_PWM_DIS_REG_STST_MASK 0x00800000 +#define TMC2241_PWM_DIS_REG_STST_SHIFT 23 +#define TMC2241_PWM_DIS_REG_STST_FIELD ((RegisterField) {TMC2241_PWM_DIS_REG_STST_MASK, TMC2241_PWM_DIS_REG_STST_SHIFT, TMC2241_PWMCONF, false}) +#define TMC2241_PWM_REG_MASK 0x0F000000 +#define TMC2241_PWM_REG_SHIFT 24 +#define TMC2241_PWM_REG_FIELD ((RegisterField) {TMC2241_PWM_REG_MASK, TMC2241_PWM_REG_SHIFT, TMC2241_PWMCONF, false}) +#define TMC2241_PWM_LIM_MASK 0xF0000000 +#define TMC2241_PWM_LIM_SHIFT 28 +#define TMC2241_PWM_LIM_FIELD ((RegisterField) {TMC2241_PWM_LIM_MASK, TMC2241_PWM_LIM_SHIFT, TMC2241_PWMCONF, false}) +#define TMC2241_PWM_SCALE_SUM_MASK 0x000003FF +#define TMC2241_PWM_SCALE_SUM_SHIFT 0 +#define TMC2241_PWM_SCALE_SUM_FIELD ((RegisterField) {TMC2241_PWM_SCALE_SUM_MASK, TMC2241_PWM_SCALE_SUM_SHIFT, TMC2241_PWM_SCALE, false}) +#define TMC2241_PWM_SCALE_AUTO_MASK 0x01FF0000 +#define TMC2241_PWM_SCALE_AUTO_SHIFT 16 +#define TMC2241_PWM_SCALE_AUTO_FIELD ((RegisterField) {TMC2241_PWM_SCALE_AUTO_MASK, TMC2241_PWM_SCALE_AUTO_SHIFT, TMC2241_PWM_SCALE, false}) +#define TMC2241_PWM_OFS_AUTO_MASK 0x000000FF +#define TMC2241_PWM_OFS_AUTO_SHIFT 0 +#define TMC2241_PWM_OFS_AUTO_FIELD ((RegisterField) {TMC2241_PWM_OFS_AUTO_MASK, TMC2241_PWM_OFS_AUTO_SHIFT, TMC2241_PWM_AUTO, false}) +#define TMC2241_PWM_GRAD_AUTO_MASK 0x00FF0000 +#define TMC2241_PWM_GRAD_AUTO_SHIFT 16 +#define TMC2241_PWM_GRAD_AUTO_FIELD ((RegisterField) {TMC2241_PWM_GRAD_AUTO_MASK, TMC2241_PWM_GRAD_AUTO_SHIFT, TMC2241_PWM_AUTO, false}) +#define TMC2241_SG4_THRS_MASK 0x000000FF +#define TMC2241_SG4_THRS_SHIFT 0 +#define TMC2241_SG4_THRS_FIELD ((RegisterField) {TMC2241_SG4_THRS_MASK, TMC2241_SG4_THRS_SHIFT, TMC2241_SG4_CONF, false}) +#define TMC2241_SG4_FILT_EN_MASK 0x00000100 +#define TMC2241_SG4_FILT_EN_SHIFT 8 +#define TMC2241_SG4_FILT_EN_FIELD ((RegisterField) {TMC2241_SG4_FILT_EN_MASK, TMC2241_SG4_FILT_EN_SHIFT, TMC2241_SG4_CONF, false}) +#define TMC2241_SG_ANGLE_OFFSET_MASK 0x00000200 +#define TMC2241_SG_ANGLE_OFFSET_SHIFT 9 +#define TMC2241_SG_ANGLE_OFFSET_FIELD ((RegisterField) {TMC2241_SG_ANGLE_OFFSET_MASK, TMC2241_SG_ANGLE_OFFSET_SHIFT, TMC2241_SG4_CONF, false}) +#define TMC2241_SG4_RESULT_MASK 0x000003FF +#define TMC2241_SG4_RESULT_SHIFT 0 +#define TMC2241_SG4_RESULT_FIELD ((RegisterField) {TMC2241_SG4_RESULT_MASK, TMC2241_SG4_RESULT_SHIFT, TMC2241_SG4_RESULT, false}) +#define TMC2241_SG4_IND_0_MASK 0x000000FF +#define TMC2241_SG4_IND_0_SHIFT 0 +#define TMC2241_SG4_IND_0_FIELD ((RegisterField) {TMC2241_SG4_IND_0_MASK, TMC2241_SG4_IND_0_SHIFT, TMC2241_SG4_IND, false}) +#define TMC2241_SG4_IND_1_MASK 0x0000FF00 +#define TMC2241_SG4_IND_1_SHIFT 8 +#define TMC2241_SG4_IND_1_FIELD ((RegisterField) {TMC2241_SG4_IND_1_MASK, TMC2241_SG4_IND_1_SHIFT, TMC2241_SG4_IND, false}) +#define TMC2241_SG4_IND_2_MASK 0x00FF0000 +#define TMC2241_SG4_IND_2_SHIFT 16 +#define TMC2241_SG4_IND_2_FIELD ((RegisterField) {TMC2241_SG4_IND_2_MASK, TMC2241_SG4_IND_2_SHIFT, TMC2241_SG4_IND, false}) +#define TMC2241_SG4_IND_3_MASK 0xFF000000 +#define TMC2241_SG4_IND_3_SHIFT 24 +#define TMC2241_SG4_IND_3_FIELD ((RegisterField) {TMC2241_SG4_IND_3_MASK, TMC2241_SG4_IND_3_SHIFT, TMC2241_SG4_IND, false}) +#endif diff --git a/firmware/lib/tmc/ic/TMC2241/registercall_hierarchy_flowchart_SPI.svg b/firmware/lib/tmc/ic/TMC2241/registercall_hierarchy_flowchart_SPI.svg new file mode 100755 index 0000000..cbad58f --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2241/registercall_hierarchy_flowchart_SPI.svg @@ -0,0 +1,3 @@ + + +

HAL

HAL

APP (Eval)

APP (Eval)

API

API
Read a register
  •  Call tmcXXXX_readRegister function
Read a register...
Returns the register read value
Returns the register read value
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
tmcXXXX.c
tmcXXXX.c
SPI.c
SPI.c
tmcXXXX_eval.c
tmcXXXX_eval.c

 Implementation of SPI_readWrite
  • Sends and receives bytes on the SPI bus
Implementation of SPI_readWrite...
Returns the raw reply data
Returns the raw reply data

Implementation of tmcXXXX_readWriteSPI
  • Sets the CSN pin to LOW
  • Takes the array of data to write
  • Calls hardware function SPI_readWrite
  • Upon completion of data transfer,
    sets CSN to 
    HIGH
Implementation of tmcXXXX_readWriteSPI...
Passes on the raw reply data to the API
Passes on the raw reply data to the API
Implementation of readRegisterSPI
  • Constructs the datagram
  • Calls HAL wrapper function 
Implementation of readRegisterSPI...
tmcXXXX_readWriteSPI
tmcXXXX_readWriteSPI
Parses the reply and returns the register value
Parses the reply and returns the register value
Implementation of tmcXXXX_readRegister 
  • Check which bus is active SPI/UART. (e.g. SPI)
  • Calls bus-specific function (e.g. readRegisterSPI)
 
Implementation of tmcXXXX_readRegister...
Returns the register read value
Returns the register read value
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC2241/registercall_hierarchy_flowchart_UART.svg b/firmware/lib/tmc/ic/TMC2241/registercall_hierarchy_flowchart_UART.svg new file mode 100755 index 0000000..425f60a --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2241/registercall_hierarchy_flowchart_UART.svg @@ -0,0 +1,3 @@ + + +

HAL

HAL

APP (Eval)

APP (Eval)

API

API
Read a register
  •  Call tmcXXXX_readRegister function
Read a register...
Returns the register read value
Returns the register read value
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
tmcXXXX.c
tmcXXXX.c
UART.c
UART.c
tmcXXXX_eval.c
tmcXXXX_eval.c

 Implementation of UART_readWrite
  • Sends and receives bytes on the UART bus
Implementation of UART_readWrite...
Returns the raw reply data
Returns the raw reply data

Implementation of tmcXXXX_readWriteUART
  • Takes the array of data to write
  • Calls hardware function UART_readWrite
Implementation of tmcXXXX_readWriteUART...
Passes on the raw reply data to the API
Passes on the raw reply data to the API
Implementation of readRegisterUART
  • Constructs the datagram
  • Calls HAL wrapper function 
Implementation of readRegisterUART...
tmcXXXX_readWriteUART
tmcXXXX_readWriteUART
Parses the reply and returns the register value
Parses the reply and returns the register value
Implementation of tmcXXXX_readRegister 
  • Check which bus is active SPI/UART. (e.g. UART)
  • Calls bus-specific function (e.g. readRegisterUART)
 
Implementation of tmcXXXX_readRegister...
Returns the register read value
Returns the register read value
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC2241/uml-tmc-api.svg b/firmware/lib/tmc/ic/TMC2241/uml-tmc-api.svg new file mode 100755 index 0000000..5a5f8dd --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2241/uml-tmc-api.svg @@ -0,0 +1,3 @@ + + +

TMCXXXX_HW_Abstraction.h



TMCXXXX_HW_Abstraction.h...
// Constants
#define TMCXXXX_MOTORS              
                          
// Register definitions
#define TMCXXXX_GCONF        
                          ⋮
// Register fields definitions
#define TMCXXXX_GCONF_OTPW_FIELD
                     
// Constants...

TMCXXXX.h



TMCXXXX.h...
extern void tmcXXXX_readWriteSPI();
extern void tmcXXXX_readWriteUART();
extern TMCXXXXBusType tmcXXXX_getBusType();
extern uint8_t tmcXXXX_getNodeAddress();
                                  ⋮
tmcXXXX_readRegister();
tmcXXXX_writeRegister();
                                  ⋮
extern void tmcXXXX_readWriteSPI();...

TMCXXXX.c



TMCXXXX.c...
const uint8_t tmcCRCTable_Poly7Reflected[256] = {...};
int32_t tmcXXXX_readRegister(){
/* Call tmcXXXX_getBusType();
 * Based on bus type, call readRegisterSPI/UART() that
 * further calls tmcXXXX_readWriteSPI/UART();
 * For UART it also calls tmcXXXX_getNodeAddress();
                                           ⋮
}
                                           ⋮
const uint8_t tmcCRCTable_Poly7Reflected[256] = {.....
TMC-API
TMC-API

TMCXXXX_Simple_Rotation.h


TMCXXXX_Simple_Rotation.h...
void initAllMotors();
             ⋮
  
void initAllMotors()...

TMCXXXX_Simple_Rotation.c


TMCXXXX_Simple_Rotation.c...
void initAllMotors(){

// Configuring registers to enable motor drivers etc..
tmcXXXX_writeRegister();
                    ⋮
}
                    ⋮
void initAllMotors(){...
Examples
Examples
User Project
User Project

User_Project.h


User_Project.h

User_Project.c








User_Project.c...

void tmcXXXX_readWriteSPI(){
                           ⋮
}
void tmcXXXX_readWriteUART(){
                           ⋮
}
TMCXXXXBusType tmcXXXX_getBusType(){
                           ⋮
}
uint8_t tmcXXXX_getNodeAddress(){
                           ⋮
}

// User Code
                           ⋮
void tmcXXXX_readWriteSPI(){...
#include "TMCXXXX_HW_Abstraction.h"
#include "TMCXXXX.h"
#include "TMCXXXX_Simple_Rotation.h"
                                ⋮
TMCXXXXBusType bus = IC_BUS_SPI/UART;
uint8_t nodeAddress = <nodeAddress>;
                                ⋮
#include "TMCXXXX_HW_Abstraction.h"...
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC2262/README.md b/firmware/lib/tmc/ic/TMC2262/README.md new file mode 100755 index 0000000..aa2abc5 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2262/README.md @@ -0,0 +1,43 @@ +# TMC2262 + + +## How to use + +To access the TMC2262's registers, the TMC-API offers two functions: **tmc2262_readRegister** and **tmc2262_writeRegister**. +Each of these functions takes in an **icID**, which is used to identify the IC when multiple ICs are connected. This identifier is passed down to the callback functions (see How to Integrate). + +## How to integrate: overview + +1. Include all the files of the TMC-API/ic/tmc/TMC2262 folder into the custom project. +2. Include the TMC2262.h file in the custom source code. +3. Implement the necessary callback functions (see below). +4. (optional): Take a look at the Examples subfolder for ready-made examples of the TMC-API usage. + +## Accessing the TMC2262 via SPI +The following diagram depicts how to access the TMC2262 via SPI using the TMC-API. + +![screenshot](registercall_hierarchy_flowchart_SPI.svg) + +The description of the functions, in the above flowchart, are as follows: +- The functions tmc2262_readRegister and tmc2262_writeRegister are used to read and write the registers respectively. These functions call the bus-specific function i.e readRegisterSPI or writeRegisterSPI. +- These bus specific functions constructs the datagram and further calls the bus specific callback 'tmcXXXX_readWriteSPI. +- This callback function further calls the hardware specific read/write function for SPI and needs to be implemented externally. + +### How to integrate: Callback functions +Implement the following callback functions to access the chip via SPI: + +1. **tmc2262_readWriteSPI()**, which is a HAL wrapper function that provides the necessary hardware access. This function should also set the chip select pin CSN to low before starting the data transfer and set to high upon completion. Please refer to the datasheet of the IC for further details. + +## Further info +### Dependency graph for the ICs with new register R/W mechanism +This graph illustrates the relationships between files within the TMC-API library, highlighting dependencies and identifying the files that are essential for integrating the library into the custom projects. + +![screenshot](uml-tmc-api.svg) + +### Example usage: TMC-Evalsystem +**For a reference usage of the TMC-API**, visit the [TMC-Evalsystem](https://github.com/analogdevicesinc/TMC-EvalSystem) + +## Migration status +The TMC2262 has been reworked to the access system described above. For more infos on the status of this and other ICs, check out the [migration page](https://github.com/analogdevicesinc/TMC-API/issues/53). + + diff --git a/firmware/lib/tmc/ic/TMC2262/TMC2262.c b/firmware/lib/tmc/ic/TMC2262/TMC2262.c new file mode 100755 index 0000000..3e76832 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2262/TMC2262.c @@ -0,0 +1,55 @@ +/******************************************************************************* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#include "TMC2262.h" + + +static int32_t readRegisterSPI(uint16_t icID, uint8_t address); +static void writeRegisterSPI(uint16_t icID, uint8_t address, int32_t value); + + +int32_t tmc2262_readRegister(uint16_t icID, uint8_t address) +{ + return readRegisterSPI(icID, address); +} + +void tmc2262_writeRegister(uint16_t icID, uint8_t address, int32_t value) +{ + writeRegisterSPI(icID, address, value); +} + +int32_t readRegisterSPI(uint16_t icID, uint8_t address) +{ + uint8_t data[5] = { 0 }; + + // clear write bit + data[0] = address & TMC2262_ADDRESS_MASK; + + // Send the read request + tmc2262_readWriteSPI(icID, &data[0], sizeof(data)); + + // Rewrite address and clear write bit + data[0] = address & TMC2262_ADDRESS_MASK; + + // Send another request to receive the read reply + tmc2262_readWriteSPI(icID, &data[0], sizeof(data)); + + return ((int32_t)data[1] << 24) | ((int32_t) data[2] << 16) | ((int32_t) data[3] << 8) | ((int32_t) data[4]); +} + +void writeRegisterSPI(uint16_t icID, uint8_t address, int32_t value) +{ + uint8_t data[5] = { 0 }; + + data[0] = address | TMC2262_WRITE_BIT; + data[1] = 0xFF & (value>>24); + data[2] = 0xFF & (value>>16); + data[3] = 0xFF & (value>>8); + data[4] = 0xFF & (value>>0); + + // Send the write request + tmc2262_readWriteSPI(icID, &data[0], sizeof(data)); +} diff --git a/firmware/lib/tmc/ic/TMC2262/TMC2262.h b/firmware/lib/tmc/ic/TMC2262/TMC2262.h new file mode 100755 index 0000000..c860d50 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2262/TMC2262.h @@ -0,0 +1,68 @@ +/******************************************************************************* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#ifndef TMC_IC_TMC2262_H_ +#define TMC_IC_TMC2262_H_ + +#include +#include +#include +#include "TMC2262_HW_Abstraction.h" + + +// => TMC-API wrapper +extern void tmc2262_readWriteSPI(uint16_t icID, uint8_t *data, size_t dataLength); +// => TMC-API wrapper + +int32_t tmc2262_readRegister(uint16_t icID, uint8_t address); +void tmc2262_writeRegister(uint16_t icID, uint8_t address, int32_t value); + +typedef struct +{ + uint32_t mask; + uint8_t shift; + uint8_t address; + bool isSigned; +} RegisterField; + +static inline uint32_t tmc2262_fieldExtract(uint32_t data, RegisterField field) +{ + uint32_t value = (data & field.mask) >> field.shift; + + if (field.isSigned) + { + // Apply signedness conversion + uint32_t baseMask = field.mask >> field.shift; + uint32_t signMask = baseMask & (~baseMask >> 1); + value = (value ^ signMask) - signMask; + } + + return value; +} + +static inline uint32_t tmc2262_fieldRead(uint16_t icID, RegisterField field) +{ + uint32_t value = tmc2262_readRegister(icID, field.address); + + return tmc2262_fieldExtract(value, field); +} + +static inline uint32_t tmc2262_fieldUpdate(uint32_t data, RegisterField field, uint32_t value) +{ + return (data & (~field.mask)) | ((value << field.shift) & field.mask); +} + +static inline void tmc2262_fieldWrite(uint16_t icID, RegisterField field, uint32_t value) +{ + uint32_t regValue = tmc2262_readRegister(icID, field.address); + + regValue = tmc2262_fieldUpdate(regValue, field, value); + + tmc2262_writeRegister(icID, field.address, regValue); +} + + +#endif /* TMC_IC_TMC2262_H_ */ diff --git a/firmware/lib/tmc/ic/TMC2262/TMC2262_HW_Abstraction.h b/firmware/lib/tmc/ic/TMC2262/TMC2262_HW_Abstraction.h new file mode 100755 index 0000000..5ddea48 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2262/TMC2262_HW_Abstraction.h @@ -0,0 +1,804 @@ +/******************************************************************************* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#ifndef TMC2262_HW_ABSTRACTION +#define TMC2262_HW_ABSTRACTION + +// Constants + +#define TMC2262_REGISTER_COUNT 128 +#define TMC2262_MOTORS 1 +#define TMC2262_WRITE_BIT 0x80 +#define TMC2262_ADDRESS_MASK 0x7F +#define TMC2262_MAX_ACCELERATION 65535 + +// ramp modes (Register TMC2262_RAMPMODE) +#define TMC2262_MODE_POSITION 0 +#define TMC2262_MODE_VELPOS 1 +#define TMC2262_MODE_VELNEG 2 +#define TMC2262_MODE_HOLD 3 + +// limit switch mode bits (Register TMC2262_SWMODE) +#define TMC2262_SW_STOPL_ENABLE 0x0001 +#define TMC2262_SW_STOPR_ENABLE 0x0002 +#define TMC2262_SW_STOPL_POLARITY 0x0004 +#define TMC2262_SW_STOPR_POLARITY 0x0008 +#define TMC2262_SW_SWAP_LR 0x0010 +#define TMC2262_SW_LATCH_L_ACT 0x0020 +#define TMC2262_SW_LATCH_L_INACT 0x0040 +#define TMC2262_SW_LATCH_R_ACT 0x0080 +#define TMC2262_SW_LATCH_R_INACT 0x0100 +#define TMC2262_SW_LATCH_ENC 0x0200 +#define TMC2262_SW_SG_STOP 0x0400 +#define TMC2262_SW_SOFTSTOP 0x0800 + +// Status bits (Register TMC2262_RAMPSTAT) +#define TMC2262_RS_STOPL 0x0001 +#define TMC2262_RS_STOPR 0x0002 +#define TMC2262_RS_LATCHL 0x0004 +#define TMC2262_RS_LATCHR 0x0008 +#define TMC2262_RS_EV_STOPL 0x0010 +#define TMC2262_RS_EV_STOPR 0x0020 +#define TMC2262_RS_EV_STOP_SG 0x0040 +#define TMC2262_RS_EV_POSREACHED 0x0080 +#define TMC2262_RS_VELREACHED 0x0100 +#define TMC2262_RS_POSREACHED 0x0200 +#define TMC2262_RS_VZERO 0x0400 +#define TMC2262_RS_ZEROWAIT 0x0800 +#define TMC2262_RS_SECONDMOVE 0x1000 +#define TMC2262_RS_SG 0x2000 + +// Encoderbits (Register TMC2262_ENCMODE) +#define TMC2262_EM_DECIMAL 0x0400 +#define TMC2262_EM_LATCH_XACT 0x0200 +#define TMC2262_EM_CLR_XENC 0x0100 +#define TMC2262_EM_NEG_EDGE 0x0080 +#define TMC2262_EM_POS_EDGE 0x0040 +#define TMC2262_EM_CLR_ONCE 0x0020 +#define TMC2262_EM_CLR_CONT 0x0010 +#define TMC2262_EM_IGNORE_AB 0x0008 +#define TMC2262_EM_POL_N 0x0004 +#define TMC2262_EM_POL_B 0x0002 +#define TMC2262_EM_POL_A 0x0001 + + +// Register fields in TMC2262 + +#define TMC2262_GCONF 0x00 +#define TMC2262_GSTAT 0x01 +#define TMC2262_DIAG_CONF 0x02 +#define TMC2262_DIAG_DAC_CONF 0x03 +#define TMC2262_IOIN 0x04 +#define TMC2262_DRV_CONF 0x0A +#define TMC2262_PLL 0x0B +#define TMC2262_IHOLD_IRUN 0x10 +#define TMC2262_TPOWERDOWN 0x11 +#define TMC2262_TSTEP 0x12 +#define TMC2262_TPWMTHRS 0x13 +#define TMC2262_TCOOLTHRS 0x14 +#define TMC2262_THIGH 0x15 +#define TMC2262_TSGP_LOW_VEL_THRS 0x16 +#define TMC2262_T_RCOIL_MEAS 0x17 +#define TMC2262_TUDCSTEP 0x18 +#define TMC2262_UDC_CONF 0x19 +#define TMC2262_STEPS_LOST 0x1A +#define TMC2262_SW_MODE 0x34 +#define TMC2262_SG_SEQ_STOP_STAT 0x35 +#define TMC2262_ENCMODE 0x38 +#define TMC2262_X_ENC 0x39 +#define TMC2262_ENC_CONST 0x3A +#define TMC2262_ENC_STATUS 0x3B +#define TMC2262_ENC_LATCH 0x3C +#define TMC2262_ENC_DEVIATION 0x3D +#define TMC2262_CURRENT_PI_REG 0x40 +#define TMC2262_ANGLE_PI_REG 0x41 +#define TMC2262_CUR_ANGLE_LIMIT 0x42 +#define TMC2262_ANGLE_LOWER_LIMIT 0x43 +#define TMC2262_CUR_ANGLE_MEAS 0x44 +#define TMC2262_PI_RESULTS 0x45 +#define TMC2262_COIL_INDUCT 0x46 +#define TMC2262_R_COIL 0x47 +#define TMC2262_R_COIL_USER 0x48 +#define TMC2262_SGP_CONF 0x49 +#define TMC2262_SGP_IND_2_3 0x4A +#define TMC2262_SGP_IND_0_1 0x4B +#define TMC2262_INDUCTANCE_VOLTAGE 0x4C +#define TMC2262_SGP_BEMF 0x4D +#define TMC2262_COOLSTEPPLUS_CONF 0x4E +#define TMC2262_COOLSTEPPLUS_PI_REG 0x4F +#define TMC2262_COOLSTEPPLUS_PI_DOWN 0x50 +#define TMC2262_COOLSTEPPLUS_RESERVE_CONF 0x51 +#define TMC2262_COOLSTEPPLUS_LOAD_RESERVE 0x52 +#define TMC2262_TSTEP_VELOCITY 0x53 +#define TMC2262_ADC_VSUPPLY_TEMP 0x58 +#define TMC2262_ADC_I 0x59 +#define TMC2262_OTW_OV_VTH 0x5A +#define TMC2262_MSLUT__ 0x60 +//#define TMC2262_MSLUT__ 0x61 +//#define TMC2262_MSLUT__ 0x62 +//#define TMC2262_MSLUT__ 0x63 +//#define TMC2262_MSLUT__ 0x64 +//#define TMC2262_MSLUT__ 0x65 +//#define TMC2262_MSLUT__ 0x66 +//#define TMC2262_MSLUT__ 0x67 +#define TMC2262_MSLUTSEL 0x68 +#define TMC2262_MSLUTSTART 0x69 +#define TMC2262_MSCNT 0x6A +#define TMC2262_MSCURACT 0x6B +#define TMC2262_CHOPCONF 0x6C +#define TMC2262_COOLCONF 0x6D +#define TMC2262_DRV_STATUS 0x6F +#define TMC2262_PWMCONF 0x70 + + +// Fields in TMC2262 + +#define TMC2262_FAST_STANDSTILL_MASK 0x00000001 +#define TMC2262_FAST_STANDSTILL_SHIFT 0 +#define TMC2262_FAST_STANDSTILL_FIELD ((RegisterField) {TMC2262_FAST_STANDSTILL_MASK, TMC2262_FAST_STANDSTILL_SHIFT, TMC2262_GCONF, false}) +#define TMC2262_EN_STEALTHCHOP_MASK 0x00000002 +#define TMC2262_EN_STEALTHCHOP_SHIFT 1 +#define TMC2262_EN_STEALTHCHOP_FIELD ((RegisterField) {TMC2262_EN_STEALTHCHOP_MASK, TMC2262_EN_STEALTHCHOP_SHIFT, TMC2262_GCONF, false}) +#define TMC2262_MULTISTEP_FILT_MASK 0x00000004 +#define TMC2262_MULTISTEP_FILT_SHIFT 2 +#define TMC2262_MULTISTEP_FILT_FIELD ((RegisterField) {TMC2262_MULTISTEP_FILT_MASK, TMC2262_MULTISTEP_FILT_SHIFT, TMC2262_GCONF, false}) +#define TMC2262_SHAFT_MASK 0x00000008 +#define TMC2262_SHAFT_SHIFT 3 +#define TMC2262_SHAFT_FIELD ((RegisterField) {TMC2262_SHAFT_MASK, TMC2262_SHAFT_SHIFT, TMC2262_GCONF, false}) +#define TMC2262_SMALL_HYSTERESIS_MASK 0x00000010 +#define TMC2262_SMALL_HYSTERESIS_SHIFT 4 +#define TMC2262_SMALL_HYSTERESIS_FIELD ((RegisterField) {TMC2262_SMALL_HYSTERESIS_MASK, TMC2262_SMALL_HYSTERESIS_SHIFT, TMC2262_GCONF, false}) +#define TMC2262_STOP_ENABLE_MASK 0x00000020 +#define TMC2262_STOP_ENABLE_SHIFT 5 +#define TMC2262_STOP_ENABLE_FIELD ((RegisterField) {TMC2262_STOP_ENABLE_MASK, TMC2262_STOP_ENABLE_SHIFT, TMC2262_GCONF, false}) +#define TMC2262_DIRECT_MODE_MASK 0x00000040 +#define TMC2262_DIRECT_MODE_SHIFT 6 +#define TMC2262_DIRECT_MODE_FIELD ((RegisterField) {TMC2262_DIRECT_MODE_MASK, TMC2262_DIRECT_MODE_SHIFT, TMC2262_GCONF, false}) +#define TMC2262_LENGTH_STEPPULSE_MASK 0x00000F00 +#define TMC2262_LENGTH_STEPPULSE_SHIFT 8 +#define TMC2262_LENGTH_STEPPULSE_FIELD ((RegisterField) {TMC2262_LENGTH_STEPPULSE_MASK, TMC2262_LENGTH_STEPPULSE_SHIFT, TMC2262_GCONF, false}) +#define TMC2262_OV_NN_MASK 0x00001000 +#define TMC2262_OV_NN_SHIFT 12 +#define TMC2262_OV_NN_FIELD ((RegisterField) {TMC2262_OV_NN_MASK, TMC2262_OV_NN_SHIFT, TMC2262_GCONF, false}) +#define TMC2262_RESET_MASK 0x00000001 +#define TMC2262_RESET_SHIFT 0 +#define TMC2262_RESET_FIELD ((RegisterField) {TMC2262_RESET_MASK, TMC2262_RESET_SHIFT, TMC2262_GSTAT, false}) +#define TMC2262_DRV_ERR_MASK 0x00000002 +#define TMC2262_DRV_ERR_SHIFT 1 +#define TMC2262_DRV_ERR_FIELD ((RegisterField) {TMC2262_DRV_ERR_MASK, TMC2262_DRV_ERR_SHIFT, TMC2262_GSTAT, false}) +#define TMC2262_UV_CP_MASK 0x00000004 +#define TMC2262_UV_CP_SHIFT 2 +#define TMC2262_UV_CP_FIELD ((RegisterField) {TMC2262_UV_CP_MASK, TMC2262_UV_CP_SHIFT, TMC2262_GSTAT, false}) +#define TMC2262_REGISTER_RESET_MASK 0x00000008 +#define TMC2262_REGISTER_RESET_SHIFT 3 +#define TMC2262_REGISTER_RESET_FIELD ((RegisterField) {TMC2262_REGISTER_RESET_MASK, TMC2262_REGISTER_RESET_SHIFT, TMC2262_GSTAT, false}) +#define TMC2262_VM_UVLO_MASK 0x00000010 +#define TMC2262_VM_UVLO_SHIFT 4 +#define TMC2262_VM_UVLO_FIELD ((RegisterField) {TMC2262_VM_UVLO_MASK, TMC2262_VM_UVLO_SHIFT, TMC2262_GSTAT, false}) +#define TMC2262_VCCIO_UV_MASK 0x00000020 +#define TMC2262_VCCIO_UV_SHIFT 5 +#define TMC2262_VCCIO_UV_FIELD ((RegisterField) {TMC2262_VCCIO_UV_MASK, TMC2262_VCCIO_UV_SHIFT, TMC2262_GSTAT, false}) +#define TMC2262_DIAG0_ERROR_MASK 0x00000001 +#define TMC2262_DIAG0_ERROR_SHIFT 0 +#define TMC2262_DIAG0_ERROR_FIELD ((RegisterField) {TMC2262_DIAG0_ERROR_MASK, TMC2262_DIAG0_ERROR_SHIFT, TMC2262_DIAG_CONF, false}) +#define TMC2262_DIAG0_OTPW_MASK 0x00000002 +#define TMC2262_DIAG0_OTPW_SHIFT 1 +#define TMC2262_DIAG0_OTPW_FIELD ((RegisterField) {TMC2262_DIAG0_OTPW_MASK, TMC2262_DIAG0_OTPW_SHIFT, TMC2262_DIAG_CONF, false}) +#define TMC2262_DIAG0_STALL_MASK 0x00000004 +#define TMC2262_DIAG0_STALL_SHIFT 2 +#define TMC2262_DIAG0_STALL_FIELD ((RegisterField) {TMC2262_DIAG0_STALL_MASK, TMC2262_DIAG0_STALL_SHIFT, TMC2262_DIAG_CONF, false}) +#define TMC2262_DIAG0_INDEX_MASK 0x00000008 +#define TMC2262_DIAG0_INDEX_SHIFT 3 +#define TMC2262_DIAG0_INDEX_FIELD ((RegisterField) {TMC2262_DIAG0_INDEX_MASK, TMC2262_DIAG0_INDEX_SHIFT, TMC2262_DIAG_CONF, false}) +#define TMC2262_DIAG0_XCOMP_MASK 0x00000040 +#define TMC2262_DIAG0_XCOMP_SHIFT 6 +#define TMC2262_DIAG0_XCOMP_FIELD ((RegisterField) {TMC2262_DIAG0_XCOMP_MASK, TMC2262_DIAG0_XCOMP_SHIFT, TMC2262_DIAG_CONF, false}) +#define TMC2262_DIAG0_OV_MASK 0x00000080 +#define TMC2262_DIAG0_OV_SHIFT 7 +#define TMC2262_DIAG0_OV_FIELD ((RegisterField) {TMC2262_DIAG0_OV_MASK, TMC2262_DIAG0_OV_SHIFT, TMC2262_DIAG_CONF, false}) +#define TMC2262_DIAG0_DCUSTEP_MASK 0x00000100 +#define TMC2262_DIAG0_DCUSTEP_SHIFT 8 +#define TMC2262_DIAG0_DCUSTEP_FIELD ((RegisterField) {TMC2262_DIAG0_DCUSTEP_MASK, TMC2262_DIAG0_DCUSTEP_SHIFT, TMC2262_DIAG_CONF, false}) +#define TMC2262_DIAG0_EV_STOP_SG_MASK 0x00000400 +#define TMC2262_DIAG0_EV_STOP_SG_SHIFT 10 +#define TMC2262_DIAG0_EV_STOP_SG_FIELD ((RegisterField) {TMC2262_DIAG0_EV_STOP_SG_MASK, TMC2262_DIAG0_EV_STOP_SG_SHIFT, TMC2262_DIAG_CONF, false}) +#define TMC2262_DIAG0_EV_N_DEVIATION_MASK 0x00001000 +#define TMC2262_DIAG0_EV_N_DEVIATION_SHIFT 12 +#define TMC2262_DIAG0_EV_N_DEVIATION_FIELD ((RegisterField) {TMC2262_DIAG0_EV_N_DEVIATION_MASK, TMC2262_DIAG0_EV_N_DEVIATION_SHIFT, TMC2262_DIAG_CONF, false}) +#define TMC2262_DIAG1_ERROR_MASK 0x00002000 +#define TMC2262_DIAG1_ERROR_SHIFT 13 +#define TMC2262_DIAG1_ERROR_FIELD ((RegisterField) {TMC2262_DIAG1_ERROR_MASK, TMC2262_DIAG1_ERROR_SHIFT, TMC2262_DIAG_CONF, false}) +#define TMC2262_DIAG1_OTPW_MASK 0x00004000 +#define TMC2262_DIAG1_OTPW_SHIFT 14 +#define TMC2262_DIAG1_OTPW_FIELD ((RegisterField) {TMC2262_DIAG1_OTPW_MASK, TMC2262_DIAG1_OTPW_SHIFT, TMC2262_DIAG_CONF, false}) +#define TMC2262_DIAG1_STALL_MASK 0x00008000 +#define TMC2262_DIAG1_STALL_SHIFT 15 +#define TMC2262_DIAG1_STALL_FIELD ((RegisterField) {TMC2262_DIAG1_STALL_MASK, TMC2262_DIAG1_STALL_SHIFT, TMC2262_DIAG_CONF, false}) +#define TMC2262_DIAG1_INDEX_MASK 0x00010000 +#define TMC2262_DIAG1_INDEX_SHIFT 16 +#define TMC2262_DIAG1_INDEX_FIELD ((RegisterField) {TMC2262_DIAG1_INDEX_MASK, TMC2262_DIAG1_INDEX_SHIFT, TMC2262_DIAG_CONF, false}) +#define TMC2262_DIAG1_OV_MASK 0x00100000 +#define TMC2262_DIAG1_OV_SHIFT 20 +#define TMC2262_DIAG1_OV_FIELD ((RegisterField) {TMC2262_DIAG1_OV_MASK, TMC2262_DIAG1_OV_SHIFT, TMC2262_DIAG_CONF, false}) +#define TMC2262_DIAG1_UDCSTEP_MASK 0x00200000 +#define TMC2262_DIAG1_UDCSTEP_SHIFT 21 +#define TMC2262_DIAG1_UDCSTEP_FIELD ((RegisterField) {TMC2262_DIAG1_UDCSTEP_MASK, TMC2262_DIAG1_UDCSTEP_SHIFT, TMC2262_DIAG_CONF, false}) +#define TMC2262_DIAG1_EV_STOP_SG_MASK 0x00800000 +#define TMC2262_DIAG1_EV_STOP_SG_SHIFT 23 +#define TMC2262_DIAG1_EV_STOP_SG_FIELD ((RegisterField) {TMC2262_DIAG1_EV_STOP_SG_MASK, TMC2262_DIAG1_EV_STOP_SG_SHIFT, TMC2262_DIAG_CONF, false}) +#define TMC2262_DIAG1_EV_N_DEVIATION_MASK 0x02000000 +#define TMC2262_DIAG1_EV_N_DEVIATION_SHIFT 25 +#define TMC2262_DIAG1_EV_N_DEVIATION_FIELD ((RegisterField) {TMC2262_DIAG1_EV_N_DEVIATION_MASK, TMC2262_DIAG1_EV_N_DEVIATION_SHIFT, TMC2262_DIAG_CONF, false}) +#define TMC2262_DIAG0_NOD_PP_MASK 0x10000000 +#define TMC2262_DIAG0_NOD_PP_SHIFT 28 +#define TMC2262_DIAG0_NOD_PP_FIELD ((RegisterField) {TMC2262_DIAG0_NOD_PP_MASK, TMC2262_DIAG0_NOD_PP_SHIFT, TMC2262_DIAG_CONF, false}) +#define TMC2262_DIAG0_INVPP_MASK 0x20000000 +#define TMC2262_DIAG0_INVPP_SHIFT 29 +#define TMC2262_DIAG0_INVPP_FIELD ((RegisterField) {TMC2262_DIAG0_INVPP_MASK, TMC2262_DIAG0_INVPP_SHIFT, TMC2262_DIAG_CONF, false}) +#define TMC2262_DIAG1_NOD_PP_MASK 0x40000000 +#define TMC2262_DIAG1_NOD_PP_SHIFT 30 +#define TMC2262_DIAG1_NOD_PP_FIELD ((RegisterField) {TMC2262_DIAG1_NOD_PP_MASK, TMC2262_DIAG1_NOD_PP_SHIFT, TMC2262_DIAG_CONF, false}) +#define TMC2262_DIAG1_INVPP_MASK 0x80000000 +#define TMC2262_DIAG1_INVPP_SHIFT 31 +#define TMC2262_DIAG1_INVPP_FIELD ((RegisterField) {TMC2262_DIAG1_INVPP_MASK, TMC2262_DIAG1_INVPP_SHIFT, TMC2262_DIAG_CONF, false}) +#define TMC2262_DIAG0_DAC_EN_MASK 0x00000001 +#define TMC2262_DIAG0_DAC_EN_SHIFT 0 +#define TMC2262_DIAG0_DAC_EN_FIELD ((RegisterField) {TMC2262_DIAG0_DAC_EN_MASK, TMC2262_DIAG0_DAC_EN_SHIFT, TMC2262_DIAG_DAC_CONF, false}) +#define TMC2262_DIAG0_DAC_SEL_MASK 0x000001F0 +#define TMC2262_DIAG0_DAC_SEL_SHIFT 4 +#define TMC2262_DIAG0_DAC_SEL_FIELD ((RegisterField) {TMC2262_DIAG0_DAC_SEL_MASK, TMC2262_DIAG0_DAC_SEL_SHIFT, TMC2262_DIAG_DAC_CONF, false}) +#define TMC2262_DIAG1_DAC_EN_MASK 0x00001000 +#define TMC2262_DIAG1_DAC_EN_SHIFT 12 +#define TMC2262_DIAG1_DAC_EN_FIELD ((RegisterField) {TMC2262_DIAG1_DAC_EN_MASK, TMC2262_DIAG1_DAC_EN_SHIFT, TMC2262_DIAG_DAC_CONF, false}) +#define TMC2262_DIAG1_DAC_SEL_MASK 0x001F0000 +#define TMC2262_DIAG1_DAC_SEL_SHIFT 16 +#define TMC2262_DIAG1_DAC_SEL_FIELD ((RegisterField) {TMC2262_DIAG1_DAC_SEL_MASK, TMC2262_DIAG1_DAC_SEL_SHIFT, TMC2262_DIAG_DAC_CONF, false}) +#define TMC2262_STEP_MASK 0x00000001 +#define TMC2262_STEP_SHIFT 0 +#define TMC2262_STEP_FIELD ((RegisterField) {TMC2262_STEP_MASK, TMC2262_STEP_SHIFT, TMC2262_IOIN, false}) +#define TMC2262_DIR_MASK 0x00000002 +#define TMC2262_DIR_SHIFT 1 +#define TMC2262_DIR_FIELD ((RegisterField) {TMC2262_DIR_MASK, TMC2262_DIR_SHIFT, TMC2262_IOIN, false}) +#define TMC2262_ENCB_MASK 0x00000004 +#define TMC2262_ENCB_SHIFT 2 +#define TMC2262_ENCB_FIELD ((RegisterField) {TMC2262_ENCB_MASK, TMC2262_ENCB_SHIFT, TMC2262_IOIN, false}) +#define TMC2262_ENCA_MASK 0x00000008 +#define TMC2262_ENCA_SHIFT 3 +#define TMC2262_ENCA_FIELD ((RegisterField) {TMC2262_ENCA_MASK, TMC2262_ENCA_SHIFT, TMC2262_IOIN, false}) +#define TMC2262_DRV_ENN_MASK 0x00000010 +#define TMC2262_DRV_ENN_SHIFT 4 +#define TMC2262_DRV_ENN_FIELD ((RegisterField) {TMC2262_DRV_ENN_MASK, TMC2262_DRV_ENN_SHIFT, TMC2262_IOIN, false}) +#define TMC2262_ENCN_MASK 0x00000020 +#define TMC2262_ENCN_SHIFT 5 +#define TMC2262_ENCN_FIELD ((RegisterField) {TMC2262_ENCN_MASK, TMC2262_ENCN_SHIFT, TMC2262_IOIN, false}) +#define TMC2262_RESERVED_MASK 0x00000080 +#define TMC2262_RESERVED_SHIFT 7 +#define TMC2262_RESERVED_FIELD ((RegisterField) {TMC2262_RESERVED_MASK, TMC2262_RESERVED_SHIFT, TMC2262_IOIN, false}) +#define TMC2262_EXT_RES_DET_MASK 0x00002000 +#define TMC2262_EXT_RES_DET_SHIFT 13 +#define TMC2262_EXT_RES_DET_FIELD ((RegisterField) {TMC2262_EXT_RES_DET_MASK, TMC2262_EXT_RES_DET_SHIFT, TMC2262_IOIN, false}) +#define TMC2262_EXT_CLK_MASK 0x00004000 +#define TMC2262_EXT_CLK_SHIFT 14 +#define TMC2262_EXT_CLK_FIELD ((RegisterField) {TMC2262_EXT_CLK_MASK, TMC2262_EXT_CLK_SHIFT, TMC2262_IOIN, false}) +#define TMC2262_SILICON_RV_MASK 0x00070000 +#define TMC2262_SILICON_RV_SHIFT 16 +#define TMC2262_SILICON_RV_FIELD ((RegisterField) {TMC2262_SILICON_RV_MASK, TMC2262_SILICON_RV_SHIFT, TMC2262_IOIN, false}) +#define TMC2262_CURRENT_RANGE_MASK 0x00000003 +#define TMC2262_CURRENT_RANGE_SHIFT 0 +#define TMC2262_CURRENT_RANGE_FIELD ((RegisterField) {TMC2262_CURRENT_RANGE_MASK, TMC2262_CURRENT_RANGE_SHIFT, TMC2262_DRV_CONF, false}) +#define TMC2262_CURRENT_RANGE_SCALE_MASK 0x0000000C +#define TMC2262_CURRENT_RANGE_SCALE_SHIFT 2 +#define TMC2262_CURRENT_RANGE_SCALE_FIELD ((RegisterField) {TMC2262_CURRENT_RANGE_SCALE_MASK, TMC2262_CURRENT_RANGE_SCALE_SHIFT, TMC2262_DRV_CONF, false}) +#define TMC2262_SLOPE_CONTROL_MASK 0x00000030 +#define TMC2262_SLOPE_CONTROL_SHIFT 4 +#define TMC2262_SLOPE_CONTROL_FIELD ((RegisterField) {TMC2262_SLOPE_CONTROL_MASK, TMC2262_SLOPE_CONTROL_SHIFT, TMC2262_DRV_CONF, false}) +#define TMC2262_COMMIT_MASK 0x00000001 +#define TMC2262_COMMIT_SHIFT 0 +#define TMC2262_COMMIT_FIELD ((RegisterField) {TMC2262_COMMIT_MASK, TMC2262_COMMIT_SHIFT, TMC2262_PLL, false}) +#define TMC2262_EXT_NOT_INT_MASK 0x00000002 +#define TMC2262_EXT_NOT_INT_SHIFT 1 +#define TMC2262_EXT_NOT_INT_FIELD ((RegisterField) {TMC2262_EXT_NOT_INT_MASK, TMC2262_EXT_NOT_INT_SHIFT, TMC2262_PLL, false}) +#define TMC2262_CLK_SYS_SEL_MASK 0x00000004 +#define TMC2262_CLK_SYS_SEL_SHIFT 2 +#define TMC2262_CLK_SYS_SEL_FIELD ((RegisterField) {TMC2262_CLK_SYS_SEL_MASK, TMC2262_CLK_SYS_SEL_SHIFT, TMC2262_PLL, false}) +#define TMC2262_ADC_CLK_ENA_MASK 0x00000008 +#define TMC2262_ADC_CLK_ENA_SHIFT 3 +#define TMC2262_ADC_CLK_ENA_FIELD ((RegisterField) {TMC2262_ADC_CLK_ENA_MASK, TMC2262_ADC_CLK_ENA_SHIFT, TMC2262_PLL, false}) +#define TMC2262_PWM_CLK_ENA_MASK 0x00000010 +#define TMC2262_PWM_CLK_ENA_SHIFT 4 +#define TMC2262_PWM_CLK_ENA_FIELD ((RegisterField) {TMC2262_PWM_CLK_ENA_MASK, TMC2262_PWM_CLK_ENA_SHIFT, TMC2262_PLL, false}) +#define TMC2262_CLOCK_DIVIDER_MASK 0x000003E0 +#define TMC2262_CLOCK_DIVIDER_SHIFT 5 +#define TMC2262_CLOCK_DIVIDER_FIELD ((RegisterField) {TMC2262_CLOCK_DIVIDER_MASK, TMC2262_CLOCK_DIVIDER_SHIFT, TMC2262_PLL, false}) +#define TMC2262_CLK_FSM_ENA_MASK 0x00000400 +#define TMC2262_CLK_FSM_ENA_SHIFT 10 +#define TMC2262_CLK_FSM_ENA_FIELD ((RegisterField) {TMC2262_CLK_FSM_ENA_MASK, TMC2262_CLK_FSM_ENA_SHIFT, TMC2262_PLL, false}) +#define TMC2262_CLK_1MO_TMO_MASK 0x00001000 +#define TMC2262_CLK_1MO_TMO_SHIFT 12 +#define TMC2262_CLK_1MO_TMO_FIELD ((RegisterField) {TMC2262_CLK_1MO_TMO_MASK, TMC2262_CLK_1MO_TMO_SHIFT, TMC2262_PLL, false}) +#define TMC2262_CLK_LOSS_MASK 0x00002000 +#define TMC2262_CLK_LOSS_SHIFT 13 +#define TMC2262_CLK_LOSS_FIELD ((RegisterField) {TMC2262_CLK_LOSS_MASK, TMC2262_CLK_LOSS_SHIFT, TMC2262_PLL, false}) +#define TMC2262_CLK_IS_STUCK_MASK 0x00004000 +#define TMC2262_CLK_IS_STUCK_SHIFT 14 +#define TMC2262_CLK_IS_STUCK_FIELD ((RegisterField) {TMC2262_CLK_IS_STUCK_MASK, TMC2262_CLK_IS_STUCK_SHIFT, TMC2262_PLL, false}) +#define TMC2262_PLL_LOCK_LOSS_MASK 0x00008000 +#define TMC2262_PLL_LOCK_LOSS_SHIFT 15 +#define TMC2262_PLL_LOCK_LOSS_FIELD ((RegisterField) {TMC2262_PLL_LOCK_LOSS_MASK, TMC2262_PLL_LOCK_LOSS_SHIFT, TMC2262_PLL, false}) +#define TMC2262_IHOLD_MASK 0x000000FF +#define TMC2262_IHOLD_SHIFT 0 +#define TMC2262_IHOLD_FIELD ((RegisterField) {TMC2262_IHOLD_MASK, TMC2262_IHOLD_SHIFT, TMC2262_IHOLD_IRUN, false}) +#define TMC2262_IRUN_MASK 0x0000FF00 +#define TMC2262_IRUN_SHIFT 8 +#define TMC2262_IRUN_FIELD ((RegisterField) {TMC2262_IRUN_MASK, TMC2262_IRUN_SHIFT, TMC2262_IHOLD_IRUN, false}) +#define TMC2262_IHOLDDELAY_MASK 0x00FF0000 +#define TMC2262_IHOLDDELAY_SHIFT 16 +#define TMC2262_IHOLDDELAY_FIELD ((RegisterField) {TMC2262_IHOLDDELAY_MASK, TMC2262_IHOLDDELAY_SHIFT, TMC2262_IHOLD_IRUN, false}) +#define TMC2262_IRUNDELAY_MASK 0x0F000000 +#define TMC2262_IRUNDELAY_SHIFT 24 +#define TMC2262_IRUNDELAY_FIELD ((RegisterField) {TMC2262_IRUNDELAY_MASK, TMC2262_IRUNDELAY_SHIFT, TMC2262_IHOLD_IRUN, false}) +#define TMC2262_TPOWERDOWN_MASK 0x000000FF +#define TMC2262_TPOWERDOWN_SHIFT 0 +#define TMC2262_TPOWERDOWN_FIELD ((RegisterField) {TMC2262_TPOWERDOWN_MASK, TMC2262_TPOWERDOWN_SHIFT, TMC2262_TPOWERDOWN, false}) +#define TMC2262_TSTEP_MASK 0x000FFFFF +#define TMC2262_TSTEP_SHIFT 0 +#define TMC2262_TSTEP_FIELD ((RegisterField) {TMC2262_TSTEP_MASK, TMC2262_TSTEP_SHIFT, TMC2262_TSTEP, false}) +#define TMC2262_TPWMTHRS_MASK 0x000FFFFF +#define TMC2262_TPWMTHRS_SHIFT 0 +#define TMC2262_TPWMTHRS_FIELD ((RegisterField) {TMC2262_TPWMTHRS_MASK, TMC2262_TPWMTHRS_SHIFT, TMC2262_TPWMTHRS, false}) +#define TMC2262_TCOOLTHRS_MASK 0x000FFFFF +#define TMC2262_TCOOLTHRS_SHIFT 0 +#define TMC2262_TCOOLTHRS_FIELD ((RegisterField) {TMC2262_TCOOLTHRS_MASK, TMC2262_TCOOLTHRS_SHIFT, TMC2262_TCOOLTHRS, false}) +#define TMC2262_THIGH_MASK 0x000FFFFF +#define TMC2262_THIGH_SHIFT 0 +#define TMC2262_THIGH_FIELD ((RegisterField) {TMC2262_THIGH_MASK, TMC2262_THIGH_SHIFT, TMC2262_THIGH, false}) +#define TMC2262_TSGP_LOW_VEL_THRS_MASK 0x000FFFFF +#define TMC2262_TSGP_LOW_VEL_THRS_SHIFT 0 +#define TMC2262_TSGP_LOW_VEL_THRS_FIELD ((RegisterField) {TMC2262_TSGP_LOW_VEL_THRS_MASK, TMC2262_TSGP_LOW_VEL_THRS_SHIFT, TMC2262_TSGP_LOW_VEL_THRS, false}) +#define TMC2262_T_RCOIL_MEAS_MASK 0x000FFFFF +#define TMC2262_T_RCOIL_MEAS_SHIFT 0 +#define TMC2262_T_RCOIL_MEAS_FIELD ((RegisterField) {TMC2262_T_RCOIL_MEAS_MASK, TMC2262_T_RCOIL_MEAS_SHIFT, TMC2262_T_RCOIL_MEAS, false}) +#define TMC2262_TUDCSTEP_MASK 0x000FFFFF +#define TMC2262_TUDCSTEP_SHIFT 0 +#define TMC2262_TUDCSTEP_FIELD ((RegisterField) {TMC2262_TUDCSTEP_MASK, TMC2262_TUDCSTEP_SHIFT, TMC2262_TUDCSTEP, false}) +#define TMC2262_DECEL_THRS_MASK 0x0000000F +#define TMC2262_DECEL_THRS_SHIFT 0 +#define TMC2262_DECEL_THRS_FIELD ((RegisterField) {TMC2262_DECEL_THRS_MASK, TMC2262_DECEL_THRS_SHIFT, TMC2262_UDC_CONF, false}) +#define TMC2262_ACCEL_THRS_MASK 0x000000F0 +#define TMC2262_ACCEL_THRS_SHIFT 4 +#define TMC2262_ACCEL_THRS_FIELD ((RegisterField) {TMC2262_ACCEL_THRS_MASK, TMC2262_ACCEL_THRS_SHIFT, TMC2262_UDC_CONF, false}) +#define TMC2262_UDC_ENABLE_MASK 0x00000100 +#define TMC2262_UDC_ENABLE_SHIFT 8 +#define TMC2262_UDC_ENABLE_FIELD ((RegisterField) {TMC2262_UDC_ENABLE_MASK, TMC2262_UDC_ENABLE_SHIFT, TMC2262_UDC_CONF, false}) +#define TMC2262_STEPS_LOST_MASK 0x000FFFFF +#define TMC2262_STEPS_LOST_SHIFT 0 +#define TMC2262_STEPS_LOST_FIELD ((RegisterField) {TMC2262_STEPS_LOST_MASK, TMC2262_STEPS_LOST_SHIFT, TMC2262_STEPS_LOST, true}) +#define TMC2262_SG_STOP_MASK 0x00000400 +#define TMC2262_SG_STOP_SHIFT 10 +#define TMC2262_SG_STOP_FIELD ((RegisterField) {TMC2262_SG_STOP_MASK, TMC2262_SG_STOP_SHIFT, TMC2262_SW_MODE, false}) +#define TMC2262_EVENT_STOP_SG_MASK 0x00000040 +#define TMC2262_EVENT_STOP_SG_SHIFT 6 +#define TMC2262_EVENT_STOP_SG_FIELD ((RegisterField) {TMC2262_EVENT_STOP_SG_MASK, TMC2262_EVENT_STOP_SG_SHIFT, TMC2262_SG_SEQ_STOP_STAT, false}) +#define TMC2262_POL_A_MASK 0x00000001 +#define TMC2262_POL_A_SHIFT 0 +#define TMC2262_POL_A_FIELD ((RegisterField) {TMC2262_POL_A_MASK, TMC2262_POL_A_SHIFT, TMC2262_ENCMODE, false}) +#define TMC2262_POL_B_MASK 0x00000002 +#define TMC2262_POL_B_SHIFT 1 +#define TMC2262_POL_B_FIELD ((RegisterField) {TMC2262_POL_B_MASK, TMC2262_POL_B_SHIFT, TMC2262_ENCMODE, false}) +#define TMC2262_POL_N_MASK 0x00000004 +#define TMC2262_POL_N_SHIFT 2 +#define TMC2262_POL_N_FIELD ((RegisterField) {TMC2262_POL_N_MASK, TMC2262_POL_N_SHIFT, TMC2262_ENCMODE, false}) +#define TMC2262_IGNORE_AB_MASK 0x00000008 +#define TMC2262_IGNORE_AB_SHIFT 3 +#define TMC2262_IGNORE_AB_FIELD ((RegisterField) {TMC2262_IGNORE_AB_MASK, TMC2262_IGNORE_AB_SHIFT, TMC2262_ENCMODE, false}) +#define TMC2262_CLR_CONT_MASK 0x00000010 +#define TMC2262_CLR_CONT_SHIFT 4 +#define TMC2262_CLR_CONT_FIELD ((RegisterField) {TMC2262_CLR_CONT_MASK, TMC2262_CLR_CONT_SHIFT, TMC2262_ENCMODE, false}) +#define TMC2262_CLR_ONCE_MASK 0x00000020 +#define TMC2262_CLR_ONCE_SHIFT 5 +#define TMC2262_CLR_ONCE_FIELD ((RegisterField) {TMC2262_CLR_ONCE_MASK, TMC2262_CLR_ONCE_SHIFT, TMC2262_ENCMODE, false}) +#define TMC2262_POS_NEG_EDGE_MASK 0x000000C0 +#define TMC2262_POS_NEG_EDGE_SHIFT 6 +#define TMC2262_POS_NEG_EDGE_FIELD ((RegisterField) {TMC2262_POS_NEG_EDGE_MASK, TMC2262_POS_NEG_EDGE_SHIFT, TMC2262_ENCMODE, false}) +#define TMC2262_CLR_ENC_X_MASK 0x00000100 +#define TMC2262_CLR_ENC_X_SHIFT 8 +#define TMC2262_CLR_ENC_X_FIELD ((RegisterField) {TMC2262_CLR_ENC_X_MASK, TMC2262_CLR_ENC_X_SHIFT, TMC2262_ENCMODE, false}) +#define TMC2262_ENC_SEL_DECIMAL_MASK 0x00000400 +#define TMC2262_ENC_SEL_DECIMAL_SHIFT 10 +#define TMC2262_ENC_SEL_DECIMAL_FIELD ((RegisterField) {TMC2262_ENC_SEL_DECIMAL_MASK, TMC2262_ENC_SEL_DECIMAL_SHIFT, TMC2262_ENCMODE, false}) +#define TMC2262_NBEMF_ABN_SEL_MASK 0x00000800 +#define TMC2262_NBEMF_ABN_SEL_SHIFT 11 +#define TMC2262_NBEMF_ABN_SEL_FIELD ((RegisterField) {TMC2262_NBEMF_ABN_SEL_MASK, TMC2262_NBEMF_ABN_SEL_SHIFT, TMC2262_ENCMODE, false}) +#define TMC2262_BEMF_HYST_MASK 0x00007000 +#define TMC2262_BEMF_HYST_SHIFT 12 +#define TMC2262_BEMF_HYST_FIELD ((RegisterField) {TMC2262_BEMF_HYST_MASK, TMC2262_BEMF_HYST_SHIFT, TMC2262_ENCMODE, false}) +#define TMC2262_BEMF_BLANK_TIME_MASK 0x00FF0000 +#define TMC2262_BEMF_BLANK_TIME_SHIFT 16 +#define TMC2262_BEMF_BLANK_TIME_FIELD ((RegisterField) {TMC2262_BEMF_BLANK_TIME_MASK, TMC2262_BEMF_BLANK_TIME_SHIFT, TMC2262_ENCMODE, false}) +#define TMC2262_BEMF_FILTER_SEL_MASK 0x30000000 +#define TMC2262_BEMF_FILTER_SEL_SHIFT 28 +#define TMC2262_BEMF_FILTER_SEL_FIELD ((RegisterField) {TMC2262_BEMF_FILTER_SEL_MASK, TMC2262_BEMF_FILTER_SEL_SHIFT, TMC2262_ENCMODE, false}) +#define TMC2262_X_ENC_MASK 0xFFFFFFFF +#define TMC2262_X_ENC_SHIFT 0 +#define TMC2262_X_ENC_FIELD ((RegisterField) {TMC2262_X_ENC_MASK, TMC2262_X_ENC_SHIFT, TMC2262_X_ENC, true}) +#define TMC2262_ENC_CONST_MASK 0xFFFFFFFF +#define TMC2262_ENC_CONST_SHIFT 0 +#define TMC2262_ENC_CONST_FIELD ((RegisterField) {TMC2262_ENC_CONST_MASK, TMC2262_ENC_CONST_SHIFT, TMC2262_ENC_CONST, true}) +#define TMC2262_N_EVENT_MASK 0x00000001 +#define TMC2262_N_EVENT_SHIFT 0 +#define TMC2262_N_EVENT_FIELD ((RegisterField) {TMC2262_N_EVENT_MASK, TMC2262_N_EVENT_SHIFT, TMC2262_ENC_STATUS, false}) +#define TMC2262_DEVIATION_WARN_MASK 0x00000002 +#define TMC2262_DEVIATION_WARN_SHIFT 1 +#define TMC2262_DEVIATION_WARN_FIELD ((RegisterField) {TMC2262_DEVIATION_WARN_MASK, TMC2262_DEVIATION_WARN_SHIFT, TMC2262_ENC_STATUS, false}) +#define TMC2262_ENC_LATCH_MASK 0xFFFFFFFF +#define TMC2262_ENC_LATCH_SHIFT 0 +#define TMC2262_ENC_LATCH_FIELD ((RegisterField) {TMC2262_ENC_LATCH_MASK, TMC2262_ENC_LATCH_SHIFT, TMC2262_ENC_LATCH, false}) +#define TMC2262_ENC_DEVIATION_MASK 0x000FFFFF +#define TMC2262_ENC_DEVIATION_SHIFT 0 +#define TMC2262_ENC_DEVIATION_FIELD ((RegisterField) {TMC2262_ENC_DEVIATION_MASK, TMC2262_ENC_DEVIATION_SHIFT, TMC2262_ENC_DEVIATION, false}) +#define TMC2262_CUR_P_MASK 0x00000FFF +#define TMC2262_CUR_P_SHIFT 0 +#define TMC2262_CUR_P_FIELD ((RegisterField) {TMC2262_CUR_P_MASK, TMC2262_CUR_P_SHIFT, TMC2262_CURRENT_PI_REG, false}) +#define TMC2262_CUR_I_MASK 0x03FF0000 +#define TMC2262_CUR_I_SHIFT 16 +#define TMC2262_CUR_I_FIELD ((RegisterField) {TMC2262_CUR_I_MASK, TMC2262_CUR_I_SHIFT, TMC2262_CURRENT_PI_REG, false}) +#define TMC2262_ANGLE_P_MASK 0x00000FFF +#define TMC2262_ANGLE_P_SHIFT 0 +#define TMC2262_ANGLE_P_FIELD ((RegisterField) {TMC2262_ANGLE_P_MASK, TMC2262_ANGLE_P_SHIFT, TMC2262_ANGLE_PI_REG, false}) +#define TMC2262_ANGLE_I_MASK 0x03FF0000 +#define TMC2262_ANGLE_I_SHIFT 16 +#define TMC2262_ANGLE_I_FIELD ((RegisterField) {TMC2262_ANGLE_I_MASK, TMC2262_ANGLE_I_SHIFT, TMC2262_ANGLE_PI_REG, false}) +#define TMC2262_ANGLE_PI_LIMIT_MASK 0x000003FF +#define TMC2262_ANGLE_PI_LIMIT_SHIFT 0 +#define TMC2262_ANGLE_PI_LIMIT_FIELD ((RegisterField) {TMC2262_ANGLE_PI_LIMIT_MASK, TMC2262_ANGLE_PI_LIMIT_SHIFT, TMC2262_CUR_ANGLE_LIMIT, false}) +#define TMC2262_ANGLE_PI_INT_POS_CLIP_MASK 0x00001000 +#define TMC2262_ANGLE_PI_INT_POS_CLIP_SHIFT 12 +#define TMC2262_ANGLE_PI_INT_POS_CLIP_FIELD ((RegisterField) {TMC2262_ANGLE_PI_INT_POS_CLIP_MASK, TMC2262_ANGLE_PI_INT_POS_CLIP_SHIFT, TMC2262_CUR_ANGLE_LIMIT, false}) +#define TMC2262_ANGLE_PI_INT_NEG_CLIP_MASK 0x00002000 +#define TMC2262_ANGLE_PI_INT_NEG_CLIP_SHIFT 13 +#define TMC2262_ANGLE_PI_INT_NEG_CLIP_FIELD ((RegisterField) {TMC2262_ANGLE_PI_INT_NEG_CLIP_MASK, TMC2262_ANGLE_PI_INT_NEG_CLIP_SHIFT, TMC2262_CUR_ANGLE_LIMIT, false}) +#define TMC2262_ANGLE_PI_POS_CLIP_MASK 0x00004000 +#define TMC2262_ANGLE_PI_POS_CLIP_SHIFT 14 +#define TMC2262_ANGLE_PI_POS_CLIP_FIELD ((RegisterField) {TMC2262_ANGLE_PI_POS_CLIP_MASK, TMC2262_ANGLE_PI_POS_CLIP_SHIFT, TMC2262_CUR_ANGLE_LIMIT, false}) +#define TMC2262_ANGLE_PI_NEG_CLIP_MASK 0x00008000 +#define TMC2262_ANGLE_PI_NEG_CLIP_SHIFT 15 +#define TMC2262_ANGLE_PI_NEG_CLIP_FIELD ((RegisterField) {TMC2262_ANGLE_PI_NEG_CLIP_MASK, TMC2262_ANGLE_PI_NEG_CLIP_SHIFT, TMC2262_CUR_ANGLE_LIMIT, false}) +#define TMC2262_CUR_PI_LIMIT_MASK 0x0FFF0000 +#define TMC2262_CUR_PI_LIMIT_SHIFT 16 +#define TMC2262_CUR_PI_LIMIT_FIELD ((RegisterField) {TMC2262_CUR_PI_LIMIT_MASK, TMC2262_CUR_PI_LIMIT_SHIFT, TMC2262_CUR_ANGLE_LIMIT, false}) +#define TMC2262_CUR_PI_INT_POS_CLIP_MASK 0x10000000 +#define TMC2262_CUR_PI_INT_POS_CLIP_SHIFT 28 +#define TMC2262_CUR_PI_INT_POS_CLIP_FIELD ((RegisterField) {TMC2262_CUR_PI_INT_POS_CLIP_MASK, TMC2262_CUR_PI_INT_POS_CLIP_SHIFT, TMC2262_CUR_ANGLE_LIMIT, false}) +#define TMC2262_CUR_PI_INT_NEG_CLIP_MASK 0x20000000 +#define TMC2262_CUR_PI_INT_NEG_CLIP_SHIFT 29 +#define TMC2262_CUR_PI_INT_NEG_CLIP_FIELD ((RegisterField) {TMC2262_CUR_PI_INT_NEG_CLIP_MASK, TMC2262_CUR_PI_INT_NEG_CLIP_SHIFT, TMC2262_CUR_ANGLE_LIMIT, false}) +#define TMC2262_CUR_PI_POS_CLIP_MASK 0x40000000 +#define TMC2262_CUR_PI_POS_CLIP_SHIFT 30 +#define TMC2262_CUR_PI_POS_CLIP_FIELD ((RegisterField) {TMC2262_CUR_PI_POS_CLIP_MASK, TMC2262_CUR_PI_POS_CLIP_SHIFT, TMC2262_CUR_ANGLE_LIMIT, false}) +#define TMC2262_CUR_PI_NEG_CLIP_MASK 0x80000000 +#define TMC2262_CUR_PI_NEG_CLIP_SHIFT 31 +#define TMC2262_CUR_PI_NEG_CLIP_FIELD ((RegisterField) {TMC2262_CUR_PI_NEG_CLIP_MASK, TMC2262_CUR_PI_NEG_CLIP_SHIFT, TMC2262_CUR_ANGLE_LIMIT, false}) +#define TMC2262_ANGLE_LOWER_I_LIMIT_MASK 0x000003FF +#define TMC2262_ANGLE_LOWER_I_LIMIT_SHIFT 0 +#define TMC2262_ANGLE_LOWER_I_LIMIT_FIELD ((RegisterField) {TMC2262_ANGLE_LOWER_I_LIMIT_MASK, TMC2262_ANGLE_LOWER_I_LIMIT_SHIFT, TMC2262_ANGLE_LOWER_LIMIT, false}) +#define TMC2262_ANGLE_ERROR_MASK 0x03FF0000 +#define TMC2262_ANGLE_ERROR_SHIFT 16 +#define TMC2262_ANGLE_ERROR_FIELD ((RegisterField) {TMC2262_ANGLE_ERROR_MASK, TMC2262_ANGLE_ERROR_SHIFT, TMC2262_ANGLE_LOWER_LIMIT, true}) +#define TMC2262_AMPL_MEAS_MASK 0x00000FFF +#define TMC2262_AMPL_MEAS_SHIFT 0 +#define TMC2262_AMPL_MEAS_FIELD ((RegisterField) {TMC2262_AMPL_MEAS_MASK, TMC2262_AMPL_MEAS_SHIFT, TMC2262_CUR_ANGLE_MEAS, false}) +#define TMC2262_ANGLE_MEAS_MASK 0x03FF0000 +#define TMC2262_ANGLE_MEAS_SHIFT 16 +#define TMC2262_ANGLE_MEAS_FIELD ((RegisterField) {TMC2262_ANGLE_MEAS_MASK, TMC2262_ANGLE_MEAS_SHIFT, TMC2262_CUR_ANGLE_MEAS, false}) +#define TMC2262_PWM_CALC_MASK 0x00001FFF +#define TMC2262_PWM_CALC_SHIFT 0 +#define TMC2262_PWM_CALC_FIELD ((RegisterField) {TMC2262_PWM_CALC_MASK, TMC2262_PWM_CALC_SHIFT, TMC2262_PI_RESULTS, true}) +#define TMC2262_ANGLE_CORR_CALC_MASK 0x03FF0000 +#define TMC2262_ANGLE_CORR_CALC_SHIFT 16 +#define TMC2262_ANGLE_CORR_CALC_FIELD ((RegisterField) {TMC2262_ANGLE_CORR_CALC_MASK, TMC2262_ANGLE_CORR_CALC_SHIFT, TMC2262_PI_RESULTS, true}) +#define TMC2262_COIL_INDUCT_MASK 0x00007FFF +#define TMC2262_COIL_INDUCT_SHIFT 0 +#define TMC2262_COIL_INDUCT_FIELD ((RegisterField) {TMC2262_COIL_INDUCT_MASK, TMC2262_COIL_INDUCT_SHIFT, TMC2262_COIL_INDUCT, false}) +#define TMC2262_RCOIL_MANUAL_MASK 0x00010000 +#define TMC2262_RCOIL_MANUAL_SHIFT 16 +#define TMC2262_RCOIL_MANUAL_FIELD ((RegisterField) {TMC2262_RCOIL_MANUAL_MASK, TMC2262_RCOIL_MANUAL_SHIFT, TMC2262_COIL_INDUCT, false}) +#define TMC2262_RCOIL_THERMAL_COUPLING_MASK 0x00020000 +#define TMC2262_RCOIL_THERMAL_COUPLING_SHIFT 17 +#define TMC2262_RCOIL_THERMAL_COUPLING_FIELD ((RegisterField) {TMC2262_RCOIL_THERMAL_COUPLING_MASK, TMC2262_RCOIL_THERMAL_COUPLING_SHIFT, TMC2262_COIL_INDUCT, false}) +#define TMC2262_R_COIL_AUTO_B_MASK 0x00000FFF +#define TMC2262_R_COIL_AUTO_B_SHIFT 0 +#define TMC2262_R_COIL_AUTO_B_FIELD ((RegisterField) {TMC2262_R_COIL_AUTO_B_MASK, TMC2262_R_COIL_AUTO_B_SHIFT, TMC2262_R_COIL, false}) +#define TMC2262_R_COIL_AUTO_A_MASK 0x0FFF0000 +#define TMC2262_R_COIL_AUTO_A_SHIFT 16 +#define TMC2262_R_COIL_AUTO_A_FIELD ((RegisterField) {TMC2262_R_COIL_AUTO_A_MASK, TMC2262_R_COIL_AUTO_A_SHIFT, TMC2262_R_COIL, false}) +#define TMC2262_R_COIL_USER_B_MASK 0x00000FFF +#define TMC2262_R_COIL_USER_B_SHIFT 0 +#define TMC2262_R_COIL_USER_B_FIELD ((RegisterField) {TMC2262_R_COIL_USER_B_MASK, TMC2262_R_COIL_USER_B_SHIFT, TMC2262_R_COIL_USER, false}) +#define TMC2262_R_COIL_USER_A_MASK 0x0FFF0000 +#define TMC2262_R_COIL_USER_A_SHIFT 16 +#define TMC2262_R_COIL_USER_A_FIELD ((RegisterField) {TMC2262_R_COIL_USER_A_MASK, TMC2262_R_COIL_USER_A_SHIFT, TMC2262_R_COIL_USER, false}) +#define TMC2262_SGP_THRS_MASK 0x000001FF +#define TMC2262_SGP_THRS_SHIFT 0 +#define TMC2262_SGP_THRS_FIELD ((RegisterField) {TMC2262_SGP_THRS_MASK, TMC2262_SGP_THRS_SHIFT, TMC2262_SGP_CONF, true}) +#define TMC2262_SGP_FILT_EN_MASK 0x00001000 +#define TMC2262_SGP_FILT_EN_SHIFT 12 +#define TMC2262_SGP_FILT_EN_FIELD ((RegisterField) {TMC2262_SGP_FILT_EN_MASK, TMC2262_SGP_FILT_EN_SHIFT, TMC2262_SGP_CONF, false}) +#define TMC2262_SGP_LOW_VEL_FREEZE_MASK 0x00002000 +#define TMC2262_SGP_LOW_VEL_FREEZE_SHIFT 13 +#define TMC2262_SGP_LOW_VEL_FREEZE_FIELD ((RegisterField) {TMC2262_SGP_LOW_VEL_FREEZE_MASK, TMC2262_SGP_LOW_VEL_FREEZE_SHIFT, TMC2262_SGP_CONF, false}) +#define TMC2262_SGP_CLEAR_CUR_PI_MASK 0x00004000 +#define TMC2262_SGP_CLEAR_CUR_PI_SHIFT 14 +#define TMC2262_SGP_CLEAR_CUR_PI_FIELD ((RegisterField) {TMC2262_SGP_CLEAR_CUR_PI_MASK, TMC2262_SGP_CLEAR_CUR_PI_SHIFT, TMC2262_SGP_CONF, false}) +#define TMC2262_SGP_LOW_VEL_SLOPE_MASK 0x00FF0000 +#define TMC2262_SGP_LOW_VEL_SLOPE_SHIFT 16 +#define TMC2262_SGP_LOW_VEL_SLOPE_FIELD ((RegisterField) {TMC2262_SGP_LOW_VEL_SLOPE_MASK, TMC2262_SGP_LOW_VEL_SLOPE_SHIFT, TMC2262_SGP_CONF, false}) +#define TMC2262_SGP_LOW_VEL_CNTS_MASK 0x30000000 +#define TMC2262_SGP_LOW_VEL_CNTS_SHIFT 28 +#define TMC2262_SGP_LOW_VEL_CNTS_FIELD ((RegisterField) {TMC2262_SGP_LOW_VEL_CNTS_MASK, TMC2262_SGP_LOW_VEL_CNTS_SHIFT, TMC2262_SGP_CONF, false}) +#define TMC2262_SGP_IND_2_MASK 0x000003FF +#define TMC2262_SGP_IND_2_SHIFT 0 +#define TMC2262_SGP_IND_2_FIELD ((RegisterField) {TMC2262_SGP_IND_2_MASK, TMC2262_SGP_IND_2_SHIFT, TMC2262_SGP_IND_2_3, true}) +#define TMC2262_SGP_IND_3_MASK 0x03FF0000 +#define TMC2262_SGP_IND_3_SHIFT 16 +#define TMC2262_SGP_IND_3_FIELD ((RegisterField) {TMC2262_SGP_IND_3_MASK, TMC2262_SGP_IND_3_SHIFT, TMC2262_SGP_IND_2_3, true}) +#define TMC2262_SGP_IND_0_MASK 0x000003FF +#define TMC2262_SGP_IND_0_SHIFT 0 +#define TMC2262_SGP_IND_0_FIELD ((RegisterField) {TMC2262_SGP_IND_0_MASK, TMC2262_SGP_IND_0_SHIFT, TMC2262_SGP_IND_0_1, true}) +#define TMC2262_SGP_IND_1_MASK 0x03FF0000 +#define TMC2262_SGP_IND_1_SHIFT 16 +#define TMC2262_SGP_IND_1_FIELD ((RegisterField) {TMC2262_SGP_IND_1_MASK, TMC2262_SGP_IND_1_SHIFT, TMC2262_SGP_IND_0_1, true}) +#define TMC2262_UL_B_MASK 0x00000FFF +#define TMC2262_UL_B_SHIFT 0 +#define TMC2262_UL_B_FIELD ((RegisterField) {TMC2262_UL_B_MASK, TMC2262_UL_B_SHIFT, TMC2262_INDUCTANCE_VOLTAGE, true}) +#define TMC2262_UL_A_MASK 0x0FFF0000 +#define TMC2262_UL_A_SHIFT 16 +#define TMC2262_UL_A_FIELD ((RegisterField) {TMC2262_UL_A_MASK, TMC2262_UL_A_SHIFT, TMC2262_INDUCTANCE_VOLTAGE, true}) +#define TMC2262_SGP_RAW_MASK 0x000003FF +#define TMC2262_SGP_RAW_SHIFT 0 +#define TMC2262_SGP_RAW_FIELD ((RegisterField) {TMC2262_SGP_RAW_MASK, TMC2262_SGP_RAW_SHIFT, TMC2262_SGP_BEMF, true}) +#define TMC2262_UBEMF_ABS_MASK 0x0FFF0000 +#define TMC2262_UBEMF_ABS_SHIFT 16 +#define TMC2262_UBEMF_ABS_FIELD ((RegisterField) {TMC2262_UBEMF_ABS_MASK, TMC2262_UBEMF_ABS_SHIFT, TMC2262_SGP_BEMF, false}) +#define TMC2262_COOL_CUR_DIV_MASK 0x0000000F +#define TMC2262_COOL_CUR_DIV_SHIFT 0 +#define TMC2262_COOL_CUR_DIV_FIELD ((RegisterField) {TMC2262_COOL_CUR_DIV_MASK, TMC2262_COOL_CUR_DIV_SHIFT, TMC2262_COOLSTEPPLUS_CONF, false}) +#define TMC2262_LOAD_FILT_EN_MASK 0x00000010 +#define TMC2262_LOAD_FILT_EN_SHIFT 4 +#define TMC2262_LOAD_FILT_EN_FIELD ((RegisterField) {TMC2262_LOAD_FILT_EN_MASK, TMC2262_LOAD_FILT_EN_SHIFT, TMC2262_COOLSTEPPLUS_CONF, false}) +#define TMC2262_COOLSTEP_P_MASK 0x00000FFF +#define TMC2262_COOLSTEP_P_SHIFT 0 +#define TMC2262_COOLSTEP_P_FIELD ((RegisterField) {TMC2262_COOLSTEP_P_MASK, TMC2262_COOLSTEP_P_SHIFT, TMC2262_COOLSTEPPLUS_PI_REG, false}) +#define TMC2262_COOLSTEP_I_MASK 0x03FF0000 +#define TMC2262_COOLSTEP_I_SHIFT 16 +#define TMC2262_COOLSTEP_I_FIELD ((RegisterField) {TMC2262_COOLSTEP_I_MASK, TMC2262_COOLSTEP_I_SHIFT, TMC2262_COOLSTEPPLUS_PI_REG, false}) +#define TMC2262_COOL_PI_DOWN_LIMIT_MASK 0x00000FFF +#define TMC2262_COOL_PI_DOWN_LIMIT_SHIFT 0 +#define TMC2262_COOL_PI_DOWN_LIMIT_FIELD ((RegisterField) {TMC2262_COOL_PI_DOWN_LIMIT_MASK, TMC2262_COOL_PI_DOWN_LIMIT_SHIFT, TMC2262_COOLSTEPPLUS_PI_DOWN, false}) +#define TMC2262_COOL_PI_OFF_SPEED_MASK 0x0FFF0000 +#define TMC2262_COOL_PI_OFF_SPEED_SHIFT 16 +#define TMC2262_COOL_PI_OFF_SPEED_FIELD ((RegisterField) {TMC2262_COOL_PI_OFF_SPEED_MASK, TMC2262_COOL_PI_OFF_SPEED_SHIFT, TMC2262_COOLSTEPPLUS_PI_DOWN, false}) +#define TMC2262_COOL_LOW_LOAD_RESERVE_MASK 0x000000FF +#define TMC2262_COOL_LOW_LOAD_RESERVE_SHIFT 0 +#define TMC2262_COOL_LOW_LOAD_RESERVE_FIELD ((RegisterField) {TMC2262_COOL_LOW_LOAD_RESERVE_MASK, TMC2262_COOL_LOW_LOAD_RESERVE_SHIFT, TMC2262_COOLSTEPPLUS_RESERVE_CONF, false}) +#define TMC2262_COOL_HI_LOAD_RESERVE_MASK 0x0000FF00 +#define TMC2262_COOL_HI_LOAD_RESERVE_SHIFT 8 +#define TMC2262_COOL_HI_LOAD_RESERVE_FIELD ((RegisterField) {TMC2262_COOL_HI_LOAD_RESERVE_MASK, TMC2262_COOL_HI_LOAD_RESERVE_SHIFT, TMC2262_COOLSTEPPLUS_RESERVE_CONF, false}) +#define TMC2262_COOL_LOW_GENERATORIC_RESERVE_MASK 0x00FF0000 +#define TMC2262_COOL_LOW_GENERATORIC_RESERVE_SHIFT 16 +#define TMC2262_COOL_LOW_GENERATORIC_RESERVE_FIELD ((RegisterField) {TMC2262_COOL_LOW_GENERATORIC_RESERVE_MASK, TMC2262_COOL_LOW_GENERATORIC_RESERVE_SHIFT, TMC2262_COOLSTEPPLUS_RESERVE_CONF, false}) +#define TMC2262_COOL_HI_GENERATORIC_RESERVE_MASK 0xFF000000 +#define TMC2262_COOL_HI_GENERATORIC_RESERVE_SHIFT 24 +#define TMC2262_COOL_HI_GENERATORIC_RESERVE_FIELD ((RegisterField) {TMC2262_COOL_HI_GENERATORIC_RESERVE_MASK, TMC2262_COOL_HI_GENERATORIC_RESERVE_SHIFT, TMC2262_COOLSTEPPLUS_RESERVE_CONF, false}) +#define TMC2262_SGP_RESULT_MASK 0x000003FF +#define TMC2262_SGP_RESULT_SHIFT 0 +#define TMC2262_SGP_RESULT_FIELD ((RegisterField) {TMC2262_SGP_RESULT_MASK, TMC2262_SGP_RESULT_SHIFT, TMC2262_COOLSTEPPLUS_LOAD_RESERVE, true}) +#define TMC2262_COOLSTEP_LOAD_RESERVE_MASK 0x01FF0000 +#define TMC2262_COOLSTEP_LOAD_RESERVE_SHIFT 16 +#define TMC2262_COOLSTEP_LOAD_RESERVE_FIELD ((RegisterField) {TMC2262_COOLSTEP_LOAD_RESERVE_MASK, TMC2262_COOLSTEP_LOAD_RESERVE_SHIFT, TMC2262_COOLSTEPPLUS_LOAD_RESERVE, false}) +#define TMC2262_TSTEP_VELOCITY_MASK 0x007FFFFF +#define TMC2262_TSTEP_VELOCITY_SHIFT 0 +#define TMC2262_TSTEP_VELOCITY_FIELD ((RegisterField) {TMC2262_TSTEP_VELOCITY_MASK, TMC2262_TSTEP_VELOCITY_SHIFT, TMC2262_TSTEP_VELOCITY, true}) +#define TMC2262_ADC_VSUPPLY_MASK 0x000001FF +#define TMC2262_ADC_VSUPPLY_SHIFT 0 +#define TMC2262_ADC_VSUPPLY_FIELD ((RegisterField) {TMC2262_ADC_VSUPPLY_MASK, TMC2262_ADC_VSUPPLY_SHIFT, TMC2262_ADC_VSUPPLY_TEMP, false}) +#define TMC2262_ADC_TEMP_MASK 0x01FF0000 +#define TMC2262_ADC_TEMP_SHIFT 16 +#define TMC2262_ADC_TEMP_FIELD ((RegisterField) {TMC2262_ADC_TEMP_MASK, TMC2262_ADC_TEMP_SHIFT, TMC2262_ADC_VSUPPLY_TEMP, false}) +#define TMC2262_ADC_I_A_MASK 0x00000FFF +#define TMC2262_ADC_I_A_SHIFT 0 +#define TMC2262_ADC_I_A_FIELD ((RegisterField) {TMC2262_ADC_I_A_MASK, TMC2262_ADC_I_A_SHIFT, TMC2262_ADC_I, true}) +#define TMC2262_ADC_I_B_MASK 0x0FFF0000 +#define TMC2262_ADC_I_B_SHIFT 16 +#define TMC2262_ADC_I_B_FIELD ((RegisterField) {TMC2262_ADC_I_B_MASK, TMC2262_ADC_I_B_SHIFT, TMC2262_ADC_I, true}) +#define TMC2262_OVERVOLTAGE_VTH_MASK 0x000001FF +#define TMC2262_OVERVOLTAGE_VTH_SHIFT 0 +#define TMC2262_OVERVOLTAGE_VTH_FIELD ((RegisterField) {TMC2262_OVERVOLTAGE_VTH_MASK, TMC2262_OVERVOLTAGE_VTH_SHIFT, TMC2262_OTW_OV_VTH, false}) +#define TMC2262_OVERTEMPPREWARNING_VTH_MASK 0x01FF0000 +#define TMC2262_OVERTEMPPREWARNING_VTH_SHIFT 16 +#define TMC2262_OVERTEMPPREWARNING_VTH_FIELD ((RegisterField) {TMC2262_OVERTEMPPREWARNING_VTH_MASK, TMC2262_OVERTEMPPREWARNING_VTH_SHIFT, TMC2262_OTW_OV_VTH, false}) +#define TMC2262_MSLUT___MASK 0xFFFFFFFF +#define TMC2262_MSLUT___SHIFT 0 +#define TMC2262_MSLUT___FIELD ((RegisterField) {TMC2262_MSLUT___MASK, TMC2262_MSLUT___SHIFT, TMC2262_MSLUT[0], false}) +//#define TMC2262_MSLUT___MASK 0xFFFFFFFF +//#define TMC2262_MSLUT___SHIFT 0 +//#define TMC2262_MSLUT___FIELD ((RegisterField) {TMC2262_MSLUT___MASK, TMC2262_MSLUT___SHIFT, TMC2262_MSLUT[1], false}) +//#define TMC2262_MSLUT___MASK 0xFFFFFFFF +//#define TMC2262_MSLUT___SHIFT 0 +//#define TMC2262_MSLUT___FIELD ((RegisterField) {TMC2262_MSLUT___MASK, TMC2262_MSLUT___SHIFT, TMC2262_MSLUT[2], false}) +//#define TMC2262_MSLUT___MASK 0xFFFFFFFF +//#define TMC2262_MSLUT___SHIFT 0 +//#define TMC2262_MSLUT___FIELD ((RegisterField) {TMC2262_MSLUT___MASK, TMC2262_MSLUT___SHIFT, TMC2262_MSLUT[3], false}) +//#define TMC2262_MSLUT___MASK 0xFFFFFFFF +//#define TMC2262_MSLUT___SHIFT 0 +//#define TMC2262_MSLUT___FIELD ((RegisterField) {TMC2262_MSLUT___MASK, TMC2262_MSLUT___SHIFT, TMC2262_MSLUT[4], false}) +//#define TMC2262_MSLUT___MASK 0xFFFFFFFF +//#define TMC2262_MSLUT___SHIFT 0 +//#define TMC2262_MSLUT___FIELD ((RegisterField) {TMC2262_MSLUT___MASK, TMC2262_MSLUT___SHIFT, TMC2262_MSLUT[5], false}) +//#define TMC2262_MSLUT___MASK 0xFFFFFFFF +//#define TMC2262_MSLUT___SHIFT 0 +//#define TMC2262_MSLUT___FIELD ((RegisterField) {TMC2262_MSLUT___MASK, TMC2262_MSLUT___SHIFT, TMC2262_MSLUT[6], false}) +//#define TMC2262_MSLUT___MASK 0xFFFFFFFF +//#define TMC2262_MSLUT___SHIFT 0 +//#define TMC2262_MSLUT___FIELD ((RegisterField) {TMC2262_MSLUT___MASK, TMC2262_MSLUT___SHIFT, TMC2262_MSLUT[7], false}) +#define TMC2262_W0_MASK 0x00000003 +#define TMC2262_W0_SHIFT 0 +#define TMC2262_W0_FIELD ((RegisterField) {TMC2262_W0_MASK, TMC2262_W0_SHIFT, TMC2262_MSLUTSEL, false}) +#define TMC2262_W1_MASK 0x0000000C +#define TMC2262_W1_SHIFT 2 +#define TMC2262_W1_FIELD ((RegisterField) {TMC2262_W1_MASK, TMC2262_W1_SHIFT, TMC2262_MSLUTSEL, false}) +#define TMC2262_W2_MASK 0x00000030 +#define TMC2262_W2_SHIFT 4 +#define TMC2262_W2_FIELD ((RegisterField) {TMC2262_W2_MASK, TMC2262_W2_SHIFT, TMC2262_MSLUTSEL, false}) +#define TMC2262_W3_MASK 0x000000C0 +#define TMC2262_W3_SHIFT 6 +#define TMC2262_W3_FIELD ((RegisterField) {TMC2262_W3_MASK, TMC2262_W3_SHIFT, TMC2262_MSLUTSEL, false}) +#define TMC2262_X1_MASK 0x0000FF00 +#define TMC2262_X1_SHIFT 8 +#define TMC2262_X1_FIELD ((RegisterField) {TMC2262_X1_MASK, TMC2262_X1_SHIFT, TMC2262_MSLUTSEL, false}) +#define TMC2262_X2_MASK 0x00FF0000 +#define TMC2262_X2_SHIFT 16 +#define TMC2262_X2_FIELD ((RegisterField) {TMC2262_X2_MASK, TMC2262_X2_SHIFT, TMC2262_MSLUTSEL, false}) +#define TMC2262_X3_MASK 0xFF000000 +#define TMC2262_X3_SHIFT 24 +#define TMC2262_X3_FIELD ((RegisterField) {TMC2262_X3_MASK, TMC2262_X3_SHIFT, TMC2262_MSLUTSEL, false}) +#define TMC2262_START_SIN_MASK 0x000000FF +#define TMC2262_START_SIN_SHIFT 0 +#define TMC2262_START_SIN_FIELD ((RegisterField) {TMC2262_START_SIN_MASK, TMC2262_START_SIN_SHIFT, TMC2262_MSLUTSTART, false}) +#define TMC2262_START_SIN90_MASK 0x00FF0000 +#define TMC2262_START_SIN90_SHIFT 16 +#define TMC2262_START_SIN90_FIELD ((RegisterField) {TMC2262_START_SIN90_MASK, TMC2262_START_SIN90_SHIFT, TMC2262_MSLUTSTART, false}) +#define TMC2262_OFFSET_SIN90_MASK 0xFF000000 +#define TMC2262_OFFSET_SIN90_SHIFT 24 +#define TMC2262_OFFSET_SIN90_FIELD ((RegisterField) {TMC2262_OFFSET_SIN90_MASK, TMC2262_OFFSET_SIN90_SHIFT, TMC2262_MSLUTSTART, true}) +#define TMC2262_MSCNT_MASK 0x000003FF +#define TMC2262_MSCNT_SHIFT 0 +#define TMC2262_MSCNT_FIELD ((RegisterField) {TMC2262_MSCNT_MASK, TMC2262_MSCNT_SHIFT, TMC2262_MSCNT, false}) +#define TMC2262_CUR_B_MASK 0x000001FF +#define TMC2262_CUR_B_SHIFT 0 +#define TMC2262_CUR_B_FIELD ((RegisterField) {TMC2262_CUR_B_MASK, TMC2262_CUR_B_SHIFT, TMC2262_MSCURACT, true}) +#define TMC2262_CUR_A_MASK 0x01FF0000 +#define TMC2262_CUR_A_SHIFT 16 +#define TMC2262_CUR_A_FIELD ((RegisterField) {TMC2262_CUR_A_MASK, TMC2262_CUR_A_SHIFT, TMC2262_MSCURACT, true}) +#define TMC2262_TOFF_MASK 0x0000000F +#define TMC2262_TOFF_SHIFT 0 +#define TMC2262_TOFF_FIELD ((RegisterField) {TMC2262_TOFF_MASK, TMC2262_TOFF_SHIFT, TMC2262_CHOPCONF, false}) +#define TMC2262_HSTRT_TFD210_MASK 0x00000070 +#define TMC2262_HSTRT_TFD210_SHIFT 4 +#define TMC2262_HSTRT_TFD210_FIELD ((RegisterField) {TMC2262_HSTRT_TFD210_MASK, TMC2262_HSTRT_TFD210_SHIFT, TMC2262_CHOPCONF, false}) +#define TMC2262_HEND_OFFSET_MASK 0x00000780 +#define TMC2262_HEND_OFFSET_SHIFT 7 +#define TMC2262_HEND_OFFSET_FIELD ((RegisterField) {TMC2262_HEND_OFFSET_MASK, TMC2262_HEND_OFFSET_SHIFT, TMC2262_CHOPCONF, false}) +#define TMC2262_FD3_MASK 0x00000800 +#define TMC2262_FD3_SHIFT 11 +#define TMC2262_FD3_FIELD ((RegisterField) {TMC2262_FD3_MASK, TMC2262_FD3_SHIFT, TMC2262_CHOPCONF, false}) +#define TMC2262_DISFDCC_MASK 0x00001000 +#define TMC2262_DISFDCC_SHIFT 12 +#define TMC2262_DISFDCC_FIELD ((RegisterField) {TMC2262_DISFDCC_MASK, TMC2262_DISFDCC_SHIFT, TMC2262_CHOPCONF, false}) +#define TMC2262_CHM_MASK 0x00004000 +#define TMC2262_CHM_SHIFT 14 +#define TMC2262_CHM_FIELD ((RegisterField) {TMC2262_CHM_MASK, TMC2262_CHM_SHIFT, TMC2262_CHOPCONF, false}) +#define TMC2262_TBL_MASK 0x00018000 +#define TMC2262_TBL_SHIFT 15 +#define TMC2262_TBL_FIELD ((RegisterField) {TMC2262_TBL_MASK, TMC2262_TBL_SHIFT, TMC2262_CHOPCONF, false}) +#define TMC2262_TPFD_MASK 0x00F00000 +#define TMC2262_TPFD_SHIFT 20 +#define TMC2262_TPFD_FIELD ((RegisterField) {TMC2262_TPFD_MASK, TMC2262_TPFD_SHIFT, TMC2262_CHOPCONF, false}) +#define TMC2262_MRES_MASK 0x0F000000 +#define TMC2262_MRES_SHIFT 24 +#define TMC2262_MRES_FIELD ((RegisterField) {TMC2262_MRES_MASK, TMC2262_MRES_SHIFT, TMC2262_CHOPCONF, false}) +#define TMC2262_INTPOL_MASK 0x10000000 +#define TMC2262_INTPOL_SHIFT 28 +#define TMC2262_INTPOL_FIELD ((RegisterField) {TMC2262_INTPOL_MASK, TMC2262_INTPOL_SHIFT, TMC2262_CHOPCONF, false}) +#define TMC2262_DEDGE_MASK 0x20000000 +#define TMC2262_DEDGE_SHIFT 29 +#define TMC2262_DEDGE_FIELD ((RegisterField) {TMC2262_DEDGE_MASK, TMC2262_DEDGE_SHIFT, TMC2262_CHOPCONF, false}) +#define TMC2262_SEMIN_MASK 0x0000000F +#define TMC2262_SEMIN_SHIFT 0 +#define TMC2262_SEMIN_FIELD ((RegisterField) {TMC2262_SEMIN_MASK, TMC2262_SEMIN_SHIFT, TMC2262_COOLCONF, false}) +#define TMC2262_SEUP_MASK 0x00000060 +#define TMC2262_SEUP_SHIFT 5 +#define TMC2262_SEUP_FIELD ((RegisterField) {TMC2262_SEUP_MASK, TMC2262_SEUP_SHIFT, TMC2262_COOLCONF, false}) +#define TMC2262_SEMAX_MASK 0x00000F00 +#define TMC2262_SEMAX_SHIFT 8 +#define TMC2262_SEMAX_FIELD ((RegisterField) {TMC2262_SEMAX_MASK, TMC2262_SEMAX_SHIFT, TMC2262_COOLCONF, false}) +#define TMC2262_SEDN_MASK 0x00007000 +#define TMC2262_SEDN_SHIFT 12 +#define TMC2262_SEDN_FIELD ((RegisterField) {TMC2262_SEDN_MASK, TMC2262_SEDN_SHIFT, TMC2262_COOLCONF, false}) +#define TMC2262_SEIMIN_MASK 0x00008000 +#define TMC2262_SEIMIN_SHIFT 15 +#define TMC2262_SEIMIN_FIELD ((RegisterField) {TMC2262_SEIMIN_MASK, TMC2262_SEIMIN_SHIFT, TMC2262_COOLCONF, false}) +#define TMC2262_SGT_MASK 0x007F0000 +#define TMC2262_SGT_SHIFT 16 +#define TMC2262_SGT_FIELD ((RegisterField) {TMC2262_SGT_MASK, TMC2262_SGT_SHIFT, TMC2262_COOLCONF, true}) +#define TMC2262_THIGH_SG_OFF_MASK 0x00800000 +#define TMC2262_THIGH_SG_OFF_SHIFT 23 +#define TMC2262_THIGH_SG_OFF_FIELD ((RegisterField) {TMC2262_THIGH_SG_OFF_MASK, TMC2262_THIGH_SG_OFF_SHIFT, TMC2262_COOLCONF, false}) +#define TMC2262_SFILT_MASK 0x01000000 +#define TMC2262_SFILT_SHIFT 24 +#define TMC2262_SFILT_FIELD ((RegisterField) {TMC2262_SFILT_MASK, TMC2262_SFILT_SHIFT, TMC2262_COOLCONF, false}) +#define TMC2262_SG_RESULT_MASK 0x000003FF +#define TMC2262_SG_RESULT_SHIFT 0 +#define TMC2262_SG_RESULT_FIELD ((RegisterField) {TMC2262_SG_RESULT_MASK, TMC2262_SG_RESULT_SHIFT, TMC2262_DRV_STATUS, false}) +#define TMC2262_SEQ_STOPPED_MASK 0x00000400 +#define TMC2262_SEQ_STOPPED_SHIFT 10 +#define TMC2262_SEQ_STOPPED_FIELD ((RegisterField) {TMC2262_SEQ_STOPPED_MASK, TMC2262_SEQ_STOPPED_SHIFT, TMC2262_DRV_STATUS, false}) +#define TMC2262_OV_MASK 0x00000800 +#define TMC2262_OV_SHIFT 11 +#define TMC2262_OV_FIELD ((RegisterField) {TMC2262_OV_MASK, TMC2262_OV_SHIFT, TMC2262_DRV_STATUS, false}) +#define TMC2262_S2VSA_MASK 0x00001000 +#define TMC2262_S2VSA_SHIFT 12 +#define TMC2262_S2VSA_FIELD ((RegisterField) {TMC2262_S2VSA_MASK, TMC2262_S2VSA_SHIFT, TMC2262_DRV_STATUS, false}) +#define TMC2262_S2VSB_MASK 0x00002000 +#define TMC2262_S2VSB_SHIFT 13 +#define TMC2262_S2VSB_FIELD ((RegisterField) {TMC2262_S2VSB_MASK, TMC2262_S2VSB_SHIFT, TMC2262_DRV_STATUS, false}) +#define TMC2262_STEALTH_MASK 0x00004000 +#define TMC2262_STEALTH_SHIFT 14 +#define TMC2262_STEALTH_FIELD ((RegisterField) {TMC2262_STEALTH_MASK, TMC2262_STEALTH_SHIFT, TMC2262_DRV_STATUS, false}) +#define TMC2262_CS_ACTUAL_MASK 0x00FF0000 +#define TMC2262_CS_ACTUAL_SHIFT 16 +#define TMC2262_CS_ACTUAL_FIELD ((RegisterField) {TMC2262_CS_ACTUAL_MASK, TMC2262_CS_ACTUAL_SHIFT, TMC2262_DRV_STATUS, false}) +#define TMC2262_STALLGUARD_MASK 0x01000000 +#define TMC2262_STALLGUARD_SHIFT 24 +#define TMC2262_STALLGUARD_FIELD ((RegisterField) {TMC2262_STALLGUARD_MASK, TMC2262_STALLGUARD_SHIFT, TMC2262_DRV_STATUS, false}) +#define TMC2262_OT_MASK 0x02000000 +#define TMC2262_OT_SHIFT 25 +#define TMC2262_OT_FIELD ((RegisterField) {TMC2262_OT_MASK, TMC2262_OT_SHIFT, TMC2262_DRV_STATUS, false}) +#define TMC2262_OTPW_MASK 0x04000000 +#define TMC2262_OTPW_SHIFT 26 +#define TMC2262_OTPW_FIELD ((RegisterField) {TMC2262_OTPW_MASK, TMC2262_OTPW_SHIFT, TMC2262_DRV_STATUS, false}) +#define TMC2262_S2GA_MASK 0x08000000 +#define TMC2262_S2GA_SHIFT 27 +#define TMC2262_S2GA_FIELD ((RegisterField) {TMC2262_S2GA_MASK, TMC2262_S2GA_SHIFT, TMC2262_DRV_STATUS, false}) +#define TMC2262_S2GB_MASK 0x10000000 +#define TMC2262_S2GB_SHIFT 28 +#define TMC2262_S2GB_FIELD ((RegisterField) {TMC2262_S2GB_MASK, TMC2262_S2GB_SHIFT, TMC2262_DRV_STATUS, false}) +#define TMC2262_OLA_MASK 0x20000000 +#define TMC2262_OLA_SHIFT 29 +#define TMC2262_OLA_FIELD ((RegisterField) {TMC2262_OLA_MASK, TMC2262_OLA_SHIFT, TMC2262_DRV_STATUS, false}) +#define TMC2262_OLB_MASK 0x40000000 +#define TMC2262_OLB_SHIFT 30 +#define TMC2262_OLB_FIELD ((RegisterField) {TMC2262_OLB_MASK, TMC2262_OLB_SHIFT, TMC2262_DRV_STATUS, false}) +#define TMC2262_STST_MASK 0x80000000 +#define TMC2262_STST_SHIFT 31 +#define TMC2262_STST_FIELD ((RegisterField) {TMC2262_STST_MASK, TMC2262_STST_SHIFT, TMC2262_DRV_STATUS, false}) +#define TMC2262_PWM_FREQ_MASK 0x0000000F +#define TMC2262_PWM_FREQ_SHIFT 0 +#define TMC2262_PWM_FREQ_FIELD ((RegisterField) {TMC2262_PWM_FREQ_MASK, TMC2262_PWM_FREQ_SHIFT, TMC2262_PWMCONF, false}) +#define TMC2262_FREEWHEEL_MASK 0x00000030 +#define TMC2262_FREEWHEEL_SHIFT 4 +#define TMC2262_FREEWHEEL_FIELD ((RegisterField) {TMC2262_FREEWHEEL_MASK, TMC2262_FREEWHEEL_SHIFT, TMC2262_PWMCONF, false}) +#define TMC2262_OL_THRSH_MASK 0x000000C0 +#define TMC2262_OL_THRSH_SHIFT 6 +#define TMC2262_OL_THRSH_FIELD ((RegisterField) {TMC2262_OL_THRSH_MASK, TMC2262_OL_THRSH_SHIFT, TMC2262_PWMCONF, false}) +#define TMC2262_SD_ON_MEAS_LO_MASK 0x0000F000 +#define TMC2262_SD_ON_MEAS_LO_SHIFT 12 +#define TMC2262_SD_ON_MEAS_LO_FIELD ((RegisterField) {TMC2262_SD_ON_MEAS_LO_MASK, TMC2262_SD_ON_MEAS_LO_SHIFT, TMC2262_PWMCONF, false}) +#define TMC2262_SD_ON_MEAS_HI_MASK 0x000F0000 +#define TMC2262_SD_ON_MEAS_HI_SHIFT 16 +#define TMC2262_SD_ON_MEAS_HI_FIELD ((RegisterField) {TMC2262_SD_ON_MEAS_HI_MASK, TMC2262_SD_ON_MEAS_HI_SHIFT, TMC2262_PWMCONF, false}) + +#endif + diff --git a/firmware/lib/tmc/ic/TMC2262/registercall_hierarchy_flowchart_SPI.svg b/firmware/lib/tmc/ic/TMC2262/registercall_hierarchy_flowchart_SPI.svg new file mode 100755 index 0000000..cbad58f --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2262/registercall_hierarchy_flowchart_SPI.svg @@ -0,0 +1,3 @@ + + +

HAL

HAL

APP (Eval)

APP (Eval)

API

API
Read a register
  •  Call tmcXXXX_readRegister function
Read a register...
Returns the register read value
Returns the register read value
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
tmcXXXX.c
tmcXXXX.c
SPI.c
SPI.c
tmcXXXX_eval.c
tmcXXXX_eval.c

 Implementation of SPI_readWrite
  • Sends and receives bytes on the SPI bus
Implementation of SPI_readWrite...
Returns the raw reply data
Returns the raw reply data

Implementation of tmcXXXX_readWriteSPI
  • Sets the CSN pin to LOW
  • Takes the array of data to write
  • Calls hardware function SPI_readWrite
  • Upon completion of data transfer,
    sets CSN to 
    HIGH
Implementation of tmcXXXX_readWriteSPI...
Passes on the raw reply data to the API
Passes on the raw reply data to the API
Implementation of readRegisterSPI
  • Constructs the datagram
  • Calls HAL wrapper function 
Implementation of readRegisterSPI...
tmcXXXX_readWriteSPI
tmcXXXX_readWriteSPI
Parses the reply and returns the register value
Parses the reply and returns the register value
Implementation of tmcXXXX_readRegister 
  • Check which bus is active SPI/UART. (e.g. SPI)
  • Calls bus-specific function (e.g. readRegisterSPI)
 
Implementation of tmcXXXX_readRegister...
Returns the register read value
Returns the register read value
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC2262/uml-tmc-api.svg b/firmware/lib/tmc/ic/TMC2262/uml-tmc-api.svg new file mode 100755 index 0000000..5a5f8dd --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2262/uml-tmc-api.svg @@ -0,0 +1,3 @@ + + +

TMCXXXX_HW_Abstraction.h



TMCXXXX_HW_Abstraction.h...
// Constants
#define TMCXXXX_MOTORS              
                          
// Register definitions
#define TMCXXXX_GCONF        
                          ⋮
// Register fields definitions
#define TMCXXXX_GCONF_OTPW_FIELD
                     
// Constants...

TMCXXXX.h



TMCXXXX.h...
extern void tmcXXXX_readWriteSPI();
extern void tmcXXXX_readWriteUART();
extern TMCXXXXBusType tmcXXXX_getBusType();
extern uint8_t tmcXXXX_getNodeAddress();
                                  ⋮
tmcXXXX_readRegister();
tmcXXXX_writeRegister();
                                  ⋮
extern void tmcXXXX_readWriteSPI();...

TMCXXXX.c



TMCXXXX.c...
const uint8_t tmcCRCTable_Poly7Reflected[256] = {...};
int32_t tmcXXXX_readRegister(){
/* Call tmcXXXX_getBusType();
 * Based on bus type, call readRegisterSPI/UART() that
 * further calls tmcXXXX_readWriteSPI/UART();
 * For UART it also calls tmcXXXX_getNodeAddress();
                                           ⋮
}
                                           ⋮
const uint8_t tmcCRCTable_Poly7Reflected[256] = {.....
TMC-API
TMC-API

TMCXXXX_Simple_Rotation.h


TMCXXXX_Simple_Rotation.h...
void initAllMotors();
             ⋮
  
void initAllMotors()...

TMCXXXX_Simple_Rotation.c


TMCXXXX_Simple_Rotation.c...
void initAllMotors(){

// Configuring registers to enable motor drivers etc..
tmcXXXX_writeRegister();
                    ⋮
}
                    ⋮
void initAllMotors(){...
Examples
Examples
User Project
User Project

User_Project.h


User_Project.h

User_Project.c








User_Project.c...

void tmcXXXX_readWriteSPI(){
                           ⋮
}
void tmcXXXX_readWriteUART(){
                           ⋮
}
TMCXXXXBusType tmcXXXX_getBusType(){
                           ⋮
}
uint8_t tmcXXXX_getNodeAddress(){
                           ⋮
}

// User Code
                           ⋮
void tmcXXXX_readWriteSPI(){...
#include "TMCXXXX_HW_Abstraction.h"
#include "TMCXXXX.h"
#include "TMCXXXX_Simple_Rotation.h"
                                ⋮
TMCXXXXBusType bus = IC_BUS_SPI/UART;
uint8_t nodeAddress = <nodeAddress>;
                                ⋮
#include "TMCXXXX_HW_Abstraction.h"...
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC2300/README.md b/firmware/lib/tmc/ic/TMC2300/README.md new file mode 100755 index 0000000..4859bb6 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2300/README.md @@ -0,0 +1,51 @@ +# TMC2300 + + +## How to use + +To access the TMC2300's registers, the TMC-API offers two functions: **tmc2300_readRegister** and **tmc2300_writeRegister**. +Each of these functions takes in an **icID**, which is used to identify the IC when multiple ICs are connected. This identifier is passed down to the callback functions (see How to Integrate). + +## How to integrate: overview + +1. Include all the files of the TMC-API/ic/tmc/TMC2300 folder into the custom project. +2. Include the TMC2300.h file in the custom source code. +3. Implement the necessary callback functions (see below). +4. (optional): Take a look at the Examples subfolder for ready-made examples of the TMC-API usage. + +## Accessing the TMC2300 via UART +The following diagram depicts how to access the TMC2300 via UART using the TMC-API. + +![screenshot](registercall_hierarchy_flowchart_UART.svg) + +The description of the functions, in the above flowchart, are as follows: +- The functions tmc2300_readRegister and tmc2300_writeRegister are used to read and write the registers respectively. These functions check the current active bus and calls the bus-specific function i.e readRegisterUART or writeRegisterUART. +- These bus specific functions constructs the datagram and further calls the bus specific callback 'tmcXXXX_readWriteUART. +- This callback function further calls the hardware specific read/write function for UART and needs to be implemented externally. + +### How to integrate: Callback functions +To communicate with TMC2300 IC, the TMC-API library needs to know which bus UART it shall use. For that, the callback function **'tmc2300_getBusType()'** needs to be implemented. +Additionally, implement the following callback functions to access the chip via UART: +1. **tmc2300_readWriteUART()**, which is a HAL wrapper function that provides the necessary hardware access. +2. **tmc2300_getNodeAddress()**, that returns the node/slave address. Node address could be set in NODECONF (0x3) register and the address could be incremented as defined by AD0, AD1 and AD2. (Node address + ADx) must be less than 255. For further details please consult the datasheet of TMC2300. + +### Sharing the CRC table with other TMC-API chips +The TMC2300 UART protocol uses an 8 bit CRC. For calculating this, a table-based algorithm is used. This table (tmcCRCTable_Poly7Reflected[256]) is 256 bytes big and identical across multiple different Trinamic chips (i.e. TMC2209). +If multiple Trinamic chips are being used in the same project, avoiding redundant copies of this table could save memory. It is possible to substitute this CRC table with another CRC table. + +### Option to use the cache logic for Write-Only registers +The chip features write-only registers that are unable to be read, necessitating the creation of a shadow copy to cache their contents. This copy is automatically updated whenever data is written to these registers. This cache logic could be enabled by setting the macro **TMC2300_CACHE** to **'1'** or disabled by setting to **'0'** respectively. If this feature is enabled then there comes another option to use **tmc2300_cache** function, which is already implemeted in the API, by defining **TMC2300_ENABLE_TMC_CACHE** macro to **'1** or one can implement their own function. The function **tmc2300_cache** works for both reading from and writing to the shadow array. It first checks whether the register has write-only access and data needs to be read from the hadow copy. On the basis of that, it returns **true** or **false**. The shadowRegisters on the premade cache implementation need to be one per chip. **TMC2300_IC_CACHE_COUNT** is set to '1' y default and is user-overwritable. If multiple chips are being used in the same project, increment its value to the number of chips connected. + +## Further info +### Dependency graph for the ICs with new register R/W mechanism +This graph illustrates the relationships between files within the TMC-API library, highlighting dependencies and identifying the files that are essential for integrating the library into the custom projects. + +![screenshot](uml-tmc-api.svg) + +### Example usage: TMC-Evalsystem +**For a reference usage of the TMC-API**, visit the [TMC-Evalsystem](https://github.com/analogdevicesinc/TMC-EvalSystem) + +## Migration status +The TMC2300 has been reworked to the access system described above. For more infos on the status of this and other ICs, check out the [migration page](https://github.com/analogdevicesinc/TMC-API/issues/53). + + diff --git a/firmware/lib/tmc/ic/TMC2300/TMC2300.c b/firmware/lib/tmc/ic/TMC2300/TMC2300.c new file mode 100755 index 0000000..64b8c5b --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2300/TMC2300.c @@ -0,0 +1,250 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#include "TMC2300.h" + +#ifdef TMC_API_EXTERNAL_CRC_TABLE +extern const uint8_t tmcCRCTable_Poly7Reflected[256]; +#else +const uint8_t tmcCRCTable_Poly7Reflected[256] = { + 0x00, 0x91, 0xE3, 0x72, 0x07, 0x96, 0xE4, 0x75, 0x0E, 0x9F, 0xED, 0x7C, 0x09, 0x98, 0xEA, 0x7B, + 0x1C, 0x8D, 0xFF, 0x6E, 0x1B, 0x8A, 0xF8, 0x69, 0x12, 0x83, 0xF1, 0x60, 0x15, 0x84, 0xF6, 0x67, + 0x38, 0xA9, 0xDB, 0x4A, 0x3F, 0xAE, 0xDC, 0x4D, 0x36, 0xA7, 0xD5, 0x44, 0x31, 0xA0, 0xD2, 0x43, + 0x24, 0xB5, 0xC7, 0x56, 0x23, 0xB2, 0xC0, 0x51, 0x2A, 0xBB, 0xC9, 0x58, 0x2D, 0xBC, 0xCE, 0x5F, + 0x70, 0xE1, 0x93, 0x02, 0x77, 0xE6, 0x94, 0x05, 0x7E, 0xEF, 0x9D, 0x0C, 0x79, 0xE8, 0x9A, 0x0B, + 0x6C, 0xFD, 0x8F, 0x1E, 0x6B, 0xFA, 0x88, 0x19, 0x62, 0xF3, 0x81, 0x10, 0x65, 0xF4, 0x86, 0x17, + 0x48, 0xD9, 0xAB, 0x3A, 0x4F, 0xDE, 0xAC, 0x3D, 0x46, 0xD7, 0xA5, 0x34, 0x41, 0xD0, 0xA2, 0x33, + 0x54, 0xC5, 0xB7, 0x26, 0x53, 0xC2, 0xB0, 0x21, 0x5A, 0xCB, 0xB9, 0x28, 0x5D, 0xCC, 0xBE, 0x2F, + 0xE0, 0x71, 0x03, 0x92, 0xE7, 0x76, 0x04, 0x95, 0xEE, 0x7F, 0x0D, 0x9C, 0xE9, 0x78, 0x0A, 0x9B, + 0xFC, 0x6D, 0x1F, 0x8E, 0xFB, 0x6A, 0x18, 0x89, 0xF2, 0x63, 0x11, 0x80, 0xF5, 0x64, 0x16, 0x87, + 0xD8, 0x49, 0x3B, 0xAA, 0xDF, 0x4E, 0x3C, 0xAD, 0xD6, 0x47, 0x35, 0xA4, 0xD1, 0x40, 0x32, 0xA3, + 0xC4, 0x55, 0x27, 0xB6, 0xC3, 0x52, 0x20, 0xB1, 0xCA, 0x5B, 0x29, 0xB8, 0xCD, 0x5C, 0x2E, 0xBF, + 0x90, 0x01, 0x73, 0xE2, 0x97, 0x06, 0x74, 0xE5, 0x9E, 0x0F, 0x7D, 0xEC, 0x99, 0x08, 0x7A, 0xEB, + 0x8C, 0x1D, 0x6F, 0xFE, 0x8B, 0x1A, 0x68, 0xF9, 0x82, 0x13, 0x61, 0xF0, 0x85, 0x14, 0x66, 0xF7, + 0xA8, 0x39, 0x4B, 0xDA, 0xAF, 0x3E, 0x4C, 0xDD, 0xA6, 0x37, 0x45, 0xD4, 0xA1, 0x30, 0x42, 0xD3, + 0xB4, 0x25, 0x57, 0xC6, 0xB3, 0x22, 0x50, 0xC1, 0xBA, 0x2B, 0x59, 0xC8, 0xBD, 0x2C, 0x5E, 0xCF, +}; +#endif +/**************************************************************** Cache Implementation *************************************************************************/ + +#if TMC2300_CACHE == 0 +static inline bool tmc2300_cache(uint16_t icID, TMC2300CacheOp operation, uint8_t address, uint32_t *value) +{ + UNUSED(icID); + UNUSED(address); + UNUSED(operation); + return false; +} +#else +#if TMC2300_ENABLE_TMC_CACHE == 1 + +uint8_t tmc2300_dirtyBits[TMC2300_IC_CACHE_COUNT][TMC2300_REGISTER_COUNT/8]= {0}; +int32_t tmc2300_shadowRegister[TMC2300_IC_CACHE_COUNT][TMC2300_REGISTER_COUNT]; + +void tmc2300_setDirtyBit(uint16_t icID, uint8_t index, bool value) +{ + if(index >= TMC2300_REGISTER_COUNT) + return; + + uint8_t *tmp = &tmc2300_dirtyBits[icID][index / 8]; + uint8_t shift = (index % 8); + uint8_t mask = 1 << shift; + *tmp = (((*tmp) & (~(mask))) | (((value) << (shift)) & (mask))); +} + +bool tmc2300_getDirtyBit(uint16_t icID, uint8_t index) +{ + if(index >= TMC2300_REGISTER_COUNT) + return false; + + uint8_t *tmp = &tmc2300_dirtyBits[icID][index / 8]; + uint8_t shift = (index % 8); + return ((*tmp) >> shift) & 1; +} +/* + * This function is used to cache the value written to the Write-Only registers in the form of shadow array. + * The shadow copy is then used to read these kinds of registers. + */ + +bool tmc2300_cache(uint16_t icID, TMC2300CacheOp operation, uint8_t address, uint32_t *value) +{ + if (operation == TMC2300_CACHE_READ) + { + // Check if the value should come from cache + + // Only supported chips have a cache + if (icID >= TMC2300_IC_CACHE_COUNT) + return false; + + // Only non-readable registers care about caching + // Note: This could also be used to cache i.e. RW config registers to reduce bus accesses + if (TMC2300_IS_READABLE(tmc2300_registerAccess[address])) + return false; + + // Grab the value from the cache + *value = tmc2300_shadowRegister[icID][address]; + return true; + } + else if (operation == TMC2300_CACHE_WRITE || operation == TMC2300_CACHE_FILL_DEFAULT) + { + // Fill the cache + + // only supported chips have a cache + if (icID >= TMC2300_IC_CACHE_COUNT) + return false; + + // Write to the shadow register. + tmc2300_shadowRegister[icID][address] = *value; + // For write operations, mark the register dirty + if (operation == TMC2300_CACHE_WRITE) + { + tmc2300_setDirtyBit(icID, address, true); + } + + return true; + } + return false; +} + +void tmc2300_initCache() +{ + // Check if we have constants defined + if(ARRAY_SIZE(tmc2300_RegisterConstants) == 0) + return; + + size_t i, j, id; + + for(i = 0, j = 0; i < TMC2300_REGISTER_COUNT; i++) + { + // We only need to worry about hardware preset, write-only registers + // that have not yet been written (no dirty bit) here. + if(tmc2300_registerAccess[i] != TMC2300_ACCESS_W_PRESET && tmc2300_registerAccess[i] != TMC2300_ACCESS_RW_PRESET) + continue; + + // Search the constant list for the current address. With the constant + // list being sorted in ascended order, we can walk through the list + // until the entry with an address equal or greater than i + while(j < ARRAY_SIZE(tmc2300_RegisterConstants) && (tmc2300_RegisterConstants[j].address < i)) + j++; + + // Abort when we reach the end of the constant list + if (j == ARRAY_SIZE(tmc2300_RegisterConstants)) + break; + + // If we have an entry for our current address, write the constant + if(tmc2300_RegisterConstants[j].address == i) + { + for (id = 0; id < TMC2300_IC_CACHE_COUNT; id++) + { + uint32_t temp = tmc2300_RegisterConstants[j].value; + tmc2300_cache(id, TMC2300_CACHE_FILL_DEFAULT, i, &temp); + } + } + } +} +#else +// User must implement their own cache +extern bool tmc2300_cache(uint16_t icID, TMC2300CacheOp operation, uint8_t address, uint32_t *value); +#endif +#endif + +/************************************************************* read / write Implementation *********************************************************************/ + +static int32_t readRegisterUART(uint16_t icID, uint8_t registerAddress); +static void writeRegisterUART(uint16_t icID, uint8_t registerAddress, int32_t value); +static uint8_t CRC8(uint8_t *data, uint32_t bytes); + + +int32_t tmc2300_readRegister(uint16_t icID, uint8_t address) +{ + return readRegisterUART(icID, address); +} +void tmc2300_writeRegister(uint16_t icID, uint8_t address, int32_t value) +{ + writeRegisterUART(icID, address, value); +} + +int32_t readRegisterUART(uint16_t icID, uint8_t registerAddress) +{ + uint32_t value; + registerAddress = registerAddress & TMC2300_ADDRESS_MASK; + + + // Read from cache for registers with write-only access + if (tmc2300_cache(icID, TMC2300_CACHE_READ, registerAddress, &value)) + return value; + + uint8_t data[8] = { 0 }; + + + data[0] = 0x05; + data[1] = tmc2300_getNodeAddress(icID); + data[2] = registerAddress; + data[3] = CRC8(data, 3); + + // When the chip is in standby or use the shadow register content instead + if (!tmc2300_readWriteUART(icID, &data[0], 4, 8)) + return tmc2300_shadowRegister[0][registerAddress]; + + // Byte 0: Sync nibble correct? + if (data[0] != 0x05) + return 0; + + // Byte 1: Master address correct? + if (data[1] != 0xFF) + return 0; + + // Byte 2: Address correct? + if (data[2] != registerAddress) + return 0; + + // Byte 7: CRC correct? + if (data[7] != CRC8(data, 7)) + return 0; + + return ((uint32_t)data[3] << 24) | ((uint32_t)data[4] << 16) | (data[5] << 8) | data[6]; +} + +void writeRegisterUART(uint16_t icID, uint8_t registerAddress, int32_t value) +{ + uint8_t data[8]; + + data[0] = 0x05; + data[1] = tmc2300_getNodeAddress(icID); + data[2] = registerAddress | TMC2300_WRITE_BIT; + data[3] = (value >> 24) & 0xFF; + data[4] = (value >> 16) & 0xFF; + data[5] = (value >> 8 ) & 0xFF; + data[6] = (value ) & 0xFF; + data[7] = CRC8(data, 7); + + tmc2300_readWriteUART(icID, &data[0], 8, 0); + + //Cache the registers with write-only access + tmc2300_cache(icID, TMC2300_CACHE_WRITE, registerAddress, (uint32_t *)&value); + +} + +static uint8_t CRC8(uint8_t *data, uint32_t bytes) +{ + uint8_t result = 0; + + while(bytes--) + result = tmcCRCTable_Poly7Reflected[result ^ *data++]; + + // Flip the result around + // swap odd and even bits + result = ((result >> 1) & 0x55) | ((result & 0x55) << 1); + // swap consecutive pairs + result = ((result >> 2) & 0x33) | ((result & 0x33) << 2); + // swap nibbles ... + result = ((result >> 4) & 0x0F) | ((result & 0x0F) << 4); + + return result; +} diff --git a/firmware/lib/tmc/ic/TMC2300/TMC2300.h b/firmware/lib/tmc/ic/TMC2300/TMC2300.h new file mode 100755 index 0000000..5a9c551 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2300/TMC2300.h @@ -0,0 +1,209 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#ifndef TMC_IC_TMC2300_H_ +#define TMC_IC_TMC2300_H_ + +#include +#include +#include +#include "TMC2300_HW_Abstraction.h" + + +/******************************************************************************* + * API Configuration Defines + * These control optional features of the TMC-API implementation. + * These can be commented in/out here or defined from the build system. + *******************************************************************************/ + +// Uncomment if you want to save space..... +// and put the table into your own .c file +//#define TMC_API_EXTERNAL_CRC_TABLE 1 + +// To enable the cache mechanism in order to keep the copy of all registers, set TMC2300_CACHE to '1'. +// With this mechanism the value of write-only registers could be read from their shadow copies. +#ifndef TMC2300_CACHE +#define TMC2300_CACHE 1 +//#define TMC2300_CACHE 0 +#endif + +// To use the caching mechanism already implemented by the TMC-API, set TMC2300_ENABLE_TMC_CACHE to '1'. +// Set TMC2300_ENABLE_TMC_CACHE to '0' if one wants to have their own cache implementation. +#ifndef TMC2300_ENABLE_TMC_CACHE +#define TMC2300_ENABLE_TMC_CACHE 1 +//#define TMC2300_ENABLE_TMC_CACHE 0 +#endif + +/******************************************************************************/ + + +/************************************************************* read / write Implementation *********************************************************************/ + +// => TMC-API wrapper +extern bool tmc2300_readWriteUART(uint16_t icID, uint8_t *data, size_t writeLength, size_t readLength); +extern uint8_t tmc2300_getNodeAddress(uint16_t icID); +// => TMC-API wrapper + +int32_t tmc2300_readRegister(uint16_t icID, uint8_t address); +void tmc2300_writeRegister(uint16_t icID, uint8_t address, int32_t value); + + + +typedef struct +{ + uint32_t mask; + uint8_t shift; + uint8_t address; + bool isSigned; +} RegisterField; + +static inline uint32_t tmc2300_fieldExtract(uint32_t data, RegisterField field) +{ + uint32_t value = (data & field.mask) >> field.shift; + + if (field.isSigned) + { + // Apply signedness conversion + uint32_t baseMask = field.mask >> field.shift; + uint32_t signMask = baseMask & (~baseMask >> 1); + value = (value ^ signMask) - signMask; + } + + return value; +} + +static inline uint32_t tmc2300_fieldRead(uint16_t icID, RegisterField field) +{ + uint32_t value = tmc2300_readRegister(icID, field.address); + + return tmc2300_fieldExtract(value, field); +} + +static inline uint32_t tmc2300_fieldUpdate(uint32_t data, RegisterField field, uint32_t value) +{ + return (data & (~field.mask)) | ((value << field.shift) & field.mask); +} + +static inline void tmc2300_fieldWrite(uint16_t icID, RegisterField field, uint32_t value) +{ + uint32_t regValue = tmc2300_readRegister(icID, field.address); + + regValue = tmc2300_fieldUpdate(regValue, field, value); + + tmc2300_writeRegister(icID, field.address, regValue); +} +/**************************************************************** Cache Implementation *************************************************************************/ +#if TMC2300_CACHE == 1 +#ifdef TMC2300_ENABLE_TMC_CACHE + + +// By default, support one IC in the cache +#ifndef TMC2300_IC_CACHE_COUNT +#define TMC2300_IC_CACHE_COUNT 1 +#endif + +typedef enum { + TMC2300_CACHE_READ, + TMC2300_CACHE_WRITE, + // Special operation: Put content into the cache without marking the entry as dirty. + // Only used to initialize the cache with hardware defaults. This will allow reading + // from write-only registers that have a value inside them on reset. When using this + // operation, a restore will *not* rewrite that filled register! + TMC2300_CACHE_FILL_DEFAULT, +} TMC2300CacheOp; + +typedef struct{ + uint8_t address; + uint32_t value; +} TMC2300RegisterConstants; + +#define TMC2300_ACCESS_DIRTY 0x08 // Register has been written since reset -> shadow register is valid for restore +#define TMC2300_ACCESS_READ 0x01 +#define TMC2300_ACCESS_Write 0x02 +#define TMC2300_ACCESS_W_PRESET 0x42 +#define TMC2300_ACCESS_RW_PRESET 0x43 +#define TMC2300_IS_READABLE(x) ((x) & TMC2300_ACCESS_READ) +#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) + +// Helper define: +// Most register permission arrays are initialized with 128 values. +// In those fields its quite hard to have an easy overview of available +// registers. For that, ____ is defined to 0, since 4 underscores are +// very easy to distinguish from the 2-digit hexadecimal values. +// This way, the used registers (permission != ACCESS_NONE) are easily spotted +// amongst unused (permission == ACCESS_NONE) registers. +#ifndef ____ + #define ____ 0x00 +#endif + +// Helper define: +// Default reset values are not used if the corresponding register has a +// hardware preset. Since this is not directly visible in the default +// register reset values array, N_A is used as an indicator for a preset +// value, where any value will be ignored anyways (N_A: not available). +#ifndef N_A + #define N_A 0x00 +#endif + +// Register access permissions: +// 0x00: none (reserved) +// 0x01: read +// 0x02: write +// 0x23: read/write, flag register (write to clear) +// 0x42: write, has hardware presets on reset +// 0x43: read/write, has hardware presets on reset +static const uint8_t tmc2300_registerAccess[TMC2300_REGISTER_COUNT] = +{ + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0x43, 0x23, 0x01, 0x02, ____, ____, 0x01, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x00 - 0x0F + 0x42, 0x42, 0x01, ____, 0x02, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x10 - 0x1F + ____, ____, 0x02, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x20 - 0x2F + ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x30 - 0x3F + 0x02, 0x01, 0x02, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x40 - 0x4F + ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x50 - 0x5F + ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, 0x01, ____, 0x43, ____, ____, 0x01, // 0x60 - 0x6F + 0x43, 0x01, 0x01, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____ // 0x70 - 0x7F +}; + +static const int32_t tmc2300_sampleRegisterPreset[TMC2300_REGISTER_COUNT] = +{ + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + N_A, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x00 - 0x0F + N_A, N_A, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x10 - 0x1F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x20 - 0x2F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x30 - 0x3F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x40 - 0x4F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x50 - 0x5F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, N_A, 0, 0, 0, // 0x60 - 0x6F + N_A, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // 0x70 - 0x7F +}; + +// Register constants. These are required for 0x42 registers, since we do not have +// any way to find out the content. For 0x43 registers, it is not necessary to +// load the constant values this way, but this allows users to directly see the +// contents while still in standby. +static const TMC2300RegisterConstants tmc2300_RegisterConstants[] = +{ // Use ascending addresses! + { 0x00, 0x00000040 }, // GCONF + { 0x10, 0x00010402 }, // IHOLD_IRUN + { 0x11, 0x00000014 }, // TPOWERDOWN + { 0x6C, 0x13008001 }, // CHOPCONF + { 0x70, 0xC40D1024 }, // PWMCONF +}; + +extern uint8_t tmc2300_dirtyBits[TMC2300_IC_CACHE_COUNT][TMC2300_REGISTER_COUNT/8]; +extern int32_t tmc2300_shadowRegister[TMC2300_IC_CACHE_COUNT][TMC2300_REGISTER_COUNT]; +bool tmc2300_cache(uint16_t icID, TMC2300CacheOp operation, uint8_t address, uint32_t *value); +void tmc2300_initCache(void); +void tmc2300_setDirtyBit(uint16_t icID, uint8_t index, bool value); +bool tmc2300_getDirtyBit(uint16_t icID, uint8_t index); +#endif +#endif +/***************************************************************************************************************************************************/ +#endif /* TMC_IC_TMC2300_H_ */ diff --git a/firmware/lib/tmc/ic/TMC2300/TMC2300_HW_Abstraction.h b/firmware/lib/tmc/ic/TMC2300/TMC2300_HW_Abstraction.h new file mode 100755 index 0000000..1acb484 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2300/TMC2300_HW_Abstraction.h @@ -0,0 +1,275 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + +#ifndef TMC2300_HW_ABSTRACTION +#define TMC2300_HW_ABSTRACTION + + +// Constants +#define TMC2300_MOTORS 1 +#define TMC2300_REGISTER_COUNT 128 +#define TMC2300_WRITE_BIT 0x80 +#define TMC2300_ADDRESS_MASK 0x7F +#define TMC2300_MAX_VELOCITY (int32_t) 2147483647 +#define TMC2300_MAX_ACCELERATION (uint32_t) 4294967295uL + +// Registers +#define TMC2300_GCONF 0x00 +#define TMC2300_GSTAT 0x01 +#define TMC2300_IFCNT 0x02 +#define TMC2300_SLAVECONF 0x03 +#define TMC2300_IOIN 0x06 + +#define TMC2300_IHOLD_IRUN 0x10 +#define TMC2300_TPOWERDOWN 0x11 +#define TMC2300_TSTEP 0x12 + +#define TMC2300_TCOOLTHRS 0x14 + +#define TMC2300_VACTUAL 0x22 +#define TMC2300_XDIRECT 0x22 + +#define TMC2300_SGTHRS 0x40 +#define TMC2300_SG_VALUE 0x41 +#define TMC2300_COOLCONF 0x42 + +#define TMC2300_MSCNT 0x6A +#define TMC2300_CHOPCONF 0x6C +#define TMC2300_DRVSTATUS 0x6F +#define TMC2300_PWMCONF 0x70 +#define TMC2300_PWM_SCALE 0x71 +#define TMC2300_PWMAUTO 0x72 + + +// Register fields (manually add) +#define TMC2300_EN_SPREADCYCLE_MASK 0x04 // GCONF // par_mode (Reset default=0) +#define TMC2300_EN_SPREADCYCLE_SHIFT 2 // par_mode (Reset default=0) +#define TMC2300_EN_SPREADCYCLE_FIELD ((RegisterField) {TMC2300_EN_SPREADCYCLE_MASK, TMC2300_EN_SPREADCYCLE_SHIFT, TMC2300_GCONF, false}) + +// Register fields +#define TMC2300__MASK 0x00000001 +#define TMC2300__SHIFT 0 +#define TMC2300__FIELD ((RegisterField) {TMC2300__MASK, TMC2300__SHIFT, TMC2300_GCONF, false}) +#define TMC2300_EXTCAP_MASK 0x00000002 +#define TMC2300_EXTCAP_SHIFT 1 +#define TMC2300_EXTCAP_FIELD ((RegisterField) {TMC2300_EXTCAP_MASK, TMC2300_EXTCAP_SHIFT, TMC2300_GCONF, false}) +#define TMC2300_SHAFT_MASK 0x00000008 +#define TMC2300_SHAFT_SHIFT 3 +#define TMC2300_SHAFT_FIELD ((RegisterField) {TMC2300_SHAFT_MASK, TMC2300_SHAFT_SHIFT, TMC2300_GCONF, false}) +#define TMC2300_DIAG_INDEX_MASK 0x00000010 +#define TMC2300_DIAG_INDEX_SHIFT 4 +#define TMC2300_DIAG_INDEX_FIELD ((RegisterField) {TMC2300_DIAG_INDEX_MASK, TMC2300_DIAG_INDEX_SHIFT, TMC2300_GCONF, false}) +#define TMC2300_DIAG_STEP_MASK 0x00000020 +#define TMC2300_DIAG_STEP_SHIFT 5 +#define TMC2300_DIAG_STEP_FIELD ((RegisterField) {TMC2300_DIAG_STEP_MASK, TMC2300_DIAG_STEP_SHIFT, TMC2300_GCONF, false}) +#define TMC2300_MULTISTEP_FILT_MASK 0x00000040 +#define TMC2300_MULTISTEP_FILT_SHIFT 6 +#define TMC2300_MULTISTEP_FILT_FIELD ((RegisterField) {TMC2300_MULTISTEP_FILT_MASK, TMC2300_MULTISTEP_FILT_SHIFT, TMC2300_GCONF, false}) +#define TMC2300_TEST_MODE_MASK 0x00000080 +#define TMC2300_TEST_MODE_SHIFT 7 +#define TMC2300_TEST_MODE_FIELD ((RegisterField) {TMC2300_TEST_MODE_MASK, TMC2300_TEST_MODE_SHIFT, TMC2300_GCONF, false}) +#define TMC2300_RESET_MASK 0x00000001 +#define TMC2300_RESET_SHIFT 0 +#define TMC2300_RESET_FIELD ((RegisterField) {TMC2300_RESET_MASK, TMC2300_RESET_SHIFT, TMC2300_GSTAT, false}) +#define TMC2300_DRV_ERR_MASK 0x00000002 +#define TMC2300_DRV_ERR_SHIFT 1 +#define TMC2300_DRV_ERR_FIELD ((RegisterField) {TMC2300_DRV_ERR_MASK, TMC2300_DRV_ERR_SHIFT, TMC2300_GSTAT, false}) +#define TMC2300_U3V5_MASK 0x00000004 +#define TMC2300_U3V5_SHIFT 2 +#define TMC2300_U3V5_FIELD ((RegisterField) {TMC2300_U3V5_MASK, TMC2300_U3V5_SHIFT, TMC2300_GSTAT, false}) +#define TMC2300_IFCNT_MASK 0x000000FF +#define TMC2300_IFCNT_SHIFT 0 +#define TMC2300_IFCNT_FIELD ((RegisterField) {TMC2300_IFCNT_MASK, TMC2300_IFCNT_SHIFT, TMC2300_IFCNT, false}) +#define TMC2300_SLAVECONF_MASK 0x00000F00 +#define TMC2300_SLAVECONF_SHIFT 8 +#define TMC2300_SLAVECONF_FIELD ((RegisterField) {TMC2300_SLAVECONF_MASK, TMC2300_SLAVECONF_SHIFT, TMC2300_SLAVECONF, false}) +#define TMC2300_EN_MASK 0x00000001 +#define TMC2300_EN_SHIFT 0 +#define TMC2300_EN_FIELD ((RegisterField) {TMC2300_EN_MASK, TMC2300_EN_SHIFT, TMC2300_IOIN, false}) +#define TMC2300_NSTDBY_MASK 0x00000002 +#define TMC2300_NSTDBY_SHIFT 1 +#define TMC2300_NSTDBY_FIELD ((RegisterField) {TMC2300_NSTDBY_MASK, TMC2300_NSTDBY_SHIFT, TMC2300_IOIN, false}) +#define TMC2300_MS1_MASK 0x00000004 +#define TMC2300_MS1_SHIFT 2 +#define TMC2300_MS1_FIELD ((RegisterField) {TMC2300_MS1_MASK, TMC2300_MS1_SHIFT, TMC2300_IOIN, false}) +#define TMC2300_MS2_MASK 0x00000008 +#define TMC2300_MS2_SHIFT 3 +#define TMC2300_MS2_FIELD ((RegisterField) {TMC2300_MS2_MASK, TMC2300_MS2_SHIFT, TMC2300_IOIN, false}) +#define TMC2300_DIAG_MASK 0x00000010 +#define TMC2300_DIAG_SHIFT 4 +#define TMC2300_DIAG_FIELD ((RegisterField) {TMC2300_DIAG_MASK, TMC2300_DIAG_SHIFT, TMC2300_IOIN, false}) +#define TMC2300_STEPPER_CLK_INPUT_MASK 0x00000020 +#define TMC2300_STEPPER_CLK_INPUT_SHIFT 5 +#define TMC2300_STEPPER_CLK_INPUT_FIELD ((RegisterField) {TMC2300_STEPPER_CLK_INPUT_MASK, TMC2300_STEPPER_CLK_INPUT_SHIFT, TMC2300_IOIN, false}) +#define TMC2300_PDN_UART_MASK 0x00000040 +#define TMC2300_PDN_UART_SHIFT 6 +#define TMC2300_PDN_UART_FIELD ((RegisterField) {TMC2300_PDN_UART_MASK, TMC2300_PDN_UART_SHIFT, TMC2300_IOIN, false}) +#define TMC2300_MODE_INPUT_MASK 0x00000080 +#define TMC2300_MODE_INPUT_SHIFT 7 +#define TMC2300_MODE_INPUT_FIELD ((RegisterField) {TMC2300_MODE_INPUT_MASK, TMC2300_MODE_INPUT_SHIFT, TMC2300_IOIN, false}) +#define TMC2300_STEP_MASK 0x00000100 +#define TMC2300_STEP_SHIFT 8 +#define TMC2300_STEP_FIELD ((RegisterField) {TMC2300_STEP_MASK, TMC2300_STEP_SHIFT, TMC2300_IOIN, false}) +#define TMC2300_DIR_MASK 0x00000200 +#define TMC2300_DIR_SHIFT 9 +#define TMC2300_DIR_FIELD ((RegisterField) {TMC2300_DIR_MASK, TMC2300_DIR_SHIFT, TMC2300_IOIN, false}) +#define TMC2300_COMP_A1A2_MASK 0x00000400 +#define TMC2300_COMP_A1A2_SHIFT 10 +#define TMC2300_COMP_A1A2_FIELD ((RegisterField) {TMC2300_COMP_A1A2_MASK, TMC2300_COMP_A1A2_SHIFT, TMC2300_IOIN, false}) +#define TMC2300_COMP_B1B2_MASK 0x00000800 +#define TMC2300_COMP_B1B2_SHIFT 11 +#define TMC2300_COMP_B1B2_FIELD ((RegisterField) {TMC2300_COMP_B1B2_MASK, TMC2300_COMP_B1B2_SHIFT, TMC2300_IOIN, false}) +#define TMC2300_VERSION_MASK 0xFF000000 +#define TMC2300_VERSION_SHIFT 24 +#define TMC2300_VERSION_FIELD ((RegisterField) {TMC2300_VERSION_MASK, TMC2300_VERSION_SHIFT, TMC2300_IOIN, false}) +#define TMC2300_IHOLD_MASK 0x0000001F +#define TMC2300_IHOLD_SHIFT 0 +#define TMC2300_IHOLD_FIELD ((RegisterField) {TMC2300_IHOLD_MASK, TMC2300_IHOLD_SHIFT, TMC2300_IHOLD_IRUN, false}) +#define TMC2300_IRUN_MASK 0x00001F00 +#define TMC2300_IRUN_SHIFT 8 +#define TMC2300_IRUN_FIELD ((RegisterField) {TMC2300_IRUN_MASK, TMC2300_IRUN_SHIFT, TMC2300_IHOLD_IRUN, false}) +#define TMC2300_IHOLDDELAY_MASK 0x000F0000 +#define TMC2300_IHOLDDELAY_SHIFT 16 +#define TMC2300_IHOLDDELAY_FIELD ((RegisterField) {TMC2300_IHOLDDELAY_MASK, TMC2300_IHOLDDELAY_SHIFT, TMC2300_IHOLD_IRUN, false}) +#define TMC2300_TPOWERDOWN_MASK 0x000000FF +#define TMC2300_TPOWERDOWN_SHIFT 0 +#define TMC2300_TPOWERDOWN_FIELD ((RegisterField) {TMC2300_TPOWERDOWN_MASK, TMC2300_TPOWERDOWN_SHIFT, TMC2300_TPOWERDOWN, false}) +#define TMC2300_TSTEP_MASK 0x000FFFFF +#define TMC2300_TSTEP_SHIFT 0 +#define TMC2300_TSTEP_FIELD ((RegisterField) {TMC2300_TSTEP_MASK, TMC2300_TSTEP_SHIFT, TMC2300_TSTEP, false}) +#define TMC2300_TCOOLTHRS_MASK 0xFFFFFFFF +#define TMC2300_TCOOLTHRS_SHIFT 0 +#define TMC2300_TCOOLTHRS_FIELD ((RegisterField) {TMC2300_TCOOLTHRS_MASK, TMC2300_TCOOLTHRS_SHIFT, TMC2300_TCOOLTHRS, true}) +#define TMC2300_VACTUAL_MASK 0x00FFFFFF +#define TMC2300_VACTUAL_SHIFT 0 +#define TMC2300_VACTUAL_FIELD ((RegisterField) {TMC2300_VACTUAL_MASK, TMC2300_VACTUAL_SHIFT, TMC2300_VACTUAL, true}) +#define TMC2300_SGTHRS_MASK 0x000000FF +#define TMC2300_SGTHRS_SHIFT 0 +#define TMC2300_SGTHRS_FIELD ((RegisterField) {TMC2300_SGTHRS_MASK, TMC2300_SGTHRS_SHIFT, TMC2300_SGTHRS, false}) +#define TMC2300_SG_VALUE_MASK 0x000003FF +#define TMC2300_SG_VALUE_SHIFT 0 +#define TMC2300_SG_VALUE_FIELD ((RegisterField) {TMC2300_SG_VALUE_MASK, TMC2300_SG_VALUE_SHIFT, TMC2300_SG_VALUE, false}) +#define TMC2300_SEMIN_MASK 0x0000000F +#define TMC2300_SEMIN_SHIFT 0 +#define TMC2300_SEMIN_FIELD ((RegisterField) {TMC2300_SEMIN_MASK, TMC2300_SEMIN_SHIFT, TMC2300_COOLCONF, false}) +#define TMC2300_SEUP_MASK 0x00000060 +#define TMC2300_SEUP_SHIFT 5 +#define TMC2300_SEUP_FIELD ((RegisterField) {TMC2300_SEUP_MASK, TMC2300_SEUP_SHIFT, TMC2300_COOLCONF, false}) +#define TMC2300_SEMAX_MASK 0x00000F00 +#define TMC2300_SEMAX_SHIFT 8 +#define TMC2300_SEMAX_FIELD ((RegisterField) {TMC2300_SEMAX_MASK, TMC2300_SEMAX_SHIFT, TMC2300_COOLCONF, false}) +#define TMC2300_SEDN_MASK 0x00006000 +#define TMC2300_SEDN_SHIFT 13 +#define TMC2300_SEDN_FIELD ((RegisterField) {TMC2300_SEDN_MASK, TMC2300_SEDN_SHIFT, TMC2300_COOLCONF, false}) +#define TMC2300_SEIMIN_MASK 0x00008000 +#define TMC2300_SEIMIN_SHIFT 15 +#define TMC2300_SEIMIN_FIELD ((RegisterField) {TMC2300_SEIMIN_MASK, TMC2300_SEIMIN_SHIFT, TMC2300_COOLCONF, false}) +#define TMC2300_MSCNT_MASK 0x000003FF +#define TMC2300_MSCNT_SHIFT 0 +#define TMC2300_MSCNT_FIELD ((RegisterField) {TMC2300_MSCNT_MASK, TMC2300_MSCNT_SHIFT, TMC2300_MSCNT, false}) +#define TMC2300_CUR_A_MASK 0x000001FF +#define TMC2300_CUR_A_SHIFT 0 +#define TMC2300_CUR_A_FIELD ((RegisterField) {TMC2300_CUR_A_MASK, TMC2300_CUR_A_SHIFT, TMC2300_MSCURACT, true}) +#define TMC2300_CUR_B_MASK 0x01FF0000 +#define TMC2300_CUR_B_SHIFT 16 +#define TMC2300_CUR_B_FIELD ((RegisterField) {TMC2300_CUR_B_MASK, TMC2300_CUR_B_SHIFT, TMC2300_MSCURACT, true}) +#define TMC2300_ENABLEDRV_MASK 0x00000001 +#define TMC2300_ENABLEDRV_SHIFT 0 +#define TMC2300_ENABLEDRV_FIELD ((RegisterField) {TMC2300_ENABLEDRV_MASK, TMC2300_ENABLEDRV_SHIFT, TMC2300_CHOPCONF, false}) +#define TMC2300_TBL_MASK 0x00018000 +#define TMC2300_TBL_SHIFT 15 +#define TMC2300_TBL_FIELD ((RegisterField) {TMC2300_TBL_MASK, TMC2300_TBL_SHIFT, TMC2300_CHOPCONF, false}) +#define TMC2300_MRES_MASK 0x0F000000 +#define TMC2300_MRES_SHIFT 24 +#define TMC2300_MRES_FIELD ((RegisterField) {TMC2300_MRES_MASK, TMC2300_MRES_SHIFT, TMC2300_CHOPCONF, false}) +#define TMC2300_INTPOL_MASK 0x10000000 +#define TMC2300_INTPOL_SHIFT 28 +#define TMC2300_INTPOL_FIELD ((RegisterField) {TMC2300_INTPOL_MASK, TMC2300_INTPOL_SHIFT, TMC2300_CHOPCONF, false}) +#define TMC2300_DEDGE_MASK 0x20000000 +#define TMC2300_DEDGE_SHIFT 29 +#define TMC2300_DEDGE_FIELD ((RegisterField) {TMC2300_DEDGE_MASK, TMC2300_DEDGE_SHIFT, TMC2300_CHOPCONF, false}) +#define TMC2300_DISS2G_MASK 0x40000000 +#define TMC2300_DISS2G_SHIFT 30 +#define TMC2300_DISS2G_FIELD ((RegisterField) {TMC2300_DISS2G_MASK, TMC2300_DISS2G_SHIFT, TMC2300_CHOPCONF, false}) +#define TMC2300_DISS2VS_MASK 0x80000000 +#define TMC2300_DISS2VS_SHIFT 31 +#define TMC2300_DISS2VS_FIELD ((RegisterField) {TMC2300_DISS2VS_MASK, TMC2300_DISS2VS_SHIFT, TMC2300_CHOPCONF, false}) +#define TMC2300_OTPW_MASK 0x00000001 +#define TMC2300_OTPW_SHIFT 0 +#define TMC2300_OTPW_FIELD ((RegisterField) {TMC2300_OTPW_MASK, TMC2300_OTPW_SHIFT, TMC2300_DRVSTATUS, false}) +#define TMC2300_OT_MASK 0x00000002 +#define TMC2300_OT_SHIFT 1 +#define TMC2300_OT_FIELD ((RegisterField) {TMC2300_OT_MASK, TMC2300_OT_SHIFT, TMC2300_DRVSTATUS, false}) +#define TMC2300_S2GA_MASK 0x00000004 +#define TMC2300_S2GA_SHIFT 2 +#define TMC2300_S2GA_FIELD ((RegisterField) {TMC2300_S2GA_MASK, TMC2300_S2GA_SHIFT, TMC2300_DRVSTATUS, false}) +#define TMC2300_S2GB_MASK 0x00000008 +#define TMC2300_S2GB_SHIFT 3 +#define TMC2300_S2GB_FIELD ((RegisterField) {TMC2300_S2GB_MASK, TMC2300_S2GB_SHIFT, TMC2300_DRVSTATUS, false}) +#define TMC2300_S2VSA_MASK 0x00000010 +#define TMC2300_S2VSA_SHIFT 4 +#define TMC2300_S2VSA_FIELD ((RegisterField) {TMC2300_S2VSA_MASK, TMC2300_S2VSA_SHIFT, TMC2300_DRVSTATUS, false}) +#define TMC2300_S2VSB_MASK 0x00000020 +#define TMC2300_S2VSB_SHIFT 5 +#define TMC2300_S2VSB_FIELD ((RegisterField) {TMC2300_S2VSB_MASK, TMC2300_S2VSB_SHIFT, TMC2300_DRVSTATUS, false}) +#define TMC2300_OLA_MASK 0x00000040 +#define TMC2300_OLA_SHIFT 6 +#define TMC2300_OLA_FIELD ((RegisterField) {TMC2300_OLA_MASK, TMC2300_OLA_SHIFT, TMC2300_DRVSTATUS, false}) +#define TMC2300_OLB_MASK 0x00000080 +#define TMC2300_OLB_SHIFT 7 +#define TMC2300_OLB_FIELD ((RegisterField) {TMC2300_OLB_MASK, TMC2300_OLB_SHIFT, TMC2300_DRVSTATUS, false}) +#define TMC2300_T120_MASK 0x00000100 +#define TMC2300_T120_SHIFT 8 +#define TMC2300_T120_FIELD ((RegisterField) {TMC2300_T120_MASK, TMC2300_T120_SHIFT, TMC2300_DRVSTATUS, false}) +#define TMC2300_T150_MASK 0x00000200 +#define TMC2300_T150_SHIFT 9 +#define TMC2300_T150_FIELD ((RegisterField) {TMC2300_T150_MASK, TMC2300_T150_SHIFT, TMC2300_DRVSTATUS, false}) +#define TMC2300_CS_ACTUAL_MASK 0x001F0000 +#define TMC2300_CS_ACTUAL_SHIFT 16 +#define TMC2300_CS_ACTUAL_FIELD ((RegisterField) {TMC2300_CS_ACTUAL_MASK, TMC2300_CS_ACTUAL_SHIFT, TMC2300_DRVSTATUS, false}) +#define TMC2300_STST_MASK 0x80000000 +#define TMC2300_STST_SHIFT 31 +#define TMC2300_STST_FIELD ((RegisterField) {TMC2300_STST_MASK, TMC2300_STST_SHIFT, TMC2300_DRVSTATUS, false}) +#define TMC2300_PWM_OFS_MASK 0x000000FF +#define TMC2300_PWM_OFS_SHIFT 0 +#define TMC2300_PWM_OFS_FIELD ((RegisterField) {TMC2300_PWM_OFS_MASK, TMC2300_PWM_OFS_SHIFT, TMC2300_PWMCONF, false}) +#define TMC2300_PWM_GRAD_MASK 0x0000FF00 +#define TMC2300_PWM_GRAD_SHIFT 8 +#define TMC2300_PWM_GRAD_FIELD ((RegisterField) {TMC2300_PWM_GRAD_MASK, TMC2300_PWM_GRAD_SHIFT, TMC2300_PWMCONF, false}) +#define TMC2300_PWM_FREQ_MASK 0x00030000 +#define TMC2300_PWM_FREQ_SHIFT 16 +#define TMC2300_PWM_FREQ_FIELD ((RegisterField) {TMC2300_PWM_FREQ_MASK, TMC2300_PWM_FREQ_SHIFT, TMC2300_PWMCONF, false}) +#define TMC2300_PWM_AUTOSCALE_MASK 0x00040000 +#define TMC2300_PWM_AUTOSCALE_SHIFT 18 +#define TMC2300_PWM_AUTOSCALE_FIELD ((RegisterField) {TMC2300_PWM_AUTOSCALE_MASK, TMC2300_PWM_AUTOSCALE_SHIFT, TMC2300_PWMCONF, false}) +#define TMC2300_PWM_AUTOGRAD_MASK 0x00080000 +#define TMC2300_PWM_AUTOGRAD_SHIFT 19 +#define TMC2300_PWM_AUTOGRAD_FIELD ((RegisterField) {TMC2300_PWM_AUTOGRAD_MASK, TMC2300_PWM_AUTOGRAD_SHIFT, TMC2300_PWMCONF, false}) +#define TMC2300_FREEWHEEL_MASK 0x00300000 +#define TMC2300_FREEWHEEL_SHIFT 20 +#define TMC2300_FREEWHEEL_FIELD ((RegisterField) {TMC2300_FREEWHEEL_MASK, TMC2300_FREEWHEEL_SHIFT, TMC2300_PWMCONF, false}) +#define TMC2300_PWM_REG_MASK 0x0F000000 +#define TMC2300_PWM_REG_SHIFT 24 +#define TMC2300_PWM_REG_FIELD ((RegisterField) {TMC2300_PWM_REG_MASK, TMC2300_PWM_REG_SHIFT, TMC2300_PWMCONF, false}) +#define TMC2300_PWM_LIM_MASK 0xF0000000 +#define TMC2300_PWM_LIM_SHIFT 28 +#define TMC2300_PWM_LIM_FIELD ((RegisterField) {TMC2300_PWM_LIM_MASK, TMC2300_PWM_LIM_SHIFT, TMC2300_PWMCONF, false}) +#define TMC2300_PWM_SCALE_SUM_MASK 0x000000FF +#define TMC2300_PWM_SCALE_SUM_SHIFT 0 +#define TMC2300_PWM_SCALE_SUM_FIELD ((RegisterField) {TMC2300_PWM_SCALE_SUM_MASK, TMC2300_PWM_SCALE_SUM_SHIFT, TMC2300_PWM_SCALE, false}) +#define TMC2300_PWM_SCALE_AUTO_MASK 0xFFFF0000 +#define TMC2300_PWM_SCALE_AUTO_SHIFT 16 +#define TMC2300_PWM_SCALE_AUTO_FIELD ((RegisterField) {TMC2300_PWM_SCALE_AUTO_MASK, TMC2300_PWM_SCALE_AUTO_SHIFT, TMC2300_PWM_SCALE, true}) +#define TMC2300_PWM_OFS_AUTO_MASK 0x000000FF +#define TMC2300_PWM_OFS_AUTO_SHIFT 0 +#define TMC2300_PWM_OFS_AUTO_FIELD ((RegisterField) {TMC2300_PWM_OFS_AUTO_MASK, TMC2300_PWM_OFS_AUTO_SHIFT, TMC2300_PWMAUTO, false}) +#define TMC2300_PWM_GRAD_AUTO_MASK 0x00FF0000 +#define TMC2300_PWM_GRAD_AUTO_SHIFT 16 +#define TMC2300_PWM_GRAD_AUTO_FIELD ((RegisterField) {TMC2300_PWM_GRAD_AUTO_MASK, TMC2300_PWM_GRAD_AUTO_SHIFT, TMC2300_PWMAUTO, false}) + +#endif diff --git a/firmware/lib/tmc/ic/TMC2300/registercall_hierarchy_flowchart_UART.svg b/firmware/lib/tmc/ic/TMC2300/registercall_hierarchy_flowchart_UART.svg new file mode 100755 index 0000000..425f60a --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2300/registercall_hierarchy_flowchart_UART.svg @@ -0,0 +1,3 @@ + + +

HAL

HAL

APP (Eval)

APP (Eval)

API

API
Read a register
  •  Call tmcXXXX_readRegister function
Read a register...
Returns the register read value
Returns the register read value
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
tmcXXXX.c
tmcXXXX.c
UART.c
UART.c
tmcXXXX_eval.c
tmcXXXX_eval.c

 Implementation of UART_readWrite
  • Sends and receives bytes on the UART bus
Implementation of UART_readWrite...
Returns the raw reply data
Returns the raw reply data

Implementation of tmcXXXX_readWriteUART
  • Takes the array of data to write
  • Calls hardware function UART_readWrite
Implementation of tmcXXXX_readWriteUART...
Passes on the raw reply data to the API
Passes on the raw reply data to the API
Implementation of readRegisterUART
  • Constructs the datagram
  • Calls HAL wrapper function 
Implementation of readRegisterUART...
tmcXXXX_readWriteUART
tmcXXXX_readWriteUART
Parses the reply and returns the register value
Parses the reply and returns the register value
Implementation of tmcXXXX_readRegister 
  • Check which bus is active SPI/UART. (e.g. UART)
  • Calls bus-specific function (e.g. readRegisterUART)
 
Implementation of tmcXXXX_readRegister...
Returns the register read value
Returns the register read value
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC2300/uml-tmc-api.svg b/firmware/lib/tmc/ic/TMC2300/uml-tmc-api.svg new file mode 100755 index 0000000..5a5f8dd --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2300/uml-tmc-api.svg @@ -0,0 +1,3 @@ + + +

TMCXXXX_HW_Abstraction.h



TMCXXXX_HW_Abstraction.h...
// Constants
#define TMCXXXX_MOTORS              
                          
// Register definitions
#define TMCXXXX_GCONF        
                          ⋮
// Register fields definitions
#define TMCXXXX_GCONF_OTPW_FIELD
                     
// Constants...

TMCXXXX.h



TMCXXXX.h...
extern void tmcXXXX_readWriteSPI();
extern void tmcXXXX_readWriteUART();
extern TMCXXXXBusType tmcXXXX_getBusType();
extern uint8_t tmcXXXX_getNodeAddress();
                                  ⋮
tmcXXXX_readRegister();
tmcXXXX_writeRegister();
                                  ⋮
extern void tmcXXXX_readWriteSPI();...

TMCXXXX.c



TMCXXXX.c...
const uint8_t tmcCRCTable_Poly7Reflected[256] = {...};
int32_t tmcXXXX_readRegister(){
/* Call tmcXXXX_getBusType();
 * Based on bus type, call readRegisterSPI/UART() that
 * further calls tmcXXXX_readWriteSPI/UART();
 * For UART it also calls tmcXXXX_getNodeAddress();
                                           ⋮
}
                                           ⋮
const uint8_t tmcCRCTable_Poly7Reflected[256] = {.....
TMC-API
TMC-API

TMCXXXX_Simple_Rotation.h


TMCXXXX_Simple_Rotation.h...
void initAllMotors();
             ⋮
  
void initAllMotors()...

TMCXXXX_Simple_Rotation.c


TMCXXXX_Simple_Rotation.c...
void initAllMotors(){

// Configuring registers to enable motor drivers etc..
tmcXXXX_writeRegister();
                    ⋮
}
                    ⋮
void initAllMotors(){...
Examples
Examples
User Project
User Project

User_Project.h


User_Project.h

User_Project.c








User_Project.c...

void tmcXXXX_readWriteSPI(){
                           ⋮
}
void tmcXXXX_readWriteUART(){
                           ⋮
}
TMCXXXXBusType tmcXXXX_getBusType(){
                           ⋮
}
uint8_t tmcXXXX_getNodeAddress(){
                           ⋮
}

// User Code
                           ⋮
void tmcXXXX_readWriteSPI(){...
#include "TMCXXXX_HW_Abstraction.h"
#include "TMCXXXX.h"
#include "TMCXXXX_Simple_Rotation.h"
                                ⋮
TMCXXXXBusType bus = IC_BUS_SPI/UART;
uint8_t nodeAddress = <nodeAddress>;
                                ⋮
#include "TMCXXXX_HW_Abstraction.h"...
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC262/TMC262.c b/firmware/lib/tmc/ic/TMC262/TMC262.c new file mode 100755 index 0000000..3521d5e --- /dev/null +++ b/firmware/lib/tmc/ic/TMC262/TMC262.c @@ -0,0 +1,830 @@ +/******************************************************************************* +* Copyright © 2017 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2023 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#include "TMC262.h" + +// Data structs for TMC262 Shadowregister +typedef struct +{ + uint8_t Intpol; + uint8_t DEdge; + uint8_t MRes; +} TStepDirConfig; + +typedef struct +{ + uint8_t BlankTime; + uint8_t ChopperMode; + uint8_t HysteresisDecay; + uint8_t RandomTOff; + uint8_t HysteresisEnd; + uint8_t HysteresisStart; + uint8_t TOff; + uint8_t DisableFlag; +} TChopperConfig; + +typedef struct +{ + uint8_t SmartIMin; + uint8_t SmartDownStep; + uint8_t SmartStallLevelMax; + uint8_t SmartUpStep; + uint8_t SmartStallLevelMin; +} TSmartEnergyControl; + +typedef struct +{ + uint8_t FilterEnable; + int8_t StallGuardThreshold; + uint8_t CurrentScale; +} TStallGuardConfig; + + +typedef struct +{ + uint8_t SlopeHighSide; + uint8_t SlopeLowSide; + uint8_t ProtectionDisable; + uint8_t ProtectionTimer; + uint8_t StepDirectionDisable; + uint8_t VSenseScale; + uint8_t ReadBackSelect; +} TDriverConfig; + +typedef enum { + RB_CHOPPER, + RB_DRIVER, + RB_SMART_ENERGY, + RB_STALL_GUARD, + RB_STEP_DIR +} TReadBackDatagram; + +// Variablen +static TStepDirConfig StepDirConfig; // Shadowregister of DRVCTRL-Register +static TChopperConfig ChopperConfig; // Shadowregister of CHOPCONF-Register +static TSmartEnergyControl SmartEnergyControl; // Shadowregister of SMARTEN-Register +static TStallGuardConfig StallGuardConfig; // Shadowregister of SGSCONF-Register +static TDriverConfig DriverConfig; // Shadowregister of DRVCONF-Register +static TReadBackDatagram ReadBackDatagram; // Next telegram to be used to read the state +static uint32_t SPIReadInt; +static uint32_t SPIWriteInt; + +static uint32_t SPIStepDirConf; +static uint32_t SPIChopperConf; +static uint32_t SPISmartConf; +static uint32_t SPISGConf; +static uint32_t SPIDriverConf; + +// Choose the configuration that suits your board // todo API 2: configuration should be chosen outside API e.g. in TMC-EvalSystem +#define DEVTYPE_TMC428 // Direct SPI communication if TMC262 is connected to the processor +//#define DEVTYPE_TMC43xx // Communication is forwarded to TMC262 by TMC43xx with "cover datagrams" + +#if defined(DEVTYPE_TMC428) + // => SPI wrapper + extern uint8_t tmc5130_spi_readWrite(uint8_t data, uint8_t lastTransfer); + // <= SPI wrapper +#elif defined(DEVTYPE_TMC43xx) + #include "tmc/ic/TMC43xx/TMC4361A_Register.h" + // => Cover data wrapper + extern int32_t tmc43xx_readInt(uint8_t address); + extern int32_t tmc43xx_writeInt(uint8_t address, uint32_t data); + // <= Cover data wrapper +#else +#error "Device not supported!" +#endif + +// Functions + +/******************************************************************* + Function: ReadWrite262() + Parameter: Read: Pointer to int for result + Write: Array with 3 bytes to be written in TMC262 + + Returns: --- + + Purpose: SPI-Communication with TMC262. The datagrams are shifted + to the correct position. +********************************************************************/ +static void ReadWrite262(uint32_t *ReadInt, uint32_t WriteInt) +{ +#if defined(DEVTYPE_TMC428) + *ReadInt = tmc5130_spi_readWrite(WriteInt>>16, FALSE); + *ReadInt <<= 8; + *ReadInt |= tmc5130_spi_readWrite(WriteInt>>8, FALSE); + *ReadInt <<= 8; + *ReadInt |= tmc5130_spi_readWrite(WriteInt & 0xFF, TRUE); + *ReadInt >>= 4; + +#elif defined(DEVTYPE_TMC43xx) + tmc43xx_writeInt(TMC4361A_EVENT_CLEAR_CONF, ~TMC4361A_COVER_DONE); + tmc43xx_readInt(TMC4361A_EVENTS); + tmc43xx_writeInt(TMC4361A_COVER_LOW_WR, WriteInt); + while(!(tmc43xx_readInt(TMC4361A_EVENTS) & TMC4361A_COVER_DONE)) {}; + *ReadInt = tmc43xx_readInt(TMC4361A_COVER_DRV_LOW_RD); + +#else +#error "Device not supported!" +#endif +} + + +/******************************************************************* + Function: WriteStepDirConfig() + Parameter: --- + + Returns: --- + + Purpose: Write register DRVCTRL of TMC262 in Step/Dir Mode. + The parameters must be pre-configured in the StepDirConfig + global variables. +********************************************************************/ +static void WriteStepDirConfig() +{ + SPIWriteInt = 0; + if(StepDirConfig.Intpol) + SPIWriteInt |= BIT9; + if(StepDirConfig.DEdge) + SPIWriteInt |= BIT8; + if(StepDirConfig.MRes > 15) + StepDirConfig.MRes = 15; + SPIWriteInt |= StepDirConfig.MRes; + + ReadWrite262(&SPIReadInt, SPIWriteInt); + SPIStepDirConf = SPIWriteInt; +} + + +/******************************************************************* + Function: WriteChopperConfig() + Parameter: --- + + Returns: --- + + Purpose: Write register CHOPCONF of TMC262 in Step/Dir Mode. + The parameters must be pre-configured in the ChopperConfig + global variables. +********************************************************************/ +static void WriteChopperConfig() +{ + ChopperConfig.BlankTime = MIN(ChopperConfig.BlankTime, 3); + ChopperConfig.HysteresisDecay = MIN(ChopperConfig.HysteresisDecay, 3); + ChopperConfig.HysteresisEnd = MIN(ChopperConfig.HysteresisEnd, 15); + ChopperConfig.HysteresisStart = MIN(ChopperConfig.HysteresisStart, 7); + ChopperConfig.TOff = MIN(ChopperConfig.TOff, 15); + + SPIWriteInt = 0; + SPIWriteInt |= BIT19; // Registeraddresse CHOPCONF; + SPIWriteInt |= ((uint32_t) ChopperConfig.BlankTime) << 15; + if(ChopperConfig.ChopperMode) + SPIWriteInt |= BIT14; + if(ChopperConfig.RandomTOff) + SPIWriteInt |= BIT13; + SPIWriteInt |= ((uint32_t) ChopperConfig.HysteresisDecay) << 11; + SPIWriteInt |= ((uint32_t) ChopperConfig.HysteresisEnd) << 7; + SPIWriteInt |= ((uint32_t) ChopperConfig.HysteresisStart) << 4; + if(!ChopperConfig.DisableFlag) + SPIWriteInt |= ((uint32_t) ChopperConfig.TOff); // wenn DisableFlag gesetzt wird 0 gesendet + + ReadWrite262(&SPIReadInt, SPIWriteInt); + SPIChopperConf = SPIWriteInt; +} + + +/******************************************************************* + Function: WriteSmartEnergyControl() + Parameter: --- + + Returns: --- + + Purpose: Write register SMARTEN of TMC262 in Step/Dir Mode. + The parameters must be pre-configured in the + SmartEnergyControl global variables. +********************************************************************/ +static void WriteSmartEnergyControl() +{ + SmartEnergyControl.SmartIMin = MIN(SmartEnergyControl.SmartIMin, 1); + SmartEnergyControl.SmartDownStep = MIN(SmartEnergyControl.SmartDownStep, 3); + SmartEnergyControl.SmartStallLevelMax = MIN(SmartEnergyControl.SmartStallLevelMax, 15); + SmartEnergyControl.SmartUpStep = MIN(SmartEnergyControl.SmartUpStep, 3); + SmartEnergyControl.SmartStallLevelMin = MIN(SmartEnergyControl.SmartStallLevelMin, 15); + + SPIWriteInt = 0; + SPIWriteInt |= BIT19 | BIT17; // Register address SMARTEN + SPIWriteInt |= ((uint32_t) SmartEnergyControl.SmartIMin) << 15; + SPIWriteInt |= ((uint32_t) SmartEnergyControl.SmartDownStep) << 13; + SPIWriteInt |= ((uint32_t) SmartEnergyControl.SmartStallLevelMax) << 8; + SPIWriteInt |= ((uint32_t) SmartEnergyControl.SmartUpStep) << 5; + SPIWriteInt |= ((uint32_t) SmartEnergyControl.SmartStallLevelMin); + + ReadWrite262(&SPIReadInt, SPIWriteInt); + SPISmartConf = SPIWriteInt; +} + + +/******************************************************************* + Function: WriteStallGuardConfig() + Parameter: --- + + Returns: --- + + Purpose: Write register SGCSCONF of TMC262 in Step/Dir Mode. + The parameters must be pre-configured in the + StallGuardConfig global variables. +********************************************************************/ +static void WriteStallGuardConfig() +{ + if(abs(StallGuardConfig.StallGuardThreshold) > 63) + StallGuardConfig.StallGuardThreshold = (StallGuardConfig.StallGuardThreshold > 0)? 63:-63; + StallGuardConfig.CurrentScale = MIN(StallGuardConfig.CurrentScale, 31); + + SPIWriteInt = 0; + SPIWriteInt |= BIT19 | BIT18; // Register address SGSCONF + if(StallGuardConfig.FilterEnable == 1) + SPIWriteInt |= BIT16; + SPIWriteInt |= ((uint32_t) StallGuardConfig.StallGuardThreshold & 0x7F) << 8; + SPIWriteInt |= ((uint32_t) StallGuardConfig.CurrentScale); + + ReadWrite262(&SPIReadInt, SPIWriteInt); + SPISGConf = SPIWriteInt; +} + + +/******************************************************************* + Function: WriteDriverConfig() + Parameter: --- + + Returns: --- + + Purpose: Write register DRVCONF of TMC262 in Step/Dir Mode. + The parameters must be pre-configured in the DriverConfig + global variables. +********************************************************************/ +static void WriteDriverConfig() +{ + SPIWriteInt = 0; + SPIWriteInt |= BIT19 | BIT18 | BIT17; // Register address DRVCONF + SPIWriteInt |= ((uint32_t) DriverConfig.SlopeHighSide) << 14; + SPIWriteInt |= ((uint32_t) DriverConfig.SlopeLowSide) << 12; + if(DriverConfig.ProtectionDisable == 1) + SPIWriteInt |= BIT10; + SPIWriteInt |= ((uint32_t) DriverConfig.ProtectionTimer) << 8; + if(DriverConfig.StepDirectionDisable == 1) + SPIWriteInt |= BIT7; + if(DriverConfig.VSenseScale == 1) + SPIWriteInt |= BIT6; + SPIWriteInt |= ((uint32_t) DriverConfig.ReadBackSelect) << 4; + + ReadWrite262(&SPIReadInt, SPIWriteInt); + SPIDriverConf = SPIWriteInt; +} + +/******************************************************************* + Function: tmc262_initMotorDrivers() + Parameter: --- + + Returns: --- + + Purpose: Initialization of TMC262 and its variables +********************************************************************/ +void tmc262_initMotorDrivers(void) +{ + // Initialize data structs + // Parameter "non cool" + StallGuardConfig.FilterEnable = 1; + StallGuardConfig.StallGuardThreshold = 5; +#if defined(DEVTYPE_TMC43xx) + StallGuardConfig.CurrentScale = 31; +#else + StallGuardConfig.CurrentScale = 5; //16; +#endif + + DriverConfig.SlopeHighSide = 3; + DriverConfig.SlopeLowSide = 3; + DriverConfig.ProtectionDisable = 0; + DriverConfig.ProtectionTimer = 0; +#if defined(DEVTYPE_TMC43xx) + DriverConfig.StepDirectionDisable = 1; +#else + DriverConfig.StepDirectionDisable = 0; +#endif + + DriverConfig.VSenseScale = 1; + DriverConfig.ReadBackSelect = TMC262_RB_SMART_ENERGY; + + SmartEnergyControl.SmartIMin = 0; + SmartEnergyControl.SmartDownStep = 0; + SmartEnergyControl.SmartStallLevelMax = 0; + SmartEnergyControl.SmartUpStep = 0; + SmartEnergyControl.SmartStallLevelMin = 0; + + StepDirConfig.Intpol = 0; + StepDirConfig.DEdge = 0; + StepDirConfig.MRes = 0; + + ChopperConfig.BlankTime = 2; + ChopperConfig.ChopperMode = 0; + ChopperConfig.RandomTOff = 0; + ChopperConfig.HysteresisDecay = 0; + ChopperConfig.HysteresisEnd = 2; + ChopperConfig.HysteresisStart = 3; + ChopperConfig.TOff = 5; + ChopperConfig.DisableFlag = FALSE; + + // Send initial values to TMC262 + WriteSmartEnergyControl(); + WriteStallGuardConfig(); + WriteDriverConfig(); + WriteStepDirConfig(); + WriteChopperConfig(); +} + +void tmc262_setStepDirMStepRes(uint8_t MicrostepResolution) +{ + StepDirConfig.MRes = MicrostepResolution; + if(MicrostepResolution != 4) + StepDirConfig.Intpol = 0; + WriteStepDirConfig(); +} + +void tmc262_setStepDirInterpolation(uint8_t Interpolation) +{ + StepDirConfig.Intpol = Interpolation; + if(Interpolation) + StepDirConfig.MRes = 4; + WriteStepDirConfig(); +} + +void tmc262_setStepDirDoubleEdge(uint8_t DoubleEdge) +{ + StepDirConfig.DEdge = DoubleEdge; + WriteStepDirConfig(); +} + +uint8_t tmc262_getStepDirMStepRes() +{ + return StepDirConfig.MRes; +} + +uint8_t tmc262_getStepDirInterpolation() +{ + return StepDirConfig.Intpol; +} + +uint8_t tmc262_getStepDirDoubleEdge() +{ + return StepDirConfig.DEdge; +} + + +void tmc262_setChopperBlankTime(uint8_t BlankTime) +{ + ChopperConfig.BlankTime = BlankTime; + WriteChopperConfig(); +} + +void tmc262_setChopperMode(uint8_t Mode) +{ + ChopperConfig.ChopperMode = Mode; + WriteChopperConfig(); +} + +void tmc262_setChopperRandomTOff(uint8_t RandomTOff) +{ + ChopperConfig.RandomTOff = RandomTOff; + WriteChopperConfig(); +} + +void tmc262_setChopperHysteresisDecay(uint8_t HysteresisDecay) +{ + ChopperConfig.HysteresisDecay = HysteresisDecay; + WriteChopperConfig(); +} + +void tmc262_setChopperHysteresisEnd(uint8_t HysteresisEnd) +{ + ChopperConfig.HysteresisEnd = HysteresisEnd; + WriteChopperConfig(); +} + +void tmc262_setChopperHysteresisStart(uint8_t HysteresisStart) +{ + ChopperConfig.HysteresisStart = HysteresisStart; + WriteChopperConfig(); +} + +void tmc262_setChopperTOff(uint8_t TOff) +{ + ChopperConfig.TOff = TOff; + WriteChopperConfig(); +} + +uint8_t tmc262_getChopperBlankTime() +{ + return ChopperConfig.BlankTime; +} + +uint8_t tmc262_getChopperMode() +{ + return ChopperConfig.ChopperMode; +} + +uint8_t tmc262_getChopperRandomTOff() +{ + return ChopperConfig.RandomTOff; +} + +uint8_t tmc262_getChopperHysteresisDecay() +{ + return ChopperConfig.HysteresisDecay; +} + +uint8_t tmc262_getChopperHysteresisEnd() +{ + return ChopperConfig.HysteresisEnd; +} + +uint8_t tmc262_getChopperHysteresisStart() +{ + return ChopperConfig.HysteresisStart; +} + +uint8_t tmc262_getChopperTOff() +{ + return ChopperConfig.TOff; +} + + +void tmc262_setSmartEnergyIMin(uint8_t SmartIMin) +{ + SmartEnergyControl.SmartIMin = SmartIMin; + WriteSmartEnergyControl(); +} + +void tmc262_setSmartEnergyDownStep(uint8_t SmartDownStep) +{ + SmartEnergyControl.SmartDownStep = SmartDownStep; + WriteSmartEnergyControl(); +} + +void tmc262_setSmartEnergyStallLevelMax(uint8_t StallLevelMax) +{ + SmartEnergyControl.SmartStallLevelMax = StallLevelMax; + WriteSmartEnergyControl(); +} + +void tmc262_setSmartEnergyUpStep(uint8_t SmartUpStep) +{ + SmartEnergyControl.SmartUpStep = SmartUpStep; + WriteSmartEnergyControl(); +} + +void tmc262_setSmartEnergyStallLevelMin(uint8_t StallLevelMin) +{ + SmartEnergyControl.SmartStallLevelMin = StallLevelMin; + WriteSmartEnergyControl(); +} + +uint8_t tmc262_getSmartEnergyIMin() +{ + return SmartEnergyControl.SmartIMin; +} + +uint8_t tmc262_getSmartEnergyDownStep() +{ + return SmartEnergyControl.SmartDownStep; +} + +uint8_t tmc262_getSmartEnergyStallLevelMax() +{ + return SmartEnergyControl.SmartStallLevelMax; +} + +uint8_t tmc262_getSmartEnergyUpStep() +{ + return SmartEnergyControl.SmartUpStep; +} + +uint8_t tmc262_getSmartEnergyStallLevelMin() +{ + return SmartEnergyControl.SmartStallLevelMin; +} + + +void tmc262_setStallGuardFilter(uint8_t Enable) +{ + StallGuardConfig.FilterEnable = Enable; + WriteStallGuardConfig(); +} + +void tmc262_setStallGuardThreshold(int8_t Threshold) +{ + StallGuardConfig.StallGuardThreshold = Threshold; + WriteStallGuardConfig(); +} + +void tmc262_setStallGuardCurrentScale(uint8_t CurrentScale) +{ + StallGuardConfig.CurrentScale = CurrentScale; + WriteStallGuardConfig(); +} + +uint8_t tmc262_getStallGuardFilter() +{ + return StallGuardConfig.FilterEnable; +} + +int8_t tmc262_getStallGuardThreshold() +{ + return StallGuardConfig.StallGuardThreshold; +} + +uint8_t tmc262_getStallGuardCurrentScale() +{ + return StallGuardConfig.CurrentScale; +} + + +void tmc262_setDriverSlopeHighSide(uint8_t SlopeHighSide) +{ + DriverConfig.SlopeHighSide = SlopeHighSide; + WriteDriverConfig(); +} + +void tmc262_setDriverSlopeLowSide(uint8_t SlopeLowSide) +{ + DriverConfig.SlopeLowSide = SlopeLowSide; + WriteDriverConfig(); +} + +void tmc262_setDriverDisableProtection(uint8_t DisableProtection) +{ + DriverConfig.ProtectionDisable = DisableProtection; + WriteDriverConfig(); +} + +void tmc262_setDriverProtectionTimer(uint8_t ProtectionTimer) +{ + DriverConfig.ProtectionTimer = ProtectionTimer; + WriteDriverConfig(); +} + +void tmc262_setDriverStepDirectionOff(uint8_t SDOff) +{ + DriverConfig.StepDirectionDisable = SDOff; + WriteDriverConfig(); +} + +void tmc262_setDriverVSenseScale(uint8_t Scale) +{ + DriverConfig.VSenseScale = Scale; + WriteDriverConfig(); +} + +void tmc262_setDriverReadSelect(uint8_t ReadSelect) +{ + DriverConfig.ReadBackSelect = ReadSelect; + WriteDriverConfig(); +} + +uint8_t tmc262_getDriverSlopeHighSide() +{ + return DriverConfig.SlopeHighSide; +} + +uint8_t tmc262_getDriverSlopeLowSide() +{ + return DriverConfig.SlopeLowSide; +} + +uint8_t tmc262_getDriverDisableProtection() +{ + return DriverConfig.ProtectionDisable; +} + +uint8_t tmc262_getDriverProtectionTimer() +{ + return DriverConfig.ProtectionTimer; +} + +uint8_t tmc262_getDriverStepDirectionOff() +{ + return DriverConfig.StepDirectionDisable; +} + +uint8_t tmc262_getDriverVSenseScale() +{ + return DriverConfig.VSenseScale; +} + +uint8_t tmc262_getDriverReadSelect() +{ + return DriverConfig.ReadBackSelect; +} + + +/******************************************************************* + Function: tmc262_readState() + Parameter: Phases: Pointer to state variable of phase bits + MStep: Pointer to variable for microstep-position + StallGuard: Pointer to variable for stallGuard + SmartEnergy: Pointer to variable for SmartEnergy + Flags: Pointer to variable for error-flags + + Returns: --- + + Purpose: Read out TMC262-state. Depending on RDSEL, the read back + values are extracted accordingly from the SPI telegram. + NULL can be used for values that are not required. +********************************************************************/ +void tmc262_readState(uint8_t *Phases, uint8_t *MStep, uint32_t *StallGuard, uint8_t *SmartEnergy, uint8_t *Flags) +{ + // Alternately use all datagram types of the TMC26x to read out the states. + // This ensures that all registers are always written with the correct values + // (if there should be a TMC26x reset between them). + switch(ReadBackDatagram) + { + case RB_CHOPPER: + WriteChopperConfig(); + ReadBackDatagram = RB_DRIVER; + break; + case RB_DRIVER: + WriteDriverConfig(); + ReadBackDatagram = RB_SMART_ENERGY; + break; + case RB_SMART_ENERGY: + WriteSmartEnergyControl(); + ReadBackDatagram = RB_STALL_GUARD; + break; + case RB_STALL_GUARD: + WriteStallGuardConfig(); + ReadBackDatagram = RB_STEP_DIR; + break; + case RB_STEP_DIR: + WriteStepDirConfig(); + ReadBackDatagram = RB_CHOPPER; + break; + default: + ReadBackDatagram = RB_CHOPPER; + break; + } + + // Decode read values depending on selected type + switch(DriverConfig.ReadBackSelect) + { + case TMC262_RB_MSTEP: + if(Phases != NULL) + *Phases = SPIReadInt >> 18; + if(MStep != NULL) + *MStep = SPIReadInt >> 10; + break; + case TMC262_RB_STALL_GUARD: + if(StallGuard != NULL) + *StallGuard=SPIReadInt >> 10; + break; + case TMC262_RB_SMART_ENERGY: + if(StallGuard != NULL) + { + *StallGuard = SPIReadInt >> 15; + *StallGuard <<= 5; + } + if(SmartEnergy != NULL) + { + *SmartEnergy = (SPIReadInt >> 10) & 0x1F; + } + break; + } + + if(Flags != NULL) + *Flags = SPIReadInt & 0xFF; +} + + +#if defined(DEVTYPE_TMC43xx) +/******************************************************************* + Function: tmc262_readStateNoCoverData() + Parameter: Phases: Pointer to state variable of phase bits + MStep: Pointer to variable for microstep-position + StallGuard: Pointer to variable for stallGuard + SmartEnergy: Pointer to variable for SmartEnergy + Flags: Pointer to variable for error-flags + + Returns: --- + + + Purpose: Read out TMC262-state, without sending a cover datagram + and thus without disturbing SPI communication. + Depending on RDSEL, the read back + values are extracted accordingly from the SPI telegram. + NULL can be used for values that are not required. +********************************************************************/ +void tmc262_readStateNoCoverData(uint8_t *Phases, uint16_t *MStep, uint32_t *StallGuard, uint8_t *SmartEnergy, uint8_t *Flags) +{ + uint32_t SPIReadData; + + SPIReadData = tmc43xx_readInt(TMC4361A_POLLING_STATUS_RD); + + // Decode read values depending on selected type + switch(DriverConfig.ReadBackSelect) + { + case TMC262_RB_MSTEP: + if(Phases != NULL) + *Phases = SPIReadData >> 18; + if(MStep != NULL) + *MStep = (SPIReadData >> 10) & 0x3FF; + break; + case TMC262_RB_STALL_GUARD: + if(StallGuard != NULL) + *StallGuard = SPIReadData >> 10; + break; + case TMC262_RB_SMART_ENERGY: + if(StallGuard != NULL) + { + *StallGuard = SPIReadData >> 15; + *StallGuard <<= 5; + } + if(SmartEnergy != NULL) + { + *SmartEnergy = (SPIReadData >> 10) & 0x1F; + } + break; + } + + if(Flags != NULL) + *Flags = SPIReadData & 0xFF; +} +#endif + + + +/******************************************************************* + Function: tmc262_disable() + Parameter: --- + + Returns: --- + + Purpose: Disconnect motor from current. This is done by setting + TOff-Time to 0 (altough the last TOff value which was set + with tmc262_setChopperTOff() is still available. +********************************************************************/ +void tmc262_disable() +{ + if(!ChopperConfig.DisableFlag) + { + ChopperConfig.DisableFlag = TRUE; + WriteChopperConfig(); + } +} + + +/******************************************************************* + Function: Enable262() + Parameter: --- + + Returns: --- + + Purpose: turn on motor. This is done by setting the TOff-Time + with the value which was written the last time by + tmc262_setChopperTOff() +********************************************************************/ +void tmc262_enable() +{ + if(ChopperConfig.DisableFlag) + { + ChopperConfig.DisableFlag = FALSE; + WriteChopperConfig(); + } +} + +void tmc262_getSPIData(uint8_t Index, int32_t *Data) +{ + switch(Index) + { + case 0: + *Data = SPIReadInt; + break; + case 1: + *Data = SPIStepDirConf; + break; + case 2: + *Data = SPIChopperConf; + break; + case 3: + *Data = SPISmartConf; + break; + case 4: + *Data = SPISGConf; + break; + case 5: + *Data = SPIDriverConf; + break; + case 6: + *Data = ChopperConfig.DisableFlag; + break; + } +} diff --git a/firmware/lib/tmc/ic/TMC262/TMC262.h b/firmware/lib/tmc/ic/TMC262/TMC262.h new file mode 100755 index 0000000..9fd0c59 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC262/TMC262.h @@ -0,0 +1,94 @@ +/******************************************************************************* +* Copyright © 2017 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2023 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#ifndef TMC_IC_TMC262_H_ +#define TMC_IC_TMC262_H_ + +#include "tmc/helpers/API_Header.h" +#include "TMC262_Register.h" + +#define TMC262_RB_MSTEP 0 +#define TMC262_RB_STALL_GUARD 1 +#define TMC262_RB_SMART_ENERGY 2 +#define TMC262_RB_ENCODER 3 + +#define TMC262_FLAG_STST 0x80 +#define TMC262_FLAG_OLB 0x40 +#define TMC262_FLAG_OLA 0x20 +#define TMC262_FLAG_S2GB 0x10 +#define TMC262_FLAG_S2GA 0x08 +#define TMC262_FLAG_OTPW 0x04 +#define TMC262_FLAG_OT 0x02 +#define TMC262_FLAG_SG 0x01 + +// Access functions for TMC262 +void tmc262_initMotorDrivers(void); +void tmc262_setStepDirMStepRes(uint8_t MicrostepResolution); +void tmc262_setStepDirInterpolation(uint8_t Interpolation); +void tmc262_setStepDirDoubleEdge(uint8_t DoubleEdge); +uint8_t tmc262_getStepDirMStepRes(); +uint8_t tmc262_getStepDirInterpolation(); +uint8_t tmc262_getStepDirDoubleEdge(); + +void tmc262_setChopperBlankTime(uint8_t BlankTime); +void tmc262_setChopperMode(uint8_t Mode); +void tmc262_setChopperRandomTOff(uint8_t RandomTOff); +void tmc262_setChopperHysteresisDecay(uint8_t HysteresisDecay); +void tmc262_setChopperHysteresisEnd(uint8_t HysteresisEnd); +void tmc262_setChopperHysteresisStart(uint8_t HysteresisStart); +void tmc262_setChopperTOff(uint8_t TOff); +uint8_t tmc262_getChopperBlankTime(); +uint8_t tmc262_getChopperMode(); +uint8_t tmc262_getChopperRandomTOff(); +uint8_t tmc262_getChopperHysteresisDecay(); +uint8_t tmc262_getChopperHysteresisEnd(); +uint8_t tmc262_getChopperHysteresisStart(); +uint8_t tmc262_getChopperTOff(); + +void tmc262_setSmartEnergyIMin(uint8_t SmartIMin); +void tmc262_setSmartEnergyDownStep(uint8_t SmartDownStep); +void tmc262_setSmartEnergyStallLevelMax(uint8_t StallLevelMax); +void tmc262_setSmartEnergyUpStep(uint8_t SmartUpStep); +void tmc262_setSmartEnergyStallLevelMin(uint8_t StallLevelMin); +uint8_t tmc262_getSmartEnergyIMin(); +uint8_t tmc262_getSmartEnergyDownStep(); +uint8_t tmc262_getSmartEnergyStallLevelMax(); +uint8_t tmc262_getSmartEnergyUpStep(); +uint8_t tmc262_getSmartEnergyStallLevelMin(); + +void tmc262_setStallGuardFilter(uint8_t Enable); +void tmc262_setStallGuardThreshold(signed char Threshold); +void tmc262_setStallGuardCurrentScale(uint8_t CurrentScale); +uint8_t tmc262_getStallGuardFilter(); +signed char tmc262_getStallGuardThreshold(); +uint8_t tmc262_getStallGuardCurrentScale(); + +void tmc262_setDriverSlopeHighSide(uint8_t SlopeHighSide); +void tmc262_setDriverSlopeLowSide(uint8_t SlopeLowSide); +void tmc262_setDriverDisableProtection(uint8_t DisableProtection); +void tmc262_setDriverProtectionTimer(uint8_t ProtectionTimer); +void tmc262_setDriverStepDirectionOff(uint8_t SDOff); +void tmc262_setDriverVSenseScale(uint8_t Scale); +void tmc262_setDriverReadSelect(uint8_t ReadSelect); +uint8_t tmc262_getDriverSlopeHighSide(); +uint8_t tmc262_getDriverSlopeLowSide(); +uint8_t tmc262_getDriverDisableProtection(); +uint8_t tmc262_getDriverProtectionTimer(); +uint8_t tmc262_getDriverStepDirectionOff(); +uint8_t tmc262_getDriverVSenseScale(); +uint8_t tmc262_getDriverReadSelect(); + +void tmc262_disable(); +void tmc262_enable(); + +void tmc262_readState(uint8_t *Phases, uint8_t *MStep, uint32_t *StallGuard, uint8_t *SmartEnergy, uint8_t *Flags); + +void tmc262_getSPIData(uint8_t Index, int32_t *Data); + +#endif /* TMC_IC_TMC262_H_ */ diff --git a/firmware/lib/tmc/ic/TMC262/TMC262_Register.h b/firmware/lib/tmc/ic/TMC262/TMC262_Register.h new file mode 100755 index 0000000..041f268 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC262/TMC262_Register.h @@ -0,0 +1,152 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2023 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#ifndef TMC262_REGISTER_H +#define TMC262_REGISTER_H + + // addresses out auf address bits from write datagrams + #define TMC262_DRVCTRL 0 + #define TMC262_CHOPCONF 4 + #define TMC262_SMARTEN 5 + #define TMC262_SGCSCONF 6 + #define TMC262_DRVCONF 7 + + #define TMC262_DRVCTRL_SDOFF_MASK (0xFFFFF) + #define TMC262_DRVCTRL_MASK (0xFFFFF & ~((0x0F<<4) | (0x7F <<10))) + #define TMC262_CHOPCONF_MASK (0xFFFFF) + #define TMC262_SMARTEN_MASK (0xFFFFF & ~((0x01<<4) | (0x01<<7) | (0x01<<12))) + #define TMC262_SGCSCONF_MASK (0xFFFFF & ~((0x07<<5) | (0x01<<15))) + #define TMC262_DRVCONF_MASK (0xFFFFF & ~((0x0F<<0) | (0x01<<11))) + + // makro function to determine register address out of write datagram + #define TMC262_GET_ADDRESS(X) ((uint8_t) ((((X) >> 18) ? ((X)>>17) : 0) & 0x07)) + #define TMC262_WRITE (1<<3) + + + // makro function to shift register data fields to correct position with masking to add them to a write datagram like : + // write &= ~TMC262_SET_CB(-1); // clearing CB field of write datagram to DRVCTRL register + // write |= TMC262_SET_CB(5); // setting value 5 to CB field of write datagram to DRVCTRL register + + // for clearing use: + + #define TMC262_SET_CB(X) (((X) & 0xFF) << 0) + #define TMC262_SET_PHB(X) (((X) & 0x01) << 0) + #define TMC262_SET_CA(X) (((X) & 0xFF) << 9) + #define TMC262_SET_PHA(X) (((X) & 0xFF) << 17) + #define TMC262_SET_MRES(X) (((X) & 0x0F) << 0) + + #define TMC262_SET_DEDGE(X) (((X) & 0x01) << 8) + #define TMC262_SET_INTERPOL(X) (((X) & 0x01) << 9) + + // TMC262_CHOPCONF + #define TMC262_SET_TOFF(X) (((X) & 0x0F) << 0) + #define TMC262_SET_HSTRT(X) (((X) & 0x07) << 4) + #define TMC262_SET_HEND(X) (((X) & 0x0F) << 7) + #define TMC262_SET_HDEC(X) (((X) & 0x03) << 11) + #define TMC262_SET_RNDTF(X) (((X) & 0x01) << 13) + #define TMC262_SET_CHM(X) (((X) & 0x01) << 14) + #define TMC262_SET_TBL(X) (((X) & 0x03) << 15) + + // TMC262_SMARTEN + #define TMC262_SET_SEMIN(X) (((X) & 0x0F) << 0) + #define TMC262_SET_SEUP(X) (((X) & 0x03) << 5) + #define TMC262_SET_SEMAX(X) (((X) & 0x0F) << 8) + #define TMC262_SET_SEDN(X) (((X) & 0x03) << 13) + #define TMC262_SET_SEIMIN(X) (((X) & 0x01) << 15) + + + // TMC262_SGCSCONF + #define TMC262_SET_CS(X) (((X) & 0x1F) << 0) + #define TMC262_SET_SGT(X) (((X) & 0x7F) << 8) + #define TMC262_SET_SFILT(X) (((X) & 0x01) << 16) + + // TMC262_DRVCONF + #define TMC262_SET_RDSEL(X) (((X) & 0x03) << 4) + #define TMC262_SET_VSENSE(X) (((X) & 0x01) << 6) + #define TMC262_SET_SDOFF(X) (((X) & 0x01) << 7) + #define TMC262_SET_TS2G(X) (((X) & 0x03) << 8) + #define TMC262_SET_DISS2G(X) (((X) & 0x01) << 10) + #define TMC262_SET_SLPL(X) (((X) & 0x03) << 12) + #define TMC262_SET_SLPH(X) (((X) & 0x03) << 14) + #define TMC262_SET_TST(X) (((X) & 0x01) << 16) + + // makro function to shift register data fields to correct position with masking to read out values out of write datagram + + // cb = TMC262_GET_CB(write); // reading CB field of write datagram to DRVCTRL register + + // TMC262_DRVCTRL + #define TMC262_GET_CB(X) (0xFF & ((X) >> 0)) + #define TMC262_GET_PHB(X) (0x01 & ((X) >> 0)) + #define TMC262_GET_CA(X) (0xFF & ((X) >> 9)) + #define TMC262_GET_PHA(X) (0xFF & ((X) >> 17)) + #define TMC262_GET_MRES(X) (0x0F & ((X) >> 0)) + + #define TMC262_GET_DEDGE(X) (0x01 & ((X) >> 8)) + #define TMC262_GET_INTERPOL(X) (0x01 & ((X) >> 9)) + + // TMC262_CHOPCONF + #define TMC262_GET_TOFF(X) (0x0F & ((X) >> 0)) + #define TMC262_GET_HSTRT(X) (0x07 & ((X) >> 4)) + #define TMC262_GET_HEND(X) (0x0F & ((X) >> 7)) + #define TMC262_GET_HDEC(X) (0x03 & ((X) >> 11)) + #define TMC262_GET_RNDTF(X) (0x01 & ((X) >> 13)) + #define TMC262_GET_CHM(X) (0x01 & ((X) >> 14)) + #define TMC262_GET_TBL(X) (0x03 & ((X) >> 15)) + + // TMC262_SMARTEN + #define TMC262_GET_SEMIN(X) (0x0F & ((X) >> 0)) + #define TMC262_GET_SEUP(X) (0x03 & ((X) >> 5)) + #define TMC262_GET_SEMAX(X) (0x0F & ((X) >> 8)) + #define TMC262_GET_SEDN(X) (0x03 & ((X) >> 13)) + #define TMC262_GET_SEIMIN(X) (0x01 & ((X) >> 15)) + + // TMC262_SGCSCONF + #define TMC262_GET_CS(X) (0x1F & ((X) >> 0)) + #define TMC262_GET_SGT(X) (0x7F & ((X) >> 8)) + #define TMC262_GET_SFILT(X) (0x01 & ((X) >> 16)) + + // TMC262_DRVCONF + #define TMC262_GET_RDSEL(X) (0x03 & ((X) >> 4)) + #define TMC262_GET_VSENSE(X) (0x01 & ((X) >> 6)) + #define TMC262_GET_SDOFF(X) (0x01 & ((X) >> 7)) + #define TMC262_GET_TS2G(X) (0x03 & ((X) >> 8)) + #define TMC262_GET_DISS2G(X) (0x01 & ((X) >> 10)) + #define TMC262_GET_SLPL(X) (0x03 & ((X) >> 12)) + #define TMC262_GET_SLPH(X) (0x03 & ((X) >> 14)) + #define TMC262_GET_TST(X) (0x01 & ((X) >> 16)) + + // read addressescorrespondes with RDSEL, added latest to access latest data of common lower 7 bits + #define TMC262_RESPONSE0 0 + #define TMC262_RESPONSE1 1 + #define TMC262_RESPONSE2 2 + #define TMC262_RESPONSE_LATEST 3 + + // makro function to shift register data fields to correct position with masking to read out values out of read datagram + + // TMC262_RESPONSE0 + #define TMC262_GET_MSTEP(X) (0x3FF & ((X) >> 10)) + + // TMC262_RESPONSE1 + #define TMC262_GET_SG(X) (0x3FF & ((X) >> 10)) + + // TMC262_RESPONSE2 + #define TMC262_GET_SGU(X) (0x1F & ((X) >> 15)) + #define TMC262_GET_SE(X) (0x1F & ((X) >> 10)) + + // TMC262_RESPONSE_LATEST + #define TMC262_GET_STST(X) (0x01 & ((X) >> 7)) + #define TMC262_GET_OLB(X) (0x01 & ((X) >> 6)) + #define TMC262_GET_OLA(X) (0x01 & ((X) >> 5)) + #define TMC262_GET_S2GB(X) (0x01 & ((X) >> 4)) + #define TMC262_GET_S2GA(X) (0x01 & ((X) >> 3)) + #define TMC262_GET_OTPW(X) (0x01 & ((X) >> 2)) + #define TMC262_GET_OT(X) (0x01 & ((X) >> 1)) + #define TMC262_GET_SGF(X) (0x01 & ((X) >> 0)) + +#endif /* TMC262_REGISTER_H */ diff --git a/firmware/lib/tmc/ic/TMC2660/README.md b/firmware/lib/tmc/ic/TMC2660/README.md new file mode 100755 index 0000000..0ee7828 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2660/README.md @@ -0,0 +1,53 @@ +# TMC2660 + + +## How to use + +To access the TMC2660's registers, the TMC-API offers two functions: **tmc2660_readRegister** and **tmc2660_writeRegister**. +Each of these functions takes in an **icID**, which is used to identify the IC when multiple ICs are connected. This identifier is passed down to the callback functions (see How to Integrate). + +## How to integrate: overview + +1. Include all the files of the TMC-API/ic/tmc/TMC2660 folder into the custom project. +2. Include the TMC2660.h file in the custom source code. +3. Implement the necessary callback functions (see below). + +## Accessing the TMC2660 via SPI +The following diagram depicts how to access the TMC2660 via SPI using the TMC-API. + +### Reading a register +![screenshot](registercall_hierarchy_flowchart_SPIRead_tmc2660.svg) + +The description of the functions, in the above flowchart, are as follows: +- The functions tmc2660_readRegister and tmc2660_writeRegister are used to read and write the registers respectively. +- tmc2660_writeRegister function calls the readWrite function which constructs the datagram and further calls the bus specific callback 'tmcXXXX_readWriteSPI'. +- This callback function further calls the hardware specific read/write function for SPI and needs to be implemented externally. +- tmc2660_readRegister function calls readImmediately function if it has to read one of the three responses. +- readImmediately funciton sets the RDSEl bits in DRVCONF register and further calls the readwrite function to receive the response. + +### Writing a register +![screenshot](registercall_hierarchy_flowchart_SPIWrite_tmc2660.svg) + +Similarly, a register is written as depicted in the flowchart above. + +### How to integrate: Callback functions +In software we use a **continuousModeEnable** variable to distinguish between a normal mode and a continuous mode. In continuous mode we periodically read all the registers to keep them updated incase of brownout. For that, the callback function **tmc2660_getcontinuousModeEnable()** needs to be implemented. +Additionally, implement the following callback functions to access the chip via SPI: +**tmc2660_readWriteSPI()**, which is a HAL wrapper function that provides the necessary hardware access. This function should also set the chip select pin CSN to low before starting the data transfer and set to high upon completion. Please refer to the datasheet of the IC for further details. + +### Option to use the cache logic for Write-Only registers +The chip features write-only registers that are unable to be read, necessitating the creation of a shadow copy to cache their contents. This copy is automatically updated whenever data is written to these registers. This cache logic could be enabled by setting the macro **TMC2660_CACHE** to **'1'** or disabled by setting to **'0'** respectively. If this feature is enabled then there comes another option to use **tmc2660_cache** function, which is already implemeted in the API, by defining **TMC2660_ENABLE_TMC_CACHE** macro to **'1** or one can implement their own function. The function **tmc2660_cache** works for both reading from and writing to the shadow array. It first checks whether the register has write-only access and data needs to be read from the hadow copy. On the basis of that, it returns **true** or **false**. The shadowRegisters on the premade cache implementation need to be one per chip. **TMC2660_IC_CACHE_COUNT** is set to '1' by default and is user-overwritable. If multiple chips are being used in the same project, increment its value to the number of chips connected. + +## Further info +### Dependency graph for the ICs with new register R/W mechanism +This graph illustrates the relationships between files within the TMC-API library, highlighting dependencies and identifying the files that are essential for integrating the library into the custom projects. + +![screenshot](uml-tmc-api.svg) + +### Example usage: TMC-Evalsystem +**For a reference usage of the TMC-API**, visit the [TMC-Evalsystem](https://github.com/analogdevicesinc/TMC-EvalSystem) + +## Migration status +The TMC2660 has been reworked to the access system described above. For more infos on the status of this and other ICs, check out the [migration page](https://github.com/analogdevicesinc/TMC-API/issues/53). + + diff --git a/firmware/lib/tmc/ic/TMC2660/TMC2660.c b/firmware/lib/tmc/ic/TMC2660/TMC2660.c new file mode 100755 index 0000000..337c5e6 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2660/TMC2660.c @@ -0,0 +1,153 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + +#include "TMC2660.h" + +/**************************************************************** Cache Implementation *************************************************************************/ + +#if TMC2660_CACHE == 0 +static inline bool tmc2660_cache(uint16_t icID, TMC2660CacheOp operation, uint8_t address, uint32_t *value) +{ + UNUSED(icID); + UNUSED(address); + UNUSED(operation); + return false; +} +#else +#if TMC2660_ENABLE_TMC_CACHE == 1 +int32_t tmc2660_shadowRegister[TMC2660_IC_CACHE_COUNT][TMC2660_REGISTER_COUNT]; + +/* + * This function is used to cache the value written to the Write-Only registers in the form of shadow array. + * The shadow copy is then used to read these kinds of registers. + */ +bool tmc2660_cache(uint16_t icID, TMC2660CacheOp operation, uint8_t address, uint32_t *value) +{ + if (operation == TMC2660_CACHE_READ) + { + // Check if the value should come from cache + + // Only supported chips have a cache + if (icID >= TMC2660_IC_CACHE_COUNT) + return false; + + // Only non-readable registers care about caching + // Note: This could also be used to cache i.e. RW config registers to reduce bus accesses + if (TMC2660_IS_READABLE(tmc2660_registerAccess[address])) + return false; + + // Grab the value from the cache + *value = tmc2660_shadowRegister[icID][address]; + return true; + } + else if (operation == TMC2660_CACHE_WRITE || operation == TMC2660_CACHE_FILL_DEFAULT) + { + // Fill the cache + + // only supported chips have a cache + if (icID >= TMC2660_IC_CACHE_COUNT) + return false; + + // Write to the shadow register + tmc2660_shadowRegister[icID][address] = *value; + + return true; + } + return false; +} + +#else +// User must implement their own cache +extern bool tmc2660_cache(uint16_t icID, TMC2660CacheOp operation, uint8_t address, uint32_t *value); +#endif +#endif + +/************************************************************** Register read / write Implementation ******************************************************************/ + +void readWrite(uint8_t icID, uint32_t datagram) +{ + uint8_t data[3] = {0}; + uint32_t reply; + uint8_t rdsel = TMC2660_GET_RDSEL(datagram); + + data[0] = 0xFF & (datagram >> 16); + data[1] = 0xFF & (datagram >> 8); + data[2] = 0xFF & (datagram >> 0); + + // Send 24 bytes of data and receive reply + tmc2660_readWriteSPI(icID, &data[0], sizeof(data)); + + reply = (data[0] << 16 | data[1] << 8 | data[2]) >> 4; + + // write value to response shadow register + tmc2660_shadowRegister[icID][rdsel] = reply; + + // Store the latest response value to extract status bits in tmc2660_getStatusBits() + tmc2660_shadowRegister[icID][TMC2660_RESPONSE_LATEST] = reply; + + // write value to response shadow register + if (TMC2660_GET_ADDRESS(datagram) == TMC2660_DRVCONF) + rdsel = TMC2660_GET_RDSEL(datagram); + + // write value to shadow register + tmc2660_shadowRegister[icID][TMC2660_GET_ADDRESS(datagram) | TMC2660_WRITE_BIT] = datagram; +} + +void readImmediately(uint8_t icID, uint8_t rdsel) +{ + // sets desired reply in DRVCONF register, resets it to previous settings whilst reading desired reply + uint32_t value; + + // additional reading to keep all replies up to date + value = tmc2660_readRegister(0, TMC2660_DRVCONF); // buffer (value and drvConf) to write back later + value &= ~TMC2660_SET_RDSEL(-1); // clear RDSEL bits + value |= TMC2660_SET_RDSEL(rdsel % 3); // set rdsel + readWrite(icID, value); // write to chip and readout reply + readWrite(icID, value); // write to chip and return desired reply +} + +void tmc2660_writeRegister(uint8_t icID, uint8_t address, uint32_t value) +{ + // Don't write to read-only registers + if (TMC2660_IS_READONLY_REGISTER(address)) + return; + + // Extract 20 bits of valid data + value &= 0x0FFFFF; + + //Cache the registers with write-only access + tmc2660_cache(icID, TMC2660_CACHE_WRITE, address, &value); + + // 0XF7 to mask the write bit + if (!tmc2660_getcontinuousModeEnable(icID)) + readWrite(icID, TMC2660_DATAGRAM((address & 0xF7), value)); +} + +uint32_t tmc2660_readRegister(uint8_t icID, uint8_t address) +{ + uint32_t value; + + // Read from cache for registers with write-only access + if (tmc2660_cache(icID, TMC2660_CACHE_READ, address, &value)) + return value; + + if (!tmc2660_getcontinuousModeEnable(icID)) + { + // Read the read-only register, refreshing the cache + readImmediately(icID, address); + } + + // Return the read-only register from cache + return tmc2660_shadowRegister[icID][address]; +} + +uint8_t tmc2660_getStatusBits(uint8_t icID) +{ + // Grab the status bits from the last request + return tmc2660_shadowRegister[icID][TMC2660_RESPONSE_LATEST] & TMC2660_STATUS_MASK; +} diff --git a/firmware/lib/tmc/ic/TMC2660/TMC2660.h b/firmware/lib/tmc/ic/TMC2660/TMC2660.h new file mode 100755 index 0000000..e682be4 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2660/TMC2660.h @@ -0,0 +1,168 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#ifndef TMC_IC_TMC2660_H_ +#define TMC_IC_TMC2660_H_ + +#include "TMC2660_HW_Abstraction.h" +#include +#include +#include + +/******************************************************************************* +* API Configuration Defines +* These control optional features of the TMC-API implementation. +* These can be commented in/out here or defined from the build system. +*******************************************************************************/ + +#ifndef TMC2660_CACHE +#define TMC2660_CACHE 1 +//#define TMC2660_CACHE 0 +#endif + +// To use the caching mechanism already implemented by the TMC-API, set TMC2660_ENABLE_TMC_CACHE to '1'. +// Set TMC2660_ENABLE_TMC_CACHE to '0' if one wants to have their own cache implementation. +#ifndef TMC2660_ENABLE_TMC_CACHE +#define TMC2660_ENABLE_TMC_CACHE 1 +//#define TMC2660_ENABLE_TMC_CACHE 0 +#endif + +/******************************************************************************/ + +typedef struct +{ + uint32_t mask; + uint8_t shift; + uint8_t address; + bool isSigned; +} TMC2660RegisterField; + +//TMC-API wrapper +extern uint8_t tmc2660_getcontinuousModeEnable(uint8_t icID); +extern void tmc2660_readWriteSPI(uint16_t icID, uint8_t *data, size_t dataLength); +//TMC-API wrapper + +void tmc2660_writeRegister(uint8_t icID, uint8_t address, uint32_t value); +uint32_t tmc2660_readRegister(uint8_t icID, uint8_t address); +uint8_t tmc2660_getStatusBits(uint8_t icID); +void readWrite(uint8_t icID, uint32_t value); +void readImmediately(uint8_t icID, uint8_t rdsel); + +static inline uint32_t tmc2660_fieldExtract(uint32_t data, TMC2660RegisterField field) +{ + uint32_t value = (data & field.mask) >> field.shift; + + if (field.isSigned) + { + // Apply signedness conversion + uint32_t baseMask = field.mask >> field.shift; + uint32_t signMask = baseMask & (~baseMask >> 1); + value = (value ^ signMask) - signMask; + } + + return value; +} + +static inline uint32_t tmc2660_fieldRead(uint16_t icID, TMC2660RegisterField field) +{ + uint32_t value = tmc2660_readRegister(icID, field.address); + + return tmc2660_fieldExtract(value, field); +} + +static inline uint32_t tmc2660_fieldUpdate(uint32_t data, TMC2660RegisterField field, uint32_t value) +{ + return (data & (~field.mask)) | ((value << field.shift) & field.mask); +} + +static inline void tmc2660_fieldWrite(uint16_t icID, TMC2660RegisterField field, uint32_t value) +{ + uint32_t regValue = tmc2660_readRegister(icID, field.address); + + regValue = tmc2660_fieldUpdate(regValue, field, value); + + tmc2660_writeRegister(icID, field.address, regValue); +} + +/**************************************************************** Cache Implementation *************************************************************************/ + +#if TMC2660_CACHE == 1 +#if TMC2660_ENABLE_TMC_CACHE == 1 + +// By default, support one IC in the cache +#ifndef TMC2660_IC_CACHE_COUNT +#define TMC2660_IC_CACHE_COUNT 1 +#endif + +typedef enum { + TMC2660_CACHE_READ, + TMC2660_CACHE_WRITE, + + // Special operation: Put content into the cache without marking the entry as dirty. + // Only used to initialize the cache with hardware defaults. This will allow reading + // from write-only registers that have a value inside them on reset. When using this + // operation, a restore will *not* rewrite that filled register! + TMC2660_CACHE_FILL_DEFAULT +} TMC2660CacheOp; + +#define TMC_ACCESS_READ 0x01 +#define TMC2660_IS_READABLE(x) ((x) & TMC_ACCESS_READ) +#define TMC_ACCESS_NONE 0x00 +#define TMC_ACCESS_WRITE 0x02 + +static const uint8_t tmc2660_registerAccess[TMC2660_REGISTER_COUNT] = +{ + TMC_ACCESS_READ, // 0: RESPONSE 0 + TMC_ACCESS_READ, // 1: RESPONSE 1 + TMC_ACCESS_READ, // 2: RESPONSE 2 + TMC_ACCESS_READ, // 3: RESPONSE_LATEST + TMC_ACCESS_NONE, // 4: UNUSED + TMC_ACCESS_NONE, // 5: UNUSED + TMC_ACCESS_NONE, // 6: UNUSED + TMC_ACCESS_NONE, // 7: UNUSED + TMC_ACCESS_WRITE, // 8: DRVCTRL + TMC_ACCESS_NONE, // 9: UNUSED + TMC_ACCESS_NONE, // A: UNUSED + TMC_ACCESS_NONE, // B: UNUSED + TMC_ACCESS_WRITE, // C: CHOPCONF + TMC_ACCESS_WRITE, // D: SMARTEN + TMC_ACCESS_WRITE, // E: SGCSCONF + TMC_ACCESS_WRITE // F: DRVCONF +}; + +static const int32_t tmc2660_sampleRegisterPreset[TMC2660_REGISTER_COUNT] = +{ + 0x00000000, // 0: UNUSED + 0x00000000, // 1: UNUSED + 0x00000000, // 2: UNUSED + 0x00000000, // 3: UNUSED + 0x00000000, // 4: UNUSED + 0x00000000, // 5: UNUSED + 0x00000000, // 6: UNUSED + 0x00000000, // 7: UNUSED + 0x00000000, // 8: DRVCTRL + 0x00000000, // 9: UNUSED + 0x00000000, // A: UNUSED + 0x00000000, // B: UNUSED + 0x00091935, // C: CHOPCONF + 0x000A0000, // D: SMARTEN + 0x000D0505, // E: SGCSCONF + 0x000EF040 // F: DRVCONF +}; + + +extern bool tmc2660_cache(uint16_t icID, TMC2660CacheOp operation, uint8_t address, uint32_t *value); +extern int32_t tmc2660_shadowRegister[TMC2660_IC_CACHE_COUNT][TMC2660_REGISTER_COUNT]; + +#endif +#endif + +/***************************************************************************************************************************************************/ + +#endif /* TMC_IC_TMC2660_H_ */ diff --git a/firmware/lib/tmc/ic/TMC2660/TMC2660_HW_Abstraction.h b/firmware/lib/tmc/ic/TMC2660/TMC2660_HW_Abstraction.h new file mode 100755 index 0000000..11fdc9c --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2660/TMC2660_HW_Abstraction.h @@ -0,0 +1,298 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2025 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + +#ifndef TMC2660_HW_ABSTRACTION +#define TMC2660_HW_ABSTRACTION + +//Constants + +#define TMC2660_REGISTER_COUNT 16 // Actual Count is 8, but due to mapping, we write 16 +#define TMC2660_MOTORS 1 +#define TMC2660_WRITE_BIT 0x08 +#define TMC2660_ADDRESS_MASK 0x07 +#define TMC2660_ADDRESS_SHIFT 20 +#define TMC2660_STATUS_MASK 0xFF +#define TMC2660_VALUE_MASK 0xFFFFF +#define TMC2660_VALUE_SHIFT 0 +#define TMC2660_MAX_VELOCITY (int32_t) 2147483647 +#define TMC2660_MAX_ACCELERATION (uint32_t) 16777215uL + +#define TMC2660_IS_WRITEONLY_REGISTER(addr) ((addr & TMC2660_WRITE_BIT) == 1) +#define TMC2660_IS_READONLY_REGISTER(addr) ((addr & TMC2660_WRITE_BIT) == 0) + +#define TMC2660_IS_WRITE(datagram) ((datagram) >> (TMC2660_ADDRESS_SHIFT + 3)) +#define TMC2660_ADDRESS(datagram) (((datagram) >> TMC2660_ADDRESS_SHIFT) & TMC2660_ADDRESS_MASK) +#define TMC2660_VALUE(datagram) ((datagram) & TMC2660_VALUE_MASK) + +// Helper macro to determine register address out of write datagram +#define TMC2660_GET_ADDRESS(datagram) ((uint8_t) ((((datagram) >> 18) ? ((datagram)>>17) : 0) & 0x07)) + +// Helper macro to construct the datagram out of the address and the value +#define TMC2660_DATAGRAM(addr, value) (((addr) << 17) | (value)) + +//registers definitions + +// addresses out auf address bits from write datagrams +#define TMC2660_RESPONSE0 0x00 +#define TMC2660_RESPONSE1 0x01 +#define TMC2660_RESPONSE2 0x02 +#define TMC2660_RESPONSE_LATEST 0x03 + +// Addresses of the write-only registers +// Note: This software abstraction maps the registers to addresses 8 and up +#define TMC2660_WRITE_ONLY_REGISTER 0x08 +#define TMC2660_DRVCTRL (0x00 | TMC2660_WRITE_ONLY_REGISTER) // 8 +#define TMC2660_CHOPCONF (0x04 | TMC2660_WRITE_ONLY_REGISTER) // C +#define TMC2660_SMARTEN (0x05 | TMC2660_WRITE_ONLY_REGISTER) // D +#define TMC2660_SGCSCONF (0x06 | TMC2660_WRITE_ONLY_REGISTER) // E +#define TMC2660_DRVCONF (0x07 | TMC2660_WRITE_ONLY_REGISTER) // F + + +//fields definitions + +#define TMC2660_MSTEP_MASK 0x000FFC00 +#define TMC2660_MSTEP_SHIFT 10 +#define TMC2660_MSTEP_FIELD ((TMC2660RegisterField) {TMC2660_MSTEP_MASK, TMC2660_MSTEP_SHIFT, TMC2660_RESPONSE0, false}) +#define TMC2660_SE_MASK 0x00007C00 +#define TMC2660_SE_SHIFT 10 +#define TMC2660_SE_FIELD ((TMC2660RegisterField) {TMC2660_SE_MASK, TMC2660_SE_SHIFT, TMC2660_RESPONSE2, false}) +#define TMC2660_SGU_MASK 0x0F8000 +#define TMC2660_SGU_SHIFT 15 +#define TMC2660_SGU_FIELD ((TMC2660RegisterField) {TMC2660_SGU_MASK, TMC2660_SGU_SHIFT, TMC2660_RESPONSE2, false}) +#define TMC2660_SG2_MASK 0x0FFC00 +#define TMC2660_SG2_SHIFT 10 +#define TMC2660_SG2_FIELD ((TMC2660RegisterField) {TMC2660_SG2_MASK, TMC2660_SG2_SHIFT, TMC2660_RESPONSE1, false}) +#define TMC2660_REGISTER_ADDRESS_BITS_MASK 0x000C0000 +#define TMC2660_REGISTER_ADDRESS_BITS_SHIFT 18 +#define TMC2660_REGISTER_ADDRESS_BITS_FIELD ((TMC2660RegisterField) {TMC2660_REGISTER_ADDRESS_BITS_MASK, TMC2660_REGISTER_ADDRESS_BITS_SHIFT, TMC2660_DRVCTRL, false}) +#define TMC2660_INTPOL_MASK 0x00000200 +#define TMC2660_INTPOL_SHIFT 9 +#define TMC2660_INTPOL_FIELD ((TMC2660RegisterField) {TMC2660_INTPOL_MASK, TMC2660_INTPOL_SHIFT, TMC2660_DRVCTRL, false}) +#define TMC2660_DEDGE_MASK 0x00000100 +#define TMC2660_DEDGE_SHIFT 8 +#define TMC2660_DEDGE_FIELD ((TMC2660RegisterField) {TMC2660_DEDGE_MASK, TMC2660_DEDGE_SHIFT, TMC2660_DRVCTRL, false}) +#define TMC2660_MRES_MASK 0x0000000F +#define TMC2660_MRES_SHIFT 0 +#define TMC2660_MRES_FIELD ((TMC2660RegisterField) {TMC2660_MRES_MASK, TMC2660_MRES_SHIFT, TMC2660_DRVCTRL, false}) +//#define TMC2660_REGISTER_ADDRESS_BITS_MASK 0x000E0000 +//#define TMC2660_REGISTER_ADDRESS_BITS_SHIFT 17 +//#define TMC2660_REGISTER_ADDRESS_BITS_FIELD ((TMC2660RegisterField) {TMC2660_REGISTER_ADDRESS_BITS_MASK, TMC2660_REGISTER_ADDRESS_BITS_SHIFT, TMC2660_DRVCTRL, false}) +#define TMC2660_PHA_MASK 0x00020000 +#define TMC2660_PHA_SHIFT 17 +#define TMC2660_PHA_FIELD ((TMC2660RegisterField) {TMC2660_PHA_MASK, TMC2660_PHA_SHIFT, TMC2660_DRVCTRL, false}) +#define TMC2660_CA_MASK 0x0001FE00 +#define TMC2660_CA_SHIFT 9 +#define TMC2660_CA_FIELD ((TMC2660RegisterField) {TMC2660_CA_MASK, TMC2660_CA_SHIFT, TMC2660_DRVCTRL, false}) +#define TMC2660_PHB_MASK 0x00000100 +#define TMC2660_PHB_SHIFT 8 +#define TMC2660_PHB_FIELD ((TMC2660RegisterField) {TMC2660_PHB_MASK, TMC2660_PHB_SHIFT, TMC2660_DRVCTRL, false}) +#define TMC2660_CB_MASK 0x000000FF +#define TMC2660_CB_SHIFT 0 +#define TMC2660_CB_FIELD ((TMC2660RegisterField) {TMC2660_CB_MASK, TMC2660_CB_SHIFT, TMC2660_DRVCTRL, false}) +//#define TMC2660_REGISTER_ADDRESS_BITS_MASK 0x000E0000 +//#define TMC2660_REGISTER_ADDRESS_BITS_SHIFT 17 +//#define TMC2660_REGISTER_ADDRESS_BITS_FIELD ((TMC2660RegisterField) {TMC2660_REGISTER_ADDRESS_BITS_MASK, TMC2660_REGISTER_ADDRESS_BITS_SHIFT, TMC2660_CHOPCONF, false}) +#define TMC2660_TBL_MASK 0x00018000 +#define TMC2660_TBL_SHIFT 15 +#define TMC2660_TBL_FIELD ((TMC2660RegisterField) {TMC2660_TBL_MASK, TMC2660_TBL_SHIFT, TMC2660_CHOPCONF, false}) +#define TMC2660_CHM_MASK 0x00004000 +#define TMC2660_CHM_SHIFT 14 +#define TMC2660_CHM_FIELD ((TMC2660RegisterField) {TMC2660_CHM_MASK, TMC2660_CHM_SHIFT, TMC2660_CHOPCONF, false}) +#define TMC2660_RNDTF_MASK 0x00002000 +#define TMC2660_RNDTF_SHIFT 13 +#define TMC2660_RNDTF_FIELD ((TMC2660RegisterField) {TMC2660_RNDTF_MASK, TMC2660_RNDTF_SHIFT, TMC2660_CHOPCONF, false}) +#define TMC2660_HDEC_MASK 0x00001800 +#define TMC2660_HDEC_SHIFT 11 +#define TMC2660_HDEC_FIELD ((TMC2660RegisterField) {TMC2660_HDEC_MASK, TMC2660_HDEC_SHIFT, TMC2660_CHOPCONF, false}) +#define TMC2660_HEND_MASK 0x00000780 +#define TMC2660_HEND_SHIFT 7 +#define TMC2660_HEND_FIELD ((TMC2660RegisterField) {TMC2660_HEND_MASK, TMC2660_HEND_SHIFT, TMC2660_CHOPCONF, false}) +#define TMC2660_HSTRT_MASK 0x00000070 +#define TMC2660_HSTRT_SHIFT 4 +#define TMC2660_HSTRT_FIELD ((TMC2660RegisterField) {TMC2660_HSTRT_MASK, TMC2660_HSTRT_SHIFT, TMC2660_CHOPCONF, false}) +#define TMC2660_HDEC1_MASK 0x00001000 +#define TMC2660_HDEC1_SHIFT 12 +#define TMC2660_HDEC1_FIELD ((TMC2660RegisterField) {TMC2660_HDEC1_MASK, TMC2660_HDEC1_SHIFT, TMC2660_CHOPCONF, false}) +#define TMC2660_HDEC0_MASK 0x00000800 +#define TMC2660_HDEC0_SHIFT 11 +#define TMC2660_HDEC0_FIELD ((TMC2660RegisterField) {TMC2660_HDEC0_MASK, TMC2660_HDEC0_SHIFT, TMC2660_CHOPCONF, false}) +#define TMC2660_TOFF_MASK 0x0000000F +#define TMC2660_TOFF_SHIFT 0 +#define TMC2660_TOFF_FIELD ((TMC2660RegisterField) {TMC2660_TOFF_MASK, TMC2660_TOFF_SHIFT, TMC2660_CHOPCONF, false}) +//#define TMC2660_REGISTER_ADDRESS_BITS_MASK 0x000E0000 +//#define TMC2660_REGISTER_ADDRESS_BITS_SHIFT 17 +//#define TMC2660_REGISTER_ADDRESS_BITS_FIELD ((TMC2660RegisterField) {TMC2660_REGISTER_ADDRESS_BITS_MASK, TMC2660_REGISTER_ADDRESS_BITS_SHIFT, TMC2660_SMARTEN, false}) +#define TMC2660_SEIMIN_MASK 0x00008000 +#define TMC2660_SEIMIN_SHIFT 15 +#define TMC2660_SEIMIN_FIELD ((TMC2660RegisterField) {TMC2660_SEIMIN_MASK, TMC2660_SEIMIN_SHIFT, TMC2660_SMARTEN, false}) +#define TMC2660_SEDN_MASK 0x00006000 +#define TMC2660_SEDN_SHIFT 13 +#define TMC2660_SEDN_FIELD ((TMC2660RegisterField) {TMC2660_SEDN_MASK, TMC2660_SEDN_SHIFT, TMC2660_SMARTEN, false}) +#define TMC2660_SEUP_MASK 0x00000060 +#define TMC2660_SEUP_SHIFT 5 +#define TMC2660_SEUP_FIELD ((TMC2660RegisterField) {TMC2660_SEUP_MASK, TMC2660_SEUP_SHIFT, TMC2660_SMARTEN, false}) +#define TMC2660_SEMAX_MASK 0x00000F00 +#define TMC2660_SEMAX_SHIFT 8 +#define TMC2660_SEMAX_FIELD ((TMC2660RegisterField) {TMC2660_SEMAX_MASK, TMC2660_SEMAX_SHIFT, TMC2660_SMARTEN, false}) +#define TMC2660_SEMIN_MASK 0x0000000F +#define TMC2660_SEMIN_SHIFT 0 +#define TMC2660_SEMIN_FIELD ((TMC2660RegisterField) {TMC2660_SEMIN_MASK, TMC2660_SEMIN_SHIFT, TMC2660_SMARTEN, false}) +//#define TMC2660_REGISTER_ADDRESS_BITS_MASK 0x000E0000 +//#define TMC2660_REGISTER_ADDRESS_BITS_SHIFT 17 +//#define TMC2660_REGISTER_ADDRESS_BITS_FIELD ((TMC2660RegisterField) {TMC2660_REGISTER_ADDRESS_BITS_MASK, TMC2660_REGISTER_ADDRESS_BITS_SHIFT, TMC2660_SGCSCONF, false}) +#define TMC2660_SFILT_MASK 0x00010000 +#define TMC2660_SFILT_SHIFT 16 +#define TMC2660_SFILT_FIELD ((TMC2660RegisterField) {TMC2660_SFILT_MASK, TMC2660_SFILT_SHIFT, TMC2660_SGCSCONF, false}) +#define TMC2660_SGT_MASK 0x00007F00 +#define TMC2660_SGT_SHIFT 8 +#define TMC2660_SGT_FIELD ((TMC2660RegisterField) {TMC2660_SGT_MASK, TMC2660_SGT_SHIFT, TMC2660_SGCSCONF, false}) +#define TMC2660_CS_MASK 0x0000001F +#define TMC2660_CS_SHIFT 0 +#define TMC2660_CS_FIELD ((TMC2660RegisterField) {TMC2660_CS_MASK, TMC2660_CS_SHIFT, TMC2660_SGCSCONF, false}) +//#define TMC2660_REGISTER_ADDRESS_BITS_MASK 0x000E0000 +//#define TMC2660_REGISTER_ADDRESS_BITS_SHIFT 17 +//#define TMC2660_REGISTER_ADDRESS_BITS_FIELD ((TMC2660RegisterField) {TMC2660_REGISTER_ADDRESS_BITS_MASK, TMC2660_REGISTER_ADDRESS_BITS_SHIFT, TMC2660_DRVCONF, false}) +#define TMC2660_TST_MASK 0x00010000 +#define TMC2660_TST_SHIFT 16 +#define TMC2660_TST_FIELD ((TMC2660RegisterField) {TMC2660_TST_MASK, TMC2660_TST_SHIFT, TMC2660_DRVCONF, false}) +#define TMC2660_SLPH_MASK 0x0000C000 +#define TMC2660_SLPH_SHIFT 14 +#define TMC2660_SLPH_FIELD ((TMC2660RegisterField) {TMC2660_SLPH_MASK, TMC2660_SLPH_SHIFT, TMC2660_DRVCONF, false}) +#define TMC2660_SLPL_MASK 0x00003000 +#define TMC2660_SLPL_SHIFT 12 +#define TMC2660_SLPL_FIELD ((TMC2660RegisterField) {TMC2660_SLPL_MASK, TMC2660_SLPL_SHIFT, TMC2660_DRVCONF, false}) +#define TMC2660_DISS2G_MASK 0x00000400 +#define TMC2660_DISS2G_SHIFT 10 +#define TMC2660_DISS2G_FIELD ((TMC2660RegisterField) {TMC2660_DISS2G_MASK, TMC2660_DISS2G_SHIFT, TMC2660_DRVCONF, false}) +#define TMC2660_TS2G_MASK 0x00000300 +#define TMC2660_TS2G_SHIFT 8 +#define TMC2660_TS2G_FIELD ((TMC2660RegisterField) {TMC2660_TS2G_MASK, TMC2660_TS2G_SHIFT, TMC2660_DRVCONF, false}) +#define TMC2660_SDOFF_MASK 0x00000080 +#define TMC2660_SDOFF_SHIFT 7 +#define TMC2660_SDOFF_FIELD ((TMC2660RegisterField) {TMC2660_SDOFF_MASK, TMC2660_SDOFF_SHIFT, TMC2660_DRVCONF, false}) +#define TMC2660_VSENSE_MASK 0x00000040 +#define TMC2660_VSENSE_SHIFT 6 +#define TMC2660_VSENSE_FIELD ((TMC2660RegisterField) {TMC2660_VSENSE_MASK, TMC2660_VSENSE_SHIFT, TMC2660_DRVCONF, false}) +#define TMC2660_RDSEL_MASK 0x00000030 +#define TMC2660_RDSEL_SHIFT 4 +#define TMC2660_RDSEL_FIELD ((TMC2660RegisterField) {TMC2660_RDSEL_MASK, TMC2660_RDSEL_SHIFT, TMC2660_DRVCONF, false}) + +// makro function to shift register data fields to correct position with masking to add them to a write datagram like : +// write &= ~TMC2660_SET_CB(-1); // clearing CB field of write datagram to DRVCTRL register +// write |= TMC2660_SET_CB(5); // setting value 5 to CB field of write datagram to DRVCTRL register + +// for clearing use: + +#define TMC2660_SET_CB(X) (((X) & 0xFF) << 0) +#define TMC2660_SET_PHB(X) (((X) & 0x01) << 0) +#define TMC2660_SET_CA(X) (((X) & 0xFF) << 9) +#define TMC2660_SET_PHA(X) (((X) & 0xFF) << 17) +#define TMC2660_SET_MRES(X) (((X) & 0x0F) << 0) + +#define TMC2660_SET_DEDGE(X) (((X) & 0x01) << 8) +#define TMC2660_SET_INTERPOL(X) (((X) & 0x01) << 9) + +// TMC2660_CHOPCONF +#define TMC2660_SET_TOFF(X) (((X) & 0x0F) << 0) +#define TMC2660_SET_HSTRT(X) (((X) & 0x07) << 4) +#define TMC2660_SET_HEND(X) (((X) & 0x0F) << 7) +#define TMC2660_SET_HDEC(X) (((X) & 0x03) << 11) +#define TMC2660_SET_RNDTF(X) (((X) & 0x01) << 13) +#define TMC2660_SET_CHM(X) (((X) & 0x01) << 14) +#define TMC2660_SET_TBL(X) (((X) & 0x03) << 15) + +// TMC2660_SMARTEN +#define TMC2660_SET_SEMIN(X) (((X) & 0x0F) << 0) +#define TMC2660_SET_SEUP(X) (((X) & 0x03) << 5) +#define TMC2660_SET_SEMAX(X) (((X) & 0x0F) << 8) +#define TMC2660_SET_SEDN(X) (((X) & 0x03) << 13) +#define TMC2660_SET_SEIMIN(X) (((X) & 0x01) << 15) + + +// TMC2660_SGCSCONF +#define TMC2660_SET_CS(X) (((X) & 0x1F) << 0) +#define TMC2660_SET_SGT(X) (((X) & 0x7F) << 8) +#define TMC2660_SET_SFILT(X) (((X) & 0x01) << 16) + +// TMC2660_DRVCONF +#define TMC2660_SET_RDSEL(X) (((X) & 0x03) << 4) +#define TMC2660_SET_VSENSE(X) (((X) & 0x01) << 6) +#define TMC2660_SET_SDOFF(X) (((X) & 0x01) << 7) +#define TMC2660_SET_TS2G(X) (((X) & 0x03) << 8) +#define TMC2660_SET_DISS2G(X) (((X) & 0x01) << 10) +#define TMC2660_SET_SLPL(X) (((X) & 0x03) << 12) +#define TMC2660_SET_SLPH(X) (((X) & 0x03) << 14) +#define TMC2660_SET_TST(X) (((X) & 0x01) << 16) + +// makro function to shift register data fields to correct position with masking to read out values out of write datagram + +// cb = TMC2660_GET_CB(write); // reading CB field of write datagram to DRVCTRL register + +// TMC2660_DRVCTRL +#define TMC2660_GET_CB(X) (0xFF & ((X) >> 0)) +#define TMC2660_GET_PHB(X) (0x01 & ((X) >> 0)) +#define TMC2660_GET_CA(X) (0xFF & ((X) >> 9)) +#define TMC2660_GET_PHA(X) (0xFF & ((X) >> 17)) +#define TMC2660_GET_MRES(X) (0x0F & ((X) >> 0)) + +#define TMC2660_GET_DEDGE(X) (0x01 & ((X) >> 8)) +#define TMC2660_GET_INTERPOL(X) (0x01 & ((X) >> 9)) + +// TMC2660_CHOPCONF +#define TMC2660_GET_TOFF(X) (0x0F & ((X) >> 0)) +#define TMC2660_GET_HSTRT(X) (0x07 & ((X) >> 4)) +#define TMC2660_GET_HEND(X) (0x0F & ((X) >> 7)) +#define TMC2660_GET_HDEC(X) (0x03 & ((X) >> 11)) +#define TMC2660_GET_RNDTF(X) (0x01 & ((X) >> 13)) +#define TMC2660_GET_CHM(X) (0x01 & ((X) >> 14)) +#define TMC2660_GET_TBL(X) (0x03 & ((X) >> 15)) + +// TMC2660_SMARTEN +#define TMC2660_GET_SEMIN(X) (0x0F & ((X) >> 0)) +#define TMC2660_GET_SEUP(X) (0x03 & ((X) >> 5)) +#define TMC2660_GET_SEMAX(X) (0x0F & ((X) >> 8)) +#define TMC2660_GET_SEDN(X) (0x03 & ((X) >> 13)) +#define TMC2660_GET_SEIMIN(X) (0x01 & ((X) >> 15)) + +// TMC2660_SGCSCONF +#define TMC2660_GET_CS(X) (0x1F & ((X) >> 0)) +#define TMC2660_GET_SGT(X) (0x7F & ((X) >> 8)) +#define TMC2660_GET_SFILT(X) (0x01 & ((X) >> 16)) + +// TMC2660_DRVCONF +#define TMC2660_GET_RDSEL(X) (0x03 & ((X) >> 4)) +#define TMC2660_GET_VSENSE(X) (0x01 & ((X) >> 6)) +#define TMC2660_GET_SDOFF(X) (0x01 & ((X) >> 7)) +#define TMC2660_GET_TS2G(X) (0x03 & ((X) >> 8)) +#define TMC2660_GET_DISS2G(X) (0x01 & ((X) >> 10)) +#define TMC2660_GET_SLPL(X) (0x03 & ((X) >> 12)) +#define TMC2660_GET_SLPH(X) (0x03 & ((X) >> 14)) +#define TMC2660_GET_TST(X) (0x01 & ((X) >> 16)) + +// makro function to shift register data fields to correct position with masking to read out values out of read datagram + +// TMC2660_RESPONSE0 +#define TMC2660_GET_MSTEP(X) (0x3FF & ((X) >> 10)) + +// TMC2660_RESPONSE1 +#define TMC2660_GET_SG(X) (0x3FF & ((X) >> 10)) + +// TMC2660_RESPONSE2 +#define TMC2660_GET_SGU(X) (0x1F & ((X) >> 15)) +#define TMC2660_GET_SE(X) (0x1F & ((X) >> 10)) + +// General status bits (contained in all TMC2660_RESPONSE0, 1 and 2) +#define TMC2660_GET_STST(X) (0x01 & ((X) >> 7)) +#define TMC2660_GET_OLB(X) (0x01 & ((X) >> 6)) +#define TMC2660_GET_OLA(X) (0x01 & ((X) >> 5)) +#define TMC2660_GET_S2GB(X) (0x01 & ((X) >> 4)) +#define TMC2660_GET_S2GA(X) (0x01 & ((X) >> 3)) +#define TMC2660_GET_OTPW(X) (0x01 & ((X) >> 2)) +#define TMC2660_GET_OT(X) (0x01 & ((X) >> 1)) +#define TMC2660_GET_SGF(X) (0x01 & ((X) >> 0)) +#endif diff --git a/firmware/lib/tmc/ic/TMC2660/registercall_hierarchy_flowchart_SPIRead_tmc2660.svg b/firmware/lib/tmc/ic/TMC2660/registercall_hierarchy_flowchart_SPIRead_tmc2660.svg new file mode 100755 index 0000000..2068909 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2660/registercall_hierarchy_flowchart_SPIRead_tmc2660.svg @@ -0,0 +1,3 @@ + + +

HAL

HAL

APP (Eval)

APP (Eval)

API

API
Read a register
  •  Calls tmc2660_readRegister function
Read a register...
Returns the register read value
Returns the register read value
1
1
2
2
3
3
4
4
5
5
6
6
7
7
10
10
TMC2660.c
TMC2660.c
SPI.c
SPI.c
TMC2660_eval.c
TMC2660_eval.c

 Implementation of SPI_readWrite
  • Sends and receives bytes on the SPI bus
Implementation of SPI_readWrite...
Returns the raw reply data
Returns the raw reply data

Implementation of tmc2660_readWriteSPI
  • Sets the CSN pin to LOW
  • Takes the array of data to write
  • Calls hardware function SPI_readWrite
  • Upon completion of data transfer,
    sets CSN to 
    HIGH
Implementation of tmc2660_readWriteSPI...
Passes on the raw reply data to the API
Passes on the raw reply data to the API
Implementation of readWrite
  • Constructs the datagram
  • Calls HAL wrapper function 
Implementation of readWrite...
tmcXXXX_readWriteSPI
tmcXXXX_readWriteSPI
Parses the reply and returns the register value
Parses the reply and returns the register value
Implementation of tmc2660_readRegister 
  • Calls readImmediately function
Implementation of tmc2660_readRegister...
Returns the register read value
Returns the register read value
Implementation of readImmediately
  • Sets RDSEL bits to determine the response type
  • Calls readWrite function
Implementation of readImmediately...
return type void
return type void
8%3CmxGraphModel%3E%3Croot%3E%3CmxCell%20id%3D%220%22%2F%3E%3CmxCell%20id%3D%221%22%20parent%3D%220%22%2F%3E%3CmxCell%20id%3D%222%22%20value%3D%223%22%20style%3D%22ellipse%3BwhiteSpace%3Dwrap%3Bhtml%3D1%3BfontStyle%3D1%22%20vertex%3D%221%22%20parent%3D%221%22%3E%3CmxGeometry%20x%3D%22886.25%22%20y%3D%22518%22%20width%3D%2220%22%20height%3D%2220%22%20as%3D%22geometry%22%2F%3E%3C%2FmxCell%3E%3C%2Froot%3E%3C%2FmxGraphModel%3E
8%3...
9
9
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC2660/registercall_hierarchy_flowchart_SPIWrite_tmc2660.svg b/firmware/lib/tmc/ic/TMC2660/registercall_hierarchy_flowchart_SPIWrite_tmc2660.svg new file mode 100755 index 0000000..cb91310 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2660/registercall_hierarchy_flowchart_SPIWrite_tmc2660.svg @@ -0,0 +1,3 @@ + + +

HAL

HAL

APP (Eval)

APP (Eval)

API

API
Write to a register
  •  Calls tmc2660_writeRegister function
Write to a register...
1
1
2
2
3
3
4
4
TMC2660.c
TMC2660.c
SPI.c
SPI.c
TMC2660_eval.c
TMC2660_eval.c

 Implementation of SPI_readWrite
  • Sends bytes on the SPI bus
Implementation of SPI_readWrite...

Implementation of tmc2660_readWriteSPI
  • Sets the CSN pin to LOW
  • Takes the array of data to write
  • Calls hardware function SPI_readWrite
  • Upon completion of data transfer,
    sets CSN to 
    HIGH
Implementation of tmc2660_readWriteSPI...
Implementation of readWrite
  • Constructs the datagram
  • Calls HAL wrapper function tmc2660_readWriteSPI
Implementation of readWrite...
Implementation of tmc2660_writeRegister 
  • Cache the register with write-only access by calling 
    tmc2660_cache.
  • Extracts 20-bit of valid data
  • calls readWrite function
 
Implementation of tmc2660_writeRegister...
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC2660/uml-tmc-api.svg b/firmware/lib/tmc/ic/TMC2660/uml-tmc-api.svg new file mode 100755 index 0000000..5a5f8dd --- /dev/null +++ b/firmware/lib/tmc/ic/TMC2660/uml-tmc-api.svg @@ -0,0 +1,3 @@ + + +

TMCXXXX_HW_Abstraction.h



TMCXXXX_HW_Abstraction.h...
// Constants
#define TMCXXXX_MOTORS              
                          
// Register definitions
#define TMCXXXX_GCONF        
                          ⋮
// Register fields definitions
#define TMCXXXX_GCONF_OTPW_FIELD
                     
// Constants...

TMCXXXX.h



TMCXXXX.h...
extern void tmcXXXX_readWriteSPI();
extern void tmcXXXX_readWriteUART();
extern TMCXXXXBusType tmcXXXX_getBusType();
extern uint8_t tmcXXXX_getNodeAddress();
                                  ⋮
tmcXXXX_readRegister();
tmcXXXX_writeRegister();
                                  ⋮
extern void tmcXXXX_readWriteSPI();...

TMCXXXX.c



TMCXXXX.c...
const uint8_t tmcCRCTable_Poly7Reflected[256] = {...};
int32_t tmcXXXX_readRegister(){
/* Call tmcXXXX_getBusType();
 * Based on bus type, call readRegisterSPI/UART() that
 * further calls tmcXXXX_readWriteSPI/UART();
 * For UART it also calls tmcXXXX_getNodeAddress();
                                           ⋮
}
                                           ⋮
const uint8_t tmcCRCTable_Poly7Reflected[256] = {.....
TMC-API
TMC-API

TMCXXXX_Simple_Rotation.h


TMCXXXX_Simple_Rotation.h...
void initAllMotors();
             ⋮
  
void initAllMotors()...

TMCXXXX_Simple_Rotation.c


TMCXXXX_Simple_Rotation.c...
void initAllMotors(){

// Configuring registers to enable motor drivers etc..
tmcXXXX_writeRegister();
                    ⋮
}
                    ⋮
void initAllMotors(){...
Examples
Examples
User Project
User Project

User_Project.h


User_Project.h

User_Project.c








User_Project.c...

void tmcXXXX_readWriteSPI(){
                           ⋮
}
void tmcXXXX_readWriteUART(){
                           ⋮
}
TMCXXXXBusType tmcXXXX_getBusType(){
                           ⋮
}
uint8_t tmcXXXX_getNodeAddress(){
                           ⋮
}

// User Code
                           ⋮
void tmcXXXX_readWriteSPI(){...
#include "TMCXXXX_HW_Abstraction.h"
#include "TMCXXXX.h"
#include "TMCXXXX_Simple_Rotation.h"
                                ⋮
TMCXXXXBusType bus = IC_BUS_SPI/UART;
uint8_t nodeAddress = <nodeAddress>;
                                ⋮
#include "TMCXXXX_HW_Abstraction.h"...
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC4361A/README.md b/firmware/lib/tmc/ic/TMC4361A/README.md new file mode 100755 index 0000000..0fa8497 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC4361A/README.md @@ -0,0 +1,43 @@ +# TMC4361A + + +## How to use + +To access the TMC4361A's registers, the TMC-API offers two functions: **tmc4361A_readRegister** and **tmc4361A_writeRegister**. +Each of these functions takes in an **icID**, which is used to identify the IC when multiple ICs are connected. This identifier is passed down to the callback functions (see How to Integrate). + +## How to integrate: overview + +1. Include all the files of the TMC-API/ic/tmc/TMC4361A folder into the custom project. +2. Include the TMC4361A.h file in the custom source code. +3. Implement the necessary callback functions (see below). +4. (optional): Take a look at the Examples subfolder for ready-made examples of the TMC-API usage. + +## Accessing the TMC4361A via SPI +The following diagram depicts how to access the TMC4361A via SPI using the TMC-API. + +![screenshot](registercall_hierarchy_flowchart_SPI.svg) + +The description of the functions, in the above flowchart, are as follows: +- The functions tmc4361A_readRegister and tmc4361A_writeRegister are used to read and write the registers respectively. These functions call the bus-specific function i.e readRegisterSPI or writeRegisterSPI. +- These bus specific functions constructs the datagram and further calls the bus specific callback 'tmcXXXX_readWriteSPI. +- This callback function further calls the hardware specific read/write function for SPI and needs to be implemented externally. + +### How to integrate: Callback functions +Implement the following callback functions to access the chip via SPI: + +1. **tmc4361A_readWriteSPI()**, which is a HAL wrapper function that provides the necessary hardware access. This function should also set the chip select pin CSN to low before starting the data transfer and set to high upon completion. Please refer to the datasheet of the IC for further details. + +## Further info +### Dependency graph for the ICs with new register R/W mechanism +This graph illustrates the relationships between files within the TMC-API library, highlighting dependencies and identifying the files that are essential for integrating the library into the custom projects. + +![screenshot](uml-tmc-api.svg) + +### Example usage: TMC-Evalsystem +**For a reference usage of the TMC-API**, visit the [TMC-Evalsystem](https://github.com/analogdevicesinc/TMC-EvalSystem) + +## Migration status +The TMC4361A has been reworked to the access system described above. For more infos on the status of this and other ICs, check out the [migration page](https://github.com/analogdevicesinc/TMC-API/issues/53). + + diff --git a/firmware/lib/tmc/ic/TMC4361A/TMC4361A.c b/firmware/lib/tmc/ic/TMC4361A/TMC4361A.c new file mode 100755 index 0000000..5c08d0a --- /dev/null +++ b/firmware/lib/tmc/ic/TMC4361A/TMC4361A.c @@ -0,0 +1,189 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + +#include "TMC4361A.h" + +/**************************************************************** Cache Implementation *************************************************************************/ +#if TMC4361A_CACHE == 0 +static inline bool tmc4361A_cache(uint16_t icID, TMC4361ACacheOp operation, uint8_t address, uint32_t *value) +{ + UNUSED(icID); + UNUSED(address); + UNUSED(operation); + return false; +} +#else +#if TMC4361A_ENABLE_TMC_CACHE == 1 +uint8_t tmc4361A_dirtyBits[TMC4361A_IC_CACHE_COUNT][TMC4361A_REGISTER_COUNT / 8] = {0}; +int32_t tmc4361A_shadowRegister[TMC4361A_IC_CACHE_COUNT][TMC4361A_REGISTER_COUNT]; + +void tmc4361A_setDirtyBit(uint16_t icID, uint8_t index, bool value) +{ + if (index >= TMC4361A_REGISTER_COUNT) + return; + + uint8_t *tmp = &tmc4361A_dirtyBits[icID][index / 8]; + uint8_t shift = (index % 8); + uint8_t mask = 1 << shift; + *tmp = (((*tmp) & (~(mask))) | (((value) << (shift)) & (mask))); +} + +bool tmc4361A_getDirtyBit(uint16_t icID, uint8_t index) +{ + if (index >= TMC4361A_REGISTER_COUNT) + return false; + + uint8_t *tmp = &tmc4361A_dirtyBits[icID][index / 8]; + uint8_t shift = (index % 8); + return ((*tmp) >> shift) & 1; +} + +/* + * This function is used to cache the value written to the Write-Only registers in the form of shadow array. + * The shadow copy is then used to read these kinds of registers. + */ +bool tmc4361A_cache(uint16_t icID, TMC4361ACacheOp operation, uint8_t address, uint32_t *value) +{ + if (operation == TMC4361A_CACHE_READ) + { + // Check if the value should come from cache + + // Only supported chips have a cache + if (icID >= TMC4361A_IC_CACHE_COUNT) + return false; + + // Only non-readable registers care about caching + // Note: This could also be used to cache i.e. RW config registers to reduce bus accesses + if (TMC4361A_IS_READABLE(tmc4361A_registerAccess[address])) + return false; + + // Grab the value from the cache + *value = tmc4361A_shadowRegister[icID][address]; + return true; + } + else if (operation == TMC4361A_CACHE_WRITE || operation == TMC4361A_CACHE_FILL_DEFAULT) + { + // Fill the cache + + // only supported chips have a cache + if (icID >= TMC4361A_IC_CACHE_COUNT) + return false; + + // Write to the shadow register and mark the register dirty + tmc4361A_shadowRegister[icID][address] = *value; + if (operation == TMC4361A_CACHE_WRITE) + { + tmc4361A_setDirtyBit(icID, address, true); + } + return true; + } + return false; +} +void tmc4361A_initCache() +{ + // Check if we have constants defined + if (ARRAY_SIZE(tmc4361A_RegisterConstants) == 0) + return; + + size_t i, j, id; + + for (i = 0, j = 0; i < TMC4361A_REGISTER_COUNT; i++) + { + // We only need to worry about hardware preset, write-only registers + // that have not yet been written (no dirty bit) here. + if (tmc4361A_registerAccess[i] != TMC4361A_ACCESS_W_PRESET) + continue; + + // Search the constant list for the current address. With the constant + // list being sorted in ascended order, we can walk through the list + // until the entry with an address equal or greater than i + while (j < ARRAY_SIZE(tmc4361A_RegisterConstants) && (tmc4361A_RegisterConstants[j].address < i)) j++; + + // Abort when we reach the end of the constant list + if (j == ARRAY_SIZE(tmc4361A_RegisterConstants)) + break; + + // If we have an entry for our current address, write the constant + if (tmc4361A_RegisterConstants[j].address == i) + { + for (id = 0; id < TMC4361A_IC_CACHE_COUNT; id++) + { + uint32_t temp = tmc4361A_RegisterConstants[j].value; + tmc4361A_cache(id, TMC4361A_CACHE_FILL_DEFAULT, i, &temp); + } + } + } +} +#else +// User must implement their own cache +extern bool tmc4361A_cache(uint16_t icID, TMC4361ACacheOp operation, uint8_t address, uint32_t *value); +#endif +#endif + +/************************************************************** Register read / write Implementation ******************************************************************/ + +static int32_t readRegisterSPI(uint16_t icID, uint8_t address); +static void writeRegisterSPI(uint16_t icID, uint8_t address, int32_t value); + +int32_t tmc4361A_readRegister(uint16_t icID, uint8_t address) +{ + uint32_t value; + + // Read from cache for registers with write-only access + if (tmc4361A_cache(icID, TMC4361A_CACHE_READ, address, &value)) + return value; + + return readRegisterSPI(icID, address); + + //ToDo: Error handling + return -1; +} + +void tmc4361A_writeRegister(uint16_t icID, uint8_t address, int32_t value) +{ + writeRegisterSPI(icID, address, value); +} + +void writeRegisterSPI(uint16_t icID, uint8_t address, int32_t value) +{ + uint8_t data[5] = {0}; + + data[0] = address | TMC4361A_WRITE_BIT; + data[1] = 0xFF & (value >> 24); + data[2] = 0xFF & (value >> 16); + data[3] = 0xFF & (value >> 8); + data[4] = 0xFF & (value >> 0); + + // Send the write request + tmc4361A_readWriteSPI(icID, &data[0], sizeof(data)); + + tmc4361A_setStatus(icID, &data[0]); + + //Cache the registers with write-only access + tmc4361A_cache(icID, TMC4361A_CACHE_WRITE, address, (uint32_t *)&value); +} + +int32_t readRegisterSPI(uint16_t icID, uint8_t address) +{ + uint8_t data[5] = {0}; + + // clear write bit + address = address & TMC4361A_ADDRESS_MASK; + + data[0] = address; + // Send the read request + tmc4361A_readWriteSPI(icID, &data[0], sizeof(data)); + + data[0] = address; + // Send another request to receive the read reply + tmc4361A_readWriteSPI(icID, &data[0], sizeof(data)); + + tmc4361A_setStatus(icID, &data[0]); + + return ((int32_t) data[1] << 24) | ((int32_t) data[2] << 16) | ((int32_t) data[3] << 8) | ((int32_t) data[4]); +} diff --git a/firmware/lib/tmc/ic/TMC4361A/TMC4361A.h b/firmware/lib/tmc/ic/TMC4361A/TMC4361A.h new file mode 100755 index 0000000..04e835c --- /dev/null +++ b/firmware/lib/tmc/ic/TMC4361A/TMC4361A.h @@ -0,0 +1,243 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#ifndef TMC_IC_TMC4361A_H_ +#define TMC_IC_TMC4361A_H_ + +#include "TMC4361A_HW_Abstraction.h" +#include +#include +#include + +/******************************************************************************* +* API Configuration Defines +* These control optional features of the TMC-API implementation. +* These can be commented in/out here or defined from the build system. +*******************************************************************************/ + +// Uncomment if you want to save space..... +// and put the table into your own .c file +//#define TMC_API_EXTERNAL_CRC_TABLE 1 + +#ifndef TMC4361A_CACHE +#define TMC4361A_CACHE 1 +//#define TMC4361A_CACHE 0 +#endif + +// To use the caching mechanism already implemented by the TMC-API, set TMC4361A_ENABLE_TMC_CACHE to '1'. +// Set TMC4361A_ENABLE_TMC_CACHE to '0' if one wants to have their own cache implementation. +#ifndef TMC4361A_ENABLE_TMC_CACHE +#define TMC4361A_ENABLE_TMC_CACHE 1 +//#define TMC4361A_ENABLE_TMC_CACHE 0 +#endif + +/******************************************************************************/ + +typedef struct +{ + uint32_t mask; + uint8_t shift; + uint8_t address; + bool isSigned; +} RegisterField; + +// => TMC-API wrapper +extern void tmc4361A_setStatus(uint16_t icID, uint8_t *data); +extern void tmc4361A_readWriteSPI(uint16_t icID, uint8_t *data, size_t dataLength); +// => TMC-API wrapper + +int32_t tmc4361A_readRegister(uint16_t icID, uint8_t address); +void tmc4361A_writeRegister(uint16_t icID, uint8_t address, int32_t value); +void tmc4361A_readWriteCover(uint16_t icID, uint8_t *data, size_t length); + + +static inline uint32_t tmc4361A_fieldExtract(uint32_t data, RegisterField field) +{ + uint32_t value = (data & field.mask) >> field.shift; + + if (field.isSigned) + { + // Apply signedness conversion + uint32_t baseMask = field.mask >> field.shift; + uint32_t signMask = baseMask & (~baseMask >> 1); + value = (value ^ signMask) - signMask; + } + + return value; +} + +static inline uint32_t tmc4361A_fieldRead(uint16_t icID, RegisterField field) +{ + uint32_t value = tmc4361A_readRegister(icID, field.address); + + return tmc4361A_fieldExtract(value, field); +} + +static inline uint32_t field_update(uint32_t data, RegisterField field, uint32_t value) +{ + return (data & (~field.mask)) | ((value << field.shift) & field.mask); +} + +static inline void tmc4361A_fieldWrite(uint16_t icID, RegisterField field, uint32_t value) +{ + uint32_t regValue = tmc4361A_readRegister(icID, field.address); + + regValue = field_update(regValue, field, value); + + tmc4361A_writeRegister(icID, field.address, regValue); +} + +/**************************************************************** Cache Implementation *************************************************************************/ + +#if TMC4361A_CACHE == 1 +#if TMC4361A_ENABLE_TMC_CACHE == 1 + +// By default, support one IC in the cache +#ifndef TMC4361A_IC_CACHE_COUNT +#define TMC4361A_IC_CACHE_COUNT 1 +#endif + +typedef enum { + TMC4361A_CACHE_READ, + TMC4361A_CACHE_WRITE, + + // Special operation: Put content into the cache without marking the entry as dirty. + // Only used to initialize the cache with hardware defaults. This will allow reading + // from write-only registers that have a value inside them on reset. When using this + // operation, a restore will *not* rewrite that filled register! + TMC4361A_CACHE_FILL_DEFAULT + +} TMC4361ACacheOp; + +typedef struct +{ + uint8_t address; + uint32_t value; +} TMC4361ARegisterConstant; + +#define TMC4361A_ACCESS_DIRTY 0x08 // Register has been written since reset -> shadow register is valid for restore +#define TMC4361A_ACCESS_READ 0x01 +#define TMC_ACCESS_WRITE 0x02 +#define TMC4361A_ACCESS_W_PRESET 0x42 +#define TMC_IS_RESETTABLE(x) (((x) & (TMC_ACCESS_W_PRESET)) == TMC_ACCESS_WRITE) // Write bit set, Hardware preset bit not set +#define TMC4361A_IS_READABLE(x) ((x) & TMC4361A_ACCESS_READ) +#define TMC_IS_WRITABLE(x) ((x) & TMC_ACCESS_WRITE) +#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) +// Memory access helpers +// Force the compiler to access a location exactly once +#define ACCESS_ONCE(x) *((volatile typeof(x) *) (&x)) + +#ifndef MAX + #define MAX(a,b) (((a)>(b)) ? (a) : (b)) +#endif + +// Default Register Values +#define R10 0x00040001 // STP_LENGTH_ADD +#define R20 0x00000001 // RAMPMODE +#define R28 0x00013880 // AMAX +#define R29 0x00013880 // DMAX +#define R2D 0x000003E8 // BOW1 +#define R2E 0x000003E8 // BOW2 +#define R2F 0x000003E8 // BOW3 +#define R30 0x000003E8 // BOW4 +#define R54 0x00009C40 // ENC_IN_RES +#define ____ 0x00 + +#ifndef N_A +#define N_A 0x00 +#endif + + + +static const int32_t tmc4361A_sampleRegisterPreset[TMC4361A_REGISTER_COUNT] = +{ +// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F + 0, 0, 0, 0, 0, 0, N_A, N_A, 0, 0, N_A, N_A, 0, 0, 0, 0, // 0x00 - 0x0F + R10, 0, N_A, 0, 0, 0, 0, 0, 0, 0, 0, 0, N_A, 0, 0, N_A, // 0x10 - 0x1F + R20, 0, 0, 0, 0, 0, 0, 0, R28, R29, 0, 0, 0, R2D, R2E, R2F, // 0x20 - 0x2F + R30, N_A, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x30 - 0x3F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x40 - 0x4F + 0, 0, 0, N_A, R54, 0, N_A, N_A, N_A, 0, 0, 0, 0, 0, 0, 0, // 0x50 - 0x5F + 0, 0, N_A, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x60 - 0x6F + N_A, N_A, N_A, N_A, N_A, N_A, N_A, N_A, N_A, 0, 0, N_A, N_A, 0, N_A, 0 // 0x70 - 0x7F +}; + +// Undefine the default register values. +// This prevents warnings in case multiple TMC-API chip headers are included at once +#undef R10 +#undef R20 +#undef R24 +#undef R28 +#undef R29 +#undef R2D +#undef R2E +#undef R2F +#undef R30 +#undef R54 + +// Register access permissions: +// 0x00: none (reserved) +// 0x01: read +// 0x02: write +// 0x03: read/write +// 0x13: read/write, separate functions/values for reading or writing +// 0x23: read/write, holds read or write to clear flags +// 0x42: write, has hardware presets on reset +// 0x43: read/write, has hardware presets on reset +// 0x53: read/write, has hardware presets on reset, separate functions/values for reading or writing +static const uint8_t tmc4361A_registerAccess[TMC4361A_REGISTER_COUNT] = +{ +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0x43, 0x03, 0x03, 0x03, 0x03, 0x03, 0x43, 0x43, 0x03, 0x03, 0x43, 0x43, 0x03, 0x03, 0x23, 0x01, // 0x00 - 0x0F + 0x03, 0x03, 0x43, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x43, 0x03, 0x03, 0x43, // 0x10 - 0x1F + 0x03, 0x03, 0x01, 0x01, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, // 0x20 - 0x2F + 0x03, 0x43, 0x03, 0x03, 0x03, 0x03, 0x13, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, // 0x30 - 0x3F + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, // 0x40 - 0x4F + 0x03, 0x13, 0x13, 0x42, 0x13, 0x02, 0x42, 0x42, 0x42, 0x03, 0x13, 0x13, 0x02, 0x13, 0x02, 0x02, // 0x50 - 0x5F + 0x02, 0x02, 0x42, 0x02, ____, 0x01, 0x01, 0x02, 0x02, 0x02, 0x01, 0x01, 0x13, 0x13, 0x01, 0x01, // 0x60 - 0x6F + 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x13, 0x01, 0x13, 0x13, 0x02, 0x42, 0x01 // 0x70 - 0x7F +}; + + +// Register constants (only required for 0x42 registers, since we do not have +// any way to find out the content but want to hold the actual value in the +// shadow register so an application (i.e. the TMCL IDE) can still display +// the values. This only works when the register content is constant. +static const TMC4361ARegisterConstant tmc4361A_RegisterConstants[] = +{ // Use ascending addresses! + { 0x53, 0xFFFFFFFF }, // ENC_POS_DEV_TOL + { 0x56, 0x00A000A0 }, // SER_CLK_IN_HIGH, SER_CLK_IN_LOW + { 0x57, 0x00F00000 }, // SSI_IN_CLK_DELAY, SSI_IN_WTIME + { 0x58, 0x00000190 }, // SER_PTIME + { 0x62, 0x00FFFFFF }, // ENC_VEL_ZERO + { 0x70, 0xAAAAB554 }, // MSLUT[0] + { 0x71, 0x4A9554AA }, // MSLUT[1] + { 0x72, 0x24492929 }, // MSLUT[2] + { 0x73, 0x10104222 }, // MSLUT[3] + { 0x74, 0xFBFFFFFF }, // MSLUT[4] + { 0x75, 0xB5BB777D }, // MSLUT[5] + { 0x76, 0x49295556 }, // MSLUT[6] + { 0x77, 0x00404222 }, // MSLUT[7] + { 0x78, 0xFFFF8056 }, // MSLUTSEL + { 0x7E, 0x00F70000 }, // START_SIN, START_SIN_90_120, DAC_OFFSET +}; + + +extern uint8_t tmc4361A_dirtyBits[TMC4361A_IC_CACHE_COUNT][TMC4361A_REGISTER_COUNT/8]; +extern int32_t tmc4361A_shadowRegister[TMC4361A_IC_CACHE_COUNT][TMC4361A_REGISTER_COUNT]; +void tmc4361A_setDirtyBit(uint16_t icID, uint8_t index, bool value); +bool tmc4361A_getDirtyBit(uint16_t icID, uint8_t index); +extern bool tmc4361A_cache(uint16_t icID, TMC4361ACacheOp operation, uint8_t address, uint32_t *value); +void tmc4361A_initCache(void); +#endif +#endif + +/***************************************************************************************************************************************************/ + +#endif /* TMC_IC_TMC4361A_H_ */ diff --git a/firmware/lib/tmc/ic/TMC4361A/TMC4361A_HW_Abstraction.h b/firmware/lib/tmc/ic/TMC4361A/TMC4361A_HW_Abstraction.h new file mode 100755 index 0000000..d649029 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC4361A/TMC4361A_HW_Abstraction.h @@ -0,0 +1,1413 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#ifndef TMC4361A_HW_ABSTRACTION +#define TMC4361A_HW_ABSTRACTION + +// Constants in TMC4361A + +#define TMC4361A_REGISTER_COUNT 128 +#define TMC4361A_MOTORS 1 +#define TMC4361A_WRITE_BIT 0x80 +#define TMC4361A_ADDRESS_MASK 0x7F +#define TMC4361A_MAX_VELOCITY (int32_t) 2147483647 +#define TMC4361A_MAX_ACCELERATION (uint32_t) 16777215uL + +#define TMC4361A_COVER_DONE (1<<25) + +#define TMC4361A_RAMP_HOLD 0 +#define TMC4361A_RAMP_TRAPEZ 1 +#define TMC4361A_RAMP_SSHAPE 2 + +#define TMC4361A_RAMP_POSITION 4 + +// Registers in TMC4361A + +#define TMC4361A_GENERAL_CONF 0x00 +#define TMC4361A_REFERENCE_CONF 0x01 +#define TMC4361A_START_CONF 0x02 +#define TMC4361A_INPUT_FILT_CONF 0x03 +#define TMC4361A_SPI_OUT_CONF 0x04 +#define TMC4361A_CURRENT_CONF 0x05 +#define TMC4361A_SCALE_VALUES 0x06 +#define TMC4361A_ENC_IN_CONF 0x07 +#define TMC4361A_ENC_IN_DATA 0x08 +#define TMC4361A_ENC_OUT_DATA 0x09 +#define TMC4361A_STEP_CONF 0x0A +#define TMC4361A_SPI_STATUS_SELECTION 0x0B +#define TMC4361A_EVENT_CLEAR_CONF 0x0C +#define TMC4361A_INTR_CONF 0x0D +#define TMC4361A_EVENTS 0x0E +#define TMC4361A_STATUS 0x0F +#define TMC4361A_STP_LENGTH_ADD 0x10 +#define TMC4361A_DIR_SETUP_TIME 0x10 +#define TMC4361A_START_OUT_ADD 0x11 +#define TMC4361A_GEAR_RATIO 0x12 +#define TMC4361A_START_DELAY 0x13 +#define TMC4361A_CLK_GATING_DELAY 0x14 +#define TMC4361A_STDBY_DELAY 0x15 +#define TMC4361A_FREEWHEEL_DELAY 0x16 +#define TMC4361A_VDRV_SCALE_LIMIT 0x17 +#define TMC4361A_PWM_VMAX 0x17 +#define TMC4361A_UP_SCALE_DELAY 0x18 +#define TMC4361A_CL_UPSCALE_DELAY 0x18 +#define TMC4361A_HOLD_SCALE_DELAY 0x19 +#define TMC4361A_CL_DNSCALE_DELAY 0x19 +#define TMC4361A_DRV_SCALE_DELAY 0x1A +#define TMC4361A_BOOST_TIME 0x1B +#define TMC4361A_CL_ANGLES 0x1C +#define TMC4361A_SPI_SWITCH_VEL 0x1D +#define TMC4361A_DAC_ADDR 0x1D +#define TMC4361A_HOME_SAFETY_MARGIN 0x1E +#define TMC4361A_PWM_FREQ 0x1F +#define TMC4361A_CHOPSYNC_DIV 0x1F +#define TMC4361A_RAMPMODE 0x20 +#define TMC4361A_XACTUAL 0x21 +#define TMC4361A_VACTUAL 0x22 +#define TMC4361A_AACTUAL 0x23 +#define TMC4361A_VMAX 0x24 +#define TMC4361A_VSTART 0x25 +#define TMC4361A_VSTOP 0x26 +#define TMC4361A_VBREAK 0x27 +#define TMC4361A_AMAX 0x28 +#define TMC4361A_DMAX 0x29 +#define TMC4361A_ASTART 0x2A +#define TMC4361A_DFINAL 0x2B +#define TMC4361A_DSTOP 0x2C +#define TMC4361A_BOW1 0x2D +#define TMC4361A_BOW2 0x2E +#define TMC4361A_BOW3 0x2F +#define TMC4361A_BOW4 0x30 +#define TMC4361A_CLK_FREQ 0x31 +#define TMC4361A_POS_COMP 0x32 +#define TMC4361A_VIRT_STOP_LEFT 0x33 +#define TMC4361A_VIRT_STOP_RIGHT 0x34 +#define TMC4361A_X_HOME 0x35 +#define TMC4361A_X_LATCH 0x36 +#define TMC4361A_REV_CNT 0x36 +#define TMC4361A_X_RANGE 0x36 +#define TMC4361A_XTARGET 0x37 +#define TMC4361A_X_PIPE0 0x38 +#define TMC4361A_X_PIPE1 0x39 +#define TMC4361A_X_PIPE2 0x3A +#define TMC4361A_X_PIPE3 0x3B +#define TMC4361A_X_PIPE4 0x3C +#define TMC4361A_X_PIPE5 0x3D +#define TMC4361A_X_PIPE6 0x3E +#define TMC4361A_X_PIPE7 0x3F +#define TMC4361A_SH_REG0 0x40 +#define TMC4361A_SH_REG1 0x41 +#define TMC4361A_SH_REG2 0x42 +#define TMC4361A_SH_REG3 0x43 +#define TMC4361A_SH_REG4 0x44 +#define TMC4361A_SH_REG5 0x45 +#define TMC4361A_SH_REG6 0x46 +#define TMC4361A_SH_REG7 0x47 +#define TMC4361A_SH_REG8 0x48 +#define TMC4361A_SH_REG9 0x49 +#define TMC4361A_SH_REG10 0x4A +#define TMC4361A_SH_REG11 0x4B +#define TMC4361A_SH_REG12 0x4C +#define TMC4361A_SH_REG13 0x4D +#define TMC4361A_FREEZE_REGISTERS 0x4E +#define TMC4361A_CLK_GATING 0x4F +#define TMC4361A_SW_RESET 0x4F +#define TMC4361A_ENC_POS 0x50 +#define TMC4361A_ENC_LATCH 0x51 +#define TMC4361A_ENC_RESET_VAL 0x51 +#define TMC4361A_ENC_POS_DEV 0x52 +#define TMC4361A_CL_TR_TOLERANCE 0x52 +#define TMC4361A_ENC_POS_DEV_TOL 0x53 +#define TMC4361A_ENC_IN_RES 0x54 +#define TMC4361A_ENC_CONST 0x54 +#define TMC4361A_ENC_OUT_RES 0x55 +#define TMC4361A_SER_CLK_IN_HIGH_LOW 0x56 +#define TMC4361A_SSI_IN_CLK_DELAY 0x57 +#define TMC4361A_SSI_IN_WTIME 0x57 +#define TMC4361A_SER_PTIME 0x58 +#define TMC4361A_CL_OFFSET 0x59 +#define TMC4361A_PID_VEL 0x5A +#define TMC4361A_PID_P 0x5A +#define TMC4361A_CL_VMAX_CALC_P 0x5A +#define TMC4361A_PID_ISUM_RD 0x5B +#define TMC4361A_PID_I 0x5B +#define TMC4361A_CL_VMAX_CALC_I 0x5B +#define TMC4361A_PID_D 0x5C +#define TMC4361A_CL_DELTA_P 0x5C +#define TMC4361A_PID_E 0x5D +#define TMC4361A_PID_I_CLIP 0x5D +#define TMC4361A_PID_D_CLKDIV 0x5D +#define TMC4361A_PID_DV_CLIP 0x5E +#define TMC4361A_PID_TOLERANCE 0x5F +#define TMC4361A_CL_TOLERANCE 0x5F +#define TMC4361A_FS_VEL 0x60 +#define TMC4361A_DC_VEL 0x60 +#define TMC4361A_CL_VMIN_EMF 0x60 +#define TMC4361A_DC_TIME 0x61 +#define TMC4361A_DC_SG 0x61 +#define TMC4361A_DC_BLKTIME 0x61 +#define TMC4361A_CL_VADD_EMF 0x61 +#define TMC4361A_DC_LSPTM 0x62 +#define TMC4361A_ENC_VEL_ZERO 0x62 +#define TMC4361A_ENC_VMEAN_WAIT 0x63 +#define TMC4361A_ENC_VMEAN_FILTER 0x63 +#define TMC4361A_ENC_VMEAN_INT 0x63 +#define TMC4361A_ENC_SER_ENC_VARIATION 0x63 +#define TMC4361A_CL_CYCLE 0x63 +#define TMC4361A_V_ENC 0x65 +#define TMC4361A_V_ENC_MEAN 0x66 +#define TMC4361A_VSTALL_LIMIT 0x67 +#define TMC4361A_ADDR_TO_ENC 0x68 +#define TMC4361A_DATA_TO_ENC 0x69 +#define TMC4361A_ADDR_FROM_ENC 0x6A +#define TMC4361A_DATA_FROM_ENC 0x6B +#define TMC4361A_COVER_LOW 0x6C +#define TMC4361A_POLLING_STATUS 0x6C +#define TMC4361A_COVER_HIGH 0x6D +#define TMC4361A_POLLING_REG 0x6D +#define TMC4361A_COVER_DRV_LOW 0x6E +#define TMC4361A_COVER_DRV_HIGH 0x6F +#define TMC4361A_MSLUT_0 0x70 +#define TMC4361A_MSLUT_1 0x71 +#define TMC4361A_MSLUT_2 0x72 +#define TMC4361A_MSLUT_3 0x73 +#define TMC4361A_MSLUT_4 0x74 +#define TMC4361A_MSLUT_5 0x75 +#define TMC4361A_MSLUT_6 0x76 +#define TMC4361A_MSLUT_7 0x77 +#define TMC4361A_MSLUTSEL 0x78 +#define TMC4361A_MSCNT 0x79 +#define TMC4361A_MSOFFSET 0x79 +#define TMC4361A_CURRENTA 0x7A +#define TMC4361A_CURRENTB 0x7A +#define TMC4361A_CURRENTA_SPI 0x7B +#define TMC4361A_CURRENTB_SPI 0x7B +#define TMC4361A_TZEROWAIT 0x7B +#define TMC4361A_SCALE_PARAM 0x7C +#define TMC4361A_CIRCULAR_DEC 0x7C +#define TMC4361A_ENC_COMP_XOFFSET 0x7D +#define TMC4361A_ENC_COMP_YOFFSET 0x7D +#define TMC4361A_ENC_COMP_AMPL 0x7D +#define TMC4361A_START_SIN 0x7E +#define TMC4361A_START_SIN90_120 0x7E +#define TMC4361A_DAC_OFFSET 0x7E +#define TMC4361A_VERSION_NO 0x7F + + +// Fields in TMC4361A + +#define TMC4361A_USE_ASTART_AND_VSTART_MASK 0x00000001 +#define TMC4361A_USE_ASTART_AND_VSTART_SHIFT 0 +#define TMC4361A_USE_ASTART_AND_VSTART_FIELD ((RegisterField) {TMC4361A_USE_ASTART_AND_VSTART_MASK, TMC4361A_USE_ASTART_AND_VSTART_SHIFT, TMC4361A_GENERAL_CONF, false}) +#define TMC4361A_DIRECT_ACC_VAL_EN_MASK 0x00000002 +#define TMC4361A_DIRECT_ACC_VAL_EN_SHIFT 1 +#define TMC4361A_DIRECT_ACC_VAL_EN_FIELD ((RegisterField) {TMC4361A_DIRECT_ACC_VAL_EN_MASK, TMC4361A_DIRECT_ACC_VAL_EN_SHIFT, TMC4361A_GENERAL_CONF, false}) +#define TMC4361A_DIRECT_BOW_VAL_EN_MASK 0x00000004 +#define TMC4361A_DIRECT_BOW_VAL_EN_SHIFT 2 +#define TMC4361A_DIRECT_BOW_VAL_EN_FIELD ((RegisterField) {TMC4361A_DIRECT_BOW_VAL_EN_MASK, TMC4361A_DIRECT_BOW_VAL_EN_SHIFT, TMC4361A_GENERAL_CONF, false}) +#define TMC4361A_STEP_INACTIVE_POL_MASK 0x00000008 +#define TMC4361A_STEP_INACTIVE_POL_SHIFT 3 +#define TMC4361A_STEP_INACTIVE_POL_FIELD ((RegisterField) {TMC4361A_STEP_INACTIVE_POL_MASK, TMC4361A_STEP_INACTIVE_POL_SHIFT, TMC4361A_GENERAL_CONF, false}) +#define TMC4361A_TOGGLE_STEP_MASK 0x00000010 +#define TMC4361A_TOGGLE_STEP_SHIFT 4 +#define TMC4361A_TOGGLE_STEP_FIELD ((RegisterField) {TMC4361A_TOGGLE_STEP_MASK, TMC4361A_TOGGLE_STEP_SHIFT, TMC4361A_GENERAL_CONF, false}) +#define TMC4361A_POL_DIR_OUT_MASK 0x00000020 +#define TMC4361A_POL_DIR_OUT_SHIFT 5 +#define TMC4361A_POL_DIR_OUT_FIELD ((RegisterField) {TMC4361A_POL_DIR_OUT_MASK, TMC4361A_POL_DIR_OUT_SHIFT, TMC4361A_GENERAL_CONF, false}) +#define TMC4361A_SDIN_MODE_MASK 0x000000c0 +#define TMC4361A_SDIN_MODE_SHIFT 6 +#define TMC4361A_SDIN_MODE_FIELD ((RegisterField) {TMC4361A_SDIN_MODE_MASK, TMC4361A_SDIN_MODE_SHIFT, TMC4361A_GENERAL_CONF, false}) +#define TMC4361A_POL_DIR_IN_MASK 0x00000100 +#define TMC4361A_POL_DIR_IN_SHIFT 8 +#define TMC4361A_POL_DIR_IN_FIELD ((RegisterField) {TMC4361A_POL_DIR_IN_MASK, TMC4361A_POL_DIR_IN_SHIFT, TMC4361A_GENERAL_CONF, false}) +#define TMC4361A_SD_INDIRECT_CONTROL_MASK 0x00000200 +#define TMC4361A_SD_INDIRECT_CONTROL_SHIFT 9 +#define TMC4361A_SD_INDIRECT_CONTROL_FIELD ((RegisterField) {TMC4361A_SD_INDIRECT_CONTROL_MASK, TMC4361A_SD_INDIRECT_CONTROL_SHIFT, TMC4361A_GENERAL_CONF, false}) +#define TMC4361A_SERIAL_ENC_IN_MODE_MASK 0x00000c00 +#define TMC4361A_SERIAL_ENC_IN_MODE_SHIFT 10 +#define TMC4361A_SERIAL_ENC_IN_MODE_FIELD ((RegisterField) {TMC4361A_SERIAL_ENC_IN_MODE_MASK, TMC4361A_SERIAL_ENC_IN_MODE_SHIFT, TMC4361A_GENERAL_CONF, false}) +#define TMC4361A_DIFF_ENC_IN_DISABLE_MASK 0x00001000 +#define TMC4361A_DIFF_ENC_IN_DISABLE_SHIFT 12 +#define TMC4361A_DIFF_ENC_IN_DISABLE_FIELD ((RegisterField) {TMC4361A_DIFF_ENC_IN_DISABLE_MASK, TMC4361A_DIFF_ENC_IN_DISABLE_SHIFT, TMC4361A_GENERAL_CONF, false}) +#define TMC4361A_STDBY_CLK_PIN_ASSIGNMENT_MASK 0x00006000 +#define TMC4361A_STDBY_CLK_PIN_ASSIGNMENT_SHIFT 13 +#define TMC4361A_STDBY_CLK_PIN_ASSIGNMENT_FIELD ((RegisterField) {TMC4361A_STDBY_CLK_PIN_ASSIGNMENT_MASK, TMC4361A_STDBY_CLK_PIN_ASSIGNMENT_SHIFT, TMC4361A_GENERAL_CONF, false}) +#define TMC4361A_INTR_POL_MASK 0x00008000 +#define TMC4361A_INTR_POL_SHIFT 15 +#define TMC4361A_INTR_POL_FIELD ((RegisterField) {TMC4361A_INTR_POL_MASK, TMC4361A_INTR_POL_SHIFT, TMC4361A_GENERAL_CONF, false}) +#define TMC4361A_INVERT_POL_TARGET_REACHED_MASK 0x00010000 +#define TMC4361A_INVERT_POL_TARGET_REACHED_SHIFT 16 +#define TMC4361A_INVERT_POL_TARGET_REACHED_FIELD ((RegisterField) {TMC4361A_INVERT_POL_TARGET_REACHED_MASK, TMC4361A_INVERT_POL_TARGET_REACHED_SHIFT, TMC4361A_GENERAL_CONF, false}) +#define TMC4361A_FS_EN_MASK 0x00080000 +#define TMC4361A_FS_EN_SHIFT 19 +#define TMC4361A_FS_EN_FIELD ((RegisterField) {TMC4361A_FS_EN_MASK, TMC4361A_FS_EN_SHIFT, TMC4361A_GENERAL_CONF, false}) +#define TMC4361A_FS_SDOUT_MASK 0x00100000 +#define TMC4361A_FS_SDOUT_SHIFT 20 +#define TMC4361A_FS_SDOUT_FIELD ((RegisterField) {TMC4361A_FS_SDOUT_MASK, TMC4361A_FS_SDOUT_SHIFT, TMC4361A_GENERAL_CONF, false}) +#define TMC4361A_DCSTEP_MODE_MASK 0x00600000 +#define TMC4361A_DCSTEP_MODE_SHIFT 21 +#define TMC4361A_DCSTEP_MODE_FIELD ((RegisterField) {TMC4361A_DCSTEP_MODE_MASK, TMC4361A_DCSTEP_MODE_SHIFT, TMC4361A_GENERAL_CONF, false}) +#define TMC4361A_PWM_OUT_EN_MASK 0x00800000 +#define TMC4361A_PWM_OUT_EN_SHIFT 23 +#define TMC4361A_PWM_OUT_EN_FIELD ((RegisterField) {TMC4361A_PWM_OUT_EN_MASK, TMC4361A_PWM_OUT_EN_SHIFT, TMC4361A_GENERAL_CONF, false}) +#define TMC4361A_SERIAL_ENC_OUT_ENABLE_MASK 0x01000000 +#define TMC4361A_SERIAL_ENC_OUT_ENABLE_SHIFT 24 +#define TMC4361A_SERIAL_ENC_OUT_ENABLE_FIELD ((RegisterField) {TMC4361A_SERIAL_ENC_OUT_ENABLE_MASK, TMC4361A_SERIAL_ENC_OUT_ENABLE_SHIFT, TMC4361A_GENERAL_CONF, false}) +#define TMC4361A_SERIAL_ENC_OUT_DIFF_DISABLE_MASK 0x02000000 +#define TMC4361A_SERIAL_ENC_OUT_DIFF_DISABLE_SHIFT 25 +#define TMC4361A_SERIAL_ENC_OUT_DIFF_DISABLE_FIELD ((RegisterField) {TMC4361A_SERIAL_ENC_OUT_DIFF_DISABLE_MASK, TMC4361A_SERIAL_ENC_OUT_DIFF_DISABLE_SHIFT, TMC4361A_GENERAL_CONF, false}) +#define TMC4361A_AUTOMATIC_DIRECT_SDIN_SWITCH_OFF_MASK 0x04000000 +#define TMC4361A_AUTOMATIC_DIRECT_SDIN_SWITCH_OFF_SHIFT 26 +#define TMC4361A_AUTOMATIC_DIRECT_SDIN_SWITCH_OFF_FIELD ((RegisterField) {TMC4361A_AUTOMATIC_DIRECT_SDIN_SWITCH_OFF_MASK, TMC4361A_AUTOMATIC_DIRECT_SDIN_SWITCH_OFF_SHIFT, TMC4361A_GENERAL_CONF, false}) +#define TMC4361A_CIRCULAR_CNT_AS_XLATCH_MASK 0x08000000 +#define TMC4361A_CIRCULAR_CNT_AS_XLATCH_SHIFT 27 +#define TMC4361A_CIRCULAR_CNT_AS_XLATCH_FIELD ((RegisterField) {TMC4361A_CIRCULAR_CNT_AS_XLATCH_MASK, TMC4361A_CIRCULAR_CNT_AS_XLATCH_SHIFT, TMC4361A_GENERAL_CONF, false}) +#define TMC4361A_REVERSE_MOTOR_DIR_MASK 0x10000000 +#define TMC4361A_REVERSE_MOTOR_DIR_SHIFT 28 +#define TMC4361A_REVERSE_MOTOR_DIR_FIELD ((RegisterField) {TMC4361A_REVERSE_MOTOR_DIR_MASK, TMC4361A_REVERSE_MOTOR_DIR_SHIFT, TMC4361A_GENERAL_CONF, false}) +#define TMC4361A_INTR_TR_PU_PD_EN_MASK 0x20000000 +#define TMC4361A_INTR_TR_PU_PD_EN_SHIFT 29 +#define TMC4361A_INTR_TR_PU_PD_EN_FIELD ((RegisterField) {TMC4361A_INTR_TR_PU_PD_EN_MASK, TMC4361A_INTR_TR_PU_PD_EN_SHIFT, TMC4361A_GENERAL_CONF, false}) +#define TMC4361A_INTR_AS_WIRED_AND_MASK 0x40000000 +#define TMC4361A_INTR_AS_WIRED_AND_SHIFT 30 +#define TMC4361A_INTR_AS_WIRED_AND_FIELD ((RegisterField) {TMC4361A_INTR_AS_WIRED_AND_MASK, TMC4361A_INTR_AS_WIRED_AND_SHIFT, TMC4361A_GENERAL_CONF, false}) +#define TMC4361A_TR_AS_WIRED_AND_MASK 0x80000000 +#define TMC4361A_TR_AS_WIRED_AND_SHIFT 31 +#define TMC4361A_TR_AS_WIRED_AND_FIELD ((RegisterField) {TMC4361A_TR_AS_WIRED_AND_MASK, TMC4361A_TR_AS_WIRED_AND_SHIFT, TMC4361A_GENERAL_CONF, false}) +#define TMC4361A_STOP_LEFT_EN_MASK 0x00000001 +#define TMC4361A_STOP_LEFT_EN_SHIFT 0 +#define TMC4361A_STOP_LEFT_EN_FIELD ((RegisterField) {TMC4361A_STOP_LEFT_EN_MASK, TMC4361A_STOP_LEFT_EN_SHIFT, TMC4361A_REFERENCE_CONF, false}) +#define TMC4361A_STOP_RIGHT_EN_MASK 0x00000002 +#define TMC4361A_STOP_RIGHT_EN_SHIFT 1 +#define TMC4361A_STOP_RIGHT_EN_FIELD ((RegisterField) {TMC4361A_STOP_RIGHT_EN_MASK, TMC4361A_STOP_RIGHT_EN_SHIFT, TMC4361A_REFERENCE_CONF, false}) +#define TMC4361A_POL_STOP_LEFT_MASK 0x00000004 +#define TMC4361A_POL_STOP_LEFT_SHIFT 2 +#define TMC4361A_POL_STOP_LEFT_FIELD ((RegisterField) {TMC4361A_POL_STOP_LEFT_MASK, TMC4361A_POL_STOP_LEFT_SHIFT, TMC4361A_REFERENCE_CONF, false}) +#define TMC4361A_POL_STOP_RIGHT_MASK 0x00000008 +#define TMC4361A_POL_STOP_RIGHT_SHIFT 3 +#define TMC4361A_POL_STOP_RIGHT_FIELD ((RegisterField) {TMC4361A_POL_STOP_RIGHT_MASK, TMC4361A_POL_STOP_RIGHT_SHIFT, TMC4361A_REFERENCE_CONF, false}) +#define TMC4361A_INVERT_STOP_DIRECTION_MASK 0x00000010 +#define TMC4361A_INVERT_STOP_DIRECTION_SHIFT 4 +#define TMC4361A_INVERT_STOP_DIRECTION_FIELD ((RegisterField) {TMC4361A_INVERT_STOP_DIRECTION_MASK, TMC4361A_INVERT_STOP_DIRECTION_SHIFT, TMC4361A_REFERENCE_CONF, false}) +#define TMC4361A_SOFT_STOP_EN_MASK 0x00000020 +#define TMC4361A_SOFT_STOP_EN_SHIFT 5 +#define TMC4361A_SOFT_STOP_EN_FIELD ((RegisterField) {TMC4361A_SOFT_STOP_EN_MASK, TMC4361A_SOFT_STOP_EN_SHIFT, TMC4361A_REFERENCE_CONF, false}) +#define TMC4361A_VIRTUAL_LEFT_LIMIT_EN_MASK 0x00000040 +#define TMC4361A_VIRTUAL_LEFT_LIMIT_EN_SHIFT 6 +#define TMC4361A_VIRTUAL_LEFT_LIMIT_EN_FIELD ((RegisterField) {TMC4361A_VIRTUAL_LEFT_LIMIT_EN_MASK, TMC4361A_VIRTUAL_LEFT_LIMIT_EN_SHIFT, TMC4361A_REFERENCE_CONF, false}) +#define TMC4361A_VIRTUAL_RIGHT_LIMIT_EN_MASK 0x00000080 +#define TMC4361A_VIRTUAL_RIGHT_LIMIT_EN_SHIFT 7 +#define TMC4361A_VIRTUAL_RIGHT_LIMIT_EN_FIELD ((RegisterField) {TMC4361A_VIRTUAL_RIGHT_LIMIT_EN_MASK, TMC4361A_VIRTUAL_RIGHT_LIMIT_EN_SHIFT, TMC4361A_REFERENCE_CONF, false}) +#define TMC4361A_VIRT_STOP_MODE_MASK 0x00000300 +#define TMC4361A_VIRT_STOP_MODE_SHIFT 8 +#define TMC4361A_VIRT_STOP_MODE_FIELD ((RegisterField) {TMC4361A_VIRT_STOP_MODE_MASK, TMC4361A_VIRT_STOP_MODE_SHIFT, TMC4361A_REFERENCE_CONF, false}) +#define TMC4361A_LATCH_X_ON_INACTIVE_L_MASK 0x00000400 +#define TMC4361A_LATCH_X_ON_INACTIVE_L_SHIFT 10 +#define TMC4361A_LATCH_X_ON_INACTIVE_L_FIELD ((RegisterField) {TMC4361A_LATCH_X_ON_INACTIVE_L_MASK, TMC4361A_LATCH_X_ON_INACTIVE_L_SHIFT, TMC4361A_REFERENCE_CONF, false}) +#define TMC4361A_LATCH_X_ON_ACTIVE_L_MASK 0x00000800 +#define TMC4361A_LATCH_X_ON_ACTIVE_L_SHIFT 11 +#define TMC4361A_LATCH_X_ON_ACTIVE_L_FIELD ((RegisterField) {TMC4361A_LATCH_X_ON_ACTIVE_L_MASK, TMC4361A_LATCH_X_ON_ACTIVE_L_SHIFT, TMC4361A_REFERENCE_CONF, false}) +#define TMC4361A_LATCH_X_ON_INACTIVE_R_MASK 0x00001000 +#define TMC4361A_LATCH_X_ON_INACTIVE_R_SHIFT 12 +#define TMC4361A_LATCH_X_ON_INACTIVE_R_FIELD ((RegisterField) {TMC4361A_LATCH_X_ON_INACTIVE_R_MASK, TMC4361A_LATCH_X_ON_INACTIVE_R_SHIFT, TMC4361A_REFERENCE_CONF, false}) +#define TMC4361A_LATCH_X_ON_ACTIVE_R_MASK 0x00002000 +#define TMC4361A_LATCH_X_ON_ACTIVE_R_SHIFT 13 +#define TMC4361A_LATCH_X_ON_ACTIVE_R_FIELD ((RegisterField) {TMC4361A_LATCH_X_ON_ACTIVE_R_MASK, TMC4361A_LATCH_X_ON_ACTIVE_R_SHIFT, TMC4361A_REFERENCE_CONF, false}) +#define TMC4361A_STOP_LEFT_IS_HOME_MASK 0x00004000 +#define TMC4361A_STOP_LEFT_IS_HOME_SHIFT 14 +#define TMC4361A_STOP_LEFT_IS_HOME_FIELD ((RegisterField) {TMC4361A_STOP_LEFT_IS_HOME_MASK, TMC4361A_STOP_LEFT_IS_HOME_SHIFT, TMC4361A_REFERENCE_CONF, false}) +#define TMC4361A_HOME_EVENT_MASK 0x000f0000 +#define TMC4361A_HOME_EVENT_SHIFT 16 +#define TMC4361A_HOME_EVENT_FIELD ((RegisterField) {TMC4361A_HOME_EVENT_MASK, TMC4361A_HOME_EVENT_SHIFT, TMC4361A_REFERENCE_CONF, false}) +#define TMC4361A_START_HOME_TRACKING_MASK 0x00100000 +#define TMC4361A_START_HOME_TRACKING_SHIFT 20 +#define TMC4361A_START_HOME_TRACKING_FIELD ((RegisterField) {TMC4361A_START_HOME_TRACKING_MASK, TMC4361A_START_HOME_TRACKING_SHIFT, TMC4361A_REFERENCE_CONF, false}) +#define TMC4361A_CLR_POS_AT_TARGET_MASK 0x00200000 +#define TMC4361A_CLR_POS_AT_TARGET_SHIFT 21 +#define TMC4361A_CLR_POS_AT_TARGET_FIELD ((RegisterField) {TMC4361A_CLR_POS_AT_TARGET_MASK, TMC4361A_CLR_POS_AT_TARGET_SHIFT, TMC4361A_REFERENCE_CONF, false}) +#define TMC4361A_CIRCULAR_MOVEMENT_EN_MASK 0x00400000 +#define TMC4361A_CIRCULAR_MOVEMENT_EN_SHIFT 22 +#define TMC4361A_CIRCULAR_MOVEMENT_EN_FIELD ((RegisterField) {TMC4361A_CIRCULAR_MOVEMENT_EN_MASK, TMC4361A_CIRCULAR_MOVEMENT_EN_SHIFT, TMC4361A_REFERENCE_CONF, false}) +#define TMC4361A_POS_COMP_OUTPUT_MASK 0x01800000 +#define TMC4361A_POS_COMP_OUTPUT_SHIFT 23 +#define TMC4361A_POS_COMP_OUTPUT_FIELD ((RegisterField) {TMC4361A_POS_COMP_OUTPUT_MASK, TMC4361A_POS_COMP_OUTPUT_SHIFT, TMC4361A_REFERENCE_CONF, false}) +#define TMC4361A_POS_COMP_SOURCE_MASK 0x02000000 +#define TMC4361A_POS_COMP_SOURCE_SHIFT 25 +#define TMC4361A_POS_COMP_SOURCE_FIELD ((RegisterField) {TMC4361A_POS_COMP_SOURCE_MASK, TMC4361A_POS_COMP_SOURCE_SHIFT, TMC4361A_REFERENCE_CONF, false}) +#define TMC4361A_STOP_ON_STALL_MASK 0x04000000 +#define TMC4361A_STOP_ON_STALL_SHIFT 26 +#define TMC4361A_STOP_ON_STALL_FIELD ((RegisterField) {TMC4361A_STOP_ON_STALL_MASK, TMC4361A_STOP_ON_STALL_SHIFT, TMC4361A_REFERENCE_CONF, false}) +#define TMC4361A_DRV_AFTER_STALL_MASK 0x08000000 +#define TMC4361A_DRV_AFTER_STALL_SHIFT 27 +#define TMC4361A_DRV_AFTER_STALL_FIELD ((RegisterField) {TMC4361A_DRV_AFTER_STALL_MASK, TMC4361A_DRV_AFTER_STALL_SHIFT, TMC4361A_REFERENCE_CONF, false}) +#define TMC4361A_MODIFIED_POS_COPARE_MASK 0x30000000 +#define TMC4361A_MODIFIED_POS_COPARE_SHIFT 28 +#define TMC4361A_MODIFIED_POS_COPARE_FIELD ((RegisterField) {TMC4361A_MODIFIED_POS_COPARE_MASK, TMC4361A_MODIFIED_POS_COPARE_SHIFT, TMC4361A_REFERENCE_CONF, false}) +#define TMC4361A_AUTOMATIC_COVER_MASK 0x40000000 +#define TMC4361A_AUTOMATIC_COVER_SHIFT 30 +#define TMC4361A_AUTOMATIC_COVER_FIELD ((RegisterField) {TMC4361A_AUTOMATIC_COVER_MASK, TMC4361A_AUTOMATIC_COVER_SHIFT, TMC4361A_REFERENCE_CONF, false}) +#define TMC4361A_CIRCULAR_ENC_EN_MASK 0x80000000 +#define TMC4361A_CIRCULAR_ENC_EN_SHIFT 31 +#define TMC4361A_CIRCULAR_ENC_EN_FIELD ((RegisterField) {TMC4361A_CIRCULAR_ENC_EN_MASK, TMC4361A_CIRCULAR_ENC_EN_SHIFT, TMC4361A_REFERENCE_CONF, false}) +#define TMC4361A_START_EN_0__MASK 0x00000001 +#define TMC4361A_START_EN_0__SHIFT 0 +#define TMC4361A_START_EN_0__FIELD ((RegisterField) {TMC4361A_START_EN_0__MASK, TMC4361A_START_EN_0__SHIFT, TMC4361A_START_CONF, false}) +#define TMC4361A_START_EN_1__MASK 0x00000002 +#define TMC4361A_START_EN_1__SHIFT 1 +#define TMC4361A_START_EN_1__FIELD ((RegisterField) {TMC4361A_START_EN_1__MASK, TMC4361A_START_EN_1__SHIFT, TMC4361A_START_CONF, false}) +#define TMC4361A_START_EN_2__MASK 0x00000004 +#define TMC4361A_START_EN_2__SHIFT 2 +#define TMC4361A_START_EN_2__FIELD ((RegisterField) {TMC4361A_START_EN_2__MASK, TMC4361A_START_EN_2__SHIFT, TMC4361A_START_CONF, false}) +#define TMC4361A_START_EN_3__MASK 0x00000008 +#define TMC4361A_START_EN_3__SHIFT 3 +#define TMC4361A_START_EN_3__FIELD ((RegisterField) {TMC4361A_START_EN_3__MASK, TMC4361A_START_EN_3__SHIFT, TMC4361A_START_CONF, false}) +#define TMC4361A_START_EN_4__MASK 0x00000010 +#define TMC4361A_START_EN_4__SHIFT 4 +#define TMC4361A_START_EN_4__FIELD ((RegisterField) {TMC4361A_START_EN_4__MASK, TMC4361A_START_EN_4__SHIFT, TMC4361A_START_CONF, false}) +#define TMC4361A_TRIGGER_EVENTS_0__MASK 0x00000020 +#define TMC4361A_TRIGGER_EVENTS_0__SHIFT 5 +#define TMC4361A_TRIGGER_EVENTS_0__FIELD ((RegisterField) {TMC4361A_TRIGGER_EVENTS_0__MASK, TMC4361A_TRIGGER_EVENTS_0__SHIFT, TMC4361A_START_CONF, false}) +#define TMC4361A_TRIGGER_EVENTS_1__MASK 0x00000040 +#define TMC4361A_TRIGGER_EVENTS_1__SHIFT 6 +#define TMC4361A_TRIGGER_EVENTS_1__FIELD ((RegisterField) {TMC4361A_TRIGGER_EVENTS_1__MASK, TMC4361A_TRIGGER_EVENTS_1__SHIFT, TMC4361A_START_CONF, false}) +#define TMC4361A_TRIGGER_EVENTS_2__MASK 0x00000080 +#define TMC4361A_TRIGGER_EVENTS_2__SHIFT 7 +#define TMC4361A_TRIGGER_EVENTS_2__FIELD ((RegisterField) {TMC4361A_TRIGGER_EVENTS_2__MASK, TMC4361A_TRIGGER_EVENTS_2__SHIFT, TMC4361A_START_CONF, false}) +#define TMC4361A_TRIGGER_EVENTS_3__MASK 0x00000100 +#define TMC4361A_TRIGGER_EVENTS_3__SHIFT 8 +#define TMC4361A_TRIGGER_EVENTS_3__FIELD ((RegisterField) {TMC4361A_TRIGGER_EVENTS_3__MASK, TMC4361A_TRIGGER_EVENTS_3__SHIFT, TMC4361A_START_CONF, false}) +#define TMC4361A_POL_START_SIGNAL_MASK 0x00000200 +#define TMC4361A_POL_START_SIGNAL_SHIFT 9 +#define TMC4361A_POL_START_SIGNAL_FIELD ((RegisterField) {TMC4361A_POL_START_SIGNAL_MASK, TMC4361A_POL_START_SIGNAL_SHIFT, TMC4361A_START_CONF, false}) +#define TMC4361A_IMMEDIATE_START_IN_MASK 0x00000400 +#define TMC4361A_IMMEDIATE_START_IN_SHIFT 10 +#define TMC4361A_IMMEDIATE_START_IN_FIELD ((RegisterField) {TMC4361A_IMMEDIATE_START_IN_MASK, TMC4361A_IMMEDIATE_START_IN_SHIFT, TMC4361A_START_CONF, false}) +#define TMC4361A_BUSY_STATE_EN_MASK 0x00000800 +#define TMC4361A_BUSY_STATE_EN_SHIFT 11 +#define TMC4361A_BUSY_STATE_EN_FIELD ((RegisterField) {TMC4361A_BUSY_STATE_EN_MASK, TMC4361A_BUSY_STATE_EN_SHIFT, TMC4361A_START_CONF, false}) +#define TMC4361A_PIPELINE_EN_0__MASK 0x00001000 +#define TMC4361A_PIPELINE_EN_0__SHIFT 12 +#define TMC4361A_PIPELINE_EN_0__FIELD ((RegisterField) {TMC4361A_PIPELINE_EN_0__MASK, TMC4361A_PIPELINE_EN_0__SHIFT, TMC4361A_START_CONF, false}) +#define TMC4361A_PIPELINE_EN_1__MASK 0x00002000 +#define TMC4361A_PIPELINE_EN_1__SHIFT 13 +#define TMC4361A_PIPELINE_EN_1__FIELD ((RegisterField) {TMC4361A_PIPELINE_EN_1__MASK, TMC4361A_PIPELINE_EN_1__SHIFT, TMC4361A_START_CONF, false}) +#define TMC4361A_PIPELINE_EN_2__MASK 0x00004000 +#define TMC4361A_PIPELINE_EN_2__SHIFT 14 +#define TMC4361A_PIPELINE_EN_2__FIELD ((RegisterField) {TMC4361A_PIPELINE_EN_2__MASK, TMC4361A_PIPELINE_EN_2__SHIFT, TMC4361A_START_CONF, false}) +#define TMC4361A_PIPELINE_EN_3__MASK 0x00008000 +#define TMC4361A_PIPELINE_EN_3__SHIFT 15 +#define TMC4361A_PIPELINE_EN_3__FIELD ((RegisterField) {TMC4361A_PIPELINE_EN_3__MASK, TMC4361A_PIPELINE_EN_3__SHIFT, TMC4361A_START_CONF, false}) +#define TMC4361A_SHADOW_OPTION_MASK 0x00030000 +#define TMC4361A_SHADOW_OPTION_SHIFT 16 +#define TMC4361A_SHADOW_OPTION_FIELD ((RegisterField) {TMC4361A_SHADOW_OPTION_MASK, TMC4361A_SHADOW_OPTION_SHIFT, TMC4361A_START_CONF, false}) +#define TMC4361A_CYCLIC_SHADOW_REGS_MASK 0x00040000 +#define TMC4361A_CYCLIC_SHADOW_REGS_SHIFT 18 +#define TMC4361A_CYCLIC_SHADOW_REGS_FIELD ((RegisterField) {TMC4361A_CYCLIC_SHADOW_REGS_MASK, TMC4361A_CYCLIC_SHADOW_REGS_SHIFT, TMC4361A_START_CONF, false}) +#define TMC4361A_SHADOW_MISS_CNT_MASK 0x00f00000 +#define TMC4361A_SHADOW_MISS_CNT_SHIFT 20 +#define TMC4361A_SHADOW_MISS_CNT_FIELD ((RegisterField) {TMC4361A_SHADOW_MISS_CNT_MASK, TMC4361A_SHADOW_MISS_CNT_SHIFT, TMC4361A_START_CONF, false}) +#define TMC4361A_XPIPE_REWRITE_REG_0__MASK 0x01000000 +#define TMC4361A_XPIPE_REWRITE_REG_0__SHIFT 24 +#define TMC4361A_XPIPE_REWRITE_REG_0__FIELD ((RegisterField) {TMC4361A_XPIPE_REWRITE_REG_0__MASK, TMC4361A_XPIPE_REWRITE_REG_0__SHIFT, TMC4361A_START_CONF, false}) +#define TMC4361A_XPIPE_REWRITE_REG_1__MASK 0x02000000 +#define TMC4361A_XPIPE_REWRITE_REG_1__SHIFT 25 +#define TMC4361A_XPIPE_REWRITE_REG_1__FIELD ((RegisterField) {TMC4361A_XPIPE_REWRITE_REG_1__MASK, TMC4361A_XPIPE_REWRITE_REG_1__SHIFT, TMC4361A_START_CONF, false}) +#define TMC4361A_XPIPE_REWRITE_REG_2__MASK 0x04000000 +#define TMC4361A_XPIPE_REWRITE_REG_2__SHIFT 26 +#define TMC4361A_XPIPE_REWRITE_REG_2__FIELD ((RegisterField) {TMC4361A_XPIPE_REWRITE_REG_2__MASK, TMC4361A_XPIPE_REWRITE_REG_2__SHIFT, TMC4361A_START_CONF, false}) +#define TMC4361A_XPIPE_REWRITE_REG_3__MASK 0x08000000 +#define TMC4361A_XPIPE_REWRITE_REG_3__SHIFT 27 +#define TMC4361A_XPIPE_REWRITE_REG_3__FIELD ((RegisterField) {TMC4361A_XPIPE_REWRITE_REG_3__MASK, TMC4361A_XPIPE_REWRITE_REG_3__SHIFT, TMC4361A_START_CONF, false}) +#define TMC4361A_XPIPE_REWRITE_REG_4__MASK 0x10000000 +#define TMC4361A_XPIPE_REWRITE_REG_4__SHIFT 28 +#define TMC4361A_XPIPE_REWRITE_REG_4__FIELD ((RegisterField) {TMC4361A_XPIPE_REWRITE_REG_4__MASK, TMC4361A_XPIPE_REWRITE_REG_4__SHIFT, TMC4361A_START_CONF, false}) +#define TMC4361A_XPIPE_REWRITE_REG_5__MASK 0x20000000 +#define TMC4361A_XPIPE_REWRITE_REG_5__SHIFT 29 +#define TMC4361A_XPIPE_REWRITE_REG_5__FIELD ((RegisterField) {TMC4361A_XPIPE_REWRITE_REG_5__MASK, TMC4361A_XPIPE_REWRITE_REG_5__SHIFT, TMC4361A_START_CONF, false}) +#define TMC4361A_XPIPE_REWRITE_REG_6__MASK 0x40000000 +#define TMC4361A_XPIPE_REWRITE_REG_6__SHIFT 30 +#define TMC4361A_XPIPE_REWRITE_REG_6__FIELD ((RegisterField) {TMC4361A_XPIPE_REWRITE_REG_6__MASK, TMC4361A_XPIPE_REWRITE_REG_6__SHIFT, TMC4361A_START_CONF, false}) +#define TMC4361A_XPIPE_REWRITE_REG_7__MASK 0x80000000 +#define TMC4361A_XPIPE_REWRITE_REG_7__SHIFT 31 +#define TMC4361A_XPIPE_REWRITE_REG_7__FIELD ((RegisterField) {TMC4361A_XPIPE_REWRITE_REG_7__MASK, TMC4361A_XPIPE_REWRITE_REG_7__SHIFT, TMC4361A_START_CONF, false}) +#define TMC4361A_SR_ENC_IN_MASK 0x00000007 +#define TMC4361A_SR_ENC_IN_SHIFT 0 +#define TMC4361A_SR_ENC_IN_FIELD ((RegisterField) {TMC4361A_SR_ENC_IN_MASK, TMC4361A_SR_ENC_IN_SHIFT, TMC4361A_INPUT_FILT_CONF, false}) +#define TMC4361A_FILT_L_ENC_IN_MASK 0x00000070 +#define TMC4361A_FILT_L_ENC_IN_SHIFT 4 +#define TMC4361A_FILT_L_ENC_IN_FIELD ((RegisterField) {TMC4361A_FILT_L_ENC_IN_MASK, TMC4361A_FILT_L_ENC_IN_SHIFT, TMC4361A_INPUT_FILT_CONF, false}) +#define TMC4361A_SD_FILT0_MASK 0x00000080 +#define TMC4361A_SD_FILT0_SHIFT 7 +#define TMC4361A_SD_FILT0_FIELD ((RegisterField) {TMC4361A_SD_FILT0_MASK, TMC4361A_SD_FILT0_SHIFT, TMC4361A_INPUT_FILT_CONF, false}) +#define TMC4361A_SR_REF_MASK 0x00000700 +#define TMC4361A_SR_REF_SHIFT 8 +#define TMC4361A_SR_REF_FIELD ((RegisterField) {TMC4361A_SR_REF_MASK, TMC4361A_SR_REF_SHIFT, TMC4361A_INPUT_FILT_CONF, false}) +#define TMC4361A_FILT_L_REF_MASK 0x00007000 +#define TMC4361A_FILT_L_REF_SHIFT 12 +#define TMC4361A_FILT_L_REF_FIELD ((RegisterField) {TMC4361A_FILT_L_REF_MASK, TMC4361A_FILT_L_REF_SHIFT, TMC4361A_INPUT_FILT_CONF, false}) +#define TMC4361A_SD_FILT1_MASK 0x00008000 +#define TMC4361A_SD_FILT1_SHIFT 15 +#define TMC4361A_SD_FILT1_FIELD ((RegisterField) {TMC4361A_SD_FILT1_MASK, TMC4361A_SD_FILT1_SHIFT, TMC4361A_INPUT_FILT_CONF, false}) +#define TMC4361A_SR_S_MASK 0x00070000 +#define TMC4361A_SR_S_SHIFT 16 +#define TMC4361A_SR_S_FIELD ((RegisterField) {TMC4361A_SR_S_MASK, TMC4361A_SR_S_SHIFT, TMC4361A_INPUT_FILT_CONF, false}) +#define TMC4361A_FILT_L_S_MASK 0x00700000 +#define TMC4361A_FILT_L_S_SHIFT 20 +#define TMC4361A_FILT_L_S_FIELD ((RegisterField) {TMC4361A_FILT_L_S_MASK, TMC4361A_FILT_L_S_SHIFT, TMC4361A_INPUT_FILT_CONF, false}) +#define TMC4361A_SD_FILT2_MASK 0x00800000 +#define TMC4361A_SD_FILT2_SHIFT 23 +#define TMC4361A_SD_FILT2_FIELD ((RegisterField) {TMC4361A_SD_FILT2_MASK, TMC4361A_SD_FILT2_SHIFT, TMC4361A_INPUT_FILT_CONF, false}) +#define TMC4361A_SR_ENC_OUT_MASK 0x07000000 +#define TMC4361A_SR_ENC_OUT_SHIFT 24 +#define TMC4361A_SR_ENC_OUT_FIELD ((RegisterField) {TMC4361A_SR_ENC_OUT_MASK, TMC4361A_SR_ENC_OUT_SHIFT, TMC4361A_INPUT_FILT_CONF, false}) +#define TMC4361A_FILT_L_ENC_OUT_MASK 0x70000000 +#define TMC4361A_FILT_L_ENC_OUT_SHIFT 28 +#define TMC4361A_FILT_L_ENC_OUT_FIELD ((RegisterField) {TMC4361A_FILT_L_ENC_OUT_MASK, TMC4361A_FILT_L_ENC_OUT_SHIFT, TMC4361A_INPUT_FILT_CONF, false}) +#define TMC4361A_SD_FILT3_MASK 0x80000000 +#define TMC4361A_SD_FILT3_SHIFT 31 +#define TMC4361A_SD_FILT3_FIELD ((RegisterField) {TMC4361A_SD_FILT3_MASK, TMC4361A_SD_FILT3_SHIFT, TMC4361A_INPUT_FILT_CONF, false}) +#define TMC4361A_SPI_OUTPUT_FORMAT_MASK 0x0000000f +#define TMC4361A_SPI_OUTPUT_FORMAT_SHIFT 0 +#define TMC4361A_SPI_OUTPUT_FORMAT_FIELD ((RegisterField) {TMC4361A_SPI_OUTPUT_FORMAT_MASK, TMC4361A_SPI_OUTPUT_FORMAT_SHIFT, TMC4361A_SPI_OUT_CONF, false}) +#define TMC4361A_SSI_OUT_MTIME_MASK 0x00fffff0 +#define TMC4361A_SSI_OUT_MTIME_SHIFT 4 +#define TMC4361A_SSI_OUT_MTIME_FIELD ((RegisterField) {TMC4361A_SSI_OUT_MTIME_MASK, TMC4361A_SSI_OUT_MTIME_SHIFT, TMC4361A_SPI_OUT_CONF, false}) +#define TMC4361A_MIXED_DECAY_MASK 0x00000030 +#define TMC4361A_MIXED_DECAY_SHIFT 4 +#define TMC4361A_MIXED_DECAY_FIELD ((RegisterField) {TMC4361A_MIXED_DECAY_MASK, TMC4361A_MIXED_DECAY_SHIFT, TMC4361A_SPI_OUT_CONF, false}) +#define TMC4361A_AUTO_DOUBLE_CHOPSYNC_MASK 0x00001000 +#define TMC4361A_AUTO_DOUBLE_CHOPSYNC_SHIFT 12 +#define TMC4361A_AUTO_DOUBLE_CHOPSYNC_FIELD ((RegisterField) {TMC4361A_AUTO_DOUBLE_CHOPSYNC_MASK, TMC4361A_AUTO_DOUBLE_CHOPSYNC_SHIFT, TMC4361A_SPI_OUT_CONF, false}) +#define TMC4361A_STDBY_ON_STALL_FOR_24X_MASK 0x00000040 +#define TMC4361A_STDBY_ON_STALL_FOR_24X_SHIFT 6 +#define TMC4361A_STDBY_ON_STALL_FOR_24X_FIELD ((RegisterField) {TMC4361A_STDBY_ON_STALL_FOR_24X_MASK, TMC4361A_STDBY_ON_STALL_FOR_24X_SHIFT, TMC4361A_SPI_OUT_CONF, false}) +#define TMC4361A_STALL_FLAG_INSTEAD_OF_UV_EN_MASK 0x00000080 +#define TMC4361A_STALL_FLAG_INSTEAD_OF_UV_EN_SHIFT 7 +#define TMC4361A_STALL_FLAG_INSTEAD_OF_UV_EN_FIELD ((RegisterField) {TMC4361A_STALL_FLAG_INSTEAD_OF_UV_EN_MASK, TMC4361A_STALL_FLAG_INSTEAD_OF_UV_EN_SHIFT, TMC4361A_SPI_OUT_CONF, false}) +#define TMC4361A_STALL_LOAD_LIMIT_MASK 0x00000700 +#define TMC4361A_STALL_LOAD_LIMIT_SHIFT 8 +#define TMC4361A_STALL_LOAD_LIMIT_FIELD ((RegisterField) {TMC4361A_STALL_LOAD_LIMIT_MASK, TMC4361A_STALL_LOAD_LIMIT_SHIFT, TMC4361A_SPI_OUT_CONF, false}) +#define TMC4361A_PWM_PHASE_SHFT_EN_MASK 0x00000800 +#define TMC4361A_PWM_PHASE_SHFT_EN_SHIFT 11 +#define TMC4361A_PWM_PHASE_SHFT_EN_FIELD ((RegisterField) {TMC4361A_PWM_PHASE_SHFT_EN_MASK, TMC4361A_PWM_PHASE_SHFT_EN_SHIFT, TMC4361A_SPI_OUT_CONF, false}) +#define TMC4361A_THREE_PHASE_STEPPER_EN_MASK 0x00000010 +#define TMC4361A_THREE_PHASE_STEPPER_EN_SHIFT 4 +#define TMC4361A_THREE_PHASE_STEPPER_EN_FIELD ((RegisterField) {TMC4361A_THREE_PHASE_STEPPER_EN_MASK, TMC4361A_THREE_PHASE_STEPPER_EN_SHIFT, TMC4361A_SPI_OUT_CONF, false}) +#define TMC4361A_AUTOREPEAT_COVER_EN_MASK 0x00000080 +#define TMC4361A_AUTOREPEAT_COVER_EN_SHIFT 7 +#define TMC4361A_AUTOREPEAT_COVER_EN_FIELD ((RegisterField) {TMC4361A_AUTOREPEAT_COVER_EN_MASK, TMC4361A_AUTOREPEAT_COVER_EN_SHIFT, TMC4361A_SPI_OUT_CONF, false}) +#define TMC4361A_COVER_DONE_ONLY_FOR_COVER_MASK 0x00001000 +#define TMC4361A_COVER_DONE_ONLY_FOR_COVER_SHIFT 12 +#define TMC4361A_COVER_DONE_ONLY_FOR_COVER_FIELD ((RegisterField) {TMC4361A_COVER_DONE_ONLY_FOR_COVER_MASK, TMC4361A_COVER_DONE_ONLY_FOR_COVER_SHIFT, TMC4361A_SPI_OUT_CONF, false}) +#define TMC4361A_SCALE_VALE_TRANSFER_EN_MASK 0x00000020 +#define TMC4361A_SCALE_VALE_TRANSFER_EN_SHIFT 5 +#define TMC4361A_SCALE_VALE_TRANSFER_EN_FIELD ((RegisterField) {TMC4361A_SCALE_VALE_TRANSFER_EN_MASK, TMC4361A_SCALE_VALE_TRANSFER_EN_SHIFT, TMC4361A_SPI_OUT_CONF, false}) +#define TMC4361A_DISABLE_POLLING_MASK 0x00000040 +#define TMC4361A_DISABLE_POLLING_SHIFT 6 +#define TMC4361A_DISABLE_POLLING_FIELD ((RegisterField) {TMC4361A_DISABLE_POLLING_MASK, TMC4361A_DISABLE_POLLING_SHIFT, TMC4361A_SPI_OUT_CONF, false}) +#define TMC4361A_POLL_BLOCK_EXP_MASK 0x00000f00 +#define TMC4361A_POLL_BLOCK_EXP_SHIFT 8 +#define TMC4361A_POLL_BLOCK_EXP_FIELD ((RegisterField) {TMC4361A_POLL_BLOCK_EXP_MASK, TMC4361A_POLL_BLOCK_EXP_SHIFT, TMC4361A_SPI_OUT_CONF, false}) +#define TMC4361A_SCK_LOW_BEFORE_CSN_MASK 0x00000010 +#define TMC4361A_SCK_LOW_BEFORE_CSN_SHIFT 4 +#define TMC4361A_SCK_LOW_BEFORE_CSN_FIELD ((RegisterField) {TMC4361A_SCK_LOW_BEFORE_CSN_MASK, TMC4361A_SCK_LOW_BEFORE_CSN_SHIFT, TMC4361A_SPI_OUT_CONF, false}) +#define TMC4361A_NEW_OUT_BIT_AT_RISE_MASK 0x00000020 +#define TMC4361A_NEW_OUT_BIT_AT_RISE_SHIFT 5 +#define TMC4361A_NEW_OUT_BIT_AT_RISE_FIELD ((RegisterField) {TMC4361A_NEW_OUT_BIT_AT_RISE_MASK, TMC4361A_NEW_OUT_BIT_AT_RISE_SHIFT, TMC4361A_SPI_OUT_CONF, false}) +#define TMC4361A_DAC_CMD_LENGTH_MASK 0x00000f80 +#define TMC4361A_DAC_CMD_LENGTH_SHIFT 7 +#define TMC4361A_DAC_CMD_LENGTH_FIELD ((RegisterField) {TMC4361A_DAC_CMD_LENGTH_MASK, TMC4361A_DAC_CMD_LENGTH_SHIFT, TMC4361A_SPI_OUT_CONF, false}) +#define TMC4361A_COVER_DATA_LENGTH_MASK 0x000fe000 +#define TMC4361A_COVER_DATA_LENGTH_SHIFT 13 +#define TMC4361A_COVER_DATA_LENGTH_FIELD ((RegisterField) {TMC4361A_COVER_DATA_LENGTH_MASK, TMC4361A_COVER_DATA_LENGTH_SHIFT, TMC4361A_SPI_OUT_CONF, false}) +#define TMC4361A_SPI_OUT_LOW_TIME_MASK 0x00f00000 +#define TMC4361A_SPI_OUT_LOW_TIME_SHIFT 20 +#define TMC4361A_SPI_OUT_LOW_TIME_FIELD ((RegisterField) {TMC4361A_SPI_OUT_LOW_TIME_MASK, TMC4361A_SPI_OUT_LOW_TIME_SHIFT, TMC4361A_SPI_OUT_CONF, false}) +#define TMC4361A_SPI_OUT_HIGH_TIME_MASK 0x0f000000 +#define TMC4361A_SPI_OUT_HIGH_TIME_SHIFT 24 +#define TMC4361A_SPI_OUT_HIGH_TIME_FIELD ((RegisterField) {TMC4361A_SPI_OUT_HIGH_TIME_MASK, TMC4361A_SPI_OUT_HIGH_TIME_SHIFT, TMC4361A_SPI_OUT_CONF, false}) +#define TMC4361A_SPI_OUT_BLOCK_TIME_MASK 0xf0000000 +#define TMC4361A_SPI_OUT_BLOCK_TIME_SHIFT 28 +#define TMC4361A_SPI_OUT_BLOCK_TIME_FIELD ((RegisterField) {TMC4361A_SPI_OUT_BLOCK_TIME_MASK, TMC4361A_SPI_OUT_BLOCK_TIME_SHIFT, TMC4361A_SPI_OUT_CONF, false}) +#define TMC4361A_HOLD_CURRENT_SCALE_EN_MASK 0x00000001 +#define TMC4361A_HOLD_CURRENT_SCALE_EN_SHIFT 0 +#define TMC4361A_HOLD_CURRENT_SCALE_EN_FIELD ((RegisterField) {TMC4361A_HOLD_CURRENT_SCALE_EN_MASK, TMC4361A_HOLD_CURRENT_SCALE_EN_SHIFT, TMC4361A_CURRENT_CONF, false}) +#define TMC4361A_DRIVE_CURRENT_SCALE_EN_MASK 0x00000002 +#define TMC4361A_DRIVE_CURRENT_SCALE_EN_SHIFT 1 +#define TMC4361A_DRIVE_CURRENT_SCALE_EN_FIELD ((RegisterField) {TMC4361A_DRIVE_CURRENT_SCALE_EN_MASK, TMC4361A_DRIVE_CURRENT_SCALE_EN_SHIFT, TMC4361A_CURRENT_CONF, false}) +#define TMC4361A_BOOST_CURRENT_ON_ACC_EN_MASK 0x00000004 +#define TMC4361A_BOOST_CURRENT_ON_ACC_EN_SHIFT 2 +#define TMC4361A_BOOST_CURRENT_ON_ACC_EN_FIELD ((RegisterField) {TMC4361A_BOOST_CURRENT_ON_ACC_EN_MASK, TMC4361A_BOOST_CURRENT_ON_ACC_EN_SHIFT, TMC4361A_CURRENT_CONF, false}) +#define TMC4361A_BOOST_CURRENT_ON_DEC_EN_MASK 0x00000008 +#define TMC4361A_BOOST_CURRENT_ON_DEC_EN_SHIFT 3 +#define TMC4361A_BOOST_CURRENT_ON_DEC_EN_FIELD ((RegisterField) {TMC4361A_BOOST_CURRENT_ON_DEC_EN_MASK, TMC4361A_BOOST_CURRENT_ON_DEC_EN_SHIFT, TMC4361A_CURRENT_CONF, false}) +#define TMC4361A_BOOST_CURRENT_AFTER_START_EN_MASK 0x00000010 +#define TMC4361A_BOOST_CURRENT_AFTER_START_EN_SHIFT 4 +#define TMC4361A_BOOST_CURRENT_AFTER_START_EN_FIELD ((RegisterField) {TMC4361A_BOOST_CURRENT_AFTER_START_EN_MASK, TMC4361A_BOOST_CURRENT_AFTER_START_EN_SHIFT, TMC4361A_CURRENT_CONF, false}) +#define TMC4361A_SEC_DRIVE_CURRENT_SCALE_EN_MASK 0x00000020 +#define TMC4361A_SEC_DRIVE_CURRENT_SCALE_EN_SHIFT 5 +#define TMC4361A_SEC_DRIVE_CURRENT_SCALE_EN_FIELD ((RegisterField) {TMC4361A_SEC_DRIVE_CURRENT_SCALE_EN_MASK, TMC4361A_SEC_DRIVE_CURRENT_SCALE_EN_SHIFT, TMC4361A_CURRENT_CONF, false}) +#define TMC4361A_FREEWHEELING_EN_MASK 0x00000040 +#define TMC4361A_FREEWHEELING_EN_SHIFT 6 +#define TMC4361A_FREEWHEELING_EN_FIELD ((RegisterField) {TMC4361A_FREEWHEELING_EN_MASK, TMC4361A_FREEWHEELING_EN_SHIFT, TMC4361A_CURRENT_CONF, false}) +#define TMC4361A_CLOSED_LOOP_SCALE_EN_MASK 0x00000080 +#define TMC4361A_CLOSED_LOOP_SCALE_EN_SHIFT 7 +#define TMC4361A_CLOSED_LOOP_SCALE_EN_FIELD ((RegisterField) {TMC4361A_CLOSED_LOOP_SCALE_EN_MASK, TMC4361A_CLOSED_LOOP_SCALE_EN_SHIFT, TMC4361A_CURRENT_CONF, false}) +#define TMC4361A_PWM_SCALE_EN_MASK 0x00000100 +#define TMC4361A_PWM_SCALE_EN_SHIFT 8 +#define TMC4361A_PWM_SCALE_EN_FIELD ((RegisterField) {TMC4361A_PWM_SCALE_EN_MASK, TMC4361A_PWM_SCALE_EN_SHIFT, TMC4361A_CURRENT_CONF, false}) +#define TMC4361A_PWM_AMPL_MASK 0xffff0000 +#define TMC4361A_PWM_AMPL_SHIFT 16 +#define TMC4361A_PWM_AMPL_FIELD ((RegisterField) {TMC4361A_PWM_AMPL_MASK, TMC4361A_PWM_AMPL_SHIFT, TMC4361A_CURRENT_CONF, false}) +#define TMC4361A_BOOST_SCALE_VAL_MASK 0x000000ff +#define TMC4361A_BOOST_SCALE_VAL_SHIFT 0 +#define TMC4361A_BOOST_SCALE_VAL_FIELD ((RegisterField) {TMC4361A_BOOST_SCALE_VAL_MASK, TMC4361A_BOOST_SCALE_VAL_SHIFT, TMC4361A_SCALE_VALUES, false}) +#define TMC4361A_DRV1_SCALE_VAL_MASK 0x0000ff00 +#define TMC4361A_DRV1_SCALE_VAL_SHIFT 8 +#define TMC4361A_DRV1_SCALE_VAL_FIELD ((RegisterField) {TMC4361A_DRV1_SCALE_VAL_MASK, TMC4361A_DRV1_SCALE_VAL_SHIFT, TMC4361A_SCALE_VALUES, false}) +#define TMC4361A_DRV2_SCALE_VAL_MASK 0x00ff0000 +#define TMC4361A_DRV2_SCALE_VAL_SHIFT 16 +#define TMC4361A_DRV2_SCALE_VAL_FIELD ((RegisterField) {TMC4361A_DRV2_SCALE_VAL_MASK, TMC4361A_DRV2_SCALE_VAL_SHIFT, TMC4361A_SCALE_VALUES, false}) +#define TMC4361A_HOLD_SCALE_VAL_MASK 0xff000000 +#define TMC4361A_HOLD_SCALE_VAL_SHIFT 24 +#define TMC4361A_HOLD_SCALE_VAL_FIELD ((RegisterField) {TMC4361A_HOLD_SCALE_VAL_MASK, TMC4361A_HOLD_SCALE_VAL_SHIFT, TMC4361A_SCALE_VALUES, false}) +#define TMC4361A_CL_IMIN_MASK 0x000000ff +#define TMC4361A_CL_IMIN_SHIFT 0 +#define TMC4361A_CL_IMIN_FIELD ((RegisterField) {TMC4361A_CL_IMIN_MASK, TMC4361A_CL_IMIN_SHIFT, TMC4361A_SCALE_VALUES, false}) +#define TMC4361A_CL_IMAX_MASK 0x0000ff00 +#define TMC4361A_CL_IMAX_SHIFT 8 +#define TMC4361A_CL_IMAX_FIELD ((RegisterField) {TMC4361A_CL_IMAX_MASK, TMC4361A_CL_IMAX_SHIFT, TMC4361A_SCALE_VALUES, false}) +#define TMC4361A_CL_START_UP_MASK 0x00ff0000 +#define TMC4361A_CL_START_UP_SHIFT 16 +#define TMC4361A_CL_START_UP_FIELD ((RegisterField) {TMC4361A_CL_START_UP_MASK, TMC4361A_CL_START_UP_SHIFT, TMC4361A_SCALE_VALUES, false}) +#define TMC4361A_CL_START_DN_MASK 0xff000000 +#define TMC4361A_CL_START_DN_SHIFT 24 +#define TMC4361A_CL_START_DN_FIELD ((RegisterField) {TMC4361A_CL_START_DN_MASK, TMC4361A_CL_START_DN_SHIFT, TMC4361A_SCALE_VALUES, false}) +#define TMC4361A_ENC_SEL_DECIMAL_MASK 0x00000001 +#define TMC4361A_ENC_SEL_DECIMAL_SHIFT 0 +#define TMC4361A_ENC_SEL_DECIMAL_FIELD ((RegisterField) {TMC4361A_ENC_SEL_DECIMAL_MASK, TMC4361A_ENC_SEL_DECIMAL_SHIFT, TMC4361A_ENC_IN_CONF, false}) +#define TMC4361A_CLEAR_ON_N_MASK 0x00000002 +#define TMC4361A_CLEAR_ON_N_SHIFT 1 +#define TMC4361A_CLEAR_ON_N_FIELD ((RegisterField) {TMC4361A_CLEAR_ON_N_MASK, TMC4361A_CLEAR_ON_N_SHIFT, TMC4361A_ENC_IN_CONF, false}) +#define TMC4361A_CLR_LATCH_CONT_ON_N_MASK 0x00000004 +#define TMC4361A_CLR_LATCH_CONT_ON_N_SHIFT 2 +#define TMC4361A_CLR_LATCH_CONT_ON_N_FIELD ((RegisterField) {TMC4361A_CLR_LATCH_CONT_ON_N_MASK, TMC4361A_CLR_LATCH_CONT_ON_N_SHIFT, TMC4361A_ENC_IN_CONF, false}) +#define TMC4361A_CLR_LATCH_ONCE_ON_N_MASK 0x00000008 +#define TMC4361A_CLR_LATCH_ONCE_ON_N_SHIFT 3 +#define TMC4361A_CLR_LATCH_ONCE_ON_N_FIELD ((RegisterField) {TMC4361A_CLR_LATCH_ONCE_ON_N_MASK, TMC4361A_CLR_LATCH_ONCE_ON_N_SHIFT, TMC4361A_ENC_IN_CONF, false}) +#define TMC4361A_POL_N_MASK 0x00000010 +#define TMC4361A_POL_N_SHIFT 4 +#define TMC4361A_POL_N_FIELD ((RegisterField) {TMC4361A_POL_N_MASK, TMC4361A_POL_N_SHIFT, TMC4361A_ENC_IN_CONF, false}) +#define TMC4361A_N_CHAN_SENSITIVITY_MASK 0x00000060 +#define TMC4361A_N_CHAN_SENSITIVITY_SHIFT 5 +#define TMC4361A_N_CHAN_SENSITIVITY_FIELD ((RegisterField) {TMC4361A_N_CHAN_SENSITIVITY_MASK, TMC4361A_N_CHAN_SENSITIVITY_SHIFT, TMC4361A_ENC_IN_CONF, false}) +#define TMC4361A_POL_A_FOR_N_MASK 0x00000080 +#define TMC4361A_POL_A_FOR_N_SHIFT 7 +#define TMC4361A_POL_A_FOR_N_FIELD ((RegisterField) {TMC4361A_POL_A_FOR_N_MASK, TMC4361A_POL_A_FOR_N_SHIFT, TMC4361A_ENC_IN_CONF, false}) +#define TMC4361A_POL_B_FOR_N_MASK 0x00000100 +#define TMC4361A_POL_B_FOR_N_SHIFT 8 +#define TMC4361A_POL_B_FOR_N_FIELD ((RegisterField) {TMC4361A_POL_B_FOR_N_MASK, TMC4361A_POL_B_FOR_N_SHIFT, TMC4361A_ENC_IN_CONF, false}) +#define TMC4361A_IGNORE_AB_MASK 0x00000200 +#define TMC4361A_IGNORE_AB_SHIFT 9 +#define TMC4361A_IGNORE_AB_FIELD ((RegisterField) {TMC4361A_IGNORE_AB_MASK, TMC4361A_IGNORE_AB_SHIFT, TMC4361A_ENC_IN_CONF, false}) +#define TMC4361A_LATCH_ENC_ON_N_MASK 0x00000400 +#define TMC4361A_LATCH_ENC_ON_N_SHIFT 10 +#define TMC4361A_LATCH_ENC_ON_N_FIELD ((RegisterField) {TMC4361A_LATCH_ENC_ON_N_MASK, TMC4361A_LATCH_ENC_ON_N_SHIFT, TMC4361A_ENC_IN_CONF, false}) +#define TMC4361A_LATCH_X_ON_N_MASK 0x00000800 +#define TMC4361A_LATCH_X_ON_N_SHIFT 11 +#define TMC4361A_LATCH_X_ON_N_FIELD ((RegisterField) {TMC4361A_LATCH_X_ON_N_MASK, TMC4361A_LATCH_X_ON_N_SHIFT, TMC4361A_ENC_IN_CONF, false}) +#define TMC4361A_MULTI_TURN_IN_EN_MASK 0x00001000 +#define TMC4361A_MULTI_TURN_IN_EN_SHIFT 12 +#define TMC4361A_MULTI_TURN_IN_EN_FIELD ((RegisterField) {TMC4361A_MULTI_TURN_IN_EN_MASK, TMC4361A_MULTI_TURN_IN_EN_SHIFT, TMC4361A_ENC_IN_CONF, false}) +#define TMC4361A_MULTI_TURN_IN_SIGNED_MASK 0x00002000 +#define TMC4361A_MULTI_TURN_IN_SIGNED_SHIFT 13 +#define TMC4361A_MULTI_TURN_IN_SIGNED_FIELD ((RegisterField) {TMC4361A_MULTI_TURN_IN_SIGNED_MASK, TMC4361A_MULTI_TURN_IN_SIGNED_SHIFT, TMC4361A_ENC_IN_CONF, false}) +#define TMC4361A_MULTI_TURN_OUT_EN_MASK 0x00004000 +#define TMC4361A_MULTI_TURN_OUT_EN_SHIFT 14 +#define TMC4361A_MULTI_TURN_OUT_EN_FIELD ((RegisterField) {TMC4361A_MULTI_TURN_OUT_EN_MASK, TMC4361A_MULTI_TURN_OUT_EN_SHIFT, TMC4361A_ENC_IN_CONF, false}) +#define TMC4361A_USE_USTEPS_INSTEAD_OF_XRANGE_MASK 0x00008000 +#define TMC4361A_USE_USTEPS_INSTEAD_OF_XRANGE_SHIFT 15 +#define TMC4361A_USE_USTEPS_INSTEAD_OF_XRANGE_FIELD ((RegisterField) {TMC4361A_USE_USTEPS_INSTEAD_OF_XRANGE_MASK, TMC4361A_USE_USTEPS_INSTEAD_OF_XRANGE_SHIFT, TMC4361A_ENC_IN_CONF, false}) +#define TMC4361A_CALC_MULTI_TURN_BEHAV_MASK 0x00010000 +#define TMC4361A_CALC_MULTI_TURN_BEHAV_SHIFT 16 +#define TMC4361A_CALC_MULTI_TURN_BEHAV_FIELD ((RegisterField) {TMC4361A_CALC_MULTI_TURN_BEHAV_MASK, TMC4361A_CALC_MULTI_TURN_BEHAV_SHIFT, TMC4361A_ENC_IN_CONF, false}) +#define TMC4361A_SSI_MULTI_CYCLE_DATA_MASK 0x00020000 +#define TMC4361A_SSI_MULTI_CYCLE_DATA_SHIFT 17 +#define TMC4361A_SSI_MULTI_CYCLE_DATA_FIELD ((RegisterField) {TMC4361A_SSI_MULTI_CYCLE_DATA_MASK, TMC4361A_SSI_MULTI_CYCLE_DATA_SHIFT, TMC4361A_ENC_IN_CONF, false}) +#define TMC4361A_SSI_GRAY_CODE_EN_MASK 0x00040000 +#define TMC4361A_SSI_GRAY_CODE_EN_SHIFT 18 +#define TMC4361A_SSI_GRAY_CODE_EN_FIELD ((RegisterField) {TMC4361A_SSI_GRAY_CODE_EN_MASK, TMC4361A_SSI_GRAY_CODE_EN_SHIFT, TMC4361A_ENC_IN_CONF, false}) +#define TMC4361A_LEFT_ALIGNED_DATA_MASK 0x00080000 +#define TMC4361A_LEFT_ALIGNED_DATA_SHIFT 19 +#define TMC4361A_LEFT_ALIGNED_DATA_FIELD ((RegisterField) {TMC4361A_LEFT_ALIGNED_DATA_MASK, TMC4361A_LEFT_ALIGNED_DATA_SHIFT, TMC4361A_ENC_IN_CONF, false}) +#define TMC4361A_SPI_DATA_ON_CS_MASK 0x00100000 +#define TMC4361A_SPI_DATA_ON_CS_SHIFT 20 +#define TMC4361A_SPI_DATA_ON_CS_FIELD ((RegisterField) {TMC4361A_SPI_DATA_ON_CS_MASK, TMC4361A_SPI_DATA_ON_CS_SHIFT, TMC4361A_ENC_IN_CONF, false}) +#define TMC4361A_SPI_LOW_BEFORE_CS_MASK 0x00200000 +#define TMC4361A_SPI_LOW_BEFORE_CS_SHIFT 21 +#define TMC4361A_SPI_LOW_BEFORE_CS_FIELD ((RegisterField) {TMC4361A_SPI_LOW_BEFORE_CS_MASK, TMC4361A_SPI_LOW_BEFORE_CS_SHIFT, TMC4361A_ENC_IN_CONF, false}) +#define TMC4361A_REGULATION_MODUS_MASK 0x00c00000 +#define TMC4361A_REGULATION_MODUS_SHIFT 22 +#define TMC4361A_REGULATION_MODUS_FIELD ((RegisterField) {TMC4361A_REGULATION_MODUS_MASK, TMC4361A_REGULATION_MODUS_SHIFT, TMC4361A_ENC_IN_CONF, false}) +#define TMC4361A_CL_CALIBRATION_EN_MASK 0x01000000 +#define TMC4361A_CL_CALIBRATION_EN_SHIFT 24 +#define TMC4361A_CL_CALIBRATION_EN_FIELD ((RegisterField) {TMC4361A_CL_CALIBRATION_EN_MASK, TMC4361A_CL_CALIBRATION_EN_SHIFT, TMC4361A_ENC_IN_CONF, false}) +#define TMC4361A_CL_EMF_EN_MASK 0x02000000 +#define TMC4361A_CL_EMF_EN_SHIFT 25 +#define TMC4361A_CL_EMF_EN_FIELD ((RegisterField) {TMC4361A_CL_EMF_EN_MASK, TMC4361A_CL_EMF_EN_SHIFT, TMC4361A_ENC_IN_CONF, false}) +#define TMC4361A_CL_CLR_XACT_MASK 0x04000000 +#define TMC4361A_CL_CLR_XACT_SHIFT 26 +#define TMC4361A_CL_CLR_XACT_FIELD ((RegisterField) {TMC4361A_CL_CLR_XACT_MASK, TMC4361A_CL_CLR_XACT_SHIFT, TMC4361A_ENC_IN_CONF, false}) +#define TMC4361A_CL_VLIMIT_EN_MASK 0x08000000 +#define TMC4361A_CL_VLIMIT_EN_SHIFT 27 +#define TMC4361A_CL_VLIMIT_EN_FIELD ((RegisterField) {TMC4361A_CL_VLIMIT_EN_MASK, TMC4361A_CL_VLIMIT_EN_SHIFT, TMC4361A_ENC_IN_CONF, false}) +#define TMC4361A_CL_VELOCITY_MODE_EN_MASK 0x10000000 +#define TMC4361A_CL_VELOCITY_MODE_EN_SHIFT 28 +#define TMC4361A_CL_VELOCITY_MODE_EN_FIELD ((RegisterField) {TMC4361A_CL_VELOCITY_MODE_EN_MASK, TMC4361A_CL_VELOCITY_MODE_EN_SHIFT, TMC4361A_ENC_IN_CONF, false}) +#define TMC4361A_INVERT_ENC_DIR_MASK 0x20000000 +#define TMC4361A_INVERT_ENC_DIR_SHIFT 29 +#define TMC4361A_INVERT_ENC_DIR_FIELD ((RegisterField) {TMC4361A_INVERT_ENC_DIR_MASK, TMC4361A_INVERT_ENC_DIR_SHIFT, TMC4361A_ENC_IN_CONF, false}) +#define TMC4361A_ENC_OUT_GRAY_MASK 0x40000000 +#define TMC4361A_ENC_OUT_GRAY_SHIFT 30 +#define TMC4361A_ENC_OUT_GRAY_FIELD ((RegisterField) {TMC4361A_ENC_OUT_GRAY_MASK, TMC4361A_ENC_OUT_GRAY_SHIFT, TMC4361A_ENC_IN_CONF, false}) +#define TMC4361A_NO_ENC_VEL_PREPROC_MASK 0x80000000 +#define TMC4361A_NO_ENC_VEL_PREPROC_SHIFT 31 +#define TMC4361A_NO_ENC_VEL_PREPROC_FIELD ((RegisterField) {TMC4361A_NO_ENC_VEL_PREPROC_MASK, TMC4361A_NO_ENC_VEL_PREPROC_SHIFT, TMC4361A_ENC_IN_CONF, false}) +#define TMC4361A_SERIAL_ENC_VARIATION_LIMIT_MASK 0x80000000 +#define TMC4361A_SERIAL_ENC_VARIATION_LIMIT_SHIFT 31 +#define TMC4361A_SERIAL_ENC_VARIATION_LIMIT_FIELD ((RegisterField) {TMC4361A_SERIAL_ENC_VARIATION_LIMIT_MASK, TMC4361A_SERIAL_ENC_VARIATION_LIMIT_SHIFT, TMC4361A_ENC_IN_CONF, false}) +#define TMC4361A_SINGLE_TURN_RES_MASK 0x0000001f +#define TMC4361A_SINGLE_TURN_RES_SHIFT 0 +#define TMC4361A_SINGLE_TURN_RES_FIELD ((RegisterField) {TMC4361A_SINGLE_TURN_RES_MASK, TMC4361A_SINGLE_TURN_RES_SHIFT, TMC4361A_ENC_IN_DATA, false}) +#define TMC4361A_MULTI_TURN_RES_MASK 0x000003e0 +#define TMC4361A_MULTI_TURN_RES_SHIFT 5 +#define TMC4361A_MULTI_TURN_RES_FIELD ((RegisterField) {TMC4361A_MULTI_TURN_RES_MASK, TMC4361A_MULTI_TURN_RES_SHIFT, TMC4361A_ENC_IN_DATA, false}) +#define TMC4361A_STATUS_BIT_CNT_MASK 0x00000c00 +#define TMC4361A_STATUS_BIT_CNT_SHIFT 10 +#define TMC4361A_STATUS_BIT_CNT_FIELD ((RegisterField) {TMC4361A_STATUS_BIT_CNT_MASK, TMC4361A_STATUS_BIT_CNT_SHIFT, TMC4361A_ENC_IN_DATA, false}) +#define TMC4361A_SERIAL_ADDR_BITS_MASK 0x00ff0000 +#define TMC4361A_SERIAL_ADDR_BITS_SHIFT 16 +#define TMC4361A_SERIAL_ADDR_BITS_FIELD ((RegisterField) {TMC4361A_SERIAL_ADDR_BITS_MASK, TMC4361A_SERIAL_ADDR_BITS_SHIFT, TMC4361A_ENC_IN_DATA, false}) +#define TMC4361A_SERIAL_DATA_BITS_MASK 0xff000000 +#define TMC4361A_SERIAL_DATA_BITS_SHIFT 24 +#define TMC4361A_SERIAL_DATA_BITS_FIELD ((RegisterField) {TMC4361A_SERIAL_DATA_BITS_MASK, TMC4361A_SERIAL_DATA_BITS_SHIFT, TMC4361A_ENC_IN_DATA, false}) +#define TMC4361A_SINGLE_TURN_RES_OUT_MASK 0x0000001f +#define TMC4361A_SINGLE_TURN_RES_OUT_SHIFT 0 +#define TMC4361A_SINGLE_TURN_RES_OUT_FIELD ((RegisterField) {TMC4361A_SINGLE_TURN_RES_OUT_MASK, TMC4361A_SINGLE_TURN_RES_OUT_SHIFT, TMC4361A_ENC_OUT_DATA, false}) +#define TMC4361A_MULTI_TURN_RES_OUT_MASK 0x000003e0 +#define TMC4361A_MULTI_TURN_RES_OUT_SHIFT 5 +#define TMC4361A_MULTI_TURN_RES_OUT_FIELD ((RegisterField) {TMC4361A_MULTI_TURN_RES_OUT_MASK, TMC4361A_MULTI_TURN_RES_OUT_SHIFT, TMC4361A_ENC_OUT_DATA, false}) +#define TMC4361A_MSTEP_PER_FS_MASK 0x0000000f +#define TMC4361A_MSTEP_PER_FS_SHIFT 0 +#define TMC4361A_MSTEP_PER_FS_FIELD ((RegisterField) {TMC4361A_MSTEP_PER_FS_MASK, TMC4361A_MSTEP_PER_FS_SHIFT, TMC4361A_STEP_CONF, false}) +#define TMC4361A_FS_PER_REV_MASK 0x0000fff0 +#define TMC4361A_FS_PER_REV_SHIFT 4 +#define TMC4361A_FS_PER_REV_FIELD ((RegisterField) {TMC4361A_FS_PER_REV_MASK, TMC4361A_FS_PER_REV_SHIFT, TMC4361A_STEP_CONF, false}) +#define TMC4361A_SG_MASK 0x00010000 +#define TMC4361A_SG_SHIFT 16 +#define TMC4361A_SG_FIELD ((RegisterField) {TMC4361A_SG_MASK, TMC4361A_SG_SHIFT, TMC4361A_STEP_CONF, false}) +#define TMC4361A_OT_MASK 0x00020000 +#define TMC4361A_OT_SHIFT 17 +#define TMC4361A_OT_FIELD ((RegisterField) {TMC4361A_OT_MASK, TMC4361A_OT_SHIFT, TMC4361A_STEP_CONF, false}) +#define TMC4361A_OTPW_MASK 0x00040000 +#define TMC4361A_OTPW_SHIFT 18 +#define TMC4361A_OTPW_FIELD ((RegisterField) {TMC4361A_OTPW_MASK, TMC4361A_OTPW_SHIFT, TMC4361A_STEP_CONF, false}) +#define TMC4361A_S2GA_MASK 0x00080000 +#define TMC4361A_S2GA_SHIFT 19 +#define TMC4361A_S2GA_FIELD ((RegisterField) {TMC4361A_S2GA_MASK, TMC4361A_S2GA_SHIFT, TMC4361A_STEP_CONF, false}) +#define TMC4361A_S2GB_MASK 0x00100000 +#define TMC4361A_S2GB_SHIFT 20 +#define TMC4361A_S2GB_FIELD ((RegisterField) {TMC4361A_S2GB_MASK, TMC4361A_S2GB_SHIFT, TMC4361A_STEP_CONF, false}) +#define TMC4361A_OLA_MASK 0x00200000 +#define TMC4361A_OLA_SHIFT 21 +#define TMC4361A_OLA_FIELD ((RegisterField) {TMC4361A_OLA_MASK, TMC4361A_OLA_SHIFT, TMC4361A_STEP_CONF, false}) +#define TMC4361A_OLB_MASK 0x00400000 +#define TMC4361A_OLB_SHIFT 22 +#define TMC4361A_OLB_FIELD ((RegisterField) {TMC4361A_OLB_MASK, TMC4361A_OLB_SHIFT, TMC4361A_STEP_CONF, false}) +#define TMC4361A_STST_MASK 0x00800000 +#define TMC4361A_STST_SHIFT 23 +#define TMC4361A_STST_FIELD ((RegisterField) {TMC4361A_STST_MASK, TMC4361A_STST_SHIFT, TMC4361A_STEP_CONF, false}) +#define TMC4361A_UV_SF_MASK 0x00010000 +#define TMC4361A_UV_SF_SHIFT 16 +#define TMC4361A_UV_SF_FIELD ((RegisterField) {TMC4361A_UV_SF_MASK, TMC4361A_UV_SF_SHIFT, TMC4361A_STEP_CONF, false}) +#define TMC4361A_OCA_MASK 0x00080000 +#define TMC4361A_OCA_SHIFT 19 +#define TMC4361A_OCA_FIELD ((RegisterField) {TMC4361A_OCA_MASK, TMC4361A_OCA_SHIFT, TMC4361A_STEP_CONF, false}) +#define TMC4361A_OCB_MASK 0x00100000 +#define TMC4361A_OCB_SHIFT 20 +#define TMC4361A_OCB_FIELD ((RegisterField) {TMC4361A_OCB_MASK, TMC4361A_OCB_SHIFT, TMC4361A_STEP_CONF, false}) +#define TMC4361A_OCHS_MASK 0x00800000 +#define TMC4361A_OCHS_SHIFT 23 +#define TMC4361A_OCHS_FIELD ((RegisterField) {TMC4361A_OCHS_MASK, TMC4361A_OCHS_SHIFT, TMC4361A_STEP_CONF, false}) +#define TMC4361A_TARGET_REACHED_MASK 0x00000001 +#define TMC4361A_TARGET_REACHED_SHIFT 0 +#define TMC4361A_TARGET_REACHED_FIELD ((RegisterField) {TMC4361A_TARGET_REACHED_MASK, TMC4361A_TARGET_REACHED_SHIFT, TMC4361A_SPI_STATUS_SELECTION, false}) +#define TMC4361A_POS_COMP_REACHED_MASK 0x00000002 +#define TMC4361A_POS_COMP_REACHED_SHIFT 1 +#define TMC4361A_POS_COMP_REACHED_FIELD ((RegisterField) {TMC4361A_POS_COMP_REACHED_MASK, TMC4361A_POS_COMP_REACHED_SHIFT, TMC4361A_SPI_STATUS_SELECTION, false}) +#define TMC4361A_VEL_REACHED_MASK 0x00000004 +#define TMC4361A_VEL_REACHED_SHIFT 2 +#define TMC4361A_VEL_REACHED_FIELD ((RegisterField) {TMC4361A_VEL_REACHED_MASK, TMC4361A_VEL_REACHED_SHIFT, TMC4361A_SPI_STATUS_SELECTION, false}) +#define TMC4361A_VEL_STATE_00_MASK 0x00000008 +#define TMC4361A_VEL_STATE_00_SHIFT 3 +#define TMC4361A_VEL_STATE_00_FIELD ((RegisterField) {TMC4361A_VEL_STATE_00_MASK, TMC4361A_VEL_STATE_00_SHIFT, TMC4361A_SPI_STATUS_SELECTION, false}) +#define TMC4361A_VEL_STATE_01_MASK 0x00000010 +#define TMC4361A_VEL_STATE_01_SHIFT 4 +#define TMC4361A_VEL_STATE_01_FIELD ((RegisterField) {TMC4361A_VEL_STATE_01_MASK, TMC4361A_VEL_STATE_01_SHIFT, TMC4361A_SPI_STATUS_SELECTION, false}) +#define TMC4361A_VEL_STATE_10_MASK 0x00000020 +#define TMC4361A_VEL_STATE_10_SHIFT 5 +#define TMC4361A_VEL_STATE_10_FIELD ((RegisterField) {TMC4361A_VEL_STATE_10_MASK, TMC4361A_VEL_STATE_10_SHIFT, TMC4361A_SPI_STATUS_SELECTION, false}) +#define TMC4361A_RAMP_STATE_00_MASK 0x00000040 +#define TMC4361A_RAMP_STATE_00_SHIFT 6 +#define TMC4361A_RAMP_STATE_00_FIELD ((RegisterField) {TMC4361A_RAMP_STATE_00_MASK, TMC4361A_RAMP_STATE_00_SHIFT, TMC4361A_SPI_STATUS_SELECTION, false}) +#define TMC4361A_RAMP_STATE_01_MASK 0x00000080 +#define TMC4361A_RAMP_STATE_01_SHIFT 7 +#define TMC4361A_RAMP_STATE_01_FIELD ((RegisterField) {TMC4361A_RAMP_STATE_01_MASK, TMC4361A_RAMP_STATE_01_SHIFT, TMC4361A_SPI_STATUS_SELECTION, false}) +#define TMC4361A_RAMP_STATE_10_MASK 0x00000100 +#define TMC4361A_RAMP_STATE_10_SHIFT 8 +#define TMC4361A_RAMP_STATE_10_FIELD ((RegisterField) {TMC4361A_RAMP_STATE_10_MASK, TMC4361A_RAMP_STATE_10_SHIFT, TMC4361A_SPI_STATUS_SELECTION, false}) +#define TMC4361A_MAX_PHASE_TRAP_MASK 0x00000200 +#define TMC4361A_MAX_PHASE_TRAP_SHIFT 9 +#define TMC4361A_MAX_PHASE_TRAP_FIELD ((RegisterField) {TMC4361A_MAX_PHASE_TRAP_MASK, TMC4361A_MAX_PHASE_TRAP_SHIFT, TMC4361A_SPI_STATUS_SELECTION, false}) +#define TMC4361A_FROZEN_MASK 0x00000400 +#define TMC4361A_FROZEN_SHIFT 10 +#define TMC4361A_FROZEN_FIELD ((RegisterField) {TMC4361A_FROZEN_MASK, TMC4361A_FROZEN_SHIFT, TMC4361A_SPI_STATUS_SELECTION, false}) +#define TMC4361A_STOPL_EVENT_MASK 0x00000800 +#define TMC4361A_STOPL_EVENT_SHIFT 11 +#define TMC4361A_STOPL_EVENT_FIELD ((RegisterField) {TMC4361A_STOPL_EVENT_MASK, TMC4361A_STOPL_EVENT_SHIFT, TMC4361A_SPI_STATUS_SELECTION, false}) +#define TMC4361A_STOPR_EVENT_MASK 0x00001000 +#define TMC4361A_STOPR_EVENT_SHIFT 12 +#define TMC4361A_STOPR_EVENT_FIELD ((RegisterField) {TMC4361A_STOPR_EVENT_MASK, TMC4361A_STOPR_EVENT_SHIFT, TMC4361A_SPI_STATUS_SELECTION, false}) +#define TMC4361A_VSTOPL_ACTIVE_MASK 0x00002000 +#define TMC4361A_VSTOPL_ACTIVE_SHIFT 13 +#define TMC4361A_VSTOPL_ACTIVE_FIELD ((RegisterField) {TMC4361A_VSTOPL_ACTIVE_MASK, TMC4361A_VSTOPL_ACTIVE_SHIFT, TMC4361A_SPI_STATUS_SELECTION, false}) +#define TMC4361A_HOME_ERROR_MASK 0x00008000 +#define TMC4361A_HOME_ERROR_SHIFT 15 +#define TMC4361A_HOME_ERROR_FIELD ((RegisterField) {TMC4361A_HOME_ERROR_MASK, TMC4361A_HOME_ERROR_SHIFT, TMC4361A_SPI_STATUS_SELECTION, false}) +#define TMC4361A_XLATCH_DONE_MASK 0x00010000 +#define TMC4361A_XLATCH_DONE_SHIFT 16 +#define TMC4361A_XLATCH_DONE_FIELD ((RegisterField) {TMC4361A_XLATCH_DONE_MASK, TMC4361A_XLATCH_DONE_SHIFT, TMC4361A_SPI_STATUS_SELECTION, false}) +#define TMC4361A_FS_ACTIVE_MASK 0x00020000 +#define TMC4361A_FS_ACTIVE_SHIFT 17 +#define TMC4361A_FS_ACTIVE_FIELD ((RegisterField) {TMC4361A_FS_ACTIVE_MASK, TMC4361A_FS_ACTIVE_SHIFT, TMC4361A_SPI_STATUS_SELECTION, false}) +#define TMC4361A_ENC_FAIL_MASK 0x00040000 +#define TMC4361A_ENC_FAIL_SHIFT 18 +#define TMC4361A_ENC_FAIL_FIELD ((RegisterField) {TMC4361A_ENC_FAIL_MASK, TMC4361A_ENC_FAIL_SHIFT, TMC4361A_SPI_STATUS_SELECTION, false}) +#define TMC4361A_N_ACTIVE_MASK 0x00080000 +#define TMC4361A_N_ACTIVE_SHIFT 19 +#define TMC4361A_N_ACTIVE_FIELD ((RegisterField) {TMC4361A_N_ACTIVE_MASK, TMC4361A_N_ACTIVE_SHIFT, TMC4361A_SPI_STATUS_SELECTION, false}) +#define TMC4361A_ENC_DONE_MASK 0x00100000 +#define TMC4361A_ENC_DONE_SHIFT 20 +#define TMC4361A_ENC_DONE_FIELD ((RegisterField) {TMC4361A_ENC_DONE_MASK, TMC4361A_ENC_DONE_SHIFT, TMC4361A_SPI_STATUS_SELECTION, false}) +#define TMC4361A_SER_ENC_DATA_FAIL_MASK 0x00200000 +#define TMC4361A_SER_ENC_DATA_FAIL_SHIFT 21 +#define TMC4361A_SER_ENC_DATA_FAIL_FIELD ((RegisterField) {TMC4361A_SER_ENC_DATA_FAIL_MASK, TMC4361A_SER_ENC_DATA_FAIL_SHIFT, TMC4361A_SPI_STATUS_SELECTION, false}) +#define TMC4361A_SER_DATA_DONE_MASK 0x00800000 +#define TMC4361A_SER_DATA_DONE_SHIFT 23 +#define TMC4361A_SER_DATA_DONE_FIELD ((RegisterField) {TMC4361A_SER_DATA_DONE_MASK, TMC4361A_SER_DATA_DONE_SHIFT, TMC4361A_SPI_STATUS_SELECTION, false}) +#define TMC4361A_SERIAL_ENC_FLAGS_MASK 0x01000000 +#define TMC4361A_SERIAL_ENC_FLAGS_SHIFT 24 +#define TMC4361A_SERIAL_ENC_FLAGS_FIELD ((RegisterField) {TMC4361A_SERIAL_ENC_FLAGS_MASK, TMC4361A_SERIAL_ENC_FLAGS_SHIFT, TMC4361A_SPI_STATUS_SELECTION, false}) +#define TMC4361A_COVER_DONE_MASK 0x02000000 +#define TMC4361A_COVER_DONE_SHIFT 25 +#define TMC4361A_COVER_DONE_FIELD ((RegisterField) {TMC4361A_COVER_DONE_MASK, TMC4361A_COVER_DONE_SHIFT, TMC4361A_SPI_STATUS_SELECTION, false}) +#define TMC4361A_ENC_VEL0_MASK 0x04000000 +#define TMC4361A_ENC_VEL0_SHIFT 26 +#define TMC4361A_ENC_VEL0_FIELD ((RegisterField) {TMC4361A_ENC_VEL0_MASK, TMC4361A_ENC_VEL0_SHIFT, TMC4361A_SPI_STATUS_SELECTION, false}) +#define TMC4361A_CL_MAX_MASK 0x08000000 +#define TMC4361A_CL_MAX_SHIFT 27 +#define TMC4361A_CL_MAX_FIELD ((RegisterField) {TMC4361A_CL_MAX_MASK, TMC4361A_CL_MAX_SHIFT, TMC4361A_SPI_STATUS_SELECTION, false}) +#define TMC4361A_CL_FIT_MASK 0x10000000 +#define TMC4361A_CL_FIT_SHIFT 28 +#define TMC4361A_CL_FIT_FIELD ((RegisterField) {TMC4361A_CL_FIT_MASK, TMC4361A_CL_FIT_SHIFT, TMC4361A_SPI_STATUS_SELECTION, false}) +#define TMC4361A_MOTOR_EV_MASK 0x40000000 +#define TMC4361A_MOTOR_EV_SHIFT 30 +#define TMC4361A_MOTOR_EV_FIELD ((RegisterField) {TMC4361A_MOTOR_EV_MASK, TMC4361A_MOTOR_EV_SHIFT, TMC4361A_SPI_STATUS_SELECTION, false}) +#define TMC4361A_RST_EV_MASK 0x80000000 +#define TMC4361A_RST_EV_SHIFT 31 +#define TMC4361A_RST_EV_FIELD ((RegisterField) {TMC4361A_RST_EV_MASK, TMC4361A_RST_EV_SHIFT, TMC4361A_SPI_STATUS_SELECTION, false}) +#define TMC4361A_TARGET_REACHED_F_MASK 0x00000001 +#define TMC4361A_TARGET_REACHED_F_SHIFT 0 +#define TMC4361A_TARGET_REACHED_F_FIELD ((RegisterField) {TMC4361A_TARGET_REACHED_F_MASK, TMC4361A_TARGET_REACHED_F_SHIFT, TMC4361A_STATUS, false}) +#define TMC4361A_POS_COMP_REACHED_F_MASK 0x00000002 +#define TMC4361A_POS_COMP_REACHED_F_SHIFT 1 +#define TMC4361A_POS_COMP_REACHED_F_FIELD ((RegisterField) {TMC4361A_POS_COMP_REACHED_F_MASK, TMC4361A_POS_COMP_REACHED_F_SHIFT, TMC4361A_STATUS, false}) +#define TMC4361A_VEL_REACHED_F_MASK 0x00000004 +#define TMC4361A_VEL_REACHED_F_SHIFT 2 +#define TMC4361A_VEL_REACHED_F_FIELD ((RegisterField) {TMC4361A_VEL_REACHED_F_MASK, TMC4361A_VEL_REACHED_F_SHIFT, TMC4361A_STATUS, false}) +#define TMC4361A_VEL_STATE_F_MASK 0x00000018 +#define TMC4361A_VEL_STATE_F_SHIFT 3 +#define TMC4361A_VEL_STATE_F_FIELD ((RegisterField) {TMC4361A_VEL_STATE_F_MASK, TMC4361A_VEL_STATE_F_SHIFT, TMC4361A_STATUS, false}) +#define TMC4361A_RAMP_STATE_F_MASK 0x00000060 +#define TMC4361A_RAMP_STATE_F_SHIFT 5 +#define TMC4361A_RAMP_STATE_F_FIELD ((RegisterField) {TMC4361A_RAMP_STATE_F_MASK, TMC4361A_RAMP_STATE_F_SHIFT, TMC4361A_STATUS, false}) +#define TMC4361A_STOPL_ACTIVE_F_MASK 0x00000080 +#define TMC4361A_STOPL_ACTIVE_F_SHIFT 7 +#define TMC4361A_STOPL_ACTIVE_F_FIELD ((RegisterField) {TMC4361A_STOPL_ACTIVE_F_MASK, TMC4361A_STOPL_ACTIVE_F_SHIFT, TMC4361A_STATUS, false}) +#define TMC4361A_STOPR_ACTIVE_F_MASK 0x00000100 +#define TMC4361A_STOPR_ACTIVE_F_SHIFT 8 +#define TMC4361A_STOPR_ACTIVE_F_FIELD ((RegisterField) {TMC4361A_STOPR_ACTIVE_F_MASK, TMC4361A_STOPR_ACTIVE_F_SHIFT, TMC4361A_STATUS, false}) +#define TMC4361A_VSTOPL_ACTIVE_F_MASK 0x00000200 +#define TMC4361A_VSTOPL_ACTIVE_F_SHIFT 9 +#define TMC4361A_VSTOPL_ACTIVE_F_FIELD ((RegisterField) {TMC4361A_VSTOPL_ACTIVE_F_MASK, TMC4361A_VSTOPL_ACTIVE_F_SHIFT, TMC4361A_STATUS, false}) +#define TMC4361A_VSTOPR_ACTIVE_F_MASK 0x00000400 +#define TMC4361A_VSTOPR_ACTIVE_F_SHIFT 10 +#define TMC4361A_VSTOPR_ACTIVE_F_FIELD ((RegisterField) {TMC4361A_VSTOPR_ACTIVE_F_MASK, TMC4361A_VSTOPR_ACTIVE_F_SHIFT, TMC4361A_STATUS, false}) +#define TMC4361A_ACTIVE_STALL_F_MASK 0x00000800 +#define TMC4361A_ACTIVE_STALL_F_SHIFT 11 +#define TMC4361A_ACTIVE_STALL_F_FIELD ((RegisterField) {TMC4361A_ACTIVE_STALL_F_MASK, TMC4361A_ACTIVE_STALL_F_SHIFT, TMC4361A_STATUS, false}) +#define TMC4361A_HOME_ERROR_F_MASK 0x00001000 +#define TMC4361A_HOME_ERROR_F_SHIFT 12 +#define TMC4361A_HOME_ERROR_F_FIELD ((RegisterField) {TMC4361A_HOME_ERROR_F_MASK, TMC4361A_HOME_ERROR_F_SHIFT, TMC4361A_STATUS, false}) +#define TMC4361A_FS_ACTIVE_F_MASK 0x00002000 +#define TMC4361A_FS_ACTIVE_F_SHIFT 13 +#define TMC4361A_FS_ACTIVE_F_FIELD ((RegisterField) {TMC4361A_FS_ACTIVE_F_MASK, TMC4361A_FS_ACTIVE_F_SHIFT, TMC4361A_STATUS, false}) +#define TMC4361A_ENC_FAIL_F_MASK 0x00004000 +#define TMC4361A_ENC_FAIL_F_SHIFT 14 +#define TMC4361A_ENC_FAIL_F_FIELD ((RegisterField) {TMC4361A_ENC_FAIL_F_MASK, TMC4361A_ENC_FAIL_F_SHIFT, TMC4361A_STATUS, false}) +#define TMC4361A_N_ACTIVE_F_MASK 0x00008000 +#define TMC4361A_N_ACTIVE_F_SHIFT 15 +#define TMC4361A_N_ACTIVE_F_FIELD ((RegisterField) {TMC4361A_N_ACTIVE_F_MASK, TMC4361A_N_ACTIVE_F_SHIFT, TMC4361A_STATUS, false}) +#define TMC4361A_ENC_LATCH_F_MASK 0x00010000 +#define TMC4361A_ENC_LATCH_F_SHIFT 16 +#define TMC4361A_ENC_LATCH_F_FIELD ((RegisterField) {TMC4361A_ENC_LATCH_F_MASK, TMC4361A_ENC_LATCH_F_SHIFT, TMC4361A_STATUS, false}) +#define TMC4361A_MULTI_CYCLE_FAIL_F___SER_ENC_VAR_F_MASK 0x00020000 +#define TMC4361A_MULTI_CYCLE_FAIL_F___SER_ENC_VAR_F_SHIFT 17 +#define TMC4361A_MULTI_CYCLE_FAIL_F___SER_ENC_VAR_F_FIELD ((RegisterField) {TMC4361A_MULTI_CYCLE_FAIL_F___SER_ENC_VAR_F_MASK, TMC4361A_MULTI_CYCLE_FAIL_F___SER_ENC_VAR_F_SHIFT, TMC4361A_STATUS, false}) +#define TMC4361A_SERIAL_ENC_FLAG___MASK 0x00100000 +#define TMC4361A_SERIAL_ENC_FLAG___SHIFT 20 +#define TMC4361A_SERIAL_ENC_FLAG___FIELD ((RegisterField) {TMC4361A_SERIAL_ENC_FLAG___MASK, TMC4361A_SERIAL_ENC_FLAG___SHIFT, TMC4361A_STATUS, false}) +#define TMC4361A_STP_LENGTH_ADD_MASK 0x0000FFFF +#define TMC4361A_STP_LENGTH_ADD_SHIFT 0 +#define TMC4361A_STP_LENGTH_ADD_FIELD ((RegisterField) {TMC4361A_STP_LENGTH_ADD_MASK, TMC4361A_STP_LENGTH_ADD_SHIFT, TMC4361A_STP_LENGTH_ADD, false}) +#define TMC4361A_DIR_SETUP_TIME_MASK 0xFFFF0000 +#define TMC4361A_DIR_SETUP_TIME_SHIFT 16 +#define TMC4361A_DIR_SETUP_TIME_FIELD ((RegisterField) {TMC4361A_DIR_SETUP_TIME_MASK, TMC4361A_DIR_SETUP_TIME_SHIFT, TMC4361A_DIR_SETUP_TIME, false}) +#define TMC4361A_START_OUT_ADD_MASK 0xFFFFFFFF +#define TMC4361A_START_OUT_ADD_SHIFT 0 +#define TMC4361A_START_OUT_ADD_FIELD ((RegisterField) {TMC4361A_START_OUT_ADD_MASK, TMC4361A_START_OUT_ADD_SHIFT, TMC4361A_START_OUT_ADD, false}) +#define TMC4361A_GEAR_RATIO_MASK 0xFFFFFFFF +#define TMC4361A_GEAR_RATIO_SHIFT 0 +#define TMC4361A_GEAR_RATIO_FIELD ((RegisterField) {TMC4361A_GEAR_RATIO_MASK, TMC4361A_GEAR_RATIO_SHIFT, TMC4361A_GEAR_RATIO, true}) +#define TMC4361A_START_DELAY_MASK 0xFFFFFFFF +#define TMC4361A_START_DELAY_SHIFT 0 +#define TMC4361A_START_DELAY_FIELD ((RegisterField) {TMC4361A_START_DELAY_MASK, TMC4361A_START_DELAY_SHIFT, TMC4361A_START_DELAY, false}) +#define TMC4361A_CLK_GATING_DELAY_MASK 0xFFFFFFFF +#define TMC4361A_CLK_GATING_DELAY_SHIFT 0 +#define TMC4361A_CLK_GATING_DELAY_FIELD ((RegisterField) {TMC4361A_CLK_GATING_DELAY_MASK, TMC4361A_CLK_GATING_DELAY_SHIFT, TMC4361A_CLK_GATING_DELAY, false}) +#define TMC4361A_STDBY_DELAY_MASK 0xFFFFFFFF +#define TMC4361A_STDBY_DELAY_SHIFT 0 +#define TMC4361A_STDBY_DELAY_FIELD ((RegisterField) {TMC4361A_STDBY_DELAY_MASK, TMC4361A_STDBY_DELAY_SHIFT, TMC4361A_STDBY_DELAY, false}) +#define TMC4361A_FREEWHEEL_DELAY_MASK 0xFFFFFFFF +#define TMC4361A_FREEWHEEL_DELAY_SHIFT 0 +#define TMC4361A_FREEWHEEL_DELAY_FIELD ((RegisterField) {TMC4361A_FREEWHEEL_DELAY_MASK, TMC4361A_FREEWHEEL_DELAY_SHIFT, TMC4361A_FREEWHEEL_DELAY, false}) +#define TMC4361A_VDRV_SCALE_LIMIT_MASK 0x00FFFFFF +#define TMC4361A_VDRV_SCALE_LIMIT_SHIFT 0 +#define TMC4361A_VDRV_SCALE_LIMIT_FIELD ((RegisterField) {TMC4361A_VDRV_SCALE_LIMIT_MASK, TMC4361A_VDRV_SCALE_LIMIT_SHIFT, TMC4361A_VDRV_SCALE_LIMIT, false}) +#define TMC4361A_PWM_VMAX_MASK 0x00FFFFFF +#define TMC4361A_PWM_VMAX_SHIFT 0 +#define TMC4361A_PWM_VMAX_FIELD ((RegisterField) {TMC4361A_PWM_VMAX_MASK, TMC4361A_PWM_VMAX_SHIFT, TMC4361A_PWM_VMAX, false}) +#define TMC4361A_UP_SCALE_DELAY_MASK 0x00FFFFFF +#define TMC4361A_UP_SCALE_DELAY_SHIFT 0 +#define TMC4361A_UP_SCALE_DELAY_FIELD ((RegisterField) {TMC4361A_UP_SCALE_DELAY_MASK, TMC4361A_UP_SCALE_DELAY_SHIFT, TMC4361A_UP_SCALE_DELAY, false}) +#define TMC4361A_CL_UPSCALE_DELAY_MASK 0x00FFFFFF +#define TMC4361A_CL_UPSCALE_DELAY_SHIFT 0 +#define TMC4361A_CL_UPSCALE_DELAY_FIELD ((RegisterField) {TMC4361A_CL_UPSCALE_DELAY_MASK, TMC4361A_CL_UPSCALE_DELAY_SHIFT, TMC4361A_CL_UPSCALE_DELAY, false}) +//#define TMC4361A_UP_SCALE_dY_FIELD ((RegisterField) {TMC4361A_UP_SCALE_DELAY_MASK, TMC4361A_UP_SCALE_DELAY_SHIFT, TMC4361A_UP_SCALE_DELAY, false}) +#define TMC4361A_HOLD_SCALE_DELAY_MASK 0x00FFFFFF +#define TMC4361A_HOLD_SCALE_DELAY_SHIFT 0 +#define TMC4361A_HOLD_SCALE_DELAY_FIELD ((RegisterField) {TMC4361A_HOLD_SCALE_DELAY_MASK, TMC4361A_HOLD_SCALE_DELAY_SHIFT, TMC4361A_HOLD_SCALE_DELAY, false}) +#define TMC4361A_CL_DNSCALE_DELAY_MASK 0x00FFFFFF +#define TMC4361A_CL_DNSCALE_DELAY_SHIFT 0 +#define TMC4361A_CL_DNSCALE_DELAY_FIELD ((RegisterField) {TMC4361A_CL_DNSCALE_DELAY_MASK, TMC4361A_CL_DNSCALE_DELAY_SHIFT, TMC4361A_CL_DNSCALE_DELAY, false}) +#define TMC4361A_DRV_SCALE_DELAY_MASK 0x00FFFFFF +#define TMC4361A_DRV_SCALE_DELAY_SHIFT 0 +#define TMC4361A_DRV_SCALE_DELAY_FIELD ((RegisterField) {TMC4361A_DRV_SCALE_DELAY_MASK, TMC4361A_DRV_SCALE_DELAY_SHIFT, TMC4361A_DRV_SCALE_DELAY, false}) +#define TMC4361A_BOOST_TIME_MASK 0x00FFFFFF +#define TMC4361A_BOOST_TIME_SHIFT 0 +#define TMC4361A_BOOST_TIME_FIELD ((RegisterField) {TMC4361A_BOOST_TIME_MASK, TMC4361A_BOOST_TIME_SHIFT, TMC4361A_BOOST_TIME, false}) +#define TMC4361A_CL_BETA_MASK 0x000001FF +#define TMC4361A_CL_BETA_SHIFT 0 +#define TMC4361A_CL_BETA_FIELD ((RegisterField) {TMC4361A_CL_BETA_MASK, TMC4361A_CL_BETA_SHIFT, TMC4361A_CL ANGLES, false}) +#define TMC4361A_CL_GAMMA_MASK 0x00FF0000 +#define TMC4361A_CL_GAMMA_SHIFT 16 +#define TMC4361A_CL_GAMMA_FIELD ((RegisterField) {TMC4361A_CL_GAMMA_MASK, TMC4361A_CL_GAMMA_SHIFT, TMC4361A_CL ANGLES, false}) +#define TMC4361A_SPI_SWITCH_VEL_MASK 0x00FFFFFF +#define TMC4361A_SPI_SWITCH_VEL_SHIFT 0 +#define TMC4361A_SPI_SWITCH_VEL_FIELD ((RegisterField) {TMC4361A_SPI_SWITCH_VEL_MASK, TMC4361A_SPI_SWITCH_VEL_SHIFT, TMC4361A_SPI_SWITCH_VEL, false}) +#define TMC4361A_DAC_ADDR_A_MASK 0x0000FFFF +#define TMC4361A_DAC_ADDR_A_SHIFT 0 +#define TMC4361A_DAC_ADDR_A_FIELD ((RegisterField) {TMC4361A_DAC_ADDR_A_MASK, TMC4361A_DAC_ADDR_A_SHIFT, TMC4361A_DAC_ADDR_A, false}) +#define TMC4361A_DAC_ADDR_B_MASK 0xFFFF0000 +#define TMC4361A_DAC_ADDR_B_SHIFT 16 +#define TMC4361A_DAC_ADDR_B_FIELD ((RegisterField) {TMC4361A_DAC_ADDR_B_MASK, TMC4361A_DAC_ADDR_B_SHIFT, TMC4361A_DAC_ADDR_B, false}) +#define TMC4361A_HOME_SAFETY_MARGIN_MASK 0x0000FFFF +#define TMC4361A_HOME_SAFETY_MARGIN_SHIFT 0 +#define TMC4361A_HOME_SAFETY_MARGIN_FIELD ((RegisterField) {TMC4361A_HOME_SAFETY_MARGIN_MASK, TMC4361A_HOME_SAFETY_MARGIN_SHIFT, TMC4361A_HOME_SAFETY_MARGIN, false}) +#define TMC4361A_PWM_FREQ_MASK 0x0000FFFF +#define TMC4361A_PWM_FREQ_SHIFT 0 +#define TMC4361A_PWM_FREQ_FIELD ((RegisterField) {TMC4361A_PWM_FREQ_MASK, TMC4361A_PWM_FREQ_SHIFT, TMC4361A_PWM_FREQ, false}) +#define TMC4361A_CHOPSYNC_DIV_MASK 0x00000FFF +#define TMC4361A_CHOPSYNC_DIV_SHIFT 0 +#define TMC4361A_CHOPSYNC_DIV_FIELD ((RegisterField) {TMC4361A_CHOPSYNC_DIV_MASK, TMC4361A_CHOPSYNC_DIV_SHIFT, TMC4361A_CHOPSYNC_DIV, false}) +#define TMC4361A_OPERATION_MODE_MASK 0x00000004 +#define TMC4361A_OPERATION_MODE_SHIFT 2 +#define TMC4361A_OPERATION_MODE_FIELD ((RegisterField) {TMC4361A_OPERATION_MODE_MASK, TMC4361A_OPERATION_MODE_SHIFT, TMC4361A_RAMPMODE, false}) +#define TMC4361A_RAMP_PROFILE_MASK 0x00000003 +#define TMC4361A_RAMP_PROFILE_SHIFT 0 +#define TMC4361A_RAMP_PROFILE_FIELD ((RegisterField) {TMC4361A_RAMP_PROFILE_MASK, TMC4361A_RAMP_PROFILE_SHIFT, TMC4361A_RAMPMODE, false}) +#define TMC4361A_XACTUAL_MASK 0xFFFFFFFF +#define TMC4361A_XACTUAL_SHIFT 0 +#define TMC4361A_XACTUAL_FIELD ((RegisterField) {TMC4361A_XACTUAL_MASK, TMC4361A_XACTUAL_SHIFT, TMC4361A_XACTUAL, true}) +#define TMC4361A_VACTUAL_MASK 0xFFFFFFFF +#define TMC4361A_VACTUAL_SHIFT 0 +#define TMC4361A_VACTUAL_FIELD ((RegisterField) {TMC4361A_VACTUAL_MASK, TMC4361A_VACTUAL_SHIFT, TMC4361A_VACTUAL, true}) +#define TMC4361A_AACTUAL_MASK 0xFFFFFFFF +#define TMC4361A_AACTUAL_SHIFT 0 +#define TMC4361A_AACTUAL_FIELD ((RegisterField) {TMC4361A_AACTUAL_MASK, TMC4361A_AACTUAL_SHIFT, TMC4361A_AACTUAL, true}) +#define TMC4361A_VMAX_MASK 0xFFFFFFFF +#define TMC4361A_VMAX_SHIFT 0 +#define TMC4361A_VMAX_FIELD ((RegisterField) {TMC4361A_VMAX_MASK, TMC4361A_VMAX_SHIFT, TMC4361A_VMAX, true}) +#define TMC4361A_VSTART_MASK 0x7FFFFFFF +#define TMC4361A_VSTART_SHIFT 0 +#define TMC4361A_VSTART_FIELD ((RegisterField) {TMC4361A_VSTART_MASK, TMC4361A_VSTART_SHIFT, TMC4361A_VSTART, false}) +#define TMC4361A_VSTOP_MASK 0x7FFFFFFF +#define TMC4361A_VSTOP_SHIFT 0 +#define TMC4361A_VSTOP_FIELD ((RegisterField) {TMC4361A_VSTOP_MASK, TMC4361A_VSTOP_SHIFT, TMC4361A_VSTOP, false}) +#define TMC4361A_VBREAK_MASK 0x7FFFFFFF +#define TMC4361A_VBREAK_SHIFT 0 +#define TMC4361A_VBREAK_FIELD ((RegisterField) {TMC4361A_VBREAK_MASK, TMC4361A_VBREAK_SHIFT, TMC4361A_VBREAK, false}) +#define TMC4361A_FREQUENCY_MODE_MASK 0x00FFFFFF +#define TMC4361A_FREQUENCY_MODE_SHIFT 0 +#define TMC4361A_FREQUENCY_MODE_FIELD ((RegisterField) {TMC4361A_FREQUENCY_MODE_MASK, TMC4361A_FREQUENCY_MODE_SHIFT, TMC4361A_AMAX, false}) +#define TMC4361A_DIRECT_MODE_MASK 0x00FFFFFF +#define TMC4361A_DIRECT_MODE_SHIFT 0 +#define TMC4361A_DIRECT_MODE_FIELD ((RegisterField) {TMC4361A_DIRECT_MODE_MASK, TMC4361A_DIRECT_MODE_SHIFT, TMC4361A_AMAX, false}) +#define TMC4361A_SIGN_AACT_MASK 0x80000000 +#define TMC4361A_SIGN_AACT_SHIFT 31 +#define TMC4361A_SIGN_AACT_FIELD ((RegisterField) {TMC4361A_SIGN_AACT_MASK, TMC4361A_SIGN_AACT_SHIFT, TMC4361A_ASTART, false}) +#define TMC4361A_CLK_FREQ_MASK 0x01FFFFFF +#define TMC4361A_CLK_FREQ_SHIFT 0 +#define TMC4361A_CLK_FREQ_FIELD ((RegisterField) {TMC4361A_CLK_FREQ_MASK, TMC4361A_CLK_FREQ_SHIFT, TMC4361A_CLK_FREQ, false}) +#define TMC4361A_POS_COMP_MASK 0xFFFFFFFF +#define TMC4361A_POS_COMP_SHIFT 0 +#define TMC4361A_POS_COMP_FIELD ((RegisterField) {TMC4361A_POS_COMP_MASK, TMC4361A_POS_COMP_SHIFT, TMC4361A_POS_COMP, true}) +#define TMC4361A_VIRT_STOP_LEFT_MASK 0xFFFFFFFF +#define TMC4361A_VIRT_STOP_LEFT_SHIFT 0 +#define TMC4361A_VIRT_STOP_LEFT_FIELD ((RegisterField) {TMC4361A_VIRT_STOP_LEFT_MASK, TMC4361A_VIRT_STOP_LEFT_SHIFT, TMC4361A_VIRT_STOP_LEFT, true}) +#define TMC4361A_VIRT_STOP_RIGHT_MASK 0xFFFFFFFF +#define TMC4361A_VIRT_STOP_RIGHT_SHIFT 0 +#define TMC4361A_VIRT_STOP_RIGHT_FIELD ((RegisterField) {TMC4361A_VIRT_STOP_RIGHT_MASK, TMC4361A_VIRT_STOP_RIGHT_SHIFT, TMC4361A_VIRT_STOP_RIGHT, true}) +#define TMC4361A_X_HOME_MASK 0xFFFFFFFF +#define TMC4361A_X_HOME_SHIFT 0 +#define TMC4361A_X_HOME_FIELD ((RegisterField) {TMC4361A_X_HOME_MASK, TMC4361A_X_HOME_SHIFT, TMC4361A_X_HOME, true}) +#define TMC4361A_X_LATCH_MASK 0xFFFFFFFF +#define TMC4361A_X_LATCH_SHIFT 0 +#define TMC4361A_X_LATCH_FIELD ((RegisterField) {TMC4361A_X_LATCH_MASK, TMC4361A_X_LATCH_SHIFT, TMC4361A_X_LATCH, true}) +#define TMC4361A_REV_CNT_MASK 0xFFFFFFFF +#define TMC4361A_REV_CNT_SHIFT 0 +#define TMC4361A_REV_CNT_FIELD ((RegisterField) {TMC4361A_REV_CNT_MASK, TMC4361A_REV_CNT_SHIFT, TMC4361A_REV_CNT, true}) +#define TMC4361A_X_RANGE_MASK 0xFFFFFFFF +#define TMC4361A_X_RANGE_SHIFT 0 +#define TMC4361A_X_RANGE_FIELD ((RegisterField) {TMC4361A_X_RANGE_MASK, TMC4361A_X_RANGE_SHIFT, TMC4361A_X_RANGE, false}) +#define TMC4361A_XTARGET_MASK 0xFFFFFFFF +#define TMC4361A_XTARGET_SHIFT 0 +#define TMC4361A_XTARGET_FIELD ((RegisterField) {TMC4361A_XTARGET_MASK, TMC4361A_XTARGET_SHIFT, TMC4361A_XTARGET, true}) +#define TMC4361A_X_PIPE0__XTARGET__MASK 0xFFFFFFFF +#define TMC4361A_X_PIPE0__XTARGET__SHIFT 0 +#define TMC4361A_X_PIPE0__XTARGET__FIELD ((RegisterField) {TMC4361A_X_PIPE0__XTARGET__MASK, TMC4361A_X_PIPE0__XTARGET__SHIFT, TMC4361A_X_PIPE0, true}) +#define TMC4361A_X_PIPE0__POS_COMP__MASK 0xFFFFFFFF +#define TMC4361A_X_PIPE0__POS_COMP__SHIFT 0 +#define TMC4361A_X_PIPE0__POS_COMP__FIELD ((RegisterField) {TMC4361A_X_PIPE0__POS_COMP__MASK, TMC4361A_X_PIPE0__POS_COMP__SHIFT, TMC4361A_X_PIPE0, true}) +#define TMC4361A_X_PIPE0__GEAR_RATIO__MASK 0xFFFFFFFF +#define TMC4361A_X_PIPE0__GEAR_RATIO__SHIFT 0 +#define TMC4361A_X_PIPE0__GEAR_RATIO__FIELD ((RegisterField) {TMC4361A_X_PIPE0__GEAR_RATIO__MASK, TMC4361A_X_PIPE0__GEAR_RATIO__SHIFT, TMC4361A_X_PIPE0, true}) +#define TMC4361A_X_PIPE0__GENERAL_CONF__MASK 0xFFFFFFFF +#define TMC4361A_X_PIPE0__GENERAL_CONF__SHIFT 0 +#define TMC4361A_X_PIPE0__GENERAL_CONF__FIELD ((RegisterField) {TMC4361A_X_PIPE0__GENERAL_CONF__MASK, TMC4361A_X_PIPE0__GENERAL_CONF__SHIFT, TMC4361A_X_PIPE0, false}) +#define TMC4361A_X_PIPE1__XTARGET__MASK 0xFFFFFFFF +#define TMC4361A_X_PIPE1__XTARGET__SHIFT 0 +#define TMC4361A_X_PIPE1__XTARGET__FIELD ((RegisterField) {TMC4361A_X_PIPE1__XTARGET__MASK, TMC4361A_X_PIPE1__XTARGET__SHIFT, TMC4361A_X_PIPE1, true}) +#define TMC4361A_X_PIPE1__POS_COMP__MASK 0xFFFFFFFF +#define TMC4361A_X_PIPE1__POS_COMP__SHIFT 0 +#define TMC4361A_X_PIPE1__POS_COMP__FIELD ((RegisterField) {TMC4361A_X_PIPE1__POS_COMP__MASK, TMC4361A_X_PIPE1__POS_COMP__SHIFT, TMC4361A_X_PIPE1, true}) +#define TMC4361A_X_PIPE1__GEAR_RATIO__MASK 0xFFFFFFFF +#define TMC4361A_X_PIPE1__GEAR_RATIO__SHIFT 0 +#define TMC4361A_X_PIPE1__GEAR_RATIO__FIELD ((RegisterField) {TMC4361A_X_PIPE1__GEAR_RATIO__MASK, TMC4361A_X_PIPE1__GEAR_RATIO__SHIFT, TMC4361A_X_PIPE1, true}) +#define TMC4361A_X_PIPE1__GENERAL_CONF__MASK 0xFFFFFFFF +#define TMC4361A_X_PIPE1__GENERAL_CONF__SHIFT 0 +#define TMC4361A_X_PIPE1__GENERAL_CONF__FIELD ((RegisterField) {TMC4361A_X_PIPE1__GENERAL_CONF__MASK, TMC4361A_X_PIPE1__GENERAL_CONF__SHIFT, TMC4361A_X_PIPE1, false}) +#define TMC4361A_X_PIPE2_MASK 0xFFFFFFFF +#define TMC4361A_X_PIPE2_SHIFT 0 +#define TMC4361A_X_PIPE2_FIELD ((RegisterField) {TMC4361A_X_PIPE2_MASK, TMC4361A_X_PIPE2_SHIFT, TMC4361A_X_PIPE2, true}) +#define TMC4361A_X_PIPE3_MASK 0xFFFFFFFF +#define TMC4361A_X_PIPE3_SHIFT 0 +#define TMC4361A_X_PIPE3_FIELD ((RegisterField) {TMC4361A_X_PIPE3_MASK, TMC4361A_X_PIPE3_SHIFT, TMC4361A_X_PIPE3, true}) +#define TMC4361A_X_PIPE4_MASK 0xFFFFFFFF +#define TMC4361A_X_PIPE4_SHIFT 0 +#define TMC4361A_X_PIPE4_FIELD ((RegisterField) {TMC4361A_X_PIPE4_MASK, TMC4361A_X_PIPE4_SHIFT, TMC4361A_X_PIPE4, true}) +#define TMC4361A_X_PIPE5_MASK 0xFFFFFFFF +#define TMC4361A_X_PIPE5_SHIFT 0 +#define TMC4361A_X_PIPE5_FIELD ((RegisterField) {TMC4361A_X_PIPE5_MASK, TMC4361A_X_PIPE5_SHIFT, TMC4361A_X_PIPE5, true}) +#define TMC4361A_X_PIPE6_MASK 0xFFFFFFFF +#define TMC4361A_X_PIPE6_SHIFT 0 +#define TMC4361A_X_PIPE6_FIELD ((RegisterField) {TMC4361A_X_PIPE6_MASK, TMC4361A_X_PIPE6_SHIFT, TMC4361A_X_PIPE6, true}) +#define TMC4361A_X_PIPE7_MASK 0xFFFFFFFF +#define TMC4361A_X_PIPE7_SHIFT 0 +#define TMC4361A_X_PIPE7_FIELD ((RegisterField) {TMC4361A_X_PIPE7_MASK, TMC4361A_X_PIPE7_SHIFT, TMC4361A_X_PIPE7, true}) +#define TMC4361A_SH_REG0_VMAX_MASK 0xFFFFFFFF +#define TMC4361A_SH_REG0_VMAX_SHIFT 0 +#define TMC4361A_SH_REG0_VMAX_FIELD ((RegisterField) {TMC4361A_SH_REG0_VMAX_MASK, TMC4361A_SH_REG0_VMAX_SHIFT, TMC4361A_SH_REG0, true}) +#define TMC4361A_SH_REG1_AMAX_MASK 0x00FFFFFF +#define TMC4361A_SH_REG1_AMAX_SHIFT 0 +#define TMC4361A_SH_REG1_AMAX_FIELD ((RegisterField) {TMC4361A_SH_REG1_AMAX_MASK, TMC4361A_SH_REG1_AMAX_SHIFT, TMC4361A_SH_REG1, false}) +#define TMC4361A_SH_REG2_DMAX_MASK 0x00FFFFFF +#define TMC4361A_SH_REG2_DMAX_SHIFT 0 +#define TMC4361A_SH_REG2_DMAX_FIELD ((RegisterField) {TMC4361A_SH_REG2_DMAX_MASK, TMC4361A_SH_REG2_DMAX_SHIFT, TMC4361A_SH_REG2, false}) +#define TMC4361A_SH_REG3_ASTART_MASK 0x00FFFFFF +#define TMC4361A_SH_REG3_ASTART_SHIFT 0 +#define TMC4361A_SH_REG3_ASTART_FIELD ((RegisterField) {TMC4361A_SH_REG3_ASTART_MASK, TMC4361A_SH_REG3_ASTART_SHIFT, TMC4361A_SH_REG3, false}) +#define TMC4361A_SH_REG3_BOW1_MASK 0x00FFFFFF +#define TMC4361A_SH_REG3_BOW1_SHIFT 0 +#define TMC4361A_SH_REG3_BOW1_FIELD ((RegisterField) {TMC4361A_SH_REG3_BOW1_MASK, TMC4361A_SH_REG3_BOW1_SHIFT, TMC4361A_SH_REG3, false}) +#define TMC4361A_SH_REG4_DFINAL_MASK 0x00FFFFFF +#define TMC4361A_SH_REG4_DFINAL_SHIFT 0 +#define TMC4361A_SH_REG4_DFINAL_FIELD ((RegisterField) {TMC4361A_SH_REG4_DFINAL_MASK, TMC4361A_SH_REG4_DFINAL_SHIFT, TMC4361A_SH_REG4, false}) +#define TMC4361A_SH_REG4_BOW2_MASK 0x00FFFFFF +#define TMC4361A_SH_REG4_BOW2_SHIFT 0 +#define TMC4361A_SH_REG4_BOW2_FIELD ((RegisterField) {TMC4361A_SH_REG4_BOW2_MASK, TMC4361A_SH_REG4_BOW2_SHIFT, TMC4361A_SH_REG4, false}) +#define TMC4361A_SH_REG5_VBREAK_MASK 0x7FFFFFFF +#define TMC4361A_SH_REG5_VBREAK_SHIFT 0 +#define TMC4361A_SH_REG5_VBREAK_FIELD ((RegisterField) {TMC4361A_SH_REG5_VBREAK_MASK, TMC4361A_SH_REG5_VBREAK_SHIFT, TMC4361A_SH_REG5, false}) +#define TMC4361A_SH_REG5_BOW3_MASK 0x00FFFFFF +#define TMC4361A_SH_REG5_BOW3_SHIFT 0 +#define TMC4361A_SH_REG5_BOW3_FIELD ((RegisterField) {TMC4361A_SH_REG5_BOW3_MASK, TMC4361A_SH_REG5_BOW3_SHIFT, TMC4361A_SH_REG5, false}) +#define TMC4361A_SH_REG6_VSTART_MASK 0x7FFFFFFF +#define TMC4361A_SH_REG6_VSTART_SHIFT 0 +#define TMC4361A_SH_REG6_VSTART_FIELD ((RegisterField) {TMC4361A_SH_REG6_VSTART_MASK, TMC4361A_SH_REG6_VSTART_SHIFT, TMC4361A_SH_REG6, false}) +#define TMC4361A_SH_REG6_BOW4_MASK 0x00FFFFFF +#define TMC4361A_SH_REG6_BOW4_SHIFT 0 +#define TMC4361A_SH_REG6_BOW4_FIELD ((RegisterField) {TMC4361A_SH_REG6_BOW4_MASK, TMC4361A_SH_REG6_BOW4_SHIFT, TMC4361A_SH_REG6, false}) +#define TMC4361A_SH_REG6_VSTOP_MASK 0x7FFFFFFF +#define TMC4361A_SH_REG6_VSTOP_SHIFT 0 +#define TMC4361A_SH_REG6_VSTOP_FIELD ((RegisterField) {TMC4361A_SH_REG6_VSTOP_MASK, TMC4361A_SH_REG6_VSTOP_SHIFT, TMC4361A_SH_REG6, false}) +#define TMC4361A_SH_REG7_VSTOP_MASK 0xFFFFFFFF +#define TMC4361A_SH_REG7_VSTOP_SHIFT 0 +#define TMC4361A_SH_REG7_VSTOP_FIELD ((RegisterField) {TMC4361A_SH_REG7_VSTOP_MASK, TMC4361A_SH_REG7_VSTOP_SHIFT, TMC4361A_SH_REG7, false}) +#define TMC4361A_SH_REG7_VMAX_MASK 0xFFFFFFFF +#define TMC4361A_SH_REG7_VMAX_SHIFT 0 +#define TMC4361A_SH_REG7_VMAX_FIELD ((RegisterField) {TMC4361A_SH_REG7_VMAX_MASK, TMC4361A_SH_REG7_VMAX_SHIFT, TMC4361A_SH_REG7, true}) +#define TMC4361A_SH_REG8_BOW1_MASK 0x00FFFFFF +#define TMC4361A_SH_REG8_BOW1_SHIFT 0 +#define TMC4361A_SH_REG8_BOW1_FIELD ((RegisterField) {TMC4361A_SH_REG8_BOW1_MASK, TMC4361A_SH_REG8_BOW1_SHIFT, TMC4361A_SH_REG8, false}) +#define TMC4361A_SH_REG8_AMAX_MASK 0x00FFFFFF +#define TMC4361A_SH_REG8_AMAX_SHIFT 0 +#define TMC4361A_SH_REG8_AMAX_FIELD ((RegisterField) {TMC4361A_SH_REG8_AMAX_MASK, TMC4361A_SH_REG8_AMAX_SHIFT, TMC4361A_SH_REG8, false}) +#define TMC4361A_SH_REG9_BOW2_MASK 0x00FFFFFF +#define TMC4361A_SH_REG9_BOW2_SHIFT 0 +#define TMC4361A_SH_REG9_BOW2_FIELD ((RegisterField) {TMC4361A_SH_REG9_BOW2_MASK, TMC4361A_SH_REG9_BOW2_SHIFT, TMC4361A_SH_REG9, false}) +#define TMC4361A_SH_REG9_DMAX_MASK 0x00FFFFFF +#define TMC4361A_SH_REG9_DMAX_SHIFT 0 +#define TMC4361A_SH_REG9_DMAX_FIELD ((RegisterField) {TMC4361A_SH_REG9_DMAX_MASK, TMC4361A_SH_REG9_DMAX_SHIFT, TMC4361A_SH_REG9, false}) +#define TMC4361A_SH_REG10_BOW3_MASK 0x00FFFFFF +#define TMC4361A_SH_REG10_BOW3_SHIFT 0 +#define TMC4361A_SH_REG10_BOW3_FIELD ((RegisterField) {TMC4361A_SH_REG10_BOW3_MASK, TMC4361A_SH_REG10_BOW3_SHIFT, TMC4361A_SH_REG10, false}) +#define TMC4361A_SH_REG10_BOW1_MASK 0x00FFFFFF +#define TMC4361A_SH_REG10_BOW1_SHIFT 0 +#define TMC4361A_SH_REG10_BOW1_FIELD ((RegisterField) {TMC4361A_SH_REG10_BOW1_MASK, TMC4361A_SH_REG10_BOW1_SHIFT, TMC4361A_SH_REG10, false}) +#define TMC4361A_SH_REG10_ASTART_MASK 0x00FFFFFF +#define TMC4361A_SH_REG10_ASTART_SHIFT 0 +#define TMC4361A_SH_REG10_ASTART_FIELD ((RegisterField) {TMC4361A_SH_REG10_ASTART_MASK, TMC4361A_SH_REG10_ASTART_SHIFT, TMC4361A_SH_REG10, false}) +#define TMC4361A_SH_REG11_BOW4_MASK 0x00FFFFFF +#define TMC4361A_SH_REG11_BOW4_SHIFT 0 +#define TMC4361A_SH_REG11_BOW4_FIELD ((RegisterField) {TMC4361A_SH_REG11_BOW4_MASK, TMC4361A_SH_REG11_BOW4_SHIFT, TMC4361A_SH_REG11, false}) +#define TMC4361A_SH_REG11_BOW2_MASK 0x00FFFFFF +#define TMC4361A_SH_REG11_BOW2_SHIFT 0 +#define TMC4361A_SH_REG11_BOW2_FIELD ((RegisterField) {TMC4361A_SH_REG11_BOW2_MASK, TMC4361A_SH_REG11_BOW2_SHIFT, TMC4361A_SH_REG11, false}) +#define TMC4361A_SH_REG11_DFINAL_MASK 0x00FFFFFF +#define TMC4361A_SH_REG11_DFINAL_SHIFT 0 +#define TMC4361A_SH_REG11_DFINAL_FIELD ((RegisterField) {TMC4361A_SH_REG11_DFINAL_MASK, TMC4361A_SH_REG11_DFINAL_SHIFT, TMC4361A_SH_REG11, false}) +#define TMC4361A_SH_REG12_BOW3_MASK 0x00FFFFFF +#define TMC4361A_SH_REG12_BOW3_SHIFT 0 +#define TMC4361A_SH_REG12_BOW3_FIELD ((RegisterField) {TMC4361A_SH_REG12_BOW3_MASK, TMC4361A_SH_REG12_BOW3_SHIFT, TMC4361A_SH_REG12, false}) +#define TMC4361A_SH_REG12_VBREAK_MASK 0x7FFFFFFF +#define TMC4361A_SH_REG12_VBREAK_SHIFT 0 +#define TMC4361A_SH_REG12_VBREAK_FIELD ((RegisterField) {TMC4361A_SH_REG12_VBREAK_MASK, TMC4361A_SH_REG12_VBREAK_SHIFT, TMC4361A_SH_REG12, false}) +#define TMC4361A_SH_REG13_BOW4_MASK 0x00FFFFFF +#define TMC4361A_SH_REG13_BOW4_SHIFT 0 +#define TMC4361A_SH_REG13_BOW4_FIELD ((RegisterField) {TMC4361A_SH_REG13_BOW4_MASK, TMC4361A_SH_REG13_BOW4_SHIFT, TMC4361A_SH_REG13, false}) +#define TMC4361A_SH_REG13_VSTART_MASK 0x7FFFFFFF +#define TMC4361A_SH_REG13_VSTART_SHIFT 0 +#define TMC4361A_SH_REG13_VSTART_FIELD ((RegisterField) {TMC4361A_SH_REG13_VSTART_MASK, TMC4361A_SH_REG13_VSTART_SHIFT, TMC4361A_SH_REG13, false}) +#define TMC4361A_SH_REG13_VSTOP_MASK 0x7FFFFFFF +#define TMC4361A_SH_REG13_VSTOP_SHIFT 0 +#define TMC4361A_SH_REG13_VSTOP_FIELD ((RegisterField) {TMC4361A_SH_REG13_VSTOP_MASK, TMC4361A_SH_REG13_VSTOP_SHIFT, TMC4361A_SH_REG13, false}) +#define TMC4361A_DFREEZE_MASK 0x00FFFFFF +#define TMC4361A_DFREEZE_SHIFT 0 +#define TMC4361A_DFREEZE_FIELD ((RegisterField) {TMC4361A_DFREEZE_MASK, TMC4361A_DFREEZE_SHIFT, TMC4361A_Freeze Registers, false}) +#define TMC4361A_IFREEZE_MASK 0xFF000000 +#define TMC4361A_IFREEZE_SHIFT 24 +#define TMC4361A_IFREEZE_FIELD ((RegisterField) {TMC4361A_IFREEZE_MASK, TMC4361A_IFREEZE_SHIFT, TMC4361A_Freeze Registers, false}) +#define TMC4361A_CLK_GATING_REG_MASK 0x00000007 +#define TMC4361A_CLK_GATING_REG_SHIFT 0 +#define TMC4361A_CLK_GATING_REG_FIELD ((RegisterField) {TMC4361A_CLK_GATING_REG_MASK, TMC4361A_CLK_GATING_REG_SHIFT, TMC4361A_CLK_GATING_REG, false}) +#define TMC4361A_RESET_REG_MASK 0xFFFFFF00 +#define TMC4361A_RESET_REG_SHIFT 8 +#define TMC4361A_RESET_REG_FIELD ((RegisterField) {TMC4361A_RESET_REG_MASK, TMC4361A_RESET_REG_SHIFT, TMC4361A_RESET_REG, false}) +#define TMC4361A_ENC_POS_MASK 0xFFFFFFFF +#define TMC4361A_ENC_POS_SHIFT 0 +#define TMC4361A_ENC_POS_FIELD ((RegisterField) {TMC4361A_ENC_POS_MASK, TMC4361A_ENC_POS_SHIFT, TMC4361A_ENC_POS, true}) +#define TMC4361A_ENC_LATCH_MASK 0xFFFFFFFF +#define TMC4361A_ENC_LATCH_SHIFT 0 +#define TMC4361A_ENC_LATCH_FIELD ((RegisterField) {TMC4361A_ENC_LATCH_MASK, TMC4361A_ENC_LATCH_SHIFT, TMC4361A_ENC_LATCH, true}) +#define TMC4361A_ENC_RESET_VAL_MASK 0xFFFFFFFF +#define TMC4361A_ENC_RESET_VAL_SHIFT 0 +#define TMC4361A_ENC_RESET_VAL_FIELD ((RegisterField) {TMC4361A_ENC_RESET_VAL_MASK, TMC4361A_ENC_RESET_VAL_SHIFT, TMC4361A_ENC_RESET_VAL, true}) +#define TMC4361A_ENC_POS_DEV_MASK 0xFFFFFFFF +#define TMC4361A_ENC_POS_DEV_SHIFT 0 +#define TMC4361A_ENC_POS_DEV_FIELD ((RegisterField) {TMC4361A_ENC_POS_DEV_MASK, TMC4361A_ENC_POS_DEV_SHIFT, TMC4361A_ENC_POS_DEV, true}) +#define TMC4361A_CL_TR_TOLERANCE_MASK 0x7FFFFFFF +#define TMC4361A_CL_TR_TOLERANCE_SHIFT 0 +#define TMC4361A_CL_TR_TOLERANCE_FIELD ((RegisterField) {TMC4361A_CL_TR_TOLERANCE_MASK, TMC4361A_CL_TR_TOLERANCE_SHIFT, TMC4361A_CL_TR_TOLERANCE, false}) +#define TMC4361A_ENC_POS_DEV_TOL_MASK 0x7FFFFFFF +#define TMC4361A_ENC_POS_DEV_TOL_SHIFT 0 +#define TMC4361A_ENC_POS_DEV_TOL_FIELD ((RegisterField) {TMC4361A_ENC_POS_DEV_TOL_MASK, TMC4361A_ENC_POS_DEV_TOL_SHIFT, TMC4361A_ENC_POS_DEV_TOL, false}) +#define TMC4361A_ENC_CONST_MASK 0x7FFFFFFF +#define TMC4361A_ENC_CONST_SHIFT 0 +#define TMC4361A_ENC_CONST_FIELD ((RegisterField) {TMC4361A_ENC_CONST_MASK, TMC4361A_ENC_CONST_SHIFT, TMC4361A_ENC_CONST, false}) +#define TMC4361A_ENC_IN_RES_MASK 0x7FFFFFFF +#define TMC4361A_ENC_IN_RES_SHIFT 0 +#define TMC4361A_ENC_IN_RES_FIELD ((RegisterField) {TMC4361A_ENC_IN_RES_MASK, TMC4361A_ENC_IN_RES_SHIFT, TMC4361A_ENC_IN_RES, false}) +#define TMC4361A_MANUAL_ENC_CONST_MASK 0x80000000 +#define TMC4361A_MANUAL_ENC_CONST_SHIFT 31 +#define TMC4361A_MANUAL_ENC_CONST_FIELD ((RegisterField) {TMC4361A_MANUAL_ENC_CONST_MASK, TMC4361A_MANUAL_ENC_CONST_SHIFT, TMC4361A_manual_enc_const, false}) +#define TMC4361A_ENC_OUT_RES_MASK 0x7FFFFFFF +#define TMC4361A_ENC_OUT_RES_SHIFT 0 +#define TMC4361A_ENC_OUT_RES_FIELD ((RegisterField) {TMC4361A_ENC_OUT_RES_MASK, TMC4361A_ENC_OUT_RES_SHIFT, TMC4361A_ENC_OUT_RES, false}) +#define TMC4361A_SER_CLK_IN_HIGH_MASK 0x0000FFFF +#define TMC4361A_SER_CLK_IN_HIGH_SHIFT 0 +#define TMC4361A_SER_CLK_IN_HIGH_FIELD ((RegisterField) {TMC4361A_SER_CLK_IN_HIGH_MASK, TMC4361A_SER_CLK_IN_HIGH_SHIFT, TMC4361A_SER_CLK_IN_HIGH, false}) +#define TMC4361A_SER_CLK_IN_LOW_MASK 0xFFFF0000 +#define TMC4361A_SER_CLK_IN_LOW_SHIFT 16 +#define TMC4361A_SER_CLK_IN_LOW_FIELD ((RegisterField) {TMC4361A_SER_CLK_IN_LOW_MASK, TMC4361A_SER_CLK_IN_LOW_SHIFT, TMC4361A_SER_CLK_IN_LOW, false}) +#define TMC4361A_SSI_IN_CLK_DELAY_MASK 0x0000FFFF +#define TMC4361A_SSI_IN_CLK_DELAY_SHIFT 0 +#define TMC4361A_SSI_IN_CLK_DELAY_FIELD ((RegisterField) {TMC4361A_SSI_IN_CLK_DELAY_MASK, TMC4361A_SSI_IN_CLK_DELAY_SHIFT, TMC4361A_SSI_IN_CLK_DELAY, false}) +#define TMC4361A_SSI_IN_WTIME_MASK 0xFFFF0000 +#define TMC4361A_SSI_IN_WTIME_SHIFT 16 +#define TMC4361A_SSI_IN_WTIME_FIELD ((RegisterField) {TMC4361A_SSI_IN_WTIME_MASK, TMC4361A_SSI_IN_WTIME_SHIFT, TMC4361A_SSI_IN_WTIME, false}) +#define TMC4361A_SER_PTIME_MASK 0x000FFFFF +#define TMC4361A_SER_PTIME_SHIFT 0 +#define TMC4361A_SER_PTIME_FIELD ((RegisterField) {TMC4361A_SER_PTIME_MASK, TMC4361A_SER_PTIME_SHIFT, TMC4361A_SER_PTIME, false}) +#define TMC4361A_CL_OFFSET_MASK 0xFFFFFFFF +#define TMC4361A_CL_OFFSET_SHIFT 0 +#define TMC4361A_CL_OFFSET_FIELD ((RegisterField) {TMC4361A_CL_OFFSET_MASK, TMC4361A_CL_OFFSET_SHIFT, TMC4361A_CL_OFFSET, true}) +#define TMC4361A_PID_VEL_MASK 0xFFFFFFFF +#define TMC4361A_PID_VEL_SHIFT 0 +#define TMC4361A_PID_VEL_FIELD ((RegisterField) {TMC4361A_PID_VEL_MASK, TMC4361A_PID_VEL_SHIFT, TMC4361A_PID_VEL, true}) +#define TMC4361A_CL_VMAX_CALC_P_MASK 0x00FFFFFF +#define TMC4361A_CL_VMAX_CALC_P_SHIFT 0 +#define TMC4361A_CL_VMAX_CALC_P_FIELD ((RegisterField) {TMC4361A_CL_VMAX_CALC_P_MASK, TMC4361A_CL_VMAX_CALC_P_SHIFT, TMC4361A_CL_VMAX_CALC_P, false}) +#define TMC4361A_PID_P_MASK 0x00FFFFFF +#define TMC4361A_PID_P_SHIFT 0 +#define TMC4361A_PID_P_FIELD ((RegisterField) {TMC4361A_PID_P_MASK, TMC4361A_PID_P_SHIFT, TMC4361A_PID_P, false}) +#define TMC4361A_PID_ISUM_RD_MASK 0xFFFFFFFF +#define TMC4361A_PID_ISUM_RD_SHIFT 0 +#define TMC4361A_PID_ISUM_RD_FIELD ((RegisterField) {TMC4361A_PID_ISUM_RD_MASK, TMC4361A_PID_ISUM_RD_SHIFT, TMC4361A_PID_ISUM_RD, true}) +#define TMC4361A_CL_VMAX_CALC_I_MASK 0x00FFFFFF +#define TMC4361A_CL_VMAX_CALC_I_SHIFT 0 +#define TMC4361A_CL_VMAX_CALC_I_FIELD ((RegisterField) {TMC4361A_CL_VMAX_CALC_I_MASK, TMC4361A_CL_VMAX_CALC_I_SHIFT, TMC4361A_CL_VMAX_CALC_I, false}) +#define TMC4361A_PID_I_MASK 0x00FFFFFF +#define TMC4361A_PID_I_SHIFT 0 +#define TMC4361A_PID_I_FIELD ((RegisterField) {TMC4361A_PID_I_MASK, TMC4361A_PID_I_SHIFT, TMC4361A_PID_I, false}) +#define TMC4361A_CL_DELTA_P_MASK 0x00FFFFFF +#define TMC4361A_CL_DELTA_P_SHIFT 0 +#define TMC4361A_CL_DELTA_P_FIELD ((RegisterField) {TMC4361A_CL_DELTA_P_MASK, TMC4361A_CL_DELTA_P_SHIFT, TMC4361A_CL_DELTA_P, false}) +#define TMC4361A_PID_D_MASK 0x00FFFFFF +#define TMC4361A_PID_D_SHIFT 0 +#define TMC4361A_PID_D_FIELD ((RegisterField) {TMC4361A_PID_D_MASK, TMC4361A_PID_D_SHIFT, TMC4361A_PID_D, false}) +#define TMC4361A_PID_E_MASK 0xFFFFFFFF +#define TMC4361A_PID_E_SHIFT 0 +#define TMC4361A_PID_E_FIELD ((RegisterField) {TMC4361A_PID_E_MASK, TMC4361A_PID_E_SHIFT, TMC4361A_PID_E, true}) +#define TMC4361A_PID_I_CLIP_MASK 0x00007FFF +#define TMC4361A_PID_I_CLIP_SHIFT 0 +#define TMC4361A_PID_I_CLIP_FIELD ((RegisterField) {TMC4361A_PID_I_CLIP_MASK, TMC4361A_PID_I_CLIP_SHIFT, TMC4361A_PID_I_CLIP, false}) +#define TMC4361A_PID_D_CLKDIV_MASK 0x00FF0000 +#define TMC4361A_PID_D_CLKDIV_SHIFT 16 +#define TMC4361A_PID_D_CLKDIV_FIELD ((RegisterField) {TMC4361A_PID_D_CLKDIV_MASK, TMC4361A_PID_D_CLKDIV_SHIFT, TMC4361A_PID_D_CLKDIV, false}) +#define TMC4361A_PID_DV_CLIP_MASK 0x7FFFFFFF +#define TMC4361A_PID_DV_CLIP_SHIFT 0 +#define TMC4361A_PID_DV_CLIP_FIELD ((RegisterField) {TMC4361A_PID_DV_CLIP_MASK, TMC4361A_PID_DV_CLIP_SHIFT, TMC4361A_PID_DV_CLIP, false}) +#define TMC4361A_CL_TOLERANCE_MASK 0x000000FF +#define TMC4361A_CL_TOLERANCE_SHIFT 0 +#define TMC4361A_CL_TOLERANCE_FIELD ((RegisterField) {TMC4361A_CL_TOLERANCE_MASK, TMC4361A_CL_TOLERANCE_SHIFT, TMC4361A_CL_TOLERANCE, false}) +#define TMC4361A_PID_TOLERANCE_MASK 0x000FFFFF +#define TMC4361A_PID_TOLERANCE_SHIFT 0 +#define TMC4361A_PID_TOLERANCE_FIELD ((RegisterField) {TMC4361A_PID_TOLERANCE_MASK, TMC4361A_PID_TOLERANCE_SHIFT, TMC4361A_PID_TOLERANCE, false}) +#define TMC4361A_FS_VEL_MASK 0x00FFFFFF +#define TMC4361A_FS_VEL_SHIFT 0 +#define TMC4361A_FS_VEL_FIELD ((RegisterField) {TMC4361A_FS_VEL_MASK, TMC4361A_FS_VEL_SHIFT, TMC4361A_FS_VEL, false}) +#define TMC4361A_DC_VEL_MASK 0x00FFFFFF +#define TMC4361A_DC_VEL_SHIFT 0 +#define TMC4361A_DC_VEL_FIELD ((RegisterField) {TMC4361A_DC_VEL_MASK, TMC4361A_DC_VEL_SHIFT, TMC4361A_DC_VEL, false}) +#define TMC4361A_CL_VMIN_EMF_MASK 0x00FFFFFF +#define TMC4361A_CL_VMIN_EMF_SHIFT 0 +#define TMC4361A_CL_VMIN_EMF_FIELD ((RegisterField) {TMC4361A_CL_VMIN_EMF_MASK, TMC4361A_CL_VMIN_EMF_SHIFT, TMC4361A_CL_VMIN_EMF, false}) +#define TMC4361A_DC_TIME_MASK 0x000000FF +#define TMC4361A_DC_TIME_SHIFT 0 +#define TMC4361A_DC_TIME_FIELD ((RegisterField) {TMC4361A_DC_TIME_MASK, TMC4361A_DC_TIME_SHIFT, TMC4361A_DC_TIME, false}) +#define TMC4361A_DC_SG_MASK 0x0000FF00 +#define TMC4361A_DC_SG_SHIFT 8 +#define TMC4361A_DC_SG_FIELD ((RegisterField) {TMC4361A_DC_SG_MASK, TMC4361A_DC_SG_SHIFT, TMC4361A_DC_SG, false}) +#define TMC4361A_DC_BLKTIME_MASK 0xFFFF0000 +#define TMC4361A_DC_BLKTIME_SHIFT 16 +#define TMC4361A_DC_BLKTIME_FIELD ((RegisterField) {TMC4361A_DC_BLKTIME_MASK, TMC4361A_DC_BLKTIME_SHIFT, TMC4361A_DC_BLKTIME, false}) +#define TMC4361A_CL_VADD_EMF_MASK 0x00FFFFFF +#define TMC4361A_CL_VADD_EMF_SHIFT 0 +#define TMC4361A_CL_VADD_EMF_FIELD ((RegisterField) {TMC4361A_CL_VADD_EMF_MASK, TMC4361A_CL_VADD_EMF_SHIFT, TMC4361A_CL_VADD_EMF, false}) +#define TMC4361A_DC_LSPTM_MASK 0xFFFFFFFF +#define TMC4361A_DC_LSPTM_SHIFT 0 +#define TMC4361A_DC_LSPTM_FIELD ((RegisterField) {TMC4361A_DC_LSPTM_MASK, TMC4361A_DC_LSPTM_SHIFT, TMC4361A_DC_LSPTM, false}) +#define TMC4361A_ENC_VEL_ZERO_MASK 0x00FFFFFF +#define TMC4361A_ENC_VEL_ZERO_SHIFT 0 +#define TMC4361A_ENC_VEL_ZERO_FIELD ((RegisterField) {TMC4361A_ENC_VEL_ZERO_MASK, TMC4361A_ENC_VEL_ZERO_SHIFT, TMC4361A_ENC_VEL_ZERO, false}) +#define TMC4361A_ENC_VMEAN_WAIT_MASK 0x000000FF +#define TMC4361A_ENC_VMEAN_WAIT_SHIFT 0 +#define TMC4361A_ENC_VMEAN_WAIT_FIELD ((RegisterField) {TMC4361A_ENC_VMEAN_WAIT_MASK, TMC4361A_ENC_VMEAN_WAIT_SHIFT, TMC4361A_ENC_VMEAN_WAIT, false}) +#define TMC4361A_ENC_VMEAN_FILTER_MASK 0x00000F00 +#define TMC4361A_ENC_VMEAN_FILTER_SHIFT 8 +#define TMC4361A_ENC_VMEAN_FILTER_FIELD ((RegisterField) {TMC4361A_ENC_VMEAN_FILTER_MASK, TMC4361A_ENC_VMEAN_FILTER_SHIFT, TMC4361A_ENC_VMEAN_FILTER, false}) +#define TMC4361A_ENC_VMEAN_INT_MASK 0xFFFF0000 +#define TMC4361A_ENC_VMEAN_INT_SHIFT 16 +#define TMC4361A_ENC_VMEAN_INT_FIELD ((RegisterField) {TMC4361A_ENC_VMEAN_INT_MASK, TMC4361A_ENC_VMEAN_INT_SHIFT, TMC4361A_ENC_VMEAN_INT, false}) +#define TMC4361A_SER_ENC_VARIATION_MASK 0x000000FF +#define TMC4361A_SER_ENC_VARIATION_SHIFT 0 +#define TMC4361A_SER_ENC_VARIATION_FIELD ((RegisterField) {TMC4361A_SER_ENC_VARIATION_MASK, TMC4361A_SER_ENC_VARIATION_SHIFT, TMC4361A_SER_ENC_VARIATION, false}) +#define TMC4361A_CL_CYCLE_MASK 0xFFFF0000 +#define TMC4361A_CL_CYCLE_SHIFT 16 +#define TMC4361A_CL_CYCLE_FIELD ((RegisterField) {TMC4361A_CL_CYCLE_MASK, TMC4361A_CL_CYCLE_SHIFT, TMC4361A_CL_CYCLE, false}) +#define TMC4361A_V_ENC_MASK 0xFFFFFFFF +#define TMC4361A_V_ENC_SHIFT 0 +#define TMC4361A_V_ENC_FIELD ((RegisterField) {TMC4361A_V_ENC_MASK, TMC4361A_V_ENC_SHIFT, TMC4361A_V_ENC, true}) +#define TMC4361A_V_ENC_MEAN_MASK 0xFFFFFFFF +#define TMC4361A_V_ENC_MEAN_SHIFT 0 +#define TMC4361A_V_ENC_MEAN_FIELD ((RegisterField) {TMC4361A_V_ENC_MEAN_MASK, TMC4361A_V_ENC_MEAN_SHIFT, TMC4361A_V_ENC_MEAN, true}) +#define TMC4361A_VSTALL_LIMIT_MASK 0x00FFFFFF +#define TMC4361A_VSTALL_LIMIT_SHIFT 0 +#define TMC4361A_VSTALL_LIMIT_FIELD ((RegisterField) {TMC4361A_VSTALL_LIMIT_MASK, TMC4361A_VSTALL_LIMIT_SHIFT, TMC4361A_VSTALL_LIMIT, false}) +#define TMC4361A_ADDR_TO_ENC_MASK 0xFFFFFFFF +#define TMC4361A_ADDR_TO_ENC_SHIFT 0 +#define TMC4361A_ADDR_TO_ENC_FIELD ((RegisterField) {TMC4361A_ADDR_TO_ENC_MASK, TMC4361A_ADDR_TO_ENC_SHIFT, TMC4361A_ADDR_TO_ENC, false}) +#define TMC4361A_DATA_TO_ENC_MASK 0xFFFFFFFF +#define TMC4361A_DATA_TO_ENC_SHIFT 0 +#define TMC4361A_DATA_TO_ENC_FIELD ((RegisterField) {TMC4361A_DATA_TO_ENC_MASK, TMC4361A_DATA_TO_ENC_SHIFT, TMC4361A_DATA_TO_ENC, false}) +#define TMC4361A_ADDR_FROM_ENC_MASK 0xFFFFFFFF +#define TMC4361A_ADDR_FROM_ENC_SHIFT 0 +#define TMC4361A_ADDR_FROM_ENC_FIELD ((RegisterField) {TMC4361A_ADDR_FROM_ENC_MASK, TMC4361A_ADDR_FROM_ENC_SHIFT, TMC4361A_ADDR_FROM_ENC, false}) +#define TMC4361A_DATA_FROM_ENC_MASK 0xFFFFFFFF +#define TMC4361A_DATA_FROM_ENC_SHIFT 0 +#define TMC4361A_DATA_FROM_ENC_FIELD ((RegisterField) {TMC4361A_DATA_FROM_ENC_MASK, TMC4361A_DATA_FROM_ENC_SHIFT, TMC4361A_DATA_FROM_ENC, false}) +#define TMC4361A_POLLING_STATUS_MASK 0xFFFFFFFF +#define TMC4361A_POLLING_STATUS_SHIFT 0 +#define TMC4361A_POLLING_STATUS_FIELD ((RegisterField) {TMC4361A_POLLING_STATUS_MASK, TMC4361A_POLLING_STATUS_SHIFT, TMC4361A_POLLING_STATUS, false}) +#define TMC4361A_COVER_LOW_MASK 0xFFFFFFFF +#define TMC4361A_COVER_LOW_SHIFT 0 +#define TMC4361A_COVER_LOW_FIELD ((RegisterField) {TMC4361A_COVER_LOW_MASK, TMC4361A_COVER_LOW_SHIFT, TMC4361A_COVER_LOW, false}) +#define TMC4361A_POLLING_REG_GSTAT_MASK 0xF0000000 +#define TMC4361A_POLLING_REG_GSTAT_SHIFT 28 +#define TMC4361A_POLLING_REG_GSTAT_FIELD ((RegisterField) {TMC4361A_POLLING_REG_GSTAT_MASK, TMC4361A_POLLING_REG_GSTAT_SHIFT, TMC4361A_POLLING_REG_GSTAT, false}) +#define TMC4361A_POLLING_REG_PWM_SCALE_MASK 0x0FF00000 +#define TMC4361A_POLLING_REG_PWM_SCALE_SHIFT 20 +#define TMC4361A_POLLING_REG_PWM_SCALE_FIELD ((RegisterField) {TMC4361A_POLLING_REG_PWM_SCALE_MASK, TMC4361A_POLLING_REG_PWM_SCALE_SHIFT, TMC4361A_POLLING_REG_PWM_SCALE, false}) +#define TMC4361A_POLLING_REG_LOST_STEPS_MASK 0xFFFFFFFF +#define TMC4361A_POLLING_REG_LOST_STEPS_SHIFT 0 +#define TMC4361A_POLLING_REG_LOST_STEPS_FIELD ((RegisterField) {TMC4361A_POLLING_REG_LOST_STEPS_MASK, TMC4361A_POLLING_REG_LOST_STEPS_SHIFT, TMC4361A_POLLING_REG_LOST_STEPS, false}) +#define TMC4361A_COVER_HIGH_MASK 0xFFFFFFFF +#define TMC4361A_COVER_HIGH_SHIFT 0 +#define TMC4361A_COVER_HIGH_FIELD ((RegisterField) {TMC4361A_COVER_HIGH_MASK, TMC4361A_COVER_HIGH_SHIFT, TMC4361A_COVER_HIGH, false}) +#define TMC4361A_COVER_DRV_LOW_MASK 0xFFFFFFFF +#define TMC4361A_COVER_DRV_LOW_SHIFT 0 +#define TMC4361A_COVER_DRV_LOW_FIELD ((RegisterField) {TMC4361A_COVER_DRV_LOW_MASK, TMC4361A_COVER_DRV_LOW_SHIFT, TMC4361A_COVER_DRV_LOW, false}) +#define TMC4361A_COVER_DRV_HIGH_MASK 0xFFFFFFFF +#define TMC4361A_COVER_DRV_HIGH_SHIFT 0 +#define TMC4361A_COVER_DRV_HIGH_FIELD ((RegisterField) {TMC4361A_COVER_DRV_HIGH_MASK, TMC4361A_COVER_DRV_HIGH_SHIFT, TMC4361A_COVER_DRV_HIGH, false}) +#define TMC4361A_MSLUT_0_MASK 0xFFFFFFFF +#define TMC4361A_MSLUT_0_SHIFT 0 +#define TMC4361A_MSLUT_0_FIELD ((RegisterField) {TMC4361A_MSLUT_0_MASK, TMC4361A_MSLUT_0_SHIFT, TMC4361A_MSLUT_0, false}) +#define TMC4361A_MSLUT_1_MASK 0xFFFFFFFF +#define TMC4361A_MSLUT_1_SHIFT 0 +#define TMC4361A_MSLUT_1_FIELD ((RegisterField) {TMC4361A_MSLUT_1_MASK, TMC4361A_MSLUT_1_SHIFT, TMC4361A_MSLUT_1, false}) +#define TMC4361A_MSLUT_2_MASK 0xFFFFFFFF +#define TMC4361A_MSLUT_2_SHIFT 0 +#define TMC4361A_MSLUT_2_FIELD ((RegisterField) {TMC4361A_MSLUT_2_MASK, TMC4361A_MSLUT_2_SHIFT, TMC4361A_MSLUT_2, false}) +#define TMC4361A_MSLUT_3_MASK 0xFFFFFFFF +#define TMC4361A_MSLUT_3_SHIFT 0 +#define TMC4361A_MSLUT_3_FIELD ((RegisterField) {TMC4361A_MSLUT_3_MASK, TMC4361A_MSLUT_3_SHIFT, TMC4361A_MSLUT_3, false}) +#define TMC4361A_MSLUT_4_MASK 0xFFFFFFFF +#define TMC4361A_MSLUT_4_SHIFT 0 +#define TMC4361A_MSLUT_4_FIELD ((RegisterField) {TMC4361A_MSLUT_4_MASK, TMC4361A_MSLUT_4_SHIFT, TMC4361A_MSLUT_4, false}) +#define TMC4361A_MSLUT_5_MASK 0xFFFFFFFF +#define TMC4361A_MSLUT_5_SHIFT 0 +#define TMC4361A_MSLUT_5_FIELD ((RegisterField) {TMC4361A_MSLUT_5_MASK, TMC4361A_MSLUT_5_SHIFT, TMC4361A_MSLUT_5, false}) +#define TMC4361A_MSLUT_6_MASK 0xFFFFFFFF +#define TMC4361A_MSLUT_6_SHIFT 0 +#define TMC4361A_MSLUT_6_FIELD ((RegisterField) {TMC4361A_MSLUT_6_MASK, TMC4361A_MSLUT_6_SHIFT, TMC4361A_MSLUT_6, false}) +#define TMC4361A_MSLUT_7_MASK 0xFFFFFFFF +#define TMC4361A_MSLUT_7_SHIFT 0 +#define TMC4361A_MSLUT_7_FIELD ((RegisterField) {TMC4361A_MSLUT_7_MASK, TMC4361A_MSLUT_7_SHIFT, TMC4361A_MSLUT_7, false}) +#define TMC4361A_MSLUTSEL_MASK 0xFFFFFFFF +#define TMC4361A_MSLUTSEL_SHIFT 0 +#define TMC4361A_MSLUTSEL_FIELD ((RegisterField) {TMC4361A_MSLUTSEL_MASK, TMC4361A_MSLUTSEL_SHIFT, TMC4361A_MSLUTSEL, false}) +#define TMC4361A_MSCNT_MASK 0x000003FF +#define TMC4361A_MSCNT_SHIFT 0 +#define TMC4361A_MSCNT_FIELD ((RegisterField) {TMC4361A_MSCNT_MASK, TMC4361A_MSCNT_SHIFT, TMC4361A_MSCNT, false}) +#define TMC4361A_MSOFFSET_MASK 0x000003FF +#define TMC4361A_MSOFFSET_SHIFT 0 +#define TMC4361A_MSOFFSET_FIELD ((RegisterField) {TMC4361A_MSOFFSET_MASK, TMC4361A_MSOFFSET_SHIFT, TMC4361A_MSOFFSET, false}) +#define TMC4361A_CURRENTA_MASK 0x000001FF +#define TMC4361A_CURRENTA_SHIFT 0 +#define TMC4361A_CURRENTA_FIELD ((RegisterField) {TMC4361A_CURRENTA_MASK, TMC4361A_CURRENTA_SHIFT, TMC4361A_CURRENTA, true}) +#define TMC4361A_CURRENTB_MASK 0x01FF0000 +#define TMC4361A_CURRENTB_SHIFT 16 +#define TMC4361A_CURRENTB_FIELD ((RegisterField) {TMC4361A_CURRENTB_MASK, TMC4361A_CURRENTB_SHIFT, TMC4361A_CURRENTB, true}) +#define TMC4361A_CURRENTA_SPI_MASK 0x000001FF +#define TMC4361A_CURRENTA_SPI_SHIFT 0 +#define TMC4361A_CURRENTA_SPI_FIELD ((RegisterField) {TMC4361A_CURRENTA_SPI_MASK, TMC4361A_CURRENTA_SPI_SHIFT, TMC4361A_CURRENTA_SPI, true}) +#define TMC4361A_CURRENTB_SPI_MASK 0x01FF0000 +#define TMC4361A_CURRENTB_SPI_SHIFT 16 +#define TMC4361A_CURRENTB_SPI_FIELD ((RegisterField) {TMC4361A_CURRENTB_SPI_MASK, TMC4361A_CURRENTB_SPI_SHIFT, TMC4361A_CURRENTB_SPI, true}) +#define TMC4361A_TZEROWAIT_MASK 0xFFFFFFFF +#define TMC4361A_TZEROWAIT_SHIFT 0 +#define TMC4361A_TZEROWAIT_FIELD ((RegisterField) {TMC4361A_TZEROWAIT_MASK, TMC4361A_TZEROWAIT_SHIFT, TMC4361A_TZEROWAIT, false}) +#define TMC4361A_SCALE_PARAM_MASK 0x000001FF +#define TMC4361A_SCALE_PARAM_SHIFT 0 +#define TMC4361A_SCALE_PARAM_FIELD ((RegisterField) {TMC4361A_SCALE_PARAM_MASK, TMC4361A_SCALE_PARAM_SHIFT, TMC4361A_SCALE_PARAM, false}) +#define TMC4361A_CIRCULAR_DEC_MASK 0xFFFFFFFF +#define TMC4361A_CIRCULAR_DEC_SHIFT 0 +#define TMC4361A_CIRCULAR_DEC_FIELD ((RegisterField) {TMC4361A_CIRCULAR_DEC_MASK, TMC4361A_CIRCULAR_DEC_SHIFT, TMC4361A_CIRCULAR_DEC, false}) +#define TMC4361A_ENC_COMP_XOFFSET_MASK 0x0000FFFF +#define TMC4361A_ENC_COMP_XOFFSET_SHIFT 0 +#define TMC4361A_ENC_COMP_XOFFSET_FIELD ((RegisterField) {TMC4361A_ENC_COMP_XOFFSET_MASK, TMC4361A_ENC_COMP_XOFFSET_SHIFT, TMC4361A_ENC_COMP_XOFFSET, false}) +#define TMC4361A_ENC_COMP_YOFFSET_MASK 0x00FF0000 +#define TMC4361A_ENC_COMP_YOFFSET_SHIFT 16 +#define TMC4361A_ENC_COMP_YOFFSET_FIELD ((RegisterField) {TMC4361A_ENC_COMP_YOFFSET_MASK, TMC4361A_ENC_COMP_YOFFSET_SHIFT, TMC4361A_ENC_COMP_YOFFSET, true}) +#define TMC4361A_START_SIN_MASK 0x000000FF +#define TMC4361A_START_SIN_SHIFT 0 +#define TMC4361A_START_SIN_FIELD ((RegisterField) {TMC4361A_START_SIN_MASK, TMC4361A_START_SIN_SHIFT, TMC4361A_START_SIN, false}) +#define TMC4361A_START_SIN90_120_MASK 0x00FF0000 +#define TMC4361A_START_SIN90_120_SHIFT 16 +#define TMC4361A_START_SIN90_120_FIELD ((RegisterField) {TMC4361A_START_SIN90_120_MASK, TMC4361A_START_SIN90_120_SHIFT, TMC4361A_START_SIN90_120, false}) +#define TMC4361A_DAC_OFFSET_MASK 0xFF000000 +#define TMC4361A_DAC_OFFSET_SHIFT 24 +#define TMC4361A_DAC_OFFSET_FIELD ((RegisterField) {TMC4361A_DAC_OFFSET_MASK, TMC4361A_DAC_OFFSET_SHIFT, TMC4361A_DAC_OFFSET, false}) +#define TMC4361A_VERSION_NO_MASK 0x0000000F +#define TMC4361A_VERSION_NO_SHIFT 0 +#define TMC4361A_VERSION_NO_FIELD ((RegisterField) {TMC4361A_VERSION_NO_MASK, TMC4361A_VERSION_NO_SHIFT, TMC4361A_VERSION_NO, true}) + +#endif /* TMC4361A_HW_ABSTRACTION_H */ diff --git a/firmware/lib/tmc/ic/TMC4361A/registercall_hierarchy_flowchart_SPI.svg b/firmware/lib/tmc/ic/TMC4361A/registercall_hierarchy_flowchart_SPI.svg new file mode 100755 index 0000000..cbad58f --- /dev/null +++ b/firmware/lib/tmc/ic/TMC4361A/registercall_hierarchy_flowchart_SPI.svg @@ -0,0 +1,3 @@ + + +

HAL

HAL

APP (Eval)

APP (Eval)

API

API
Read a register
  •  Call tmcXXXX_readRegister function
Read a register...
Returns the register read value
Returns the register read value
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
tmcXXXX.c
tmcXXXX.c
SPI.c
SPI.c
tmcXXXX_eval.c
tmcXXXX_eval.c

 Implementation of SPI_readWrite
  • Sends and receives bytes on the SPI bus
Implementation of SPI_readWrite...
Returns the raw reply data
Returns the raw reply data

Implementation of tmcXXXX_readWriteSPI
  • Sets the CSN pin to LOW
  • Takes the array of data to write
  • Calls hardware function SPI_readWrite
  • Upon completion of data transfer,
    sets CSN to 
    HIGH
Implementation of tmcXXXX_readWriteSPI...
Passes on the raw reply data to the API
Passes on the raw reply data to the API
Implementation of readRegisterSPI
  • Constructs the datagram
  • Calls HAL wrapper function 
Implementation of readRegisterSPI...
tmcXXXX_readWriteSPI
tmcXXXX_readWriteSPI
Parses the reply and returns the register value
Parses the reply and returns the register value
Implementation of tmcXXXX_readRegister 
  • Check which bus is active SPI/UART. (e.g. SPI)
  • Calls bus-specific function (e.g. readRegisterSPI)
 
Implementation of tmcXXXX_readRegister...
Returns the register read value
Returns the register read value
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC4361A/uml-tmc-api.svg b/firmware/lib/tmc/ic/TMC4361A/uml-tmc-api.svg new file mode 100755 index 0000000..5a5f8dd --- /dev/null +++ b/firmware/lib/tmc/ic/TMC4361A/uml-tmc-api.svg @@ -0,0 +1,3 @@ + + +

TMCXXXX_HW_Abstraction.h



TMCXXXX_HW_Abstraction.h...
// Constants
#define TMCXXXX_MOTORS              
                          
// Register definitions
#define TMCXXXX_GCONF        
                          ⋮
// Register fields definitions
#define TMCXXXX_GCONF_OTPW_FIELD
                     
// Constants...

TMCXXXX.h



TMCXXXX.h...
extern void tmcXXXX_readWriteSPI();
extern void tmcXXXX_readWriteUART();
extern TMCXXXXBusType tmcXXXX_getBusType();
extern uint8_t tmcXXXX_getNodeAddress();
                                  ⋮
tmcXXXX_readRegister();
tmcXXXX_writeRegister();
                                  ⋮
extern void tmcXXXX_readWriteSPI();...

TMCXXXX.c



TMCXXXX.c...
const uint8_t tmcCRCTable_Poly7Reflected[256] = {...};
int32_t tmcXXXX_readRegister(){
/* Call tmcXXXX_getBusType();
 * Based on bus type, call readRegisterSPI/UART() that
 * further calls tmcXXXX_readWriteSPI/UART();
 * For UART it also calls tmcXXXX_getNodeAddress();
                                           ⋮
}
                                           ⋮
const uint8_t tmcCRCTable_Poly7Reflected[256] = {.....
TMC-API
TMC-API

TMCXXXX_Simple_Rotation.h


TMCXXXX_Simple_Rotation.h...
void initAllMotors();
             ⋮
  
void initAllMotors()...

TMCXXXX_Simple_Rotation.c


TMCXXXX_Simple_Rotation.c...
void initAllMotors(){

// Configuring registers to enable motor drivers etc..
tmcXXXX_writeRegister();
                    ⋮
}
                    ⋮
void initAllMotors(){...
Examples
Examples
User Project
User Project

User_Project.h


User_Project.h

User_Project.c








User_Project.c...

void tmcXXXX_readWriteSPI(){
                           ⋮
}
void tmcXXXX_readWriteUART(){
                           ⋮
}
TMCXXXXBusType tmcXXXX_getBusType(){
                           ⋮
}
uint8_t tmcXXXX_getNodeAddress(){
                           ⋮
}

// User Code
                           ⋮
void tmcXXXX_readWriteSPI(){...
#include "TMCXXXX_HW_Abstraction.h"
#include "TMCXXXX.h"
#include "TMCXXXX_Simple_Rotation.h"
                                ⋮
TMCXXXXBusType bus = IC_BUS_SPI/UART;
uint8_t nodeAddress = <nodeAddress>;
                                ⋮
#include "TMCXXXX_HW_Abstraction.h"...
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC4671/README.md b/firmware/lib/tmc/ic/TMC4671/README.md new file mode 100755 index 0000000..f622a4e --- /dev/null +++ b/firmware/lib/tmc/ic/TMC4671/README.md @@ -0,0 +1,42 @@ +# TMC4671 + + +## How to use + +To access the TMC4671's registers, the TMC-API offers two functions: **tmc4671_readRegister** and **tmc4671_writeRegister**. +Each of these functions takes in an **icID**, which is used to identify the IC when multiple ICs are connected. This identifier is passed down to the callback functions (see How to Integrate). + +## How to integrate: overview + +1. Include all the files of the TMC-API/ic/tmc/TMC4671 folder into the custom project. +2. Include the TMC4671.h file in the custom source code. +3. Implement the necessary callback functions (see below). +4. (optional): Take a look at the Examples subfolder for ready-made examples of the TMC-API usage. + +## Accessing the TMC4671 via SPI +The following diagram depicts how to access the TMC4671 via SPI using the TMC-API. + +![screenshot](registercall_hierarchy_flowchart_SPI.svg) + +The description of the functions, in the above flowchart, are as follows: +- The functions tmc4671_readRegister and tmc4671_writeRegister are used to read and write the registers respectively. These functions check the current active bus and calls the bus-specific function i.e readRegisterSPI or writeRegisterSPI. +- These bus specific functions constructs the datagram and further calls the bus specific callback 'tmcXXXX_readWriteSPI. +- This callback function further calls the hardware specific read/write function for SPI and needs to be implemented externally. + +### How to integrate: Callback functions +Implement the following callback functions to access the chip via SPI: +1. **tmc4671_readWriteSPI()**, which is a HAL wrapper function that provides the necessary hardware access. This function should also set the chip select pin CSN to low before starting the data transfer and set to high upon completion. Please refer to the datasheet of the IC for further details. + +## Further info +### Dependency graph for the ICs with new register R/W mechanism +This graph illustrates the relationships between files within the TMC-API library, highlighting dependencies and identifying the files that are essential for integrating the library into the custom projects. + +![screenshot](uml-tmc-api.svg) + +### Example usage: TMC-Evalsystem +**For a reference usage of the TMC-API**, visit the [TMC-Evalsystem](https://github.com/analogdevicesinc/TMC-EvalSystem) + +## Migration status +The TMC4671 has been reworked to the access system described above. For more infos on the status of this and other ICs, check out the [migration page](https://github.com/analogdevicesinc/TMC-API/issues/53). + + diff --git a/firmware/lib/tmc/ic/TMC4671/TMC4671.c b/firmware/lib/tmc/ic/TMC4671/TMC4671.c new file mode 100755 index 0000000..736dba0 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC4671/TMC4671.c @@ -0,0 +1,510 @@ +/******************************************************************************* +* Copyright © 2016 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + +#include "TMC4671.h" + +#define TMC4671_WRITE_BIT 0x80 +#define TMC4671_ADDRESS_MASK 0x7F + +#define STATE_NOTHING_TO_DO 0 +#define STATE_START_INIT 1 +#define STATE_WAIT_INIT_TIME 2 +#define STATE_ESTIMATE_OFFSET 3 + +// => SPI wrapper +extern void tmc4671_readWriteSPI(uint16_t icID, uint8_t *data, size_t dataLength); +// <= SPI wrapper + +// spi access +int32_t tmc4671_readRegister(uint16_t icID, uint8_t address) +{ + uint8_t data[5] = { 0 }; + + // clear write bit + data[0] = address & TMC4671_ADDRESS_MASK; + + // Send the read request + tmc4671_readWriteSPI(icID, &data[0], sizeof(data)); + + return ((int32_t)data[1] << 24) | ((int32_t) data[2] << 16) | ((int32_t) data[3] << 8) | ((int32_t) data[4]); +} + +void tmc4671_writeRegister(uint16_t icID, uint8_t address, int32_t value) +{ + uint8_t data[5] = { 0 }; + + data[0] = address | TMC4671_WRITE_BIT; + data[1] = 0xFF & (value>>24); + data[2] = 0xFF & (value>>16); + data[3] = 0xFF & (value>>8); + data[4] = 0xFF & (value>>0); + + // Send the write request + tmc4671_readWriteSPI(icID, &data[0], sizeof(data)); +} + +void tmc4671_switchToMotionMode(uint16_t icID, uint8_t mode) +{ + // switch motion mode + tmc4671_fieldWrite(icID, TMC4671_MODE_MOTION_FIELD, mode); +} + +void tmc4671_setTargetTorque_raw(uint16_t icID, int32_t targetTorque) +{ + tmc4671_switchToMotionMode(icID, TMC4671_MOTION_MODE_TORQUE); + tmc4671_fieldWrite(icID, TMC4671_PID_TORQUE_TARGET_FIELD, targetTorque); +} + +int32_t tmc4671_getTargetTorque_raw(uint16_t icID) +{ + // remember last set index + uint32_t lastIndex = tmc4671_readRegister(icID, TMC4671_INTERIM_ADDR); + + // get value + tmc4671_writeRegister(icID, TMC4671_INTERIM_ADDR, 0); + int32_t value = (int32_t)tmc4671_readRegister(icID, TMC4671_INTERIM_DATA); + + // reset last set index + tmc4671_writeRegister(icID, TMC4671_INTERIM_ADDR, lastIndex); + return value; +} + +int32_t tmc4671_getActualTorque_raw(uint16_t icID) +{ + return tmc4671_fieldRead(icID, TMC4671_PID_TORQUE_ACTUAL_FIELD); +} + +void tmc4671_setTargetTorque_mA(uint16_t icID, uint16_t torqueMeasurementFactor, int32_t targetTorque) +{ + tmc4671_switchToMotionMode(icID, TMC4671_MOTION_MODE_TORQUE); + tmc4671_fieldWrite(icID, TMC4671_PID_TORQUE_TARGET_FIELD, (targetTorque * 256) / (int32_t)torqueMeasurementFactor); +} + +int32_t tmc4671_getTargetTorque_mA(uint16_t icID, uint16_t torqueMeasurementFactor) +{ + return (tmc4671_getTargetTorque_raw(icID) * (int32_t)torqueMeasurementFactor) / 256; +} + +int32_t tmc4671_getActualTorque_mA(uint16_t icID, uint16_t torqueMeasurementFactor) +{ + return (tmc4671_getActualTorque_raw(icID) * (int32_t)torqueMeasurementFactor) / 256; +} + +int32_t tmc4671_getTargetTorqueFluxSum_mA(uint16_t icID, uint16_t torqueMeasurementFactor) +{ + // remember last set index + uint32_t lastIndex = tmc4671_readRegister(icID, TMC4671_INTERIM_ADDR); + + // get target torque value + tmc4671_writeRegister(icID, TMC4671_INTERIM_ADDR, 0); + int32_t torque = (int32_t)tmc4671_readRegister(icID, TMC4671_INTERIM_DATA); + + // get target flux value + tmc4671_writeRegister(icID, TMC4671_INTERIM_ADDR, 1); + int32_t flux = (int32_t)tmc4671_readRegister(icID, TMC4671_INTERIM_DATA); + + // reset last set index + tmc4671_writeRegister(icID, TMC4671_INTERIM_ADDR, lastIndex); + + return (((int32_t)flux+(int32_t)torque) * (int32_t)torqueMeasurementFactor) / 256; +} + +int32_t tmc4671_getActualTorqueFluxSum_mA(uint16_t icID, uint16_t torqueMeasurementFactor) +{ + int32_t registerValue = tmc4671_readRegister(icID, TMC4671_PID_TORQUE_FLUX_ACTUAL); + int16_t flux = (registerValue & 0xFFFF); + int16_t torque = ((registerValue >> 16) & 0xFFFF); + return (((int32_t)flux+(int32_t)torque) * (int32_t)torqueMeasurementFactor) / 256; +} + +void tmc4671_setTargetFlux_raw(uint16_t icID, int32_t targetFlux) +{ + // do not change the MOTION_MODE here! target flux can also be used during velocity and position modes + tmc4671_fieldWrite(icID, TMC4671_PID_FLUX_TARGET_FIELD, targetFlux); +} + +int32_t tmc4671_getTargetFlux_raw(uint16_t icID) +{ + // remember last set index + uint32_t lastIndex = tmc4671_readRegister(icID, TMC4671_INTERIM_ADDR); + + // get value + tmc4671_writeRegister(icID, TMC4671_INTERIM_ADDR, 1); + int32_t value = (int32_t)tmc4671_readRegister(icID, TMC4671_INTERIM_DATA); + + // reset last set index + tmc4671_writeRegister(icID, TMC4671_INTERIM_ADDR, lastIndex); + return value; +} + +int32_t tmc4671_getActualFlux_raw(uint16_t icID) +{ + return tmc4671_fieldRead(icID, TMC4671_PID_FLUX_ACTUAL_FIELD); +} + +void tmc4671_setTargetFlux_mA(uint16_t icID, uint16_t torqueMeasurementFactor, int32_t targetFlux) +{ + // do not change the MOTION_MODE here! target flux can also be used during velocity and position modes + tmc4671_fieldWrite(icID, TMC4671_PID_FLUX_TARGET_FIELD, (targetFlux * 256) / (int32_t)torqueMeasurementFactor); +} + +int32_t tmc4671_getTargetFlux_mA(uint16_t icID, uint16_t torqueMeasurementFactor) +{ + return (tmc4671_getTargetFlux_raw(icID) * (int32_t)torqueMeasurementFactor) / 256; +} + +int32_t tmc4671_getActualFlux_mA(uint16_t icID, uint16_t torqueMeasurementFactor) +{ + return (tmc4671_getActualFlux_raw(icID) * (int32_t)torqueMeasurementFactor) / 256; +} + +void tmc4671_setTorqueFluxLimit_mA(uint16_t icID, uint16_t torqueMeasurementFactor, int32_t max) +{ + tmc4671_fieldWrite(icID, TMC4671_PID_TORQUE_FLUX_LIMITS_FIELD, (max * 256) / (int32_t)torqueMeasurementFactor); +} + +int32_t tmc4671_getTorqueFluxLimit_mA(uint16_t icID, uint16_t torqueMeasurementFactor) +{ + return ((int32_t)tmc4671_fieldRead(icID, TMC4671_PID_TORQUE_FLUX_LIMITS_FIELD) * (int32_t)torqueMeasurementFactor) / 256; +} + +void tmc4671_setTargetVelocity(uint16_t icID, int32_t targetVelocity) +{ + tmc4671_switchToMotionMode(icID, TMC4671_MOTION_MODE_VELOCITY); + tmc4671_writeRegister(icID, TMC4671_PID_VELOCITY_TARGET, targetVelocity); +} + +int32_t tmc4671_getTargetVelocity(uint16_t icID) +{ + return (int32_t)tmc4671_readRegister(icID, TMC4671_PID_VELOCITY_TARGET); +} + +int32_t tmc4671_getActualVelocity(uint16_t icID) +{ + return (int32_t)tmc4671_readRegister(icID, TMC4671_PID_VELOCITY_ACTUAL); +} + +void tmc4671_setAbsolutTargetPosition(uint16_t icID, int32_t targetPosition) +{ + tmc4671_switchToMotionMode(icID, TMC4671_MOTION_MODE_POSITION); + tmc4671_writeRegister(icID, TMC4671_PID_POSITION_TARGET, targetPosition); +} + +void tmc4671_setRelativeTargetPosition(uint16_t icID, int32_t relativePosition) +{ + tmc4671_switchToMotionMode(icID, TMC4671_MOTION_MODE_POSITION); + // determine actual position and add relative position ticks + tmc4671_writeRegister(icID, TMC4671_PID_POSITION_TARGET, (int32_t)tmc4671_readRegister(icID, TMC4671_PID_POSITION_ACTUAL) + relativePosition); +} + +int32_t tmc4671_getTargetPosition(uint16_t icID) +{ + return (int32_t)tmc4671_readRegister(icID, TMC4671_PID_POSITION_TARGET); +} + +void tmc4671_setActualPosition(uint16_t icID, int32_t actualPosition) +{ + tmc4671_writeRegister(icID, TMC4671_PID_POSITION_ACTUAL, actualPosition); +} + +int32_t tmc4671_getActualPosition(uint16_t icID) +{ + return (int32_t)tmc4671_readRegister(icID, TMC4671_PID_POSITION_ACTUAL); +} + +// ABN encoder initialization +void tmc4671_doEncoderInitializationMode0(uint16_t icID, uint8_t *initState, uint16_t initWaitTime, uint16_t *actualInitWaitTime, uint16_t startVoltage, + uint16_t *last_Phi_E_Selection, uint32_t *last_UQ_UD_EXT, int16_t *last_PHI_E_EXT) +{ + switch (*initState) + { + case STATE_NOTHING_TO_DO: + *actualInitWaitTime = 0; + break; + case STATE_START_INIT: // started by writing 1 to initState + + // save actual set values for PHI_E_SELECTION, UQ_UD_EXT, and PHI_E_EXT + *last_Phi_E_Selection = (uint16_t)tmc4671_fieldRead(icID, TMC4671_PHI_E_SELECTION_FIELD); + *last_UQ_UD_EXT = (uint32_t)tmc4671_readRegister(icID, TMC4671_UQ_UD_EXT); + *last_PHI_E_EXT = (int16_t)tmc4671_fieldRead(icID, TMC4671_PHI_E_EXT_FIELD); + + //switch motion mode for running icID in open loop + tmc4671_writeRegister(icID, TMC4671_MODE_RAMP_MODE_MOTION, TMC4671_MOTION_MODE_UQ_UD_EXT); + + // set ABN_DECODER_PHI_E_OFFSET to zero + tmc4671_fieldWrite(icID, TMC4671_ABN_DECODER_PHI_E_OFFSET_FIELD, 0); + + // select phi_e_ext + tmc4671_fieldWrite(icID, TMC4671_PHI_E_SELECTION_FIELD, 1); + + // set an initialization voltage on UD_EXT (to the flux, not the torque!) + tmc4671_fieldWrite(icID, TMC4671_UQ_EXT_FIELD, 0); + tmc4671_fieldWrite(icID, TMC4671_UD_EXT_FIELD, startVoltage); + + // set the "zero" angle + tmc4671_fieldWrite(icID, TMC4671_PHI_E_EXT_FIELD, 0); + + *initState = STATE_WAIT_INIT_TIME; + break; + case STATE_WAIT_INIT_TIME: + // wait until initialization time is over (until no more vibration on the icID) + (*actualInitWaitTime)++; + if(*actualInitWaitTime >= initWaitTime) + { + // set internal encoder value to zero + tmc4671_writeRegister(icID, TMC4671_ABN_DECODER_COUNT, 0); + + // switch back to last used UQ_UD_EXT setting + tmc4671_writeRegister(icID, TMC4671_UQ_UD_EXT, *last_UQ_UD_EXT); + + // set PHI_E_EXT back to last value + tmc4671_fieldWrite(icID, TMC4671_PHI_E_EXT_FIELD, *last_PHI_E_EXT); + + // switch back to last used PHI_E_SELECTION setting + tmc4671_fieldWrite(icID, TMC4671_PHI_E_SELECTION_FIELD, *last_Phi_E_Selection); + + // go to next state + *initState = STATE_ESTIMATE_OFFSET; + } + break; + case STATE_ESTIMATE_OFFSET: + // you can do offset estimation here (wait for N-Channel if available and save encoder value) + + // go to ready state + *initState = 0; + break; + default: + *initState = 0; + break; + } +} + +int16_t tmc4671_getS16CircleDifference(int16_t newValue, int16_t oldValue) +{ + return (newValue - oldValue); +} + +void tmc4671_doEncoderInitializationMode2(uint16_t icID, uint8_t *initState, uint16_t *actualInitWaitTime, + int16_t *hall_phi_e_old, int16_t *hall_phi_e_new, int16_t *hall_actual_coarse_offset, uint16_t *last_Phi_E_Selection) +{ + switch (*initState) + { + case STATE_NOTHING_TO_DO: + *actualInitWaitTime = 0; + break; + case STATE_START_INIT: // started by writing 1 to initState + // save actual set value for PHI_E_SELECTION + *last_Phi_E_Selection = (uint16_t)tmc4671_fieldRead(icID, TMC4671_PHI_E_SELECTION_FIELD); + + // turn hall_mode interpolation off (read, clear bit 8, write back) + tmc4671_writeRegister(icID, TMC4671_HALL_MODE, tmc4671_readRegister(icID, TMC4671_HALL_MODE) & 0xFFFFFEFF); + + // set ABN_DECODER_PHI_E_OFFSET to zero + tmc4671_fieldWrite(icID, TMC4671_ABN_DECODER_PHI_E_OFFSET_FIELD, 0); + + // read actual hall angle + *hall_phi_e_old = tmc4671_fieldRead(icID, TMC4671_HALL_PHI_E_FIELD); + + // read actual abn_decoder angle and compute difference to actual hall angle + *hall_actual_coarse_offset = tmc4671_getS16CircleDifference(*hall_phi_e_old, (int16_t)tmc4671_fieldRead(icID, TMC4671_ABN_DECODER_PHI_E_FIELD)); + + // set ABN_DECODER_PHI_E_OFFSET to actual hall-abn-difference, to use the actual hall angle for coarse initialization + tmc4671_fieldWrite(icID, TMC4671_ABN_DECODER_PHI_E_OFFSET_FIELD, *hall_actual_coarse_offset); + + // normally MOTION_MODE_UQ_UD_EXT is only used by e.g. a wizard, not in normal operation + if (tmc4671_fieldRead(icID, TMC4671_MODE_MOTION_FIELD) != TMC4671_MOTION_MODE_UQ_UD_EXT) + { + // select the use of phi_e_hall to start icID with hall signals + tmc4671_fieldWrite(icID, TMC4671_PHI_E_SELECTION_FIELD, TMC4671_PHI_E_HALL); + } + + *initState = STATE_WAIT_INIT_TIME; + break; + case STATE_WAIT_INIT_TIME: + // read actual hall angle + *hall_phi_e_new = tmc4671_fieldRead(icID, TMC4671_HALL_PHI_E_FIELD); + + // wait until hall angle changed + if(*hall_phi_e_old != *hall_phi_e_new) + { + // estimated value = old value + diff between old and new (handle int16_t overrun) + int16_t hall_phi_e_estimated = *hall_phi_e_old + tmc4671_getS16CircleDifference(*hall_phi_e_new, *hall_phi_e_old)/2; + + // read actual abn_decoder angle and consider last set abn_decoder_offset + int16_t abn_phi_e_actual = (int16_t)tmc4671_fieldRead(icID, TMC4671_ABN_DECODER_PHI_E_FIELD) - *hall_actual_coarse_offset; + + // set ABN_DECODER_PHI_E_OFFSET to actual estimated angle - abn_phi_e_actual difference + tmc4671_fieldWrite(icID, TMC4671_ABN_DECODER_PHI_E_OFFSET_FIELD, tmc4671_getS16CircleDifference(hall_phi_e_estimated, abn_phi_e_actual)); + + // switch back to last used PHI_E_SELECTION setting + tmc4671_fieldWrite(icID, TMC4671_PHI_E_SELECTION_FIELD, *last_Phi_E_Selection); + + // go to ready state + *initState = 0; + } + break; + default: + *initState = 0; + break; + } +} + +// analog encoder initialization +void tmc4671_doEncoderInitializationMode3(uint16_t icID, uint8_t *initState, uint16_t initWaitTime, uint16_t *actualInitWaitTime, uint16_t startVoltage, + uint16_t *last_Phi_E_Selection, uint32_t *last_UQ_UD_EXT, int16_t *last_PHI_E_EXT) +{ + switch (*initState) + { + case STATE_NOTHING_TO_DO: + *actualInitWaitTime = 0; + break; + case STATE_START_INIT: // started by writing 1 to initState + + // save actual set values for PHI_E_SELECTION, UQ_UD_EXT, and PHI_E_EXT + *last_Phi_E_Selection = (uint16_t)tmc4671_fieldRead(icID, TMC4671_PHI_E_SELECTION_FIELD); + *last_UQ_UD_EXT = (uint32_t)tmc4671_readRegister(icID, TMC4671_UQ_UD_EXT); + *last_PHI_E_EXT = (int16_t)tmc4671_fieldRead(icID, TMC4671_PHI_E_EXT_FIELD); + + // switch motion mode for running motor in open loop + tmc4671_writeRegister(icID, TMC4671_MODE_RAMP_MODE_MOTION, TMC4671_MOTION_MODE_UQ_UD_EXT); + + // set AENC_DECODER_PHI_E_PHI_M_OFFSET and AENC_DECODER_PHI_A_OFFSET to zero + tmc4671_writeRegister(icID, TMC4671_AENC_DECODER_PHI_E_PHI_M_OFFSET, 0); + tmc4671_fieldWrite(icID, TMC4671_AENC_DECODER_PHI_A_OFFSET_FIELD, 0); + + // select phi_e_ext + tmc4671_fieldWrite(icID, TMC4671_PHI_E_SELECTION_FIELD, 1); + + // set an initialization voltage on UD_EXT (to the flux, not the torque!) + tmc4671_fieldWrite(icID, TMC4671_UQ_EXT_FIELD, 0); + tmc4671_fieldWrite(icID, TMC4671_UD_EXT_FIELD, startVoltage); + + // set the "zero" angle + tmc4671_fieldWrite(icID, TMC4671_PHI_E_EXT_FIELD, 0); + + *initState = STATE_WAIT_INIT_TIME; + break; + case STATE_WAIT_INIT_TIME: + // wait until initialization time is over (until no more vibration on the motor) + (*actualInitWaitTime)++; + if(*actualInitWaitTime >= initWaitTime) + { + // save actual DECODER_PHI_M as -DECODER_PHI_M_OFFSET + int16_t offset_raw = tmc4671_fieldRead(icID, TMC4671_AENC_DECODER_PHI_M_FIELD); + + // update PHI_M and keep PHI_E and PH_A at zero + tmc4671_fieldWrite(icID, TMC4671_AENC_DECODER_PHI_E_OFFSET_FIELD, 0); + + tmc4671_fieldWrite(icID, TMC4671_AENC_DECODER_PHI_M_OFFSET_FIELD, -offset_raw); + tmc4671_fieldWrite(icID, TMC4671_AENC_DECODER_PHI_A_OFFSET_FIELD, 0); + + // switch back to last used UQ_UD_EXT setting + tmc4671_writeRegister(icID, TMC4671_UQ_UD_EXT, *last_UQ_UD_EXT); + + // set PHI_E_EXT back to last value + tmc4671_fieldWrite(icID, TMC4671_PHI_E_EXT_FIELD, *last_PHI_E_EXT); + + // switch back to last used PHI_E_SELECTION setting + tmc4671_fieldWrite(icID, TMC4671_PHI_E_SELECTION_FIELD, *last_Phi_E_Selection); + + // go to next state + *initState = STATE_ESTIMATE_OFFSET; + } + break; + case STATE_ESTIMATE_OFFSET: + // you can do offset estimation here (wait for N-Channel if available and save encoder value) + + // go to ready state + *initState = 0; + break; + default: + *initState = 0; + break; + } +} + +void tmc4671_checkEncderInitialization(uint16_t icID, uint32_t actualSystick, uint8_t initMode, uint8_t *initState, uint16_t initWaitTime, uint16_t *actualInitWaitTime, uint16_t startVoltage, + int16_t *hall_phi_e_old, int16_t *hall_phi_e_new, int16_t *hall_actual_coarse_offset, + uint16_t *last_Phi_E_Selection, uint32_t *last_UQ_UD_EXT, int16_t *last_PHI_E_EXT) +{ + // use the systick as 1ms timer for encoder initialization + static uint32_t lastSystick = 0; + if(actualSystick != lastSystick) + { + // needs timer to use the wait time + if(initMode == 0) + { + tmc4671_doEncoderInitializationMode0(icID, initState, initWaitTime, actualInitWaitTime, startVoltage, last_Phi_E_Selection, last_UQ_UD_EXT, last_PHI_E_EXT); + } + else if (initMode == 3) // analog encoder initialization + { + tmc4671_doEncoderInitializationMode3(icID, initState, initWaitTime, actualInitWaitTime, startVoltage, last_Phi_E_Selection, last_UQ_UD_EXT, last_PHI_E_EXT); + } + lastSystick = actualSystick; + } + + // needs no timer + if(initMode == 2) + { + tmc4671_doEncoderInitializationMode2(icID, initState, actualInitWaitTime, hall_phi_e_old, hall_phi_e_new, hall_actual_coarse_offset, last_Phi_E_Selection); + } +} + +void tmc4671_periodicJob(uint16_t icID, uint32_t actualSystick, uint8_t initMode, uint8_t *initState, uint16_t initWaitTime, uint16_t *actualInitWaitTime, uint16_t startVoltage, + int16_t *hall_phi_e_old, int16_t *hall_phi_e_new, int16_t *hall_actual_coarse_offset, + uint16_t *last_Phi_E_Selection, uint32_t *last_UQ_UD_EXT, int16_t *last_PHI_E_EXT) +{ + tmc4671_checkEncderInitialization(icID, actualSystick, initMode, initState, initWaitTime, actualInitWaitTime, startVoltage, + hall_phi_e_old, hall_phi_e_new, hall_actual_coarse_offset, last_Phi_E_Selection, last_UQ_UD_EXT, last_PHI_E_EXT); +} + +void tmc4671_startEncoderInitialization(uint8_t mode, uint8_t *initMode, uint8_t *initState) +{ + // allow only a new initialization if no actual initialization is running + if(*initState == STATE_NOTHING_TO_DO) + { + if(mode == 0) // estimate offset + { + // set mode + *initMode = 0; + + // start initialization + *initState = 1; + } + else if(mode == 2) // use hall sensor signals + { + // set mode + *initMode = 2; + + // start initialization + *initState = 1; + } + else if (mode == 3) // use analog encoder initialization + { + // set mode + *initMode = 3; + + // start initialization + *initState = 1; + } + } +} + +int32_t tmc4671_readFieldWithDependency(uint16_t icID, RegisterField field, uint8_t dependsReg, uint32_t dependsValue) +{ + // remember old depends value + uint32_t lastDependsValue = tmc4671_readRegister(icID, dependsReg); + + // set needed depends value + tmc4671_writeRegister(icID, dependsReg, dependsValue); + uint32_t value = tmc4671_fieldRead(icID, field); + + // set old depends value + tmc4671_writeRegister(icID, dependsReg, lastDependsValue); + return value; +} diff --git a/firmware/lib/tmc/ic/TMC4671/TMC4671.h b/firmware/lib/tmc/ic/TMC4671/TMC4671.h new file mode 100755 index 0000000..673f893 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC4671/TMC4671.h @@ -0,0 +1,116 @@ +/******************************************************************************* +* Copyright © 2016 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + +#ifndef TMC_IC_TMC4671_H_ +#define TMC_IC_TMC4671_H_ + +#include +#include +#include +#include "TMC4671_HW_Abstraction.h" + +int32_t tmc4671_readRegister(uint16_t icID, uint8_t address); +void tmc4671_writeRegister(uint16_t icID, uint8_t address, int32_t value); + +typedef struct +{ + uint32_t mask; + uint8_t shift; + uint8_t address; + bool isSigned; +} RegisterField; + +static inline uint32_t tmc4671_fieldExtract(uint32_t data, RegisterField field) +{ + uint32_t value = (data & field.mask) >> field.shift; + + if (field.isSigned) + { + // Apply signedness conversion + uint32_t baseMask = field.mask >> field.shift; + uint32_t signMask = baseMask & (~baseMask >> 1); + value = (value ^ signMask) - signMask; + } + + return value; +} + +static inline uint32_t tmc4671_fieldRead(uint16_t icID, RegisterField field) +{ + uint32_t value = tmc4671_readRegister(icID, field.address); + + return tmc4671_fieldExtract(value, field); +} + +static inline uint32_t tmc4671_fieldUpdate(uint32_t data, RegisterField field, uint32_t value) +{ + return (data & (~field.mask)) | ((value << field.shift) & field.mask); +} + +static inline void tmc4671_fieldWrite(uint16_t icID, RegisterField field, uint32_t value) +{ + uint32_t regValue = tmc4671_readRegister(icID, field.address); + + regValue = tmc4671_fieldUpdate(regValue, field, value); + + tmc4671_writeRegister(icID, field.address, regValue); +} + +// Do cyclic tasks +void tmc4671_periodicJob(uint16_t icID, uint32_t actualSystick, uint8_t initMode, uint8_t *initState, uint16_t initWaitTime, uint16_t *actualInitWaitTime, uint16_t startVoltage, + int16_t *hall_phi_e_old, int16_t *hall_phi_e_new, int16_t *hall_actual_coarse_offset, + uint16_t *last_Phi_E_Selection, uint32_t *last_UQ_UD_EXT, int16_t *last_PHI_E_EXT); + +// Encoder initialization functions +void tmc4671_startEncoderInitialization(uint8_t mode, uint8_t *initMode, uint8_t *initState); + +// Modes of operation +void tmc4671_switchToMotionMode(uint16_t icID, uint8_t mode); + +// Torque mode +void tmc4671_setTargetTorque_raw(uint16_t icID, int32_t targetTorque); +int32_t tmc4671_getTargetTorque_raw(uint16_t icID); +int32_t tmc4671_getActualTorque_raw(uint16_t icID); + +// Torque mode real world unit scaling +void tmc4671_setTargetTorque_mA(uint16_t icID, uint16_t torqueMeasurementFactor, int32_t targetTorque); +int32_t tmc4671_getTargetTorque_mA(uint16_t icID, uint16_t torqueMeasurementFactor); +int32_t tmc4671_getActualTorque_mA(uint16_t icID, uint16_t torqueMeasurementFactor); +int32_t tmc4671_getTargetTorqueFluxSum_mA(uint16_t icID, uint16_t torqueMeasurementFactor); +int32_t tmc4671_getActualTorqueFluxSum_mA(uint16_t icID, uint16_t torqueMeasurementFactor); + +// Flux +void tmc4671_setTargetFlux_raw(uint16_t icID, int32_t targetFlux); +int32_t tmc4671_getTargetFlux_raw(uint16_t icID); +int32_t tmc4671_getActualFlux_raw(uint16_t icID); + +// Flux regulation real world unit scaling +void tmc4671_setTargetFlux_mA(uint16_t icID, uint16_t torqueMeasurementFactor, int32_t targetFlux); +int32_t tmc4671_getTargetFlux_mA(uint16_t icID, uint16_t torqueMeasurementFactor); +int32_t tmc4671_getActualFlux_mA(uint16_t icID, uint16_t torqueMeasurementFactor); + +// Torque/flux limit in real world units +void tmc4671_setTorqueFluxLimit_mA(uint16_t icID, uint16_t torqueMeasurementFactor, int32_t max); +int32_t tmc4671_getTorqueFluxLimit_mA(uint16_t icID, uint16_t torqueMeasurementFactor); + +// Velocity mode +void tmc4671_setTargetVelocity(uint16_t icID, int32_t targetVelocity); +int32_t tmc4671_getTargetVelocity(uint16_t icID); +int32_t tmc4671_getActualVelocity(uint16_t icID); + +// Position mode +void tmc4671_setAbsolutTargetPosition(uint16_t icID, int32_t targetPosition); +void tmc4671_setRelativeTargetPosition(uint16_t icID, int32_t relativePosition); +int32_t tmc4671_getTargetPosition(uint16_t icID); +void tmc4671_setActualPosition(uint16_t icID, int32_t actualPosition); +int32_t tmc4671_getActualPosition(uint16_t icID); + +// Access for register with dependency register +int32_t tmc4671_readFieldWithDependency(uint16_t icID, RegisterField field, uint8_t dependsReg, uint32_t dependsValue); + +#endif /* TMC_IC_TMC4671_H_ */ diff --git a/firmware/lib/tmc/ic/TMC4671/TMC4671_HW_Abstraction.h b/firmware/lib/tmc/ic/TMC4671/TMC4671_HW_Abstraction.h new file mode 100755 index 0000000..1c6626f --- /dev/null +++ b/firmware/lib/tmc/ic/TMC4671/TMC4671_HW_Abstraction.h @@ -0,0 +1,1453 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + +#ifndef TMC4671_HW_ABSTRACTION_H_ +#define TMC4671_HW_ABSTRACTION_H_ + +// Register set + +#define TMC4671_CHIPINFO_DATA 0x00 +#define TMC4671_CHIPINFO_ADDR 0x01 + +#define TMC4671_ADC_RAW_DATA 0x02 +#define TMC4671_ADC_RAW_ADDR 0x03 + +#define TMC4671_DSADC_MCFG_B_MCFG_A 0x04 +#define TMC4671_DSADC_MCLK_A 0x05 +#define TMC4671_DSADC_MCLK_B 0x06 +#define TMC4671_DSADC_MDEC_B_MDEC_A 0x07 + +#define TMC4671_ADC_I1_SCALE_OFFSET 0x08 +#define TMC4671_ADC_I0_SCALE_OFFSET 0x09 +#define TMC4671_ADC_I_SELECT 0x0A +#define TMC4671_ADC_I1_I0_EXT 0x0B + +#define TMC4671_DS_ANALOG_INPUT_STAGE_CFG 0x0C + +#define TMC4671_AENC_0_SCALE_OFFSET 0x0D +#define TMC4671_AENC_1_SCALE_OFFSET 0x0E +#define TMC4671_AENC_2_SCALE_OFFSET 0x0F +#define TMC4671_AENC_SELECT 0x11 + +#define TMC4671_ADC_IWY_IUX 0x12 +#define TMC4671_ADC_IV 0x13 +#define TMC4671_AENC_WY_UX 0x15 +#define TMC4671_AENC_VN 0x16 + +#define TMC4671_PWM_POLARITIES 0x17 +#define TMC4671_PWM_MAXCNT 0x18 +#define TMC4671_PWM_BBM_H_BBM_L 0x19 +#define TMC4671_PWM_SV_CHOP 0x1A + +#define TMC4671_MOTOR_TYPE_N_POLE_PAIRS 0x1B + +#define TMC4671_PHI_E_EXT 0x1C +#define TMC4671_PHI_M_EXT 0x1D +#define TMC4671_POSITION_EXT 0x1E + +#define TMC4671_OPENLOOP_MODE 0x1F +#define TMC4671_OPENLOOP_ACCELERATION 0x20 +#define TMC4671_OPENLOOP_VELOCITY_TARGET 0x21 +#define TMC4671_OPENLOOP_VELOCITY_ACTUAL 0x22 +#define TMC4671_OPENLOOP_PHI 0x23 +#define TMC4671_UQ_UD_EXT 0x24 + +#define TMC4671_ABN_DECODER_MODE 0x25 +#define TMC4671_ABN_DECODER_PPR 0x26 +#define TMC4671_ABN_DECODER_COUNT 0x27 +#define TMC4671_ABN_DECODER_COUNT_N 0x28 +#define TMC4671_ABN_DECODER_PHI_E_PHI_M_OFFSET 0x29 +#define TMC4671_ABN_DECODER_PHI_E_PHI_M 0x2A + +#define TMC4671_ABN_2_DECODER_MODE 0x2C +#define TMC4671_ABN_2_DECODER_PPR 0x2D +#define TMC4671_ABN_2_DECODER_COUNT 0x2E +#define TMC4671_ABN_2_DECODER_COUNT_N 0x2F +#define TMC4671_ABN_2_DECODER_PHI_M_OFFSET 0x30 +#define TMC4671_ABN_2_DECODER_PHI_M 0x31 + +#define TMC4671_HALL_MODE 0x33 +#define TMC4671_HALL_POSITION_060_000 0x34 +#define TMC4671_HALL_POSITION_180_120 0x35 +#define TMC4671_HALL_POSITION_300_240 0x36 +#define TMC4671_HALL_PHI_E_PHI_M_OFFSET 0x37 +#define TMC4671_HALL_DPHI_MAX 0x38 +#define TMC4671_HALL_PHI_E_INTERPOLATED_PHI_E 0x39 +#define TMC4671_HALL_PHI_M 0x3A + +#define TMC4671_AENC_DECODER_MODE 0x3B +#define TMC4671_AENC_DECODER_N_THRESHOLD 0x3C +#define TMC4671_AENC_DECODER_PHI_A_RAW 0x3D +#define TMC4671_AENC_DECODER_PHI_A_OFFSET 0x3E +#define TMC4671_AENC_DECODER_PHI_A 0x3F + +#define TMC4671_AENC_DECODER_PPR 0x40 +#define TMC4671_AENC_DECODER_COUNT 0x41 +#define TMC4671_AENC_DECODER_COUNT_N 0x42 +#define TMC4671_AENC_DECODER_PHI_E_PHI_M_OFFSET 0x45 +#define TMC4671_AENC_DECODER_PHI_E_PHI_M 0x46 +#define TMC4671_AENC_DECODER_POSITION 0x47 + +#define TMC4671_CONFIG_DATA 0x4D +#define TMC4671_CONFIG_ADDR 0x4E + +#define TMC4671_VELOCITY_SELECTION 0x50 +#define TMC4671_POSITION_SELECTION 0x51 +#define TMC4671_PHI_E_SELECTION 0x52 +#define TMC4671_PHI_E 0x53 + +#define TMC4671_PID_FLUX_P_FLUX_I 0x54 +#define TMC4671_PID_TORQUE_P_TORQUE_I 0x56 +#define TMC4671_PID_VELOCITY_P_VELOCITY_I 0x58 +#define TMC4671_PID_POSITION_P_POSITION_I 0x5A +#define TMC4671_PID_TORQUE_FLUX_TARGET_DDT_LIMITS 0x5C +#define TMC4671_PIDOUT_UQ_UD_LIMITS 0x5D +#define TMC4671_PID_TORQUE_FLUX_LIMITS 0x5E +#define TMC4671_PID_VELOCITY_LIMIT 0x60 +#define TMC4671_PID_POSITION_LIMIT_LOW 0x61 +#define TMC4671_PID_POSITION_LIMIT_HIGH 0x62 + +#define TMC4671_MODE_RAMP_MODE_MOTION 0x63 +#define TMC4671_PID_TORQUE_FLUX_TARGET 0x64 +#define TMC4671_PID_TORQUE_FLUX_OFFSET 0x65 +#define TMC4671_PID_VELOCITY_TARGET 0x66 +#define TMC4671_PID_VELOCITY_OFFSET 0x67 +#define TMC4671_PID_POSITION_TARGET 0x68 + +#define TMC4671_PID_TORQUE_FLUX_ACTUAL 0x69 +#define TMC4671_PID_VELOCITY_ACTUAL 0x6A +#define TMC4671_PID_POSITION_ACTUAL 0x6B + +#define TMC4671_PID_ERROR_DATA 0x6C +#define TMC4671_PID_ERROR_ADDR 0x6D +#define TMC4671_INTERIM_DATA 0x6E +#define TMC4671_INTERIM_ADDR 0x6F + +#define TMC4671_WATCHDOG_CFG 0x74 +#define TMC4671_ADC_VM_LIMITS 0x75 +#define TMC4671_INPUTS_RAW 0x76 +#define TMC4671_OUTPUTS_RAW 0x77 + +#define TMC4671_STEP_WIDTH 0x78 +#define TMC4671_UART_BPS 0x79 +#define TMC4671_UART_ADDRS 0x7A +#define TMC4671_GPIO_DSADCI_CONFIG 0x7B + +#define TMC4671_STATUS_FLAGS 0x7C +#define TMC4671_STATUS_MASK 0x7D + +// Register variants +#define CHIPINFO_ADDR_SI_TYPE 0 +#define CHIPINFO_ADDR_SI_VERSION 1 +#define CHIPINFO_ADDR_SI_DATA 2 +#define CHIPINFO_ADDR_SI_TIME 3 +#define CHIPINFO_ADDR_SI_VARIANT 4 +#define CHIPINFO_ADDR_SI_BUILD 5 + +#define ADC_RAW_ADDR_ADC_I1_RAW_ADC_I0_RAW 0 +#define ADC_RAW_ADDR_ADC_AGPI_A_RAW_ADC_VM_RAW 1 +#define ADC_RAW_ADDR_ADC_AENC_UX_RAW_ADC_AGPI_B_RAW 2 +#define ADC_RAW_ADDR_ADC_AENC_WY_RAW_ADC_AENC_VN_RAW 3 + +#define CONFIG_ADDR_BIQUAD_X_A_1 1 +#define CONFIG_ADDR_BIQUAD_X_A_2 2 +#define CONFIG_ADDR_BIQUAD_X_B_0 4 +#define CONFIG_ADDR_BIQUAD_X_B_1 5 +#define CONFIG_ADDR_BIQUAD_X_B_2 6 +#define CONFIG_ADDR_BIQUAD_X_ENABLE 7 +#define CONFIG_ADDR_BIQUAD_V_A_1 9 +#define CONFIG_ADDR_BIQUAD_V_A_2 10 +#define CONFIG_ADDR_BIQUAD_V_B_0 12 +#define CONFIG_ADDR_BIQUAD_V_B_1 13 +#define CONFIG_ADDR_BIQUAD_V_B_2 14 +#define CONFIG_ADDR_BIQUAD_V_ENABLE 15 +#define CONFIG_ADDR_BIQUAD_T_A_1 17 +#define CONFIG_ADDR_BIQUAD_T_A_2 18 +#define CONFIG_ADDR_BIQUAD_T_B_0 20 +#define CONFIG_ADDR_BIQUAD_T_B_1 21 +#define CONFIG_ADDR_BIQUAD_T_B_2 22 +#define CONFIG_ADDR_BIQUAD_T_ENABLE 23 +#define CONFIG_ADDR_BIQUAD_F_A_1 25 +#define CONFIG_ADDR_BIQUAD_F_A_2 26 +#define CONFIG_ADDR_BIQUAD_F_B_0 28 +#define CONFIG_ADDR_BIQUAD_F_B_1 29 +#define CONFIG_ADDR_BIQUAD_F_B_2 30 +#define CONFIG_ADDR_BIQUAD_F_ENABLE 31 +#define CONFIG_ADDR_PRBS_AMPLITUDE 32 +#define CONFIG_ADDR_PRBS_DOWN_SAMPLING_RATIO 33 +#define CONFIG_ADDR_FEED_FORWARD_VELOCITY_GAIN 40 +#define CONFIG_ADDR_FEED_FORWARD_VELOCITY_FILTER_CONSTANT 41 +#define CONFIG_ADDR_FEED_FORWARD_TORQUE_GAIN 42 +#define CONFIG_ADDR_FEED_FORWARD_TORQUE_FILTER_CONSTANT 43 +#define CONFIG_ADDR_VELOCITY_METER_PPTM_MIN_POS_DEV 50 +#define CONFIG_ADDR_REF_SWITCH_CONFIG 51 +#define CONFIG_ADDR_ENCODER_INIT_HALL_ENABLE 52 +#define CONFIG_ADDR_SINGLE_PIN_IF_STATUS_CFG 60 +#define CONFIG_ADDR_SINGLE_PIN_IF_SCALE_OFFSET 61 + +#define PID_ERROR_ADDR_PID_TORQUE_ERROR 0 +#define PID_ERROR_ADDR_PID_FLUX_ERROR 1 +#define PID_ERROR_ADDR_PID_VELOCITY_ERROR 2 +#define PID_ERROR_ADDR_PID_POSITION_ERROR 3 +#define PID_ERROR_ADDR_PID_TORQUE_ERROR_SUM 4 +#define PID_ERROR_ADDR_PID_FLUX_ERROR_SUM 5 +#define PID_ERROR_ADDR_PID_VELOCITY_ERROR_SUM 6 +#define PID_ERROR_ADDR_PID_POSITION_ERROR_SUM 7 + +#define INTERIM_ADDR_PIDIN_TARGET_TORQUE 0 +#define INTERIM_ADDR_PIDIN_TARGET_FLUX 1 +#define INTERIM_ADDR_PIDIN_TARGET_VELOCITY 2 +#define INTERIM_ADDR_PIDIN_TARGET_POSITION 3 +#define INTERIM_ADDR_PIDOUT_TARGET_TORQUE 4 +#define INTERIM_ADDR_PIDOUT_TARGET_FLUX 5 +#define INTERIM_ADDR_PIDOUT_TARGET_VELOCITY 6 +#define INTERIM_ADDR_PIDOUT_TARGET_POSITION 7 +#define INTERIM_ADDR_FOC_IWY_IUX 8 +#define INTERIM_ADDR_FOC_IV 9 +#define INTERIM_ADDR_FOC_IB_IA 10 +#define INTERIM_ADDR_FOC_IQ_ID 11 +#define INTERIM_ADDR_FOC_UQ_UD 12 +#define INTERIM_ADDR_FOC_UQ_UD_LIMITED 13 +#define INTERIM_ADDR_FOC_UB_UA 14 +#define INTERIM_ADDR_FOC_UWY_UUX 15 +#define INTERIM_ADDR_FOC_UV 16 +#define INTERIM_ADDR_PWM_WY_UX 17 +#define INTERIM_ADDR_PWM_UV 18 +#define INTERIM_ADDR_ADC_I1_I0 19 +#define INTERIM_ADDR_PID_TORQUE_TARGET_FLUX_TARGET_TORQUE_ACTUAL_FLUX_ACTUAL_DIV256 20 +#define INTERIM_ADDR_PID_TORQUE_TARGET_TORQUE_ACTUAL 21 +#define INTERIM_ADDR_PID_FLUX_TARGET_FLUX_ACTUAL 22 +#define INTERIM_ADDR_PID_VELOCITY_TARGET_VELOCITY_ACTUAL_DIV256 23 +#define INTERIM_ADDR_PID_VELOCITY_TARGET_VELOCITY_ACTUAL 24 +#define INTERIM_ADDR_PID_POSITION_TARGET_POSITION_ACTUAL_DIV256 25 +#define INTERIM_ADDR_PID_POSITION_TARGET_POSITION_ACTUAL 26 +#define INTERIM_ADDR_FF_VELOCITY 27 +#define INTERIM_ADDR_FF_TORQUE 28 +#define INTERIM_ADDR_ACTUAL_VELOCITY_PPTM 29 +#define INTERIM_ADDR_REF_SWITCH_STATUS 30 +#define INTERIM_ADDR_HOME_POSITION 31 +#define INTERIM_ADDR_LEFT_POSITION 32 +#define INTERIM_ADDR_RIGHT_POSITION 33 +#define INTERIM_ADDR_ENC_INIT_HALL_STATUS 34 +#define INTERIM_ADDR_ENC_INIT_HALL_PHI_E_ABN_OFFSET 35 +#define INTERIM_ADDR_ENC_INIT_HALL_PHI_E_AENC_OFFSET 36 +#define INTERIM_ADDR_ENC_INIT_HALL_PHI_A_AENC_OFFSET 37 +#define INTERIM_ADDR_enc_init_mini_move_u_d_status 40 +#define INTERIM_ADDR_enc_init_mini_move_phi_e_phi_e_offset 41 +#define INTERIM_ADDR_SINGLE_PIN_IF_PWM_DUTY_CYCLE_TORQUE_TARGET 42 +#define INTERIM_ADDR_SINGLE_PIN_IF_VELOCITY_TARGET 43 +#define INTERIM_ADDR_SINGLE_PIN_IF_POSITION_TARGET 44 +#define INTERIM_ADDR_DEBUG_VALUE_1_0 192 +#define INTERIM_ADDR_DEBUG_VALUE_3_2 193 +#define INTERIM_ADDR_DEBUG_VALUE_5_4 194 +#define INTERIM_ADDR_DEBUG_VALUE_7_6 195 +#define INTERIM_ADDR_DEBUG_VALUE_9_8 196 +#define INTERIM_ADDR_DEBUG_VALUE_11_10 197 +#define INTERIM_ADDR_DEBUG_VALUE_13_12 198 +#define INTERIM_ADDR_DEBUG_VALUE_15_14 199 +#define INTERIM_ADDR_DEBUG_VALUE_16 200 +#define INTERIM_ADDR_DEBUG_VALUE_17 201 +#define INTERIM_ADDR_DEBUG_VALUE_18 202 +#define INTERIM_ADDR_DEBUG_VALUE_19 203 +#define INTERIM_ADDR_CONFIG_REG_0 208 +#define INTERIM_ADDR_CONFIG_REG_1 209 +#define INTERIM_ADDR_CTRL_PARAM_10 210 +#define INTERIM_ADDR_CTRL_PARAM_32 211 +#define INTERIM_ADDR_STATUS_REG_0 212 +#define INTERIM_ADDR_STATUS_REG_1 213 +#define INTERIM_ADDR_STATUS_PARAM_10 214 +#define INTERIM_ADDR_STATUS_PARAM_32 215 + +// Motor types +#define TMC4671_NO_MOTOR 0 +#define TMC4671_SINGLE_PHASE_DC 1 +#define TMC4671_TWO_PHASE_STEPPER 2 +#define TMC4671_THREE_PHASE_BLDC 3 + +// Motion modes +#define TMC4671_MOTION_MODE_STOPPED 0 +#define TMC4671_MOTION_MODE_TORQUE 1 +#define TMC4671_MOTION_MODE_VELOCITY 2 +#define TMC4671_MOTION_MODE_POSITION 3 +#define TMC4671_MOTION_MODE_PRBS_FLUX 4 +#define TMC4671_MOTION_MODE_PRBS_TORQUE 5 +#define TMC4671_MOTION_MODE_PRBS_VELOCITY 6 +#define TMC4671_MOTION_MODE_PRBS_POSITION 7 +#define TMC4671_MOTION_MODE_UQ_UD_EXT 8 + +// PHI_E selection +#define TMC4671_PHI_E_EXTERNAL 1 +#define TMC4671_PHI_E_OPEN_LOOP 2 +#define TMC4671_PHI_E_ABN 3 +#define TMC4671_PHI_E_HALL 5 +#define TMC4671_PHI_E_AENC 6 +#define TMC4671_PHI_A_AENC 7 + +// Velocity selection +#define TMC4671_VELOCITY_PHI_E_SELECTION 0 +#define TMC4671_VELOCITY_PHI_E_EXT 1 +#define TMC4671_VELOCITY_PHI_E_OPENLOOP 2 +#define TMC4671_VELOCITY_PHI_E_ABN 3 + +#define TMC4671_VELOCITY_PHI_E_HAL 5 +#define TMC4671_VELOCITY_PHI_E_AENC 6 +#define TMC4671_VELOCITY_PHI_A_AENC 7 + +#define TMC4671_VELOCITY_PHI_M_ABN 9 +#define TMC4671_VELOCITY_PHI_M_ABN_2 10 +#define TMC4671_VELOCITY_PHI_M_AENC 11 +#define TMC4671_VELOCITY_PHI_M_HAL 12 + +// Position selection +#define TMC4671_POSITION_PHI_E_SELECTION 0 +#define TMC4671_POSITION_PHI_E_EXT 1 +#define TMC4671_POSITION_PHI_E_OPENLOOP 2 +#define TMC4671_POSITION_PHI_E_ABN 3 + +#define TMC4671_POSITION_PHI_E_HAL 5 +#define TMC4671_POSITION_PHI_E_AENC 6 +#define TMC4671_POSITION_PHI_A_AENC 7 + +#define TMC4671_POSITION_PHI_M_ABN 9 +#define TMC4671_POSITION_PHI_M_ABN_2 10 +#define TMC4671_POSITION_PHI_M_AENC 11 +#define TMC4671_POSITION_PHI_M_HAL 12 + +// Other constants +#define TMC4671_MOTORS 1 + +// Register fields +#define TMC4671_SI_TYPE_MASK 0xFFFFFFFF +#define TMC4671_SI_TYPE_SHIFT 0 +#define TMC4671_SI_TYPE_FIELD ((RegisterField) {TMC4671_SI_TYPE_MASK, TMC4671_SI_TYPE_SHIFT, TMC4671_CHIPINFO_DATA, false}) +#define TMC4671_SI_VERSION_MASK 0xFFFFFFFF +#define TMC4671_SI_VERSION_SHIFT 0 +#define TMC4671_SI_VERSION_FIELD ((RegisterField) {TMC4671_SI_VERSION_MASK, TMC4671_SI_VERSION_SHIFT, TMC4671_CHIPINFO_DATA, false}) +#define TMC4671_SI_DATE_MASK 0xFFFFFFFF +#define TMC4671_SI_DATE_SHIFT 0 +#define TMC4671_SI_DATE_FIELD ((RegisterField) {TMC4671_SI_DATE_MASK, TMC4671_SI_DATE_SHIFT, TMC4671_CHIPINFO_DATA, false}) +#define TMC4671_SI_TIME_MASK 0xFFFFFFFF +#define TMC4671_SI_TIME_SHIFT 0 +#define TMC4671_SI_TIME_FIELD ((RegisterField) {TMC4671_SI_TIME_MASK, TMC4671_SI_TIME_SHIFT, TMC4671_CHIPINFO_DATA, false}) +#define TMC4671_SI_VARIANT_MASK 0xFFFFFFFF +#define TMC4671_SI_VARIANT_SHIFT 0 +#define TMC4671_SI_VARIANT_FIELD ((RegisterField) {TMC4671_SI_VARIANT_MASK, TMC4671_SI_VARIANT_SHIFT, TMC4671_CHIPINFO_DATA, false}) +#define TMC4671_SI_BUILD_MASK 0xFFFFFFFF +#define TMC4671_SI_BUILD_SHIFT 0 +#define TMC4671_SI_BUILD_FIELD ((RegisterField) {TMC4671_SI_BUILD_MASK, TMC4671_SI_BUILD_SHIFT, TMC4671_CHIPINFO_DATA, false}) +#define TMC4671_CHIP_INFO_ADDRESS_MASK 0x000000FF +#define TMC4671_CHIP_INFO_ADDRESS_SHIFT 0 +#define TMC4671_CHIP_INFO_ADDRESS_FIELD ((RegisterField) {TMC4671_CHIP_INFO_ADDRESS_MASK, TMC4671_CHIP_INFO_ADDRESS_SHIFT, TMC4671_CHIPINFO_ADDR, false}) + +#define TMC4671_ADC_I0_RAW_MASK 0x0000FFFF +#define TMC4671_ADC_I0_RAW_SHIFT 0 +#define TMC4671_ADC_I0_RAW_FIELD ((RegisterField) {TMC4671_ADC_I0_RAW_MASK, TMC4671_ADC_I0_RAW_SHIFT, TMC4671_ADC_RAW_DATA, false}) +#define TMC4671_ADC_I1_RAW_MASK 0xFFFF0000 +#define TMC4671_ADC_I1_RAW_SHIFT 16 +#define TMC4671_ADC_I1_RAW_FIELD ((RegisterField) {TMC4671_ADC_I1_RAW_MASK, TMC4671_ADC_I1_RAW_SHIFT, TMC4671_ADC_RAW_DATA, false}) +#define TMC4671_ADC_VM_RAW_MASK 0x0000FFFF +#define TMC4671_ADC_VM_RAW_SHIFT 0 +#define TMC4671_ADC_VM_RAW_FIELD ((RegisterField) {TMC4671_ADC_VM_RAW_MASK, TMC4671_ADC_VM_RAW_SHIFT, TMC4671_ADC_RAW_DATA, false}) +#define TMC4671_ADC_AGPI_A_RAW_MASK 0xFFFF0000 +#define TMC4671_ADC_AGPI_A_RAW_SHIFT 16 +#define TMC4671_ADC_AGPI_A_RAW_FIELD ((RegisterField) {TMC4671_ADC_AGPI_A_RAW_MASK, TMC4671_ADC_AGPI_A_RAW_SHIFT, TMC4671_ADC_RAW_DATA, false}) +#define TMC4671_ADC_AGPI_B_RAW_MASK 0x0000FFFF +#define TMC4671_ADC_AGPI_B_RAW_SHIFT 0 +#define TMC4671_ADC_AGPI_B_RAW_FIELD ((RegisterField) {TMC4671_ADC_AGPI_B_RAW_MASK, TMC4671_ADC_AGPI_B_RAW_SHIFT, TMC4671_ADC_RAW_DATA, false}) +#define TMC4671_ADC_AENC_UX_RAW_MASK 0xFFFF0000 +#define TMC4671_ADC_AENC_UX_RAW_SHIFT 16 +#define TMC4671_ADC_AENC_UX_RAW_FIELD ((RegisterField) {TMC4671_ADC_AENC_UX_RAW_MASK, TMC4671_ADC_AENC_UX_RAW_SHIFT, TMC4671_ADC_RAW_DATA, false}) +#define TMC4671_ADC_AENC_VN_RAW_MASK 0x0000FFFF +#define TMC4671_ADC_AENC_VN_RAW_SHIFT 0 +#define TMC4671_ADC_AENC_VN_RAW_FIELD ((RegisterField) {TMC4671_ADC_AENC_VN_RAW_MASK, TMC4671_ADC_AENC_VN_RAW_SHIFT, TMC4671_ADC_RAW_DATA, false}) +#define TMC4671_ADC_AENC_WY_RAW_MASK 0xFFFF0000 +#define TMC4671_ADC_AENC_WY_RAW_SHIFT 16 +#define TMC4671_ADC_AENC_WY_RAW_FIELD ((RegisterField) {TMC4671_ADC_AENC_WY_RAW_MASK, TMC4671_ADC_AENC_WY_RAW_SHIFT, TMC4671_ADC_RAW_DATA, false}) +#define TMC4671_ADC_RAW_ADDR_MASK 0x000000FF +#define TMC4671_ADC_RAW_ADDR_SHIFT 0 +#define TMC4671_ADC_RAW_ADDR_FIELD ((RegisterField) {TMC4671_ADC_RAW_ADDR_MASK, TMC4671_ADC_RAW_ADDR_SHIFT, TMC4671_ADC_RAW_ADDR, false}) + +#define TMC4671_CFG_DSMODULATOR_A_MASK 0x00000003 +#define TMC4671_CFG_DSMODULATOR_A_SHIFT 0 +#define TMC4671_CFG_DSMODULATOR_A_FIELD ((RegisterField) {TMC4671_CFG_DSMODULATOR_A_MASK, TMC4671_CFG_DSMODULATOR_A_SHIFT, TMC4671_dsADC_MCFG_B_MCFG_A, false}) +#define TMC4671_MCLK_POLARITY_A_MASK 0x00000004 +#define TMC4671_MCLK_POLARITY_A_SHIFT 2 +#define TMC4671_MCLK_POLARITY_A_FIELD ((RegisterField) {TMC4671_MCLK_POLARITY_A_MASK, TMC4671_MCLK_POLARITY_A_SHIFT, TMC4671_dsADC_MCFG_B_MCFG_A, false}) +#define TMC4671_MDAT_POLARITY_A_MASK 0x00000008 +#define TMC4671_MDAT_POLARITY_A_SHIFT 3 +#define TMC4671_MDAT_POLARITY_A_FIELD ((RegisterField) {TMC4671_MDAT_POLARITY_A_MASK, TMC4671_MDAT_POLARITY_A_SHIFT, TMC4671_dsADC_MCFG_B_MCFG_A, false}) +#define TMC4671_SEL_NCLK_MCLK_I_A_MASK 0x00000010 +#define TMC4671_SEL_NCLK_MCLK_I_A_SHIFT 4 +#define TMC4671_SEL_NCLK_MCLK_I_A_FIELD ((RegisterField) {TMC4671_SEL_NCLK_MCLK_I_A_MASK, TMC4671_SEL_NCLK_MCLK_I_A_SHIFT, TMC4671_dsADC_MCFG_B_MCFG_A, false}) +#define TMC4671_BLANKING_A_MASK 0x0000FF00 +#define TMC4671_BLANKING_A_SHIFT 8 +#define TMC4671_BLANKING_A_FIELD ((RegisterField) {TMC4671_BLANKING_A_MASK, TMC4671_BLANKING_A_SHIFT, TMC4671_dsADC_MCFG_B_MCFG_A, false}) +#define TMC4671_CFG_DSMODULATOR_B_MASK 0x00030000 +#define TMC4671_CFG_DSMODULATOR_B_SHIFT 16 +#define TMC4671_CFG_DSMODULATOR_B_FIELD ((RegisterField) {TMC4671_CFG_DSMODULATOR_B_MASK, TMC4671_CFG_DSMODULATOR_B_SHIFT, TMC4671_dsADC_MCFG_B_MCFG_A, false}) +#define TMC4671_MCLK_POLARITY_B_MASK 0x00040000 +#define TMC4671_MCLK_POLARITY_B_SHIFT 18 +#define TMC4671_MCLK_POLARITY_B_FIELD ((RegisterField) {TMC4671_MCLK_POLARITY_B_MASK, TMC4671_MCLK_POLARITY_B_SHIFT, TMC4671_dsADC_MCFG_B_MCFG_A, false}) +#define TMC4671_MDAT_POLARITY_B_MASK 0x00080000 +#define TMC4671_MDAT_POLARITY_B_SHIFT 19 +#define TMC4671_MDAT_POLARITY_B_FIELD ((RegisterField) {TMC4671_MDAT_POLARITY_B_MASK, TMC4671_MDAT_POLARITY_B_SHIFT, TMC4671_dsADC_MCFG_B_MCFG_A, false}) +#define TMC4671_SEL_NCLK_MCLK_I_B_MASK 0x00100000 +#define TMC4671_SEL_NCLK_MCLK_I_B_SHIFT 20 +#define TMC4671_SEL_NCLK_MCLK_I_B_FIELD ((RegisterField) {TMC4671_SEL_NCLK_MCLK_I_B_MASK, TMC4671_SEL_NCLK_MCLK_I_B_SHIFT, TMC4671_dsADC_MCFG_B_MCFG_A, false}) +#define TMC4671_BLANKING_B_MASK 0xFF000000 +#define TMC4671_BLANKING_B_SHIFT 24 +#define TMC4671_BLANKING_B_FIELD ((RegisterField) {TMC4671_BLANKING_B_MASK, TMC4671_BLANKING_B_SHIFT, TMC4671_dsADC_MCFG_B_MCFG_A, false}) +#define TMC4671_DSADC_MCLK_A_MASK 0xFFFFFFFF +#define TMC4671_DSADC_MCLK_A_SHIFT 0 +#define TMC4671_DSADC_MCLK_A_FIELD ((RegisterField) {TMC4671_DSADC_MCLK_A_MASK, TMC4671_DSADC_MCLK_A_SHIFT, TMC4671_dsADC_MCLK_A, false}) +#define TMC4671_DSADC_MCLK_B_MASK 0xFFFFFFFF +#define TMC4671_DSADC_MCLK_B_SHIFT 0 +#define TMC4671_DSADC_MCLK_B_FIELD ((RegisterField) {TMC4671_DSADC_MCLK_B_MASK, TMC4671_DSADC_MCLK_B_SHIFT, TMC4671_dsADC_MCLK_B, false}) +#define TMC4671_DSADC_MDEC_A_MASK 0x0000FFFF +#define TMC4671_DSADC_MDEC_A_SHIFT 0 +#define TMC4671_DSADC_MDEC_A_FIELD ((RegisterField) {TMC4671_DSADC_MDEC_A_MASK, TMC4671_DSADC_MDEC_A_SHIFT, TMC4671_dsADC_MDEC_B_MDEC_A, false}) +#define TMC4671_DSADC_MDEC_B_MASK 0xFFFF0000 +#define TMC4671_DSADC_MDEC_B_SHIFT 16 +#define TMC4671_DSADC_MDEC_B_FIELD ((RegisterField) {TMC4671_DSADC_MDEC_B_MASK, TMC4671_DSADC_MDEC_B_SHIFT, TMC4671_dsADC_MDEC_B_MDEC_A, false}) + +#define TMC4671_ADC_I1_OFFSET_MASK 0x0000FFFF +#define TMC4671_ADC_I1_OFFSET_SHIFT 0 +#define TMC4671_ADC_I1_OFFSET_FIELD ((RegisterField) {TMC4671_ADC_I1_OFFSET_MASK, TMC4671_ADC_I1_OFFSET_SHIFT, TMC4671_ADC_I1_SCALE_OFFSET, false}) +#define TMC4671_ADC_I1_SCALE_MASK 0xFFFF0000 +#define TMC4671_ADC_I1_SCALE_SHIFT 16 +#define TMC4671_ADC_I1_SCALE_FIELD ((RegisterField) {TMC4671_ADC_I1_SCALE_MASK, TMC4671_ADC_I1_SCALE_SHIFT, TMC4671_ADC_I1_SCALE_OFFSET, true}) +#define TMC4671_ADC_I0_OFFSET_MASK 0x0000FFFF +#define TMC4671_ADC_I0_OFFSET_SHIFT 0 +#define TMC4671_ADC_I0_OFFSET_FIELD ((RegisterField) {TMC4671_ADC_I0_OFFSET_MASK, TMC4671_ADC_I0_OFFSET_SHIFT, TMC4671_ADC_I0_SCALE_OFFSET, false}) +#define TMC4671_ADC_I0_SCALE_MASK 0xFFFF0000 +#define TMC4671_ADC_I0_SCALE_SHIFT 16 +#define TMC4671_ADC_I0_SCALE_FIELD ((RegisterField) {TMC4671_ADC_I0_SCALE_MASK, TMC4671_ADC_I0_SCALE_SHIFT, TMC4671_ADC_I0_SCALE_OFFSET, true}) +#define TMC4671_ADC_I0_SELECT_MASK 0x000000FF +#define TMC4671_ADC_I0_SELECT_SHIFT 0 +#define TMC4671_ADC_I0_SELECT_FIELD ((RegisterField) {TMC4671_ADC_I0_SELECT_MASK, TMC4671_ADC_I0_SELECT_SHIFT, TMC4671_ADC_I_SELECT, false}) +#define TMC4671_ADC_I1_SELECT_MASK 0x0000FF00 +#define TMC4671_ADC_I1_SELECT_SHIFT 8 +#define TMC4671_ADC_I1_SELECT_FIELD ((RegisterField) {TMC4671_ADC_I1_SELECT_MASK, TMC4671_ADC_I1_SELECT_SHIFT, TMC4671_ADC_I_SELECT, false}) +#define TMC4671_ADC_I_UX_SELECT_MASK 0x03000000 +#define TMC4671_ADC_I_UX_SELECT_SHIFT 24 +#define TMC4671_ADC_I_UX_SELECT_FIELD ((RegisterField) {TMC4671_ADC_I_UX_SELECT_MASK, TMC4671_ADC_I_UX_SELECT_SHIFT, TMC4671_ADC_I_SELECT, false}) +#define TMC4671_ADC_I_V_SELECT_MASK 0x0C000000 +#define TMC4671_ADC_I_V_SELECT_SHIFT 26 +#define TMC4671_ADC_I_V_SELECT_FIELD ((RegisterField) {TMC4671_ADC_I_V_SELECT_MASK, TMC4671_ADC_I_V_SELECT_SHIFT, TMC4671_ADC_I_SELECT, false}) +#define TMC4671_ADC_I_WY_SELECT_MASK 0x30000000 +#define TMC4671_ADC_I_WY_SELECT_SHIFT 28 +#define TMC4671_ADC_I_WY_SELECT_FIELD ((RegisterField) {TMC4671_ADC_I_WY_SELECT_MASK, TMC4671_ADC_I_WY_SELECT_SHIFT, TMC4671_ADC_I_SELECT, false}) +#define TMC4671_ADC_I0_EXT_MASK 0x0000FFFF +#define TMC4671_ADC_I0_EXT_SHIFT 0 +#define TMC4671_ADC_I0_EXT_FIELD ((RegisterField) {TMC4671_ADC_I0_EXT_MASK, TMC4671_ADC_I0_EXT_SHIFT, TMC4671_ADC_I1_I0_EXT, false}) +#define TMC4671_ADC_I1_EXT_MASK 0xFFFF0000 +#define TMC4671_ADC_I1_EXT_SHIFT 16 +#define TMC4671_ADC_I1_EXT_FIELD ((RegisterField) {TMC4671_ADC_I1_EXT_MASK, TMC4671_ADC_I1_EXT_SHIFT, TMC4671_ADC_I1_I0_EXT, false}) +#define TMC4671_ADC_I0_MASK 0x0000000F +#define TMC4671_ADC_I0_SHIFT 0 +#define TMC4671_ADC_I0_FIELD ((RegisterField) {TMC4671_ADC_I0_MASK, TMC4671_ADC_I0_SHIFT, TMC4671_DS_ANALOG_INPUT_STAGE_CFG, false}) +#define TMC4671_ADC_I1_MASK 0x000000F0 +#define TMC4671_ADC_I1_SHIFT 4 +#define TMC4671_ADC_I1_FIELD ((RegisterField) {TMC4671_ADC_I1_MASK, TMC4671_ADC_I1_SHIFT, TMC4671_DS_ANALOG_INPUT_STAGE_CFG, false}) +#define TMC4671_ADC_VM_MASK 0x00000F00 +#define TMC4671_ADC_VM_SHIFT 8 +#define TMC4671_ADC_VM_FIELD ((RegisterField) {TMC4671_ADC_VM_MASK, TMC4671_ADC_VM_SHIFT, TMC4671_DS_ANALOG_INPUT_STAGE_CFG, false}) +#define TMC4671_ADC_AGPI_A_MASK 0x0000F000 +#define TMC4671_ADC_AGPI_A_SHIFT 12 +#define TMC4671_ADC_AGPI_A_FIELD ((RegisterField) {TMC4671_ADC_AGPI_A_MASK, TMC4671_ADC_AGPI_A_SHIFT, TMC4671_DS_ANALOG_INPUT_STAGE_CFG, false}) +#define TMC4671_ADC_AGPI_B_MASK 0x000F0000 +#define TMC4671_ADC_AGPI_B_SHIFT 16 +#define TMC4671_ADC_AGPI_B_FIELD ((RegisterField) {TMC4671_ADC_AGPI_B_MASK, TMC4671_ADC_AGPI_B_SHIFT, TMC4671_DS_ANALOG_INPUT_STAGE_CFG, false}) +#define TMC4671_ADC_AENC_UX_MASK 0x00F00000 +#define TMC4671_ADC_AENC_UX_SHIFT 20 +#define TMC4671_ADC_AENC_UX_FIELD ((RegisterField) {TMC4671_ADC_AENC_UX_MASK, TMC4671_ADC_AENC_UX_SHIFT, TMC4671_DS_ANALOG_INPUT_STAGE_CFG, false}) +#define TMC4671_ADC_AENC_VN_MASK 0x0F000000 +#define TMC4671_ADC_AENC_VN_SHIFT 24 +#define TMC4671_ADC_AENC_VN_FIELD ((RegisterField) {TMC4671_ADC_AENC_VN_MASK, TMC4671_ADC_AENC_VN_SHIFT, TMC4671_DS_ANALOG_INPUT_STAGE_CFG, false}) +#define TMC4671_ADC_AENC_WY_MASK 0xF0000000 +#define TMC4671_ADC_AENC_WY_SHIFT 28 +#define TMC4671_ADC_AENC_WY_FIELD ((RegisterField) {TMC4671_ADC_AENC_WY_MASK, TMC4671_ADC_AENC_WY_SHIFT, TMC4671_DS_ANALOG_INPUT_STAGE_CFG, false}) + +#define TMC4671_AENC_0_OFFSET_MASK 0x0000FFFF +#define TMC4671_AENC_0_OFFSET_SHIFT 0 +#define TMC4671_AENC_0_OFFSET_FIELD ((RegisterField) {TMC4671_AENC_0_OFFSET_MASK, TMC4671_AENC_0_OFFSET_SHIFT, TMC4671_AENC_0_SCALE_OFFSET, false}) +#define TMC4671_AENC_0_SCALE_MASK 0xFFFF0000 +#define TMC4671_AENC_0_SCALE_SHIFT 16 +#define TMC4671_AENC_0_SCALE_FIELD ((RegisterField) {TMC4671_AENC_0_SCALE_MASK, TMC4671_AENC_0_SCALE_SHIFT, TMC4671_AENC_0_SCALE_OFFSET, true}) +#define TMC4671_AENC_1_OFFSET_MASK 0x0000FFFF +#define TMC4671_AENC_1_OFFSET_SHIFT 0 +#define TMC4671_AENC_1_OFFSET_FIELD ((RegisterField) {TMC4671_AENC_1_OFFSET_MASK, TMC4671_AENC_1_OFFSET_SHIFT, TMC4671_AENC_1_SCALE_OFFSET, false}) +#define TMC4671_AENC_1_SCALE_MASK 0xFFFF0000 +#define TMC4671_AENC_1_SCALE_SHIFT 16 +#define TMC4671_AENC_1_SCALE_FIELD ((RegisterField) {TMC4671_AENC_1_SCALE_MASK, TMC4671_AENC_1_SCALE_SHIFT, TMC4671_AENC_1_SCALE_OFFSET, true}) +#define TMC4671_AENC_2_OFFSET_MASK 0x0000FFFF +#define TMC4671_AENC_2_OFFSET_SHIFT 0 +#define TMC4671_AENC_2_OFFSET_FIELD ((RegisterField) {TMC4671_AENC_2_OFFSET_MASK, TMC4671_AENC_2_OFFSET_SHIFT, TMC4671_AENC_2_SCALE_OFFSET, false}) +#define TMC4671_AENC_2_SCALE_MASK 0xFFFF0000 +#define TMC4671_AENC_2_SCALE_SHIFT 16 +#define TMC4671_AENC_2_SCALE_FIELD ((RegisterField) {TMC4671_AENC_2_SCALE_MASK, TMC4671_AENC_2_SCALE_SHIFT, TMC4671_AENC_2_SCALE_OFFSET, true}) +#define TMC4671_AENC_0_SELECT_MASK 0x000000FF +#define TMC4671_AENC_0_SELECT_SHIFT 0 +#define TMC4671_AENC_0_SELECT_FIELD ((RegisterField) {TMC4671_AENC_0_SELECT_MASK, TMC4671_AENC_0_SELECT_SHIFT, TMC4671_AENC_SELECT, false}) +#define TMC4671_AENC_1_SELECT_MASK 0x0000FF00 +#define TMC4671_AENC_1_SELECT_SHIFT 8 +#define TMC4671_AENC_1_SELECT_FIELD ((RegisterField) {TMC4671_AENC_1_SELECT_MASK, TMC4671_AENC_1_SELECT_SHIFT, TMC4671_AENC_SELECT, false}) +#define TMC4671_AENC_2_SELECT_MASK 0x00FF0000 +#define TMC4671_AENC_2_SELECT_SHIFT 16 +#define TMC4671_AENC_2_SELECT_FIELD ((RegisterField) {TMC4671_AENC_2_SELECT_MASK, TMC4671_AENC_2_SELECT_SHIFT, TMC4671_AENC_SELECT, false}) + +#define TMC4671_ADC_IUX_MASK 0x0000FFFF +#define TMC4671_ADC_IUX_SHIFT 0 +#define TMC4671_ADC_IUX_FIELD ((RegisterField) {TMC4671_ADC_IUX_MASK, TMC4671_ADC_IUX_SHIFT, TMC4671_ADC_IWY_IUX, true}) +#define TMC4671_ADC_IWY_MASK 0xFFFF0000 +#define TMC4671_ADC_IWY_SHIFT 16 +#define TMC4671_ADC_IWY_FIELD ((RegisterField) {TMC4671_ADC_IWY_MASK, TMC4671_ADC_IWY_SHIFT, TMC4671_ADC_IWY_IUX, true}) +#define TMC4671_ADC_IV_MASK 0x0000FFFF +#define TMC4671_ADC_IV_SHIFT 0 +#define TMC4671_ADC_IV_FIELD ((RegisterField) {TMC4671_ADC_IV_MASK, TMC4671_ADC_IV_SHIFT, TMC4671_ADC_IV, true}) +#define TMC4671_AENC_UX_MASK 0x0000FFFF +#define TMC4671_AENC_UX_SHIFT 0 +#define TMC4671_AENC_UX_FIELD ((RegisterField) {TMC4671_AENC_UX_MASK, TMC4671_AENC_UX_SHIFT, TMC4671_AENC_WY_UX, true}) +#define TMC4671_AENC_WY_MASK 0xFFFF0000 +#define TMC4671_AENC_WY_SHIFT 16 +#define TMC4671_AENC_WY_FIELD ((RegisterField) {TMC4671_AENC_WY_MASK, TMC4671_AENC_WY_SHIFT, TMC4671_AENC_WY_UX, true}) +#define TMC4671_AENC_VN_MASK 0x0000FFFF +#define TMC4671_AENC_VN_SHIFT 0 +#define TMC4671_AENC_VN_FIELD ((RegisterField) {TMC4671_AENC_VN_MASK, TMC4671_AENC_VN_SHIFT, TMC4671_AENC_VN, true}) + +#define TMC4671_PWM_POLARITIES_0_MASK 0x00000001 +#define TMC4671_PWM_POLARITIES_0_SHIFT 0 +#define TMC4671_PWM_POLARITIES_0_FIELD ((RegisterField) {TMC4671_PWM_POLARITIES_0_MASK, TMC4671_PWM_POLARITIES_0_SHIFT, TMC4671_PWM_POLARITIES, false}) +#define TMC4671_PWM_POLARITIES_1_MASK 0x00000002 +#define TMC4671_PWM_POLARITIES_1_SHIFT 1 +#define TMC4671_PWM_POLARITIES_1_FIELD ((RegisterField) {TMC4671_PWM_POLARITIES_1_MASK, TMC4671_PWM_POLARITIES_1_SHIFT, TMC4671_PWM_POLARITIES, false}) +#define TMC4671_PWM_MAXCNT_MASK 0x0000FFFF +#define TMC4671_PWM_MAXCNT_SHIFT 0 +#define TMC4671_PWM_MAXCNT_FIELD ((RegisterField) {TMC4671_PWM_MAXCNT_MASK, TMC4671_PWM_MAXCNT_SHIFT, TMC4671_PWM_MAXCNT, false}) +#define TMC4671_PWM_BBM_L_MASK 0x000000FF +#define TMC4671_PWM_BBM_L_SHIFT 0 +#define TMC4671_PWM_BBM_L_FIELD ((RegisterField) {TMC4671_PWM_BBM_L_MASK, TMC4671_PWM_BBM_L_SHIFT, TMC4671_PWM_BBM_H_BBM_L, false}) +#define TMC4671_PWM_BBM_H_MASK 0x0000FF00 +#define TMC4671_PWM_BBM_H_SHIFT 8 +#define TMC4671_PWM_BBM_H_FIELD ((RegisterField) {TMC4671_PWM_BBM_H_MASK, TMC4671_PWM_BBM_H_SHIFT, TMC4671_PWM_BBM_H_BBM_L, false}) +#define TMC4671_PWM_CHOP_MASK 0x000000FF +#define TMC4671_PWM_CHOP_SHIFT 0 +#define TMC4671_PWM_CHOP_FIELD ((RegisterField) {TMC4671_PWM_CHOP_MASK, TMC4671_PWM_CHOP_SHIFT, TMC4671_PWM_SV_CHOP, false}) +#define TMC4671_PWM_SV_MASK 0x00000100 +#define TMC4671_PWM_SV_SHIFT 8 +#define TMC4671_PWM_SV_FIELD ((RegisterField) {TMC4671_PWM_SV_MASK, TMC4671_PWM_SV_SHIFT, TMC4671_PWM_SV_CHOP, false}) + +#define TMC4671_N_POLE_PAIRS_MASK 0x0000FFFF +#define TMC4671_N_POLE_PAIRS_SHIFT 0 +#define TMC4671_N_POLE_PAIRS_FIELD ((RegisterField) {TMC4671_N_POLE_PAIRS_MASK, TMC4671_N_POLE_PAIRS_SHIFT, TMC4671_MOTOR_TYPE_N_POLE_PAIRS, false}) +#define TMC4671_MOTOR_TYPE_MASK 0x00FF0000 +#define TMC4671_MOTOR_TYPE_SHIFT 16 +#define TMC4671_MOTOR_TYPE_FIELD ((RegisterField) {TMC4671_MOTOR_TYPE_MASK, TMC4671_MOTOR_TYPE_SHIFT, TMC4671_MOTOR_TYPE_N_POLE_PAIRS, false}) + +#define TMC4671_PHI_E_EXT_MASK 0x0000FFFF +#define TMC4671_PHI_E_EXT_SHIFT 0 +#define TMC4671_PHI_E_EXT_FIELD ((RegisterField) {TMC4671_PHI_E_EXT_MASK, TMC4671_PHI_E_EXT_SHIFT, TMC4671_PHI_E_EXT, true}) + +#define TMC4671_OPENLOOP_PHI_DIRECTION_MASK 0x00001000 +#define TMC4671_OPENLOOP_PHI_DIRECTION_SHIFT 12 +#define TMC4671_OPENLOOP_PHI_DIRECTION_FIELD ((RegisterField) {TMC4671_OPENLOOP_PHI_DIRECTION_MASK, TMC4671_OPENLOOP_PHI_DIRECTION_SHIFT, TMC4671_OPENLOOP_MODE, false}) +#define TMC4671_OPENLOOP_ACCELERATION_MASK 0x000FFFFF +#define TMC4671_OPENLOOP_ACCELERATION_SHIFT 0 +#define TMC4671_OPENLOOP_ACCELERATION_FIELD ((RegisterField) {TMC4671_OPENLOOP_ACCELERATION_MASK, TMC4671_OPENLOOP_ACCELERATION_SHIFT, TMC4671_OPENLOOP_ACCELERATION, false}) +#define TMC4671_OPENLOOP_VELOCITY_TARGET_MASK 0xFFFFFFFF +#define TMC4671_OPENLOOP_VELOCITY_TARGET_SHIFT 0 +#define TMC4671_OPENLOOP_VELOCITY_TARGET_FIELD ((RegisterField) {TMC4671_OPENLOOP_VELOCITY_TARGET_MASK, TMC4671_OPENLOOP_VELOCITY_TARGET_SHIFT, TMC4671_OPENLOOP_VELOCITY_TARGET, true}) +#define TMC4671_OPENLOOP_VELOCITY_ACTUAL_MASK 0xFFFFFFFF +#define TMC4671_OPENLOOP_VELOCITY_ACTUAL_SHIFT 0 +#define TMC4671_OPENLOOP_VELOCITY_ACTUAL_FIELD ((RegisterField) {TMC4671_OPENLOOP_VELOCITY_ACTUAL_MASK, TMC4671_OPENLOOP_VELOCITY_ACTUAL_SHIFT, TMC4671_OPENLOOP_VELOCITY_ACTUAL, true}) +#define TMC4671_OPENLOOP_PHI_MASK 0x0000FFFF +#define TMC4671_OPENLOOP_PHI_SHIFT 0 +#define TMC4671_OPENLOOP_PHI_FIELD ((RegisterField) {TMC4671_OPENLOOP_PHI_MASK, TMC4671_OPENLOOP_PHI_SHIFT, TMC4671_OPENLOOP_PHI, true}) + +#define TMC4671_UD_EXT_MASK 0x0000FFFF +#define TMC4671_UD_EXT_SHIFT 0 +#define TMC4671_UD_EXT_FIELD ((RegisterField) {TMC4671_UD_EXT_MASK, TMC4671_UD_EXT_SHIFT, TMC4671_UQ_UD_EXT, true}) +#define TMC4671_UQ_EXT_MASK 0xFFFF0000 +#define TMC4671_UQ_EXT_SHIFT 16 +#define TMC4671_UQ_EXT_FIELD ((RegisterField) {TMC4671_UQ_EXT_MASK, TMC4671_UQ_EXT_SHIFT, TMC4671_UQ_UD_EXT, true}) + +#define TMC4671_ABN_APOL_MASK 0x00000001 +#define TMC4671_ABN_APOL_SHIFT 0 +#define TMC4671_ABN_APOL_FIELD ((RegisterField) {TMC4671_ABN_APOL_MASK, TMC4671_ABN_APOL_SHIFT, TMC4671_ABN_DECODER_MODE, false}) +#define TMC4671_ABN_BPOL_MASK 0x00000002 +#define TMC4671_ABN_BPOL_SHIFT 1 +#define TMC4671_ABN_BPOL_FIELD ((RegisterField) {TMC4671_ABN_BPOL_MASK, TMC4671_ABN_BPOL_SHIFT, TMC4671_ABN_DECODER_MODE, false}) +#define TMC4671_ABN_NPOL_MASK 0x00000004 +#define TMC4671_ABN_NPOL_SHIFT 2 +#define TMC4671_ABN_NPOL_FIELD ((RegisterField) {TMC4671_ABN_NPOL_MASK, TMC4671_ABN_NPOL_SHIFT, TMC4671_ABN_DECODER_MODE, false}) +#define TMC4671_USE_ABN_AS_N_MASK 0x00000008 +#define TMC4671_USE_ABN_AS_N_SHIFT 3 +#define TMC4671_USE_ABN_AS_N_FIELD ((RegisterField) {TMC4671_USE_ABN_AS_N_MASK, TMC4671_USE_ABN_AS_N_SHIFT, TMC4671_ABN_DECODER_MODE, false}) +#define TMC4671_ABN_CLN_MASK 0x00000100 +#define TMC4671_ABN_CLN_SHIFT 8 +#define TMC4671_ABN_CLN_FIELD ((RegisterField) {TMC4671_ABN_CLN_MASK, TMC4671_ABN_CLN_SHIFT, TMC4671_ABN_DECODER_MODE, false}) +#define TMC4671_ABN_DIRECTION_MASK 0x00001000 +#define TMC4671_ABN_DIRECTION_SHIFT 12 +#define TMC4671_ABN_DIRECTION_FIELD ((RegisterField) {TMC4671_ABN_DIRECTION_MASK, TMC4671_ABN_DIRECTION_SHIFT, TMC4671_ABN_DECODER_MODE, false}) +#define TMC4671_ABN_DECODER_PPR_MASK 0x00FFFFFF +#define TMC4671_ABN_DECODER_PPR_SHIFT 0 +#define TMC4671_ABN_DECODER_PPR_FIELD ((RegisterField) {TMC4671_ABN_DECODER_PPR_MASK, TMC4671_ABN_DECODER_PPR_SHIFT, TMC4671_ABN_DECODER_PPR, false}) +#define TMC4671_ABN_DECODER_COUNT_MASK 0x00FFFFFF +#define TMC4671_ABN_DECODER_COUNT_SHIFT 0 +#define TMC4671_ABN_DECODER_COUNT_FIELD ((RegisterField) {TMC4671_ABN_DECODER_COUNT_MASK, TMC4671_ABN_DECODER_COUNT_SHIFT, TMC4671_ABN_DECODER_COUNT, false}) +#define TMC4671_ABN_DECODER_COUNT_N_MASK 0x00FFFFFF +#define TMC4671_ABN_DECODER_COUNT_N_SHIFT 0 +#define TMC4671_ABN_DECODER_COUNT_N_FIELD ((RegisterField) {TMC4671_ABN_DECODER_COUNT_N_MASK, TMC4671_ABN_DECODER_COUNT_N_SHIFT, TMC4671_ABN_DECODER_COUNT_N, false}) +#define TMC4671_ABN_DECODER_PHI_M_OFFSET_MASK 0x0000FFFF +#define TMC4671_ABN_DECODER_PHI_M_OFFSET_SHIFT 0 +#define TMC4671_ABN_DECODER_PHI_M_OFFSET_FIELD ((RegisterField) {TMC4671_ABN_DECODER_PHI_M_OFFSET_MASK, TMC4671_ABN_DECODER_PHI_M_OFFSET_SHIFT, TMC4671_ABN_DECODER_PHI_E_PHI_M_OFFSET, true}) +#define TMC4671_ABN_DECODER_PHI_E_OFFSET_MASK 0xFFFF0000 +#define TMC4671_ABN_DECODER_PHI_E_OFFSET_SHIFT 16 +#define TMC4671_ABN_DECODER_PHI_E_OFFSET_FIELD ((RegisterField) {TMC4671_ABN_DECODER_PHI_E_OFFSET_MASK, TMC4671_ABN_DECODER_PHI_E_OFFSET_SHIFT, TMC4671_ABN_DECODER_PHI_E_PHI_M_OFFSET, true}) +#define TMC4671_ABN_DECODER_PHI_M_MASK 0x0000FFFF +#define TMC4671_ABN_DECODER_PHI_M_SHIFT 0 +#define TMC4671_ABN_DECODER_PHI_M_FIELD ((RegisterField) {TMC4671_ABN_DECODER_PHI_M_MASK, TMC4671_ABN_DECODER_PHI_M_SHIFT, TMC4671_ABN_DECODER_PHI_E_PHI_M, true}) +#define TMC4671_ABN_DECODER_PHI_E_MASK 0xFFFF0000 +#define TMC4671_ABN_DECODER_PHI_E_SHIFT 16 +#define TMC4671_ABN_DECODER_PHI_E_FIELD ((RegisterField) {TMC4671_ABN_DECODER_PHI_E_MASK, TMC4671_ABN_DECODER_PHI_E_SHIFT, TMC4671_ABN_DECODER_PHI_E_PHI_M, true}) + +#define TMC4671_ABN_2_APOL_MASK 0x00000001 +#define TMC4671_ABN_2_APOL_SHIFT 0 +#define TMC4671_ABN_2_APOL_FIELD ((RegisterField) {TMC4671_ABN_2_APOL_MASK, TMC4671_ABN_2_APOL_SHIFT, TMC4671_ABN_2_DECODER_MODE, false}) +#define TMC4671_ABN_2_BPOL_MASK 0x00000002 +#define TMC4671_ABN_2_BPOL_SHIFT 1 +#define TMC4671_ABN_2_BPOL_FIELD ((RegisterField) {TMC4671_ABN_2_BPOL_MASK, TMC4671_ABN_2_BPOL_SHIFT, TMC4671_ABN_2_DECODER_MODE, false}) +#define TMC4671_ABN_2_NPOL_MASK 0x00000004 +#define TMC4671_ABN_2_NPOL_SHIFT 2 +#define TMC4671_ABN_2_NPOL_FIELD ((RegisterField) {TMC4671_ABN_2_NPOL_MASK, TMC4671_ABN_2_NPOL_SHIFT, TMC4671_ABN_2_DECODER_MODE, false}) +#define TMC4671_USE_ABN_2_AS_N_MASK 0x00000008 +#define TMC4671_USE_ABN_2_AS_N_SHIFT 3 +#define TMC4671_USE_ABN_2_AS_N_FIELD ((RegisterField) {TMC4671_USE_ABN_2_AS_N_MASK, TMC4671_USE_ABN_2_AS_N_SHIFT, TMC4671_ABN_2_DECODER_MODE, false}) +#define TMC4671_ABN_2_CLN_MASK 0x00000100 +#define TMC4671_ABN_2_CLN_SHIFT 8 +#define TMC4671_ABN_2_CLN_FIELD ((RegisterField) {TMC4671_ABN_2_CLN_MASK, TMC4671_ABN_2_CLN_SHIFT, TMC4671_ABN_2_DECODER_MODE, false}) +#define TMC4671_ABN_2_DIRECTION_MASK 0x00001000 +#define TMC4671_ABN_2_DIRECTION_SHIFT 12 +#define TMC4671_ABN_2_DIRECTION_FIELD ((RegisterField) {TMC4671_ABN_2_DIRECTION_MASK, TMC4671_ABN_2_DIRECTION_SHIFT, TMC4671_ABN_2_DECODER_MODE, false}) +#define TMC4671_ABN_2_DECODER_PPR_MASK 0x00FFFFFF +#define TMC4671_ABN_2_DECODER_PPR_SHIFT 0 +#define TMC4671_ABN_2_DECODER_PPR_FIELD ((RegisterField) {TMC4671_ABN_2_DECODER_PPR_MASK, TMC4671_ABN_2_DECODER_PPR_SHIFT, TMC4671_ABN_2_DECODER_PPR, false}) +#define TMC4671_ABN_2_DECODER_COUNT_MASK 0x00FFFFFF +#define TMC4671_ABN_2_DECODER_COUNT_SHIFT 0 +#define TMC4671_ABN_2_DECODER_COUNT_FIELD ((RegisterField) {TMC4671_ABN_2_DECODER_COUNT_MASK, TMC4671_ABN_2_DECODER_COUNT_SHIFT, TMC4671_ABN_2_DECODER_COUNT, false}) +#define TMC4671_ABN_2_DECODER_COUNT_N_MASK 0x00FFFFFF +#define TMC4671_ABN_2_DECODER_COUNT_N_SHIFT 0 +#define TMC4671_ABN_2_DECODER_COUNT_N_FIELD ((RegisterField) {TMC4671_ABN_2_DECODER_COUNT_N_MASK, TMC4671_ABN_2_DECODER_COUNT_N_SHIFT, TMC4671_ABN_2_DECODER_COUNT_N, false}) +#define TMC4671_ABN_2_DECODER_PHI_M_OFFSET_MASK 0x0000FFFF +#define TMC4671_ABN_2_DECODER_PHI_M_OFFSET_SHIFT 0 +#define TMC4671_ABN_2_DECODER_PHI_M_OFFSET_FIELD ((RegisterField) {TMC4671_ABN_2_DECODER_PHI_M_OFFSET_MASK, TMC4671_ABN_2_DECODER_PHI_M_OFFSET_SHIFT, TMC4671_ABN_2_DECODER_PHI_M_OFFSET, true}) +#define TMC4671_ABN_2_DECODER_PHI_M_MASK 0x0000FFFF +#define TMC4671_ABN_2_DECODER_PHI_M_SHIFT 0 +#define TMC4671_ABN_2_DECODER_PHI_M_FIELD ((RegisterField) {TMC4671_ABN_2_DECODER_PHI_M_MASK, TMC4671_ABN_2_DECODER_PHI_M_SHIFT, TMC4671_ABN_2_DECODER_PHI_M, true}) + +#define TMC4671_HALL_POLARITY_MASK 0x00000001 +#define TMC4671_HALL_POLARITY_SHIFT 0 +#define TMC4671_HALL_POLARITY_FIELD ((RegisterField) {TMC4671_HALL_POLARITY_MASK, TMC4671_HALL_POLARITY_SHIFT, TMC4671_HALL_MODE, false}) +#define TMC4671_HALL_SYNCHRONOUS_PWM_SAMPLING_MASK 0x00000010 +#define TMC4671_HALL_SYNCHRONOUS_PWM_SAMPLING_SHIFT 4 +#define TMC4671_HALL_SYNCHRONOUS_PWM_SAMPLING_FIELD ((RegisterField) {TMC4671_HALL_SYNCHRONOUS_PWM_SAMPLING_MASK, TMC4671_HALL_SYNCHRONOUS_PWM_SAMPLING_SHIFT, TMC4671_HALL_MODE, false}) +#define TMC4671_HALL_INTERPOLATION_MASK 0x00000100 +#define TMC4671_HALL_INTERPOLATION_SHIFT 8 +#define TMC4671_HALL_INTERPOLATION_FIELD ((RegisterField) {TMC4671_HALL_INTERPOLATION_MASK, TMC4671_HALL_INTERPOLATION_SHIFT, TMC4671_HALL_MODE, false}) +#define TMC4671_HALL_DIRECTION_MASK 0x00001000 +#define TMC4671_HALL_DIRECTION_SHIFT 12 +#define TMC4671_HALL_DIRECTION_FIELD ((RegisterField) {TMC4671_HALL_DIRECTION_MASK, TMC4671_HALL_DIRECTION_SHIFT, TMC4671_HALL_MODE, false}) +#define TMC4671_HALL_BLANK_MASK 0x0FFF0000 +#define TMC4671_HALL_BLANK_SHIFT 16 +#define TMC4671_HALL_BLANK_FIELD ((RegisterField) {TMC4671_HALL_BLANK_MASK, TMC4671_HALL_BLANK_SHIFT, TMC4671_HALL_MODE, false}) +#define TMC4671_HALL_POSITION_000_MASK 0x0000FFFF +#define TMC4671_HALL_POSITION_000_SHIFT 0 +#define TMC4671_HALL_POSITION_000_FIELD ((RegisterField) {TMC4671_HALL_POSITION_000_MASK, TMC4671_HALL_POSITION_000_SHIFT, TMC4671_HALL_POSITION_060_000, true}) +#define TMC4671_HALL_POSITION_060_MASK 0xFFFF0000 +#define TMC4671_HALL_POSITION_060_SHIFT 16 +#define TMC4671_HALL_POSITION_060_FIELD ((RegisterField) {TMC4671_HALL_POSITION_060_MASK, TMC4671_HALL_POSITION_060_SHIFT, TMC4671_HALL_POSITION_060_000, true}) +#define TMC4671_HALL_POSITION_120_MASK 0x0000FFFF +#define TMC4671_HALL_POSITION_120_SHIFT 0 +#define TMC4671_HALL_POSITION_120_FIELD ((RegisterField) {TMC4671_HALL_POSITION_120_MASK, TMC4671_HALL_POSITION_120_SHIFT, TMC4671_HALL_POSITION_180_120, true}) +#define TMC4671_HALL_POSITION_180_MASK 0xFFFF0000 +#define TMC4671_HALL_POSITION_180_SHIFT 16 +#define TMC4671_HALL_POSITION_180_FIELD ((RegisterField) {TMC4671_HALL_POSITION_180_MASK, TMC4671_HALL_POSITION_180_SHIFT, TMC4671_HALL_POSITION_180_120, true}) +#define TMC4671_HALL_POSITION_240_MASK 0x0000FFFF +#define TMC4671_HALL_POSITION_240_SHIFT 0 +#define TMC4671_HALL_POSITION_240_FIELD ((RegisterField) {TMC4671_HALL_POSITION_240_MASK, TMC4671_HALL_POSITION_240_SHIFT, TMC4671_HALL_POSITION_300_240, true}) +#define TMC4671_HALL_POSITION_300_MASK 0xFFFF0000 +#define TMC4671_HALL_POSITION_300_SHIFT 16 +#define TMC4671_HALL_POSITION_300_FIELD ((RegisterField) {TMC4671_HALL_POSITION_300_MASK, TMC4671_HALL_POSITION_300_SHIFT, TMC4671_HALL_POSITION_300_240, true}) +#define TMC4671_HALL_PHI_M_OFFSET_MASK 0x0000FFFF +#define TMC4671_HALL_PHI_M_OFFSET_SHIFT 0 +#define TMC4671_HALL_PHI_M_OFFSET_FIELD ((RegisterField) {TMC4671_HALL_PHI_M_OFFSET_MASK, TMC4671_HALL_PHI_M_OFFSET_SHIFT, TMC4671_HALL_PHI_E_PHI_M_OFFSET, true}) +#define TMC4671_HALL_PHI_E_OFFSET_MASK 0xFFFF0000 +#define TMC4671_HALL_PHI_E_OFFSET_SHIFT 16 +#define TMC4671_HALL_PHI_E_OFFSET_FIELD ((RegisterField) {TMC4671_HALL_PHI_E_OFFSET_MASK, TMC4671_HALL_PHI_E_OFFSET_SHIFT, TMC4671_HALL_PHI_E_PHI_M_OFFSET, true}) +#define TMC4671_HALL_DPHI_MAX_MASK 0x0000FFFF +#define TMC4671_HALL_DPHI_MAX_SHIFT 0 +#define TMC4671_HALL_DPHI_MAX_FIELD ((RegisterField) {TMC4671_HALL_DPHI_MAX_MASK, TMC4671_HALL_DPHI_MAX_SHIFT, TMC4671_HALL_DPHI_MAX, false}) +#define TMC4671_HALL_PHI_E_MASK 0x0000FFFF +#define TMC4671_HALL_PHI_E_SHIFT 0 +#define TMC4671_HALL_PHI_E_FIELD ((RegisterField) {TMC4671_HALL_PHI_E_MASK, TMC4671_HALL_PHI_E_SHIFT, TMC4671_HALL_PHI_E_INTERPOLATED_PHI_E, true}) +#define TMC4671_HALL_PHI_E_INTERPOLATED_MASK 0xFFFF0000 +#define TMC4671_HALL_PHI_E_INTERPOLATED_SHIFT 16 +#define TMC4671_HALL_PHI_E_INTERPOLATED_FIELD ((RegisterField) {TMC4671_HALL_PHI_E_INTERPOLATED_MASK, TMC4671_HALL_PHI_E_INTERPOLATED_SHIFT, TMC4671_HALL_PHI_E_INTERPOLATED_PHI_E, true}) +#define TMC4671_HALL_PHI_M_MASK 0x0000FFFF +#define TMC4671_HALL_PHI_M_SHIFT 0 +#define TMC4671_HALL_PHI_M_FIELD ((RegisterField) {TMC4671_HALL_PHI_M_MASK, TMC4671_HALL_PHI_M_SHIFT, TMC4671_HALL_PHI_M, true}) + +#define TMC4671_AENC_DECODER_MODE_0_MASK 0x00000001 +#define TMC4671_AENC_DECODER_MODE_0_SHIFT 0 +#define TMC4671_AENC_DECODER_MODE_0_FIELD ((RegisterField) {TMC4671_AENC_DECODER_MODE_0_MASK, TMC4671_AENC_DECODER_MODE_0_SHIFT, TMC4671_AENC_DECODER_MODE, false}) +#define TMC4671_AENC_DECODER_MODE_12_MASK 0x00001000 +#define TMC4671_AENC_DECODER_MODE_12_SHIFT 12 +#define TMC4671_AENC_DECODER_MODE_12_FIELD ((RegisterField) {TMC4671_AENC_DECODER_MODE_12_MASK, TMC4671_AENC_DECODER_MODE_12_SHIFT, TMC4671_AENC_DECODER_MODE, false}) +#define TMC4671_AENC_DECODER_N_THRESHOLD_MASK 0x0000FFFF +#define TMC4671_AENC_DECODER_N_THRESHOLD_SHIFT 0 +#define TMC4671_AENC_DECODER_N_THRESHOLD_FIELD ((RegisterField) {TMC4671_AENC_DECODER_N_THRESHOLD_MASK, TMC4671_AENC_DECODER_N_THRESHOLD_SHIFT, TMC4671_AENC_DECODER_N_THRESHOLD, false}) +#define TMC4671_AENC_DECODER_PHI_A_RAW_MASK 0x0000FFFF +#define TMC4671_AENC_DECODER_PHI_A_RAW_SHIFT 0 +#define TMC4671_AENC_DECODER_PHI_A_RAW_FIELD ((RegisterField) {TMC4671_AENC_DECODER_PHI_A_RAW_MASK, TMC4671_AENC_DECODER_PHI_A_RAW_SHIFT, TMC4671_AENC_DECODER_PHI_A_RAW, true}) +#define TMC4671_AENC_DECODER_PHI_A_OFFSET_MASK 0x0000FFFF +#define TMC4671_AENC_DECODER_PHI_A_OFFSET_SHIFT 0 +#define TMC4671_AENC_DECODER_PHI_A_OFFSET_FIELD ((RegisterField) {TMC4671_AENC_DECODER_PHI_A_OFFSET_MASK, TMC4671_AENC_DECODER_PHI_A_OFFSET_SHIFT, TMC4671_AENC_DECODER_PHI_A_OFFSET, true}) +#define TMC4671_AENC_DECODER_PHI_A_MASK 0x0000FFFF +#define TMC4671_AENC_DECODER_PHI_A_SHIFT 0 +#define TMC4671_AENC_DECODER_PHI_A_FIELD ((RegisterField) {TMC4671_AENC_DECODER_PHI_A_MASK, TMC4671_AENC_DECODER_PHI_A_SHIFT, TMC4671_AENC_DECODER_PHI_A, true}) +#define TMC4671_AENC_DECODER_PPR_MASK 0x0000FFFF +#define TMC4671_AENC_DECODER_PPR_SHIFT 0 +#define TMC4671_AENC_DECODER_PPR_FIELD ((RegisterField) {TMC4671_AENC_DECODER_PPR_MASK, TMC4671_AENC_DECODER_PPR_SHIFT, TMC4671_AENC_DECODER_PPR, true}) +#define TMC4671_AENC_DECODER_COUNT_MASK 0xFFFFFFFF +#define TMC4671_AENC_DECODER_COUNT_SHIFT 0 +#define TMC4671_AENC_DECODER_COUNT_FIELD ((RegisterField) {TMC4671_AENC_DECODER_COUNT_MASK, TMC4671_AENC_DECODER_COUNT_SHIFT, TMC4671_AENC_DECODER_COUNT, true}) +#define TMC4671_AENC_DECODER_COUNT_N_MASK 0xFFFFFFFF +#define TMC4671_AENC_DECODER_COUNT_N_SHIFT 0 +#define TMC4671_AENC_DECODER_COUNT_N_FIELD ((RegisterField) {TMC4671_AENC_DECODER_COUNT_N_MASK, TMC4671_AENC_DECODER_COUNT_N_SHIFT, TMC4671_AENC_DECODER_COUNT_N, true}) +#define TMC4671_AENC_DECODER_PHI_M_OFFSET_MASK 0x0000FFFF +#define TMC4671_AENC_DECODER_PHI_M_OFFSET_SHIFT 0 +#define TMC4671_AENC_DECODER_PHI_M_OFFSET_FIELD ((RegisterField) {TMC4671_AENC_DECODER_PHI_M_OFFSET_MASK, TMC4671_AENC_DECODER_PHI_M_OFFSET_SHIFT, TMC4671_AENC_DECODER_PHI_E_PHI_M_OFFSET, true}) +#define TMC4671_AENC_DECODER_PHI_E_OFFSET_MASK 0xFFFF0000 +#define TMC4671_AENC_DECODER_PHI_E_OFFSET_SHIFT 16 +#define TMC4671_AENC_DECODER_PHI_E_OFFSET_FIELD ((RegisterField) {TMC4671_AENC_DECODER_PHI_E_OFFSET_MASK, TMC4671_AENC_DECODER_PHI_E_OFFSET_SHIFT, TMC4671_AENC_DECODER_PHI_E_PHI_M_OFFSET, true}) +#define TMC4671_AENC_DECODER_PHI_M_MASK 0x0000FFFF +#define TMC4671_AENC_DECODER_PHI_M_SHIFT 0 +#define TMC4671_AENC_DECODER_PHI_M_FIELD ((RegisterField) {TMC4671_AENC_DECODER_PHI_M_MASK, TMC4671_AENC_DECODER_PHI_M_SHIFT, TMC4671_AENC_DECODER_PHI_E_PHI_M, true}) +#define TMC4671_AENC_DECODER_PHI_E_MASK 0xFFFF0000 +#define TMC4671_AENC_DECODER_PHI_E_SHIFT 16 +#define TMC4671_AENC_DECODER_PHI_E_FIELD ((RegisterField) {TMC4671_AENC_DECODER_PHI_E_MASK, TMC4671_AENC_DECODER_PHI_E_SHIFT, TMC4671_AENC_DECODER_PHI_E_PHI_M, true}) + +#define TMC4671_BIQUAD_X_A_1_MASK 0xFFFFFFFF +#define TMC4671_BIQUAD_X_A_1_SHIFT 0 +#define TMC4671_BIQUAD_X_A_1_FIELD ((RegisterField) {TMC4671_BIQUAD_X_A_1_MASK, TMC4671_BIQUAD_X_A_1_SHIFT, TMC4671_CONFIG_DATA, true}) +#define TMC4671_BIQUAD_X_A_2_MASK 0xFFFFFFFF +#define TMC4671_BIQUAD_X_A_2_SHIFT 0 +#define TMC4671_BIQUAD_X_A_2_FIELD ((RegisterField) {TMC4671_BIQUAD_X_A_2_MASK, TMC4671_BIQUAD_X_A_2_SHIFT, TMC4671_CONFIG_DATA, true}) +#define TMC4671_BIQUAD_X_B_0_MASK 0xFFFFFFFF +#define TMC4671_BIQUAD_X_B_0_SHIFT 0 +#define TMC4671_BIQUAD_X_B_0_FIELD ((RegisterField) {TMC4671_BIQUAD_X_B_0_MASK, TMC4671_BIQUAD_X_B_0_SHIFT, TMC4671_CONFIG_DATA, true}) +#define TMC4671_BIQUAD_X_B_1_MASK 0xFFFFFFFF +#define TMC4671_BIQUAD_X_B_1_SHIFT 0 +#define TMC4671_BIQUAD_X_B_1_FIELD ((RegisterField) {TMC4671_BIQUAD_X_B_1_MASK, TMC4671_BIQUAD_X_B_1_SHIFT, TMC4671_CONFIG_DATA, true}) +#define TMC4671_BIQUAD_X_B_2_MASK 0xFFFFFFFF +#define TMC4671_BIQUAD_X_B_2_SHIFT 0 +#define TMC4671_BIQUAD_X_B_2_FIELD ((RegisterField) {TMC4671_BIQUAD_X_B_2_MASK, TMC4671_BIQUAD_X_B_2_SHIFT, TMC4671_CONFIG_DATA, true}) +#define TMC4671_BIQUAD_X_ENABLE_MASK 0xFFFFFFFF +#define TMC4671_BIQUAD_X_ENABLE_SHIFT 0 +#define TMC4671_BIQUAD_X_ENABLE_FIELD ((RegisterField) {TMC4671_BIQUAD_X_ENABLE_MASK, TMC4671_BIQUAD_X_ENABLE_SHIFT, TMC4671_CONFIG_DATA, false}) +#define TMC4671_BIQUAD_V_A_1_MASK 0xFFFFFFFF +#define TMC4671_BIQUAD_V_A_1_SHIFT 0 +#define TMC4671_BIQUAD_V_A_1_FIELD ((RegisterField) {TMC4671_BIQUAD_V_A_1_MASK, TMC4671_BIQUAD_V_A_1_SHIFT, TMC4671_CONFIG_DATA, true}) +#define TMC4671_BIQUAD_V_A_2_MASK 0xFFFFFFFF +#define TMC4671_BIQUAD_V_A_2_SHIFT 0 +#define TMC4671_BIQUAD_V_A_2_FIELD ((RegisterField) {TMC4671_BIQUAD_V_A_2_MASK, TMC4671_BIQUAD_V_A_2_SHIFT, TMC4671_CONFIG_DATA, true}) +#define TMC4671_BIQUAD_V_B_0_MASK 0xFFFFFFFF +#define TMC4671_BIQUAD_V_B_0_SHIFT 0 +#define TMC4671_BIQUAD_V_B_0_FIELD ((RegisterField) {TMC4671_BIQUAD_V_B_0_MASK, TMC4671_BIQUAD_V_B_0_SHIFT, TMC4671_CONFIG_DATA, true}) +#define TMC4671_BIQUAD_V_B_1_MASK 0xFFFFFFFF +#define TMC4671_BIQUAD_V_B_1_SHIFT 0 +#define TMC4671_BIQUAD_V_B_1_FIELD ((RegisterField) {TMC4671_BIQUAD_V_B_1_MASK, TMC4671_BIQUAD_V_B_1_SHIFT, TMC4671_CONFIG_DATA, true}) +#define TMC4671_BIQUAD_V_B_2_MASK 0xFFFFFFFF +#define TMC4671_BIQUAD_V_B_2_SHIFT 0 +#define TMC4671_BIQUAD_V_B_2_FIELD ((RegisterField) {TMC4671_BIQUAD_V_B_2_MASK, TMC4671_BIQUAD_V_B_2_SHIFT, TMC4671_CONFIG_DATA, true}) +#define TMC4671_BIQUAD_V_ENABLE_MASK 0xFFFFFFFF +#define TMC4671_BIQUAD_V_ENABLE_SHIFT 0 +#define TMC4671_BIQUAD_V_ENABLE_FIELD ((RegisterField) {TMC4671_BIQUAD_V_ENABLE_MASK, TMC4671_BIQUAD_V_ENABLE_SHIFT, TMC4671_CONFIG_DATA, false}) +#define TMC4671_BIQUAD_T_A_1_MASK 0xFFFFFFFF +#define TMC4671_BIQUAD_T_A_1_SHIFT 0 +#define TMC4671_BIQUAD_T_A_1_FIELD ((RegisterField) {TMC4671_BIQUAD_T_A_1_MASK, TMC4671_BIQUAD_T_A_1_SHIFT, TMC4671_CONFIG_DATA, true}) +#define TMC4671_BIQUAD_T_A_2_MASK 0xFFFFFFFF +#define TMC4671_BIQUAD_T_A_2_SHIFT 0 +#define TMC4671_BIQUAD_T_A_2_FIELD ((RegisterField) {TMC4671_BIQUAD_T_A_2_MASK, TMC4671_BIQUAD_T_A_2_SHIFT, TMC4671_CONFIG_DATA, true}) +#define TMC4671_BIQUAD_T_B_0_MASK 0xFFFFFFFF +#define TMC4671_BIQUAD_T_B_0_SHIFT 0 +#define TMC4671_BIQUAD_T_B_0_FIELD ((RegisterField) {TMC4671_BIQUAD_T_B_0_MASK, TMC4671_BIQUAD_T_B_0_SHIFT, TMC4671_CONFIG_DATA, true}) +#define TMC4671_BIQUAD_T_B_1_MASK 0xFFFFFFFF +#define TMC4671_BIQUAD_T_B_1_SHIFT 0 +#define TMC4671_BIQUAD_T_B_1_FIELD ((RegisterField) {TMC4671_BIQUAD_T_B_1_MASK, TMC4671_BIQUAD_T_B_1_SHIFT, TMC4671_CONFIG_DATA, true}) +#define TMC4671_BIQUAD_T_B_2_MASK 0xFFFFFFFF +#define TMC4671_BIQUAD_T_B_2_SHIFT 0 +#define TMC4671_BIQUAD_T_B_2_FIELD ((RegisterField) {TMC4671_BIQUAD_T_B_2_MASK, TMC4671_BIQUAD_T_B_2_SHIFT, TMC4671_CONFIG_DATA, true}) +#define TMC4671_BIQUAD_T_ENABLE_MASK 0xFFFFFFFF +#define TMC4671_BIQUAD_T_ENABLE_SHIFT 0 +#define TMC4671_BIQUAD_T_ENABLE_FIELD ((RegisterField) {TMC4671_BIQUAD_T_ENABLE_MASK, TMC4671_BIQUAD_T_ENABLE_SHIFT, TMC4671_CONFIG_DATA, false}) +#define TMC4671_BIQUAD_F_A_1_MASK 0xFFFFFFFF +#define TMC4671_BIQUAD_F_A_1_SHIFT 0 +#define TMC4671_BIQUAD_F_A_1_FIELD ((RegisterField) {TMC4671_BIQUAD_F_A_1_MASK, TMC4671_BIQUAD_F_A_1_SHIFT, TMC4671_CONFIG_DATA, true}) +#define TMC4671_BIQUAD_F_A_2_MASK 0xFFFFFFFF +#define TMC4671_BIQUAD_F_A_2_SHIFT 0 +#define TMC4671_BIQUAD_F_A_2_FIELD ((RegisterField) {TMC4671_BIQUAD_F_A_2_MASK, TMC4671_BIQUAD_F_A_2_SHIFT, TMC4671_CONFIG_DATA, true}) +#define TMC4671_BIQUAD_F_B_0_MASK 0xFFFFFFFF +#define TMC4671_BIQUAD_F_B_0_SHIFT 0 +#define TMC4671_BIQUAD_F_B_0_FIELD ((RegisterField) {TMC4671_BIQUAD_F_B_0_MASK, TMC4671_BIQUAD_F_B_0_SHIFT, TMC4671_CONFIG_DATA, true}) +#define TMC4671_BIQUAD_F_B_1_MASK 0xFFFFFFFF +#define TMC4671_BIQUAD_F_B_1_SHIFT 0 +#define TMC4671_BIQUAD_F_B_1_FIELD ((RegisterField) {TMC4671_BIQUAD_F_B_1_MASK, TMC4671_BIQUAD_F_B_1_SHIFT, TMC4671_CONFIG_DATA, true}) +#define TMC4671_BIQUAD_F_B_2_MASK 0xFFFFFFFF +#define TMC4671_BIQUAD_F_B_2_SHIFT 0 +#define TMC4671_BIQUAD_F_B_2_FIELD ((RegisterField) {TMC4671_BIQUAD_F_B_2_MASK, TMC4671_BIQUAD_F_B_2_SHIFT, TMC4671_CONFIG_DATA, true}) +#define TMC4671_BIQUAD_F_ENABLE_MASK 0xFFFFFFFF +#define TMC4671_BIQUAD_F_ENABLE_SHIFT 0 +#define TMC4671_BIQUAD_F_ENABLE_FIELD ((RegisterField) {TMC4671_BIQUAD_F_ENABLE_MASK, TMC4671_BIQUAD_F_ENABLE_SHIFT, TMC4671_CONFIG_DATA, false}) +#define TMC4671_PRBS_AMPLITUDE_MASK 0xFFFFFFFF +#define TMC4671_PRBS_AMPLITUDE_SHIFT 0 +#define TMC4671_PRBS_AMPLITUDE_FIELD ((RegisterField) {TMC4671_PRBS_AMPLITUDE_MASK, TMC4671_PRBS_AMPLITUDE_SHIFT, TMC4671_CONFIG_DATA, true}) +#define TMC4671_PRBS_DOWN_SAMPLING_RATIO_MASK 0xFFFFFFFF +#define TMC4671_PRBS_DOWN_SAMPLING_RATIO_SHIFT 0 +#define TMC4671_PRBS_DOWN_SAMPLING_RATIO_FIELD ((RegisterField) {TMC4671_PRBS_DOWN_SAMPLING_RATIO_MASK, TMC4671_PRBS_DOWN_SAMPLING_RATIO_SHIFT, TMC4671_CONFIG_DATA, true}) +#define TMC4671_REF_SWITCH_ENABLE_MASK 0x00000001 +#define TMC4671_REF_SWITCH_ENABLE_SHIFT 0 +#define TMC4671_REF_SWITCH_ENABLE_FIELD ((RegisterField) {TMC4671_REF_SWITCH_ENABLE_MASK, TMC4671_REF_SWITCH_ENABLE_SHIFT, TMC4671_CONFIG_DATA, false}) +#define TMC4671_HOME_SWITCH_POLARITY_MASK 0x00000002 +#define TMC4671_HOME_SWITCH_POLARITY_SHIFT 1 +#define TMC4671_HOME_SWITCH_POLARITY_FIELD ((RegisterField) {TMC4671_HOME_SWITCH_POLARITY_MASK, TMC4671_HOME_SWITCH_POLARITY_SHIFT, TMC4671_CONFIG_DATA, false}) +#define TMC4671_LEFT_SWITCH_POLARITY_MASK 0x00000004 +#define TMC4671_LEFT_SWITCH_POLARITY_SHIFT 2 +#define TMC4671_LEFT_SWITCH_POLARITY_FIELD ((RegisterField) {TMC4671_LEFT_SWITCH_POLARITY_MASK, TMC4671_LEFT_SWITCH_POLARITY_SHIFT, TMC4671_CONFIG_DATA, false}) +#define TMC4671_RIGHT_SWITCH_POLARITY_MASK 0x00000008 +#define TMC4671_RIGHT_SWITCH_POLARITY_SHIFT 3 +#define TMC4671_RIGHT_SWITCH_POLARITY_FIELD ((RegisterField) {TMC4671_RIGHT_SWITCH_POLARITY_MASK, TMC4671_RIGHT_SWITCH_POLARITY_SHIFT, TMC4671_CONFIG_DATA, false}) +#define TMC4671_ENCODER_INIT_HALL_ENABLE_MASK 0x00000001 +#define TMC4671_ENCODER_INIT_HALL_ENABLE_SHIFT 0 +#define TMC4671_ENCODER_INIT_HALL_ENABLE_FIELD ((RegisterField) {TMC4671_ENCODER_INIT_HALL_ENABLE_MASK, TMC4671_ENCODER_INIT_HALL_ENABLE_SHIFT, TMC4671_CONFIG_DATA, false}) +#define TMC4671_SINGLE_PIN_IF_CFG_MASK 0x000000FF +#define TMC4671_SINGLE_PIN_IF_CFG_SHIFT 0 +#define TMC4671_SINGLE_PIN_IF_CFG_FIELD ((RegisterField) {TMC4671_SINGLE_PIN_IF_CFG_MASK, TMC4671_SINGLE_PIN_IF_CFG_SHIFT, TMC4671_CONFIG_DATA, false}) +#define TMC4671_SINGLE_PIN_IF_STATUS_MASK 0xFFFF0000 +#define TMC4671_SINGLE_PIN_IF_STATUS_SHIFT 16 +#define TMC4671_SINGLE_PIN_IF_STATUS_FIELD ((RegisterField) {TMC4671_SINGLE_PIN_IF_STATUS_MASK, TMC4671_SINGLE_PIN_IF_STATUS_SHIFT, TMC4671_CONFIG_DATA, false}) +#define TMC4671_SINGLE_PIN_IF_OFFSET_MASK 0x0000FFFF +#define TMC4671_SINGLE_PIN_IF_OFFSET_SHIFT 0 +#define TMC4671_SINGLE_PIN_IF_OFFSET_FIELD ((RegisterField) {TMC4671_SINGLE_PIN_IF_OFFSET_MASK, TMC4671_SINGLE_PIN_IF_OFFSET_SHIFT, TMC4671_CONFIG_DATA, false}) +#define TMC4671_SINGLE_PIN_IF_SCALE_MASK 0xFFFF0000 +#define TMC4671_SINGLE_PIN_IF_SCALE_SHIFT 16 +#define TMC4671_SINGLE_PIN_IF_SCALE_FIELD ((RegisterField) {TMC4671_SINGLE_PIN_IF_SCALE_MASK, TMC4671_SINGLE_PIN_IF_SCALE_SHIFT, TMC4671_CONFIG_DATA, true}) +#define TMC4671_CURRENT_I_NQ8_8_Q4_12_MASK 0x00000001 +#define TMC4671_CURRENT_I_NQ8_8_Q4_12_SHIFT 0 +#define TMC4671_CURRENT_I_NQ8_8_Q4_12_FIELD ((RegisterField) {TMC4671_CURRENT_I_NQ8_8_Q4_12_MASK, TMC4671_CURRENT_I_NQ8_8_Q4_12_SHIFT, TMC4671_CONFIG_DATA, false}) +#define TMC4671_CURRENT_P_NQ8_8_Q4_12_MASK 0x00000002 +#define TMC4671_CURRENT_P_NQ8_8_Q4_12_SHIFT 1 +#define TMC4671_CURRENT_P_NQ8_8_Q4_12_FIELD ((RegisterField) {TMC4671_CURRENT_P_NQ8_8_Q4_12_MASK, TMC4671_CURRENT_P_NQ8_8_Q4_12_SHIFT, TMC4671_CONFIG_DATA, false}) +#define TMC4671_VELOCITY_I_NQ8_8_Q4_12_MASK 0x00000004 +#define TMC4671_VELOCITY_I_NQ8_8_Q4_12_SHIFT 2 +#define TMC4671_VELOCITY_I_NQ8_8_Q4_12_FIELD ((RegisterField) {TMC4671_VELOCITY_I_NQ8_8_Q4_12_MASK, TMC4671_VELOCITY_I_NQ8_8_Q4_12_SHIFT, TMC4671_CONFIG_DATA, false}) +#define TMC4671_VELOCITY_P_NQ8_8_Q4_12_MASK 0x00000008 +#define TMC4671_VELOCITY_P_NQ8_8_Q4_12_SHIFT 3 +#define TMC4671_VELOCITY_P_NQ8_8_Q4_12_FIELD ((RegisterField) {TMC4671_VELOCITY_P_NQ8_8_Q4_12_MASK, TMC4671_VELOCITY_P_NQ8_8_Q4_12_SHIFT, TMC4671_CONFIG_DATA, false}) +#define TMC4671_POSITION_I_NQ8_8_Q4_12_MASK 0x00000010 +#define TMC4671_POSITION_I_NQ8_8_Q4_12_SHIFT 4 +#define TMC4671_POSITION_I_NQ8_8_Q4_12_FIELD ((RegisterField) {TMC4671_POSITION_I_NQ8_8_Q4_12_MASK, TMC4671_POSITION_I_NQ8_8_Q4_12_SHIFT, TMC4671_CONFIG_DATA, false}) +#define TMC4671_POSITION_P_NQ8_8_Q4_12_MASK 0x00000020 +#define TMC4671_POSITION_P_NQ8_8_Q4_12_SHIFT 5 +#define TMC4671_POSITION_P_NQ8_8_Q4_12_FIELD ((RegisterField) {TMC4671_POSITION_P_NQ8_8_Q4_12_MASK, TMC4671_POSITION_P_NQ8_8_Q4_12_SHIFT, TMC4671_CONFIG_DATA, false}) +#define TMC4671_CONFIG_ADDR_MASK 0xFFFFFFFF +#define TMC4671_CONFIG_ADDR_SHIFT 0 +#define TMC4671_CONFIG_ADDR_FIELD ((RegisterField) {TMC4671_CONFIG_ADDR_MASK, TMC4671_CONFIG_ADDR_SHIFT, TMC4671_CONFIG_ADDR, false}) + +#define TMC4671_VELOCITY_SELECTION_MASK 0x000000FF +#define TMC4671_VELOCITY_SELECTION_SHIFT 0 +#define TMC4671_VELOCITY_SELECTION_FIELD ((RegisterField) {TMC4671_VELOCITY_SELECTION_MASK, TMC4671_VELOCITY_SELECTION_SHIFT, TMC4671_VELOCITY_SELECTION, false}) +#define TMC4671_VELOCITY_METER_SELECTION_MASK 0x0000FF00 +#define TMC4671_VELOCITY_METER_SELECTION_SHIFT 8 +#define TMC4671_VELOCITY_METER_SELECTION_FIELD ((RegisterField) {TMC4671_VELOCITY_METER_SELECTION_MASK, TMC4671_VELOCITY_METER_SELECTION_SHIFT, TMC4671_VELOCITY_SELECTION, false}) +#define TMC4671_POSITION_SELECTION_MASK 0x000000FF +#define TMC4671_POSITION_SELECTION_SHIFT 0 +#define TMC4671_POSITION_SELECTION_FIELD ((RegisterField) {TMC4671_POSITION_SELECTION_MASK, TMC4671_POSITION_SELECTION_SHIFT, TMC4671_POSITION_SELECTION, false}) +#define TMC4671_PHI_E_SELECTION_MASK 0x000000FF +#define TMC4671_PHI_E_SELECTION_SHIFT 0 +#define TMC4671_PHI_E_SELECTION_FIELD ((RegisterField) {TMC4671_PHI_E_SELECTION_MASK, TMC4671_PHI_E_SELECTION_SHIFT, TMC4671_PHI_E_SELECTION, false}) +#define TMC4671_PHI_E_MASK 0x0000FFFF +#define TMC4671_PHI_E_SHIFT 0 +#define TMC4671_PHI_E_FIELD ((RegisterField) {TMC4671_PHI_E_MASK, TMC4671_PHI_E_SHIFT, TMC4671_PHI_E, true}) + +#define TMC4671_PID_FLUX_I_MASK 0x0000FFFF +#define TMC4671_PID_FLUX_I_SHIFT 0 +#define TMC4671_PID_FLUX_I_FIELD ((RegisterField) {TMC4671_PID_FLUX_I_MASK, TMC4671_PID_FLUX_I_SHIFT, TMC4671_PID_FLUX_P_FLUX_I, true}) +#define TMC4671_PID_FLUX_P_MASK 0xFFFF0000 +#define TMC4671_PID_FLUX_P_SHIFT 16 +#define TMC4671_PID_FLUX_P_FIELD ((RegisterField) {TMC4671_PID_FLUX_P_MASK, TMC4671_PID_FLUX_P_SHIFT, TMC4671_PID_FLUX_P_FLUX_I, true}) +#define TMC4671_PID_TORQUE_I_MASK 0x0000FFFF +#define TMC4671_PID_TORQUE_I_SHIFT 0 +#define TMC4671_PID_TORQUE_I_FIELD ((RegisterField) {TMC4671_PID_TORQUE_I_MASK, TMC4671_PID_TORQUE_I_SHIFT, TMC4671_PID_TORQUE_P_TORQUE_I, true}) +#define TMC4671_PID_TORQUE_P_MASK 0xFFFF0000 +#define TMC4671_PID_TORQUE_P_SHIFT 16 +#define TMC4671_PID_TORQUE_P_FIELD ((RegisterField) {TMC4671_PID_TORQUE_P_MASK, TMC4671_PID_TORQUE_P_SHIFT, TMC4671_PID_TORQUE_P_TORQUE_I, true}) +#define TMC4671_PID_VELOCITY_I_MASK 0x0000FFFF +#define TMC4671_PID_VELOCITY_I_SHIFT 0 +#define TMC4671_PID_VELOCITY_I_FIELD ((RegisterField) {TMC4671_PID_VELOCITY_I_MASK, TMC4671_PID_VELOCITY_I_SHIFT, TMC4671_PID_VELOCITY_P_VELOCITY_I, true}) +#define TMC4671_PID_VELOCITY_P_MASK 0xFFFF0000 +#define TMC4671_PID_VELOCITY_P_SHIFT 16 +#define TMC4671_PID_VELOCITY_P_FIELD ((RegisterField) {TMC4671_PID_VELOCITY_P_MASK, TMC4671_PID_VELOCITY_P_SHIFT, TMC4671_PID_VELOCITY_P_VELOCITY_I, true}) +#define TMC4671_PID_POSITION_I_MASK 0x0000FFFF +#define TMC4671_PID_POSITION_I_SHIFT 0 +#define TMC4671_PID_POSITION_I_FIELD ((RegisterField) {TMC4671_PID_POSITION_I_MASK, TMC4671_PID_POSITION_I_SHIFT, TMC4671_PID_POSITION_P_POSITION_I, true}) +#define TMC4671_PID_POSITION_P_MASK 0xFFFF0000 +#define TMC4671_PID_POSITION_P_SHIFT 16 +#define TMC4671_PID_POSITION_P_FIELD ((RegisterField) {TMC4671_PID_POSITION_P_MASK, TMC4671_PID_POSITION_P_SHIFT, TMC4671_PID_POSITION_P_POSITION_I, true}) + +#define TMC4671_PIDOUT_UQ_UD_LIMITS_MASK 0x0000FFFF +#define TMC4671_PIDOUT_UQ_UD_LIMITS_SHIFT 0 +#define TMC4671_PIDOUT_UQ_UD_LIMITS_FIELD ((RegisterField) {TMC4671_PIDOUT_UQ_UD_LIMITS_MASK, TMC4671_PIDOUT_UQ_UD_LIMITS_SHIFT, TMC4671_PIDOUT_UQ_UD_LIMITS, false}) +#define TMC4671_PID_TORQUE_FLUX_LIMITS_MASK 0x0000FFFF +#define TMC4671_PID_TORQUE_FLUX_LIMITS_SHIFT 0 +#define TMC4671_PID_TORQUE_FLUX_LIMITS_FIELD ((RegisterField) {TMC4671_PID_TORQUE_FLUX_LIMITS_MASK, TMC4671_PID_TORQUE_FLUX_LIMITS_SHIFT, TMC4671_PID_TORQUE_FLUX_LIMITS, false}) +#define TMC4671_PID_VELOCITY_LIMIT_MASK 0xFFFFFFFF +#define TMC4671_PID_VELOCITY_LIMIT_SHIFT 0 +#define TMC4671_PID_VELOCITY_LIMIT_FIELD ((RegisterField) {TMC4671_PID_VELOCITY_LIMIT_MASK, TMC4671_PID_VELOCITY_LIMIT_SHIFT, TMC4671_PID_VELOCITY_LIMIT, false}) + +#define TMC4671_PID_POSITION_LIMIT_LOW_MASK 0xFFFFFFFF +#define TMC4671_PID_POSITION_LIMIT_LOW_SHIFT 0 +#define TMC4671_PID_POSITION_LIMIT_LOW_FIELD ((RegisterField) {TMC4671_PID_POSITION_LIMIT_LOW_MASK, TMC4671_PID_POSITION_LIMIT_LOW_SHIFT, TMC4671_PID_POSITION_LIMIT_LOW, true}) +#define TMC4671_PID_POSITION_LIMIT_HIGH_MASK 0xFFFFFFFF +#define TMC4671_PID_POSITION_LIMIT_HIGH_SHIFT 0 +#define TMC4671_PID_POSITION_LIMIT_HIGH_FIELD ((RegisterField) {TMC4671_PID_POSITION_LIMIT_HIGH_MASK, TMC4671_PID_POSITION_LIMIT_HIGH_SHIFT, TMC4671_PID_POSITION_LIMIT_HIGH, true}) + +#define TMC4671_MODE_MOTION_MASK 0x000000FF +#define TMC4671_MODE_MOTION_SHIFT 0 +#define TMC4671_MODE_MOTION_FIELD ((RegisterField) {TMC4671_MODE_MOTION_MASK, TMC4671_MODE_MOTION_SHIFT, TMC4671_MODE_RAMP_MODE_MOTION, false}) +#define TMC4671_MODE_RAMP_MASK 0x0000FF00 +#define TMC4671_MODE_RAMP_SHIFT 8 +#define TMC4671_MODE_RAMP_FIELD ((RegisterField) {TMC4671_MODE_RAMP_MASK, TMC4671_MODE_RAMP_SHIFT, TMC4671_MODE_RAMP_MODE_MOTION, false}) +#define TMC4671_MODE_FF_MASK 0x00FF0000 +#define TMC4671_MODE_FF_SHIFT 16 +#define TMC4671_MODE_FF_FIELD ((RegisterField) {TMC4671_MODE_FF_MASK, TMC4671_MODE_FF_SHIFT, TMC4671_MODE_RAMP_MODE_MOTION, false}) +#define TMC4671_MODE_PID_SMPL_MASK 0x7F000000 +#define TMC4671_MODE_PID_SMPL_SHIFT 24 +#define TMC4671_MODE_PID_SMPL_FIELD ((RegisterField) {TMC4671_MODE_PID_SMPL_MASK, TMC4671_MODE_PID_SMPL_SHIFT, TMC4671_MODE_RAMP_MODE_MOTION, false}) +#define TMC4671_MODE_PID_TYPE_MASK 0x80000000 +#define TMC4671_MODE_PID_TYPE_SHIFT 31 +#define TMC4671_MODE_PID_TYPE_FIELD ((RegisterField) {TMC4671_MODE_PID_TYPE_MASK, TMC4671_MODE_PID_TYPE_SHIFT, TMC4671_MODE_RAMP_MODE_MOTION, false}) + +#define TMC4671_PID_FLUX_TARGET_MASK 0x0000FFFF +#define TMC4671_PID_FLUX_TARGET_SHIFT 0 +#define TMC4671_PID_FLUX_TARGET_FIELD ((RegisterField) {TMC4671_PID_FLUX_TARGET_MASK, TMC4671_PID_FLUX_TARGET_SHIFT, TMC4671_PID_TORQUE_FLUX_TARGET, true}) +#define TMC4671_PID_TORQUE_TARGET_MASK 0xFFFF0000 +#define TMC4671_PID_TORQUE_TARGET_SHIFT 16 +#define TMC4671_PID_TORQUE_TARGET_FIELD ((RegisterField) {TMC4671_PID_TORQUE_TARGET_MASK, TMC4671_PID_TORQUE_TARGET_SHIFT, TMC4671_PID_TORQUE_FLUX_TARGET, true}) + +#define TMC4671_PID_FLUX_OFFSET_MASK 0x0000FFFF +#define TMC4671_PID_FLUX_OFFSET_SHIFT 0 +#define TMC4671_PID_FLUX_OFFSET_FIELD ((RegisterField) {TMC4671_PID_FLUX_OFFSET_MASK, TMC4671_PID_FLUX_OFFSET_SHIFT, TMC4671_PID_TORQUE_FLUX_OFFSET, true}) +#define TMC4671_PID_TORQUE_OFFSET_MASK 0xFFFF0000 +#define TMC4671_PID_TORQUE_OFFSET_SHIFT 16 +#define TMC4671_PID_TORQUE_OFFSET_FIELD ((RegisterField) {TMC4671_PID_TORQUE_OFFSET_MASK, TMC4671_PID_TORQUE_OFFSET_SHIFT, TMC4671_PID_TORQUE_FLUX_OFFSET, true}) + +#define TMC4671_PID_VELOCITY_TARGET_MASK 0xFFFFFFFF +#define TMC4671_PID_VELOCITY_TARGET_SHIFT 0 +#define TMC4671_PID_VELOCITY_TARGET_FIELD ((RegisterField) {TMC4671_PID_VELOCITY_TARGET_MASK, TMC4671_PID_VELOCITY_TARGET_SHIFT, TMC4671_PID_VELOCITY_TARGET, true}) +#define TMC4671_PID_VELOCITY_OFFSET_MASK 0xFFFFFFFF +#define TMC4671_PID_VELOCITY_OFFSET_SHIFT 0 +#define TMC4671_PID_VELOCITY_OFFSET_FIELD ((RegisterField) {TMC4671_PID_VELOCITY_OFFSET_MASK, TMC4671_PID_VELOCITY_OFFSET_SHIFT, TMC4671_PID_VELOCITY_OFFSET, true}) +#define TMC4671_PID_POSITION_TARGET_MASK 0xFFFFFFFF +#define TMC4671_PID_POSITION_TARGET_SHIFT 0 +#define TMC4671_PID_POSITION_TARGET_FIELD ((RegisterField) {TMC4671_PID_POSITION_TARGET_MASK, TMC4671_PID_POSITION_TARGET_SHIFT, TMC4671_PID_POSITION_TARGET, true}) + +#define TMC4671_PID_FLUX_ACTUAL_MASK 0x0000FFFF +#define TMC4671_PID_FLUX_ACTUAL_SHIFT 0 +#define TMC4671_PID_FLUX_ACTUAL_FIELD ((RegisterField) {TMC4671_PID_FLUX_ACTUAL_MASK, TMC4671_PID_FLUX_ACTUAL_SHIFT, TMC4671_PID_TORQUE_FLUX_ACTUAL, true}) +#define TMC4671_PID_TORQUE_ACTUAL_MASK 0xFFFF0000 +#define TMC4671_PID_TORQUE_ACTUAL_SHIFT 16 +#define TMC4671_PID_TORQUE_ACTUAL_FIELD ((RegisterField) {TMC4671_PID_TORQUE_ACTUAL_MASK, TMC4671_PID_TORQUE_ACTUAL_SHIFT, TMC4671_PID_TORQUE_FLUX_ACTUAL, true}) + +#define TMC4671_PID_VELOCITY_ACTUAL_MASK 0xFFFFFFFF +#define TMC4671_PID_VELOCITY_ACTUAL_SHIFT 0 +#define TMC4671_PID_VELOCITY_ACTUAL_FIELD ((RegisterField) {TMC4671_PID_VELOCITY_ACTUAL_MASK, TMC4671_PID_VELOCITY_ACTUAL_SHIFT, TMC4671_PID_VELOCITY_ACTUAL, true}) +#define TMC4671_PID_POSITION_ACTUAL_MASK 0xFFFFFFFF +#define TMC4671_PID_POSITION_ACTUAL_SHIFT 0 +#define TMC4671_PID_POSITION_ACTUAL_FIELD ((RegisterField) {TMC4671_PID_POSITION_ACTUAL_MASK, TMC4671_PID_POSITION_ACTUAL_SHIFT, TMC4671_PID_POSITION_ACTUAL, true}) +#define TMC4671_PID_TORQUE_ERROR_MASK 0xFFFFFFFF +#define TMC4671_PID_TORQUE_ERROR_SHIFT 0 +#define TMC4671_PID_TORQUE_ERROR_FIELD ((RegisterField) {TMC4671_PID_TORQUE_ERROR_MASK, TMC4671_PID_TORQUE_ERROR_SHIFT, TMC4671_PID_ERROR_DATA, true}) +#define TMC4671_PID_FLUX_ERROR_MASK 0xFFFFFFFF +#define TMC4671_PID_FLUX_ERROR_SHIFT 0 +#define TMC4671_PID_FLUX_ERROR_FIELD ((RegisterField) {TMC4671_PID_FLUX_ERROR_MASK, TMC4671_PID_FLUX_ERROR_SHIFT, TMC4671_PID_ERROR_DATA, true}) +#define TMC4671_PID_VELOCITY_ERROR_MASK 0xFFFFFFFF +#define TMC4671_PID_VELOCITY_ERROR_SHIFT 0 +#define TMC4671_PID_VELOCITY_ERROR_FIELD ((RegisterField) {TMC4671_PID_VELOCITY_ERROR_MASK, TMC4671_PID_VELOCITY_ERROR_SHIFT, TMC4671_PID_ERROR_DATA, true}) +#define TMC4671_PID_POSITION_ERROR_MASK 0xFFFFFFFF +#define TMC4671_PID_POSITION_ERROR_SHIFT 0 +#define TMC4671_PID_POSITION_ERROR_FIELD ((RegisterField) {TMC4671_PID_POSITION_ERROR_MASK, TMC4671_PID_POSITION_ERROR_SHIFT, TMC4671_PID_ERROR_DATA, true}) +#define TMC4671_PID_TORQUE_ERROR_SUM_MASK 0xFFFFFFFF +#define TMC4671_PID_TORQUE_ERROR_SUM_SHIFT 0 +#define TMC4671_PID_TORQUE_ERROR_SUM_FIELD ((RegisterField) {TMC4671_PID_TORQUE_ERROR_SUM_MASK, TMC4671_PID_TORQUE_ERROR_SUM_SHIFT, TMC4671_PID_ERROR_DATA, true}) +#define TMC4671_PID_FLUX_ERROR_SUM_MASK 0xFFFFFFFF +#define TMC4671_PID_FLUX_ERROR_SUM_SHIFT 0 +#define TMC4671_PID_FLUX_ERROR_SUM_FIELD ((RegisterField) {TMC4671_PID_FLUX_ERROR_SUM_MASK, TMC4671_PID_FLUX_ERROR_SUM_SHIFT, TMC4671_PID_ERROR_DATA, true}) +#define TMC4671_PID_VELOCITY_ERROR_SUM_MASK 0xFFFFFFFF +#define TMC4671_PID_VELOCITY_ERROR_SUM_SHIFT 0 +#define TMC4671_PID_VELOCITY_ERROR_SUM_FIELD ((RegisterField) {TMC4671_PID_VELOCITY_ERROR_SUM_MASK, TMC4671_PID_VELOCITY_ERROR_SUM_SHIFT, TMC4671_PID_ERROR_DATA, true}) +#define TMC4671_PID_POSITION_ERROR_SUM_MASK 0xFFFFFFFF +#define TMC4671_PID_POSITION_ERROR_SUM_SHIFT 0 +#define TMC4671_PID_POSITION_ERROR_SUM_FIELD ((RegisterField) {TMC4671_PID_POSITION_ERROR_SUM_MASK, TMC4671_PID_POSITION_ERROR_SUM_SHIFT, TMC4671_PID_ERROR_DATA, true}) +#define TMC4671_PID_ERROR_ADDR_MASK 0x000000FF +#define TMC4671_PID_ERROR_ADDR_SHIFT 0 +#define TMC4671_PID_ERROR_ADDR_FIELD ((RegisterField) {TMC4671_PID_ERROR_ADDR_MASK, TMC4671_PID_ERROR_ADDR_SHIFT, TMC4671_PID_ERROR_ADDR, false}) +#define TMC4671_PIDIN_TARGET_TORQUE_MASK 0xFFFFFFFF +#define TMC4671_PIDIN_TARGET_TORQUE_SHIFT 0 +#define TMC4671_PIDIN_TARGET_TORQUE_FIELD ((RegisterField) {TMC4671_PIDIN_TARGET_TORQUE_MASK, TMC4671_PIDIN_TARGET_TORQUE_SHIFT, TMC4671_INTERIM_DATA, true}) +#define TMC4671_PIDIN_TARGET_FLUX_MASK 0xFFFFFFFF +#define TMC4671_PIDIN_TARGET_FLUX_SHIFT 0 +#define TMC4671_PIDIN_TARGET_FLUX_FIELD ((RegisterField) {TMC4671_PIDIN_TARGET_FLUX_MASK, TMC4671_PIDIN_TARGET_FLUX_SHIFT, TMC4671_INTERIM_DATA, true}) +#define TMC4671_PIDIN_TARGET_VELOCITY_MASK 0xFFFFFFFF +#define TMC4671_PIDIN_TARGET_VELOCITY_SHIFT 0 +#define TMC4671_PIDIN_TARGET_VELOCITY_FIELD ((RegisterField) {TMC4671_PIDIN_TARGET_VELOCITY_MASK, TMC4671_PIDIN_TARGET_VELOCITY_SHIFT, TMC4671_INTERIM_DATA, true}) + +#define TMC4671_PIDIN_TARGET_POSITION_MASK 0xFFFFFFFF +#define TMC4671_PIDIN_TARGET_POSITION_SHIFT 0 +#define TMC4671_PIDIN_TARGET_POSITION_FIELD ((RegisterField) {TMC4671_PIDIN_TARGET_POSITION_MASK, TMC4671_PIDIN_TARGET_POSITION_SHIFT, TMC4671_INTERIM_DATA, true}) +#define TMC4671_PIDOUT_TARGET_TORQUE_MASK 0xFFFFFFFF +#define TMC4671_PIDOUT_TARGET_TORQUE_SHIFT 0 +#define TMC4671_PIDOUT_TARGET_TORQUE_FIELD ((RegisterField) {TMC4671_PIDOUT_TARGET_TORQUE_MASK, TMC4671_PIDOUT_TARGET_TORQUE_SHIFT, TMC4671_INTERIM_DATA, true}) +#define TMC4671_PIDOUT_TARGET_FLUX_MASK 0xFFFFFFFF +#define TMC4671_PIDOUT_TARGET_FLUX_SHIFT 0 +#define TMC4671_PIDOUT_TARGET_FLUX_FIELD ((RegisterField) {TMC4671_PIDOUT_TARGET_FLUX_MASK, TMC4671_PIDOUT_TARGET_FLUX_SHIFT, TMC4671_INTERIM_DATA, true}) +#define TMC4671_PIDOUT_TARGET_VELOCITY_MASK 0xFFFFFFFF +#define TMC4671_PIDOUT_TARGET_VELOCITY_SHIFT 0 +#define TMC4671_PIDOUT_TARGET_VELOCITY_FIELD ((RegisterField) {TMC4671_PIDOUT_TARGET_VELOCITY_MASK, TMC4671_PIDOUT_TARGET_VELOCITY_SHIFT, TMC4671_INTERIM_DATA, true}) +#define TMC4671_PIDOUT_TARGET_POSITION_MASK 0xFFFFFFFF +#define TMC4671_PIDOUT_TARGET_POSITION_SHIFT 0 +#define TMC4671_PIDOUT_TARGET_POSITION_FIELD ((RegisterField) {TMC4671_PIDOUT_TARGET_POSITION_MASK, TMC4671_PIDOUT_TARGET_POSITION_SHIFT, TMC4671_INTERIM_DATA, true}) +#define TMC4671_FOC_IUX_MASK 0x0000FFFF +#define TMC4671_FOC_IUX_SHIFT 0 +#define TMC4671_FOC_IUX_FIELD ((RegisterField) {TMC4671_FOC_IUX_MASK, TMC4671_FOC_IUX_SHIFT, TMC4671_INTERIM_DATA, true}) +#define TMC4671_FOC_IWY_MASK 0xFFFF0000 +#define TMC4671_FOC_IWY_SHIFT 16 +#define TMC4671_FOC_IWY_FIELD ((RegisterField) {TMC4671_FOC_IWY_MASK, TMC4671_FOC_IWY_SHIFT, TMC4671_INTERIM_DATA, true}) +#define TMC4671_FOC_IV_MASK 0x0000FFFF +#define TMC4671_FOC_IV_SHIFT 0 +#define TMC4671_FOC_IV_FIELD ((RegisterField) {TMC4671_FOC_IV_MASK, TMC4671_FOC_IV_SHIFT, TMC4671_INTERIM_DATA, true}) +#define TMC4671_FOC_IA_MASK 0x0000FFFF +#define TMC4671_FOC_IA_SHIFT 0 +#define TMC4671_FOC_IA_FIELD ((RegisterField) {TMC4671_FOC_IA_MASK, TMC4671_FOC_IA_SHIFT, TMC4671_INTERIM_DATA, true}) +#define TMC4671_FOC_IB_MASK 0xFFFF0000 +#define TMC4671_FOC_IB_SHIFT 16 +#define TMC4671_FOC_IB_FIELD ((RegisterField) {TMC4671_FOC_IB_MASK, TMC4671_FOC_IB_SHIFT, TMC4671_INTERIM_DATA, true}) +#define TMC4671_FOC_ID_MASK 0x0000FFFF +#define TMC4671_FOC_ID_SHIFT 0 +#define TMC4671_FOC_ID_FIELD ((RegisterField) {TMC4671_FOC_ID_MASK, TMC4671_FOC_ID_SHIFT, TMC4671_INTERIM_DATA, true}) +#define TMC4671_FOC_IQ_MASK 0xFFFF0000 +#define TMC4671_FOC_IQ_SHIFT 16 +#define TMC4671_FOC_IQ_FIELD ((RegisterField) {TMC4671_FOC_IQ_MASK, TMC4671_FOC_IQ_SHIFT, TMC4671_INTERIM_DATA, true}) +#define TMC4671_FOC_UD_MASK 0x0000FFFF +#define TMC4671_FOC_UD_SHIFT 0 +#define TMC4671_FOC_UD_FIELD ((RegisterField) {TMC4671_FOC_UD_MASK, TMC4671_FOC_UD_SHIFT, TMC4671_INTERIM_DATA, true}) +#define TMC4671_FOC_UQ_MASK 0xFFFF0000 +#define TMC4671_FOC_UQ_SHIFT 16 +#define TMC4671_FOC_UQ_FIELD ((RegisterField) {TMC4671_FOC_UQ_MASK, TMC4671_FOC_UQ_SHIFT, TMC4671_INTERIM_DATA, true}) +#define TMC4671_FOC_UD_LIMITED_MASK 0x0000FFFF +#define TMC4671_FOC_UD_LIMITED_SHIFT 0 +#define TMC4671_FOC_UD_LIMITED_FIELD ((RegisterField) {TMC4671_FOC_UD_LIMITED_MASK, TMC4671_FOC_UD_LIMITED_SHIFT, TMC4671_INTERIM_DATA, true}) +#define TMC4671_FOC_UQ_LIMITED_MASK 0xFFFF0000 +#define TMC4671_FOC_UQ_LIMITED_SHIFT 16 +#define TMC4671_FOC_UQ_LIMITED_FIELD ((RegisterField) {TMC4671_FOC_UQ_LIMITED_MASK, TMC4671_FOC_UQ_LIMITED_SHIFT, TMC4671_INTERIM_DATA, true}) +#define TMC4671_FOC_UA_MASK 0x0000FFFF +#define TMC4671_FOC_UA_SHIFT 0 +#define TMC4671_FOC_UA_FIELD ((RegisterField) {TMC4671_FOC_UA_MASK, TMC4671_FOC_UA_SHIFT, TMC4671_INTERIM_DATA, true}) +#define TMC4671_FOC_UB_MASK 0xFFFF0000 +#define TMC4671_FOC_UB_SHIFT 16 +#define TMC4671_FOC_UB_FIELD ((RegisterField) {TMC4671_FOC_UB_MASK, TMC4671_FOC_UB_SHIFT, TMC4671_INTERIM_DATA, true}) +#define TMC4671_FOC_UUX_MASK 0x0000FFFF +#define TMC4671_FOC_UUX_SHIFT 0 +#define TMC4671_FOC_UUX_FIELD ((RegisterField) {TMC4671_FOC_UUX_MASK, TMC4671_FOC_UUX_SHIFT, TMC4671_INTERIM_DATA, true}) +#define TMC4671_FOC_UWY_MASK 0xFFFF0000 +#define TMC4671_FOC_UWY_SHIFT 16 +#define TMC4671_FOC_UWY_FIELD ((RegisterField) {TMC4671_FOC_UWY_MASK, TMC4671_FOC_UWY_SHIFT, TMC4671_INTERIM_DATA, true}) +#define TMC4671_FOC_UV_MASK 0x0000FFFF +#define TMC4671_FOC_UV_SHIFT 0 +#define TMC4671_FOC_UV_FIELD ((RegisterField) {TMC4671_FOC_UV_MASK, TMC4671_FOC_UV_SHIFT, TMC4671_INTERIM_DATA, true}) +#define TMC4671_PWM_UX_MASK 0x0000FFFF +#define TMC4671_PWM_UX_SHIFT 0 +#define TMC4671_PWM_UX_FIELD ((RegisterField) {TMC4671_PWM_UX_MASK, TMC4671_PWM_UX_SHIFT, TMC4671_INTERIM_DATA, true}) +#define TMC4671_PWM_WY_MASK 0xFFFF0000 +#define TMC4671_PWM_WY_SHIFT 16 +#define TMC4671_PWM_WY_FIELD ((RegisterField) {TMC4671_PWM_WY_MASK, TMC4671_PWM_WY_SHIFT, TMC4671_INTERIM_DATA, true}) +#define TMC4671_PWM_V_MASK 0x0000FFFF +#define TMC4671_PWM_V_SHIFT 0 +#define TMC4671_PWM_V_FIELD ((RegisterField) {TMC4671_PWM_V_MASK, TMC4671_PWM_V_SHIFT, TMC4671_INTERIM_DATA, true}) +#define TMC4671_ADC_I_0_MASK 0x0000FFFF +#define TMC4671_ADC_I_0_SHIFT 0 +#define TMC4671_ADC_I_0_FIELD ((RegisterField) {TMC4671_ADC_I_0_MASK, TMC4671_ADC_I_0_SHIFT, TMC4671_INTERIM_DATA, true}) +#define TMC4671_ADC_I_1_MASK 0xFFFF0000 +#define TMC4671_ADC_I_1_SHIFT 16 +#define TMC4671_ADC_I_1_FIELD ((RegisterField) {TMC4671_ADC_I_1_MASK, TMC4671_ADC_I_1_SHIFT, TMC4671_INTERIM_DATA, true}) +#define TMC4671_PID_FLUX_ACTUAL_DIV256_MASK 0x000000FF +#define TMC4671_PID_FLUX_ACTUAL_DIV256_SHIFT 0 +#define TMC4671_PID_FLUX_ACTUAL_DIV256_FIELD ((RegisterField) {TMC4671_PID_FLUX_ACTUAL_DIV256_MASK, TMC4671_PID_FLUX_ACTUAL_DIV256_SHIFT, TMC4671_INTERIM_DATA, true}) +#define TMC4671_PID_TORQUE_ACTUAL_DIV256_MASK 0x0000FF00 +#define TMC4671_PID_TORQUE_ACTUAL_DIV256_SHIFT 8 +#define TMC4671_PID_TORQUE_ACTUAL_DIV256_FIELD ((RegisterField) {TMC4671_PID_TORQUE_ACTUAL_DIV256_MASK, TMC4671_PID_TORQUE_ACTUAL_DIV256_SHIFT, TMC4671_INTERIM_DATA, true}) +#define TMC4671_PID_FLUX_TARGET_DIV256_MASK 0x00FF0000 +#define TMC4671_PID_FLUX_TARGET_DIV256_SHIFT 16 +#define TMC4671_PID_FLUX_TARGET_DIV256_FIELD ((RegisterField) {TMC4671_PID_FLUX_TARGET_DIV256_MASK, TMC4671_PID_FLUX_TARGET_DIV256_SHIFT, TMC4671_INTERIM_DATA, true}) +#define TMC4671_PID_TORQUE_TARGET_DIV256_MASK 0xFF000000 +#define TMC4671_PID_TORQUE_TARGET_DIV256_SHIFT 24 +#define TMC4671_PID_TORQUE_TARGET_DIV256_FIELD ((RegisterField) {TMC4671_PID_TORQUE_TARGET_DIV256_MASK, TMC4671_PID_TORQUE_TARGET_DIV256_SHIFT, TMC4671_INTERIM_DATA, true}) + +#define TMC4671_PID_VELOCITY_ACTUAL_DIV256_MASK 0x0000FFFF +#define TMC4671_PID_VELOCITY_ACTUAL_DIV256_SHIFT 0 +#define TMC4671_PID_VELOCITY_ACTUAL_DIV256_FIELD ((RegisterField) {TMC4671_PID_VELOCITY_ACTUAL_DIV256_MASK, TMC4671_PID_VELOCITY_ACTUAL_DIV256_SHIFT, TMC4671_INTERIM_DATA, true}) +#define TMC4671_PID_VELOCITY_TARGET_DIV256_MASK 0xFFFF0000 +#define TMC4671_PID_VELOCITY_TARGET_DIV256_SHIFT 16 +#define TMC4671_PID_VELOCITY_TARGET_DIV256_FIELD ((RegisterField) {TMC4671_PID_VELOCITY_TARGET_DIV256_MASK, TMC4671_PID_VELOCITY_TARGET_DIV256_SHIFT, TMC4671_INTERIM_DATA, true}) +#define TMC4671_PID_VELOCITY_ACTUAL_LSB_MASK 0x0000FFFF +#define TMC4671_PID_VELOCITY_ACTUAL_LSB_SHIFT 0 +#define TMC4671_PID_VELOCITY_ACTUAL_LSB_FIELD ((RegisterField) {TMC4671_PID_VELOCITY_ACTUAL_LSB_MASK, TMC4671_PID_VELOCITY_ACTUAL_LSB_SHIFT, TMC4671_INTERIM_DATA, true}) +#define TMC4671_PID_VELOCITY_TARGET_LSB_MASK 0xFFFF0000 +#define TMC4671_PID_VELOCITY_TARGET_LSB_SHIFT 16 +#define TMC4671_PID_VELOCITY_TARGET_LSB_FIELD ((RegisterField) {TMC4671_PID_VELOCITY_TARGET_LSB_MASK, TMC4671_PID_VELOCITY_TARGET_LSB_SHIFT, TMC4671_INTERIM_DATA, true}) +#define TMC4671_PID_POSITION_ACTUAL_DIV256_MASK 0x0000FFFF +#define TMC4671_PID_POSITION_ACTUAL_DIV256_SHIFT 0 +#define TMC4671_PID_POSITION_ACTUAL_DIV256_FIELD ((RegisterField) {TMC4671_PID_POSITION_ACTUAL_DIV256_MASK, TMC4671_PID_POSITION_ACTUAL_DIV256_SHIFT, TMC4671_INTERIM_DATA, true}) +#define TMC4671_PID_POSITION_TARGET_DIV256_MASK 0xFFFF0000 +#define TMC4671_PID_POSITION_TARGET_DIV256_SHIFT 16 +#define TMC4671_PID_POSITION_TARGET_DIV256_FIELD ((RegisterField) {TMC4671_PID_POSITION_TARGET_DIV256_MASK, TMC4671_PID_POSITION_TARGET_DIV256_SHIFT, TMC4671_INTERIM_DATA, true}) +#define TMC4671_PID_POSITION_ACTUAL_LSB_MASK 0x0000FFFF +#define TMC4671_PID_POSITION_ACTUAL_LSB_SHIFT 0 +#define TMC4671_PID_POSITION_ACTUAL_LSB_FIELD ((RegisterField) {TMC4671_PID_POSITION_ACTUAL_LSB_MASK, TMC4671_PID_POSITION_ACTUAL_LSB_SHIFT, TMC4671_INTERIM_DATA, true}) +#define TMC4671_PID_POSITION_TARGET_LSB_MASK 0xFFFF0000 +#define TMC4671_PID_POSITION_TARGET_LSB_SHIFT 16 +#define TMC4671_PID_POSITION_TARGET_LSB_FIELD ((RegisterField) {TMC4671_PID_POSITION_TARGET_LSB_MASK, TMC4671_PID_POSITION_TARGET_LSB_SHIFT, TMC4671_INTERIM_DATA, true}) +#define TMC4671_FF_VELOCITY_MASK 0xFFFFFFFF +#define TMC4671_FF_VELOCITY_SHIFT 0 +#define TMC4671_FF_VELOCITY_FIELD ((RegisterField) {TMC4671_FF_VELOCITY_MASK, TMC4671_FF_VELOCITY_SHIFT, TMC4671_INTERIM_DATA, true}) +#define TMC4671_FF_TORQUE_MASK 0x0000FFFF +#define TMC4671_FF_TORQUE_SHIFT 0 +#define TMC4671_FF_TORQUE_FIELD ((RegisterField) {TMC4671_FF_TORQUE_MASK, TMC4671_FF_TORQUE_SHIFT, TMC4671_INTERIM_DATA, true}) +#define TMC4671_ACTUAL_VELOCITY_PPTM_MASK 0xFFFFFFFF +#define TMC4671_ACTUAL_VELOCITY_PPTM_SHIFT 0 +#define TMC4671_ACTUAL_VELOCITY_PPTM_FIELD ((RegisterField) {TMC4671_ACTUAL_VELOCITY_PPTM_MASK, TMC4671_ACTUAL_VELOCITY_PPTM_SHIFT, TMC4671_INTERIM_DATA, true}) +#define TMC4671_HOME_SWITCH_STATUS_MASK 0x00000001 +#define TMC4671_HOME_SWITCH_STATUS_SHIFT 0 +#define TMC4671_HOME_SWITCH_STATUS_FIELD ((RegisterField) {TMC4671_HOME_SWITCH_STATUS_MASK, TMC4671_HOME_SWITCH_STATUS_SHIFT, TMC4671_INTERIM_DATA, false}) +#define TMC4671_LEFT_SWITCH_STATUS_MASK 0x00000002 +#define TMC4671_LEFT_SWITCH_STATUS_SHIFT 1 +#define TMC4671_LEFT_SWITCH_STATUS_FIELD ((RegisterField) {TMC4671_LEFT_SWITCH_STATUS_MASK, TMC4671_LEFT_SWITCH_STATUS_SHIFT, TMC4671_INTERIM_DATA, false}) +#define TMC4671_RIGHT_SWITCH_STATUS_MASK 0x00000004 +#define TMC4671_RIGHT_SWITCH_STATUS_SHIFT 2 +#define TMC4671_RIGHT_SWITCH_STATUS_FIELD ((RegisterField) {TMC4671_RIGHT_SWITCH_STATUS_MASK, TMC4671_RIGHT_SWITCH_STATUS_SHIFT, TMC4671_INTERIM_DATA, false}) +#define TMC4671_HOME_POSITION_MASK 0xFFFFFFFF +#define TMC4671_HOME_POSITION_SHIFT 0 +#define TMC4671_HOME_POSITION_FIELD ((RegisterField) {TMC4671_HOME_POSITION_MASK, TMC4671_HOME_POSITION_SHIFT, TMC4671_INTERIM_DATA, true}) +#define TMC4671_LEFT_POSITION_MASK 0xFFFFFFFF +#define TMC4671_LEFT_POSITION_SHIFT 0 +#define TMC4671_LEFT_POSITION_FIELD ((RegisterField) {TMC4671_LEFT_POSITION_MASK, TMC4671_LEFT_POSITION_SHIFT, TMC4671_INTERIM_DATA, true}) +#define TMC4671_RIGHT_POSITION_MASK 0xFFFFFFFF +#define TMC4671_RIGHT_POSITION_SHIFT 0 +#define TMC4671_RIGHT_POSITION_FIELD ((RegisterField) {TMC4671_RIGHT_POSITION_MASK, TMC4671_RIGHT_POSITION_SHIFT, TMC4671_INTERIM_DATA, true}) +#define TMC4671_ENC_INIT_HALL_STATUS_MASK 0x0000FFFF +#define TMC4671_ENC_INIT_HALL_STATUS_SHIFT 0 +#define TMC4671_ENC_INIT_HALL_STATUS_FIELD ((RegisterField) {TMC4671_ENC_INIT_HALL_STATUS_MASK, TMC4671_ENC_INIT_HALL_STATUS_SHIFT, TMC4671_INTERIM_DATA, false}) +#define TMC4671_ENC_INIT_HALL_PHI_E_ABN_OFFSET_MASK 0x0000FFFF +#define TMC4671_ENC_INIT_HALL_PHI_E_ABN_OFFSET_SHIFT 0 +#define TMC4671_ENC_INIT_HALL_PHI_E_ABN_OFFSET_FIELD ((RegisterField) {TMC4671_ENC_INIT_HALL_PHI_E_ABN_OFFSET_MASK, TMC4671_ENC_INIT_HALL_PHI_E_ABN_OFFSET_SHIFT, TMC4671_INTERIM_DATA, false}) +#define TMC4671_ENC_INIT_HALL_PHI_E_AENC_OFFSET_MASK 0x0000FFFF +#define TMC4671_ENC_INIT_HALL_PHI_E_AENC_OFFSET_SHIFT 0 +#define TMC4671_ENC_INIT_HALL_PHI_E_AENC_OFFSET_FIELD ((RegisterField) {TMC4671_ENC_INIT_HALL_PHI_E_AENC_OFFSET_MASK, TMC4671_ENC_INIT_HALL_PHI_E_AENC_OFFSET_SHIFT, TMC4671_INTERIM_DATA, false}) +#define TMC4671_ENC_INIT_HALL_PHI_A_AENC_OFFSET_MASK 0x0000FFFF +#define TMC4671_ENC_INIT_HALL_PHI_A_AENC_OFFSET_SHIFT 0 +#define TMC4671_ENC_INIT_HALL_PHI_A_AENC_OFFSET_FIELD ((RegisterField) {TMC4671_ENC_INIT_HALL_PHI_A_AENC_OFFSET_MASK, TMC4671_ENC_INIT_HALL_PHI_A_AENC_OFFSET_SHIFT, TMC4671_INTERIM_DATA, false}) +#define TMC4671_ENC_INIT_MINI_MOVE_STATUS_MASK 0x0000FFFF +#define TMC4671_ENC_INIT_MINI_MOVE_STATUS_SHIFT 0 +#define TMC4671_ENC_INIT_MINI_MOVE_STATUS_FIELD ((RegisterField) {TMC4671_ENC_INIT_MINI_MOVE_STATUS_MASK, TMC4671_ENC_INIT_MINI_MOVE_STATUS_SHIFT, TMC4671_INTERIM_DATA, false}) +#define TMC4671_ENC_INIT_MINI_MOVE_U_D_MASK 0xFFFF0000 +#define TMC4671_ENC_INIT_MINI_MOVE_U_D_SHIFT 16 +#define TMC4671_ENC_INIT_MINI_MOVE_U_D_FIELD ((RegisterField) {TMC4671_ENC_INIT_MINI_MOVE_U_D_MASK, TMC4671_ENC_INIT_MINI_MOVE_U_D_SHIFT, TMC4671_INTERIM_DATA, true}) +#define TMC4671_ENC_INIT_MINI_MOVE_PHI_E_OFFSET_MASK 0x0000FFFF +#define TMC4671_ENC_INIT_MINI_MOVE_PHI_E_OFFSET_SHIFT 0 +#define TMC4671_ENC_INIT_MINI_MOVE_PHI_E_OFFSET_FIELD ((RegisterField) {TMC4671_ENC_INIT_MINI_MOVE_PHI_E_OFFSET_MASK, TMC4671_ENC_INIT_MINI_MOVE_PHI_E_OFFSET_SHIFT, TMC4671_INTERIM_DATA, false}) +#define TMC4671_ENC_INIT_MINI_MOVE_PHI_E_MASK 0xFFFF0000 +#define TMC4671_ENC_INIT_MINI_MOVE_PHI_E_SHIFT 16 +#define TMC4671_ENC_INIT_MINI_MOVE_PHI_E_FIELD ((RegisterField) {TMC4671_ENC_INIT_MINI_MOVE_PHI_E_MASK, TMC4671_ENC_INIT_MINI_MOVE_PHI_E_SHIFT, TMC4671_INTERIM_DATA, false}) +#define TMC4671_SINGLE_PIN_IF_TARGET_TORQUE_MASK 0x0000FFFF +#define TMC4671_SINGLE_PIN_IF_TARGET_TORQUE_SHIFT 0 +#define TMC4671_SINGLE_PIN_IF_TARGET_TORQUE_FIELD ((RegisterField) {TMC4671_SINGLE_PIN_IF_TARGET_TORQUE_MASK, TMC4671_SINGLE_PIN_IF_TARGET_TORQUE_SHIFT, TMC4671_INTERIM_DATA, true}) +#define TMC4671_SINGLE_PIN_IF_PWM_DUTY_CYCLE_MASK 0xFFFF0000 +#define TMC4671_SINGLE_PIN_IF_PWM_DUTY_CYCLE_SHIFT 16 +#define TMC4671_SINGLE_PIN_IF_PWM_DUTY_CYCLE_FIELD ((RegisterField) {TMC4671_SINGLE_PIN_IF_PWM_DUTY_CYCLE_MASK, TMC4671_SINGLE_PIN_IF_PWM_DUTY_CYCLE_SHIFT, TMC4671_INTERIM_DATA, true}) +#define TMC4671_SINGLE_PIN_IF_TARGET_VELOCITY_MASK 0xFFFFFFFF +#define TMC4671_SINGLE_PIN_IF_TARGET_VELOCITY_SHIFT 0 +#define TMC4671_SINGLE_PIN_IF_TARGET_VELOCITY_FIELD ((RegisterField) {TMC4671_SINGLE_PIN_IF_TARGET_VELOCITY_MASK, TMC4671_SINGLE_PIN_IF_TARGET_VELOCITY_SHIFT, TMC4671_INTERIM_DATA, true}) +#define TMC4671_SINGLE_PIN_IF_TARGET_POSITION_MASK 0xFFFFFFFF +#define TMC4671_SINGLE_PIN_IF_TARGET_POSITION_SHIFT 0 +#define TMC4671_SINGLE_PIN_IF_TARGET_POSITION_FIELD ((RegisterField) {TMC4671_SINGLE_PIN_IF_TARGET_POSITION_MASK, TMC4671_SINGLE_PIN_IF_TARGET_POSITION_SHIFT, TMC4671_INTERIM_DATA, true}) +#define TMC4671_INTERIM_ADDR_MASK 0x000000FF +#define TMC4671_INTERIM_ADDR_SHIFT 0 +#define TMC4671_INTERIM_ADDR_FIELD ((RegisterField) {TMC4671_INTERIM_ADDR_MASK, TMC4671_INTERIM_ADDR_SHIFT, TMC4671_INTERIM_ADDR, false}) + +#define TMC4671_WATCHDOG_CFG_MASK 0x00000003 +#define TMC4671_WATCHDOG_CFG_SHIFT 0 +#define TMC4671_WATCHDOG_CFG_FIELD ((RegisterField) {TMC4671_WATCHDOG_CFG_MASK, TMC4671_WATCHDOG_CFG_SHIFT, TMC4671_WATCHDOG_CFG, false}) +#define TMC4671_ADC_VM_LIMIT_LOW_MASK 0x0000FFFF +#define TMC4671_ADC_VM_LIMIT_LOW_SHIFT 0 +#define TMC4671_ADC_VM_LIMIT_LOW_FIELD ((RegisterField) {TMC4671_ADC_VM_LIMIT_LOW_MASK, TMC4671_ADC_VM_LIMIT_LOW_SHIFT, TMC4671_ADC_VM_LIMITS, false}) +#define TMC4671_ADC_VM_LIMIT_HIGH_MASK 0xFFFF0000 +#define TMC4671_ADC_VM_LIMIT_HIGH_SHIFT 16 +#define TMC4671_ADC_VM_LIMIT_HIGH_FIELD ((RegisterField) {TMC4671_ADC_VM_LIMIT_HIGH_MASK, TMC4671_ADC_VM_LIMIT_HIGH_SHIFT, TMC4671_ADC_VM_LIMITS, false}) + +#define TMC4671_A_OF_ABN_RAW_MASK 0x00000001 +#define TMC4671_A_OF_ABN_RAW_SHIFT 0 +#define TMC4671_A_OF_ABN_RAW_FIELD ((RegisterField) {TMC4671_A_OF_ABN_RAW_MASK, TMC4671_A_OF_ABN_RAW_SHIFT, TMC4671_INPUTS_RAW, false}) +#define TMC4671_B_OF_ABN_RAW_MASK 0x00000002 +#define TMC4671_B_OF_ABN_RAW_SHIFT 1 +#define TMC4671_B_OF_ABN_RAW_FIELD ((RegisterField) {TMC4671_B_OF_ABN_RAW_MASK, TMC4671_B_OF_ABN_RAW_SHIFT, TMC4671_INPUTS_RAW, false}) +#define TMC4671_N_OF_ABN_RAW_MASK 0x00000004 +#define TMC4671_N_OF_ABN_RAW_SHIFT 2 +#define TMC4671_N_OF_ABN_RAW_FIELD ((RegisterField) {TMC4671_N_OF_ABN_RAW_MASK, TMC4671_N_OF_ABN_RAW_SHIFT, TMC4671_INPUTS_RAW, false}) + +#define TMC4671_A_OF_ABN_2_RAW_MASK 0x00000010 +#define TMC4671_A_OF_ABN_2_RAW_SHIFT 4 +#define TMC4671_A_OF_ABN_2_RAW_FIELD ((RegisterField) {TMC4671_A_OF_ABN_2_RAW_MASK, TMC4671_A_OF_ABN_2_RAW_SHIFT, TMC4671_INPUTS_RAW, false}) +#define TMC4671_B_OF_ABN_2_RAW_MASK 0x00000020 +#define TMC4671_B_OF_ABN_2_RAW_SHIFT 5 +#define TMC4671_B_OF_ABN_2_RAW_FIELD ((RegisterField) {TMC4671_B_OF_ABN_2_RAW_MASK, TMC4671_B_OF_ABN_2_RAW_SHIFT, TMC4671_INPUTS_RAW, false}) +#define TMC4671_N_OF_ABN_2_RAW_MASK 0x00000040 +#define TMC4671_N_OF_ABN_2_RAW_SHIFT 6 +#define TMC4671_N_OF_ABN_2_RAW_FIELD ((RegisterField) {TMC4671_N_OF_ABN_2_RAW_MASK, TMC4671_N_OF_ABN_2_RAW_SHIFT, TMC4671_INPUTS_RAW, false}) + +#define TMC4671_HALL_UX_OF_HALL_RAW_MASK 0x00000100 +#define TMC4671_HALL_UX_OF_HALL_RAW_SHIFT 8 +#define TMC4671_HALL_UX_OF_HALL_RAW_FIELD ((RegisterField) {TMC4671_HALL_UX_OF_HALL_RAW_MASK, TMC4671_HALL_UX_OF_HALL_RAW_SHIFT, TMC4671_INPUTS_RAW, false}) +#define TMC4671_HALL_V_OF_HALL_RAW_MASK 0x00000200 +#define TMC4671_HALL_V_OF_HALL_RAW_SHIFT 9 +#define TMC4671_HALL_V_OF_HALL_RAW_FIELD ((RegisterField) {TMC4671_HALL_V_OF_HALL_RAW_MASK, TMC4671_HALL_V_OF_HALL_RAW_SHIFT, TMC4671_INPUTS_RAW, false}) +#define TMC4671_HALL_WY_OF_HALL_RAW_MASK 0x00000400 +#define TMC4671_HALL_WY_OF_HALL_RAW_SHIFT 10 +#define TMC4671_HALL_WY_OF_HALL_RAW_FIELD ((RegisterField) {TMC4671_HALL_WY_OF_HALL_RAW_MASK, TMC4671_HALL_WY_OF_HALL_RAW_SHIFT, TMC4671_INPUTS_RAW, false}) + +#define TMC4671_REF_SW_R_RAW_MASK 0x00001000 +#define TMC4671_REF_SW_R_RAW_SHIFT 12 +#define TMC4671_REF_SW_R_RAW_FIELD ((RegisterField) {TMC4671_REF_SW_R_RAW_MASK, TMC4671_REF_SW_R_RAW_SHIFT, TMC4671_INPUTS_RAW, false}) +#define TMC4671_REF_SW_H_RAW_MASK 0x00002000 +#define TMC4671_REF_SW_H_RAW_SHIFT 13 +#define TMC4671_REF_SW_H_RAW_FIELD ((RegisterField) {TMC4671_REF_SW_H_RAW_MASK, TMC4671_REF_SW_H_RAW_SHIFT, TMC4671_INPUTS_RAW, false}) +#define TMC4671_REF_SW_L_RAW_MASK 0x00004000 +#define TMC4671_REF_SW_L_RAW_SHIFT 14 +#define TMC4671_REF_SW_L_RAW_FIELD ((RegisterField) {TMC4671_REF_SW_L_RAW_MASK, TMC4671_REF_SW_L_RAW_SHIFT, TMC4671_INPUTS_RAW, false}) +#define TMC4671_ENABLE_IN_RAW_MASK 0x00008000 +#define TMC4671_ENABLE_IN_RAW_SHIFT 15 +#define TMC4671_ENABLE_IN_RAW_FIELD ((RegisterField) {TMC4671_ENABLE_IN_RAW_MASK, TMC4671_ENABLE_IN_RAW_SHIFT, TMC4671_INPUTS_RAW, false}) +#define TMC4671_STP_OF_DIRSTP_RAW_MASK 0x00010000 +#define TMC4671_STP_OF_DIRSTP_RAW_SHIFT 16 +#define TMC4671_STP_OF_DIRSTP_RAW_FIELD ((RegisterField) {TMC4671_STP_OF_DIRSTP_RAW_MASK, TMC4671_STP_OF_DIRSTP_RAW_SHIFT, TMC4671_INPUTS_RAW, false}) +#define TMC4671_DIR_OF_DIRSTP_RAW_MASK 0x00020000 +#define TMC4671_DIR_OF_DIRSTP_RAW_SHIFT 17 +#define TMC4671_DIR_OF_DIRSTP_RAW_FIELD ((RegisterField) {TMC4671_DIR_OF_DIRSTP_RAW_MASK, TMC4671_DIR_OF_DIRSTP_RAW_SHIFT, TMC4671_INPUTS_RAW, false}) +#define TMC4671_PWM_IN_RAW_MASK 0x00040000 +#define TMC4671_PWM_IN_RAW_SHIFT 18 +#define TMC4671_PWM_IN_RAW_FIELD ((RegisterField) {TMC4671_PWM_IN_RAW_MASK, TMC4671_PWM_IN_RAW_SHIFT, TMC4671_INPUTS_RAW, false}) + +#define TMC4671_HALL_UX_FILT_MASK 0x00100000 +#define TMC4671_HALL_UX_FILT_SHIFT 20 +#define TMC4671_HALL_UX_FILT_FIELD ((RegisterField) {TMC4671_HALL_UX_FILT_MASK, TMC4671_HALL_UX_FILT_SHIFT, TMC4671_INPUTS_RAW, false}) +#define TMC4671_HALL_V_FILT_MASK 0x00200000 +#define TMC4671_HALL_V_FILT_SHIFT 21 +#define TMC4671_HALL_V_FILT_FIELD ((RegisterField) {TMC4671_HALL_V_FILT_MASK, TMC4671_HALL_V_FILT_SHIFT, TMC4671_INPUTS_RAW, false}) +#define TMC4671_HALL_WY_FILT_MASK 0x00400000 +#define TMC4671_HALL_WY_FILT_SHIFT 22 +#define TMC4671_HALL_WY_FILT_FIELD ((RegisterField) {TMC4671_HALL_WY_FILT_MASK, TMC4671_HALL_WY_FILT_SHIFT, TMC4671_INPUTS_RAW, false}) + +#define TMC4671_PWM_IDLE_L_RAW_MASK 0x10000000 +#define TMC4671_PWM_IDLE_L_RAW_SHIFT 28 +#define TMC4671_PWM_IDLE_L_RAW_FIELD ((RegisterField) {TMC4671_PWM_IDLE_L_RAW_MASK, TMC4671_PWM_IDLE_L_RAW_SHIFT, TMC4671_INPUTS_RAW, false}) +#define TMC4671_PWM_IDLE_H_RAW_MASK 0x20000000 +#define TMC4671_PWM_IDLE_H_RAW_SHIFT 29 +#define TMC4671_PWM_IDLE_H_RAW_FIELD ((RegisterField) {TMC4671_PWM_IDLE_H_RAW_MASK, TMC4671_PWM_IDLE_H_RAW_SHIFT, TMC4671_INPUTS_RAW, false}) + +#define TMC4671_OUTPUTS_RAW_0_MASK 0x00000001 +#define TMC4671_OUTPUTS_RAW_0_SHIFT 0 +#define TMC4671_OUTPUTS_RAW_0_FIELD ((RegisterField) {TMC4671_OUTPUTS_RAW_0_MASK, TMC4671_OUTPUTS_RAW_0_SHIFT, TMC4671_OUTPUTS_RAW, false}) +#define TMC4671_OUTPUTS_RAW_1_MASK 0x00000002 +#define TMC4671_OUTPUTS_RAW_1_SHIFT 1 +#define TMC4671_OUTPUTS_RAW_1_FIELD ((RegisterField) {TMC4671_OUTPUTS_RAW_1_MASK, TMC4671_OUTPUTS_RAW_1_SHIFT, TMC4671_OUTPUTS_RAW, false}) +#define TMC4671_OUTPUTS_RAW_2_MASK 0x00000004 +#define TMC4671_OUTPUTS_RAW_2_SHIFT 2 +#define TMC4671_OUTPUTS_RAW_2_FIELD ((RegisterField) {TMC4671_OUTPUTS_RAW_2_MASK, TMC4671_OUTPUTS_RAW_2_SHIFT, TMC4671_OUTPUTS_RAW, false}) +#define TMC4671_OUTPUTS_RAW_3_MASK 0x00000008 +#define TMC4671_OUTPUTS_RAW_3_SHIFT 3 +#define TMC4671_OUTPUTS_RAW_3_FIELD ((RegisterField) {TMC4671_OUTPUTS_RAW_3_MASK, TMC4671_OUTPUTS_RAW_3_SHIFT, TMC4671_OUTPUTS_RAW, false}) +#define TMC4671_OUTPUTS_RAW_4_MASK 0x00000010 +#define TMC4671_OUTPUTS_RAW_4_SHIFT 4 +#define TMC4671_OUTPUTS_RAW_4_FIELD ((RegisterField) {TMC4671_OUTPUTS_RAW_4_MASK, TMC4671_OUTPUTS_RAW_4_SHIFT, TMC4671_OUTPUTS_RAW, false}) +#define TMC4671_OUTPUTS_RAW_5_MASK 0x00000020 +#define TMC4671_OUTPUTS_RAW_5_SHIFT 5 +#define TMC4671_OUTPUTS_RAW_5_FIELD ((RegisterField) {TMC4671_OUTPUTS_RAW_5_MASK, TMC4671_OUTPUTS_RAW_5_SHIFT, TMC4671_OUTPUTS_RAW, false}) +#define TMC4671_OUTPUTS_RAW_6_MASK 0x00000040 +#define TMC4671_OUTPUTS_RAW_6_SHIFT 6 +#define TMC4671_OUTPUTS_RAW_6_FIELD ((RegisterField) {TMC4671_OUTPUTS_RAW_6_MASK, TMC4671_OUTPUTS_RAW_6_SHIFT, TMC4671_OUTPUTS_RAW, false}) +#define TMC4671_OUTPUTS_RAW_7_MASK 0x00000080 +#define TMC4671_OUTPUTS_RAW_7_SHIFT 7 +#define TMC4671_OUTPUTS_RAW_7_FIELD ((RegisterField) {TMC4671_OUTPUTS_RAW_7_MASK, TMC4671_OUTPUTS_RAW_7_SHIFT, TMC4671_OUTPUTS_RAW, false}) + +#define TMC4671_STEP_WIDTH_MASK 0xFFFFFFFF +#define TMC4671_STEP_WIDTH_SHIFT 0 +#define TMC4671_STEP_WIDTH_FIELD ((RegisterField) {TMC4671_STEP_WIDTH_MASK, TMC4671_STEP_WIDTH_SHIFT, TMC4671_STEP_WIDTH, true}) +#define TMC4671_UART_BPS_MASK 0x03FFFFFF +#define TMC4671_UART_BPS_SHIFT 0 +#define TMC4671_UART_BPS_FIELD ((RegisterField) {TMC4671_UART_BPS_MASK, TMC4671_UART_BPS_SHIFT, TMC4671_UART_BPS, false}) +#define TMC4671_ADDR_A_MASK 0x000000FF +#define TMC4671_ADDR_A_SHIFT 0 +#define TMC4671_ADDR_A_FIELD ((RegisterField) {TMC4671_ADDR_A_MASK, TMC4671_ADDR_A_SHIFT, TMC4671_UART_ADDRS, false}) +#define TMC4671_ADDR_B_MASK 0x0000FF00 +#define TMC4671_ADDR_B_SHIFT 8 +#define TMC4671_ADDR_B_FIELD ((RegisterField) {TMC4671_ADDR_B_MASK, TMC4671_ADDR_B_SHIFT, TMC4671_UART_ADDRS, false}) +#define TMC4671_ADDR_C_MASK 0x00FF0000 +#define TMC4671_ADDR_C_SHIFT 16 +#define TMC4671_ADDR_C_FIELD ((RegisterField) {TMC4671_ADDR_C_MASK, TMC4671_ADDR_C_SHIFT, TMC4671_UART_ADDRS, false}) +#define TMC4671_ADDR_D_MASK 0xFF000000 +#define TMC4671_ADDR_D_SHIFT 24 +#define TMC4671_ADDR_D_FIELD ((RegisterField) {TMC4671_ADDR_D_MASK, TMC4671_ADDR_D_SHIFT, TMC4671_UART_ADDRS, false}) +#define TMC4671_GPIO_DSADCI_CONFIG_0_MASK 0x00000001 +#define TMC4671_GPIO_DSADCI_CONFIG_0_SHIFT 0 +#define TMC4671_GPIO_DSADCI_CONFIG_0_FIELD ((RegisterField) {TMC4671_GPIO_DSADCI_CONFIG_0_MASK, TMC4671_GPIO_DSADCI_CONFIG_0_SHIFT, TMC4671_GPIO_dsADCI_CONFIG, false}) +#define TMC4671_GPIO_DSADCI_CONFIG_1_MASK 0x00000002 +#define TMC4671_GPIO_DSADCI_CONFIG_1_SHIFT 1 +#define TMC4671_GPIO_DSADCI_CONFIG_1_FIELD ((RegisterField) {TMC4671_GPIO_DSADCI_CONFIG_1_MASK, TMC4671_GPIO_DSADCI_CONFIG_1_SHIFT, TMC4671_GPIO_dsADCI_CONFIG, false}) +#define TMC4671_GPIO_DSADCI_CONFIG_2_MASK 0x00000004 +#define TMC4671_GPIO_DSADCI_CONFIG_2_SHIFT 2 +#define TMC4671_GPIO_DSADCI_CONFIG_2_FIELD ((RegisterField) {TMC4671_GPIO_DSADCI_CONFIG_2_MASK, TMC4671_GPIO_DSADCI_CONFIG_2_SHIFT, TMC4671_GPIO_dsADCI_CONFIG, false}) +#define TMC4671_GPIO_DSADCI_CONFIG_3_MASK 0x00000008 +#define TMC4671_GPIO_DSADCI_CONFIG_3_SHIFT 3 +#define TMC4671_GPIO_DSADCI_CONFIG_3_FIELD ((RegisterField) {TMC4671_GPIO_DSADCI_CONFIG_3_MASK, TMC4671_GPIO_DSADCI_CONFIG_3_SHIFT, TMC4671_GPIO_dsADCI_CONFIG, false}) +#define TMC4671_GPIO_DSADCI_CONFIG_4_MASK 0x00000010 +#define TMC4671_GPIO_DSADCI_CONFIG_4_SHIFT 4 +#define TMC4671_GPIO_DSADCI_CONFIG_4_FIELD ((RegisterField) {TMC4671_GPIO_DSADCI_CONFIG_4_MASK, TMC4671_GPIO_DSADCI_CONFIG_4_SHIFT, TMC4671_GPIO_dsADCI_CONFIG, false}) +#define TMC4671_GPIO_DSADCI_CONFIG_5_MASK 0x00000020 +#define TMC4671_GPIO_DSADCI_CONFIG_5_SHIFT 5 +#define TMC4671_GPIO_DSADCI_CONFIG_5_FIELD ((RegisterField) {TMC4671_GPIO_DSADCI_CONFIG_5_MASK, TMC4671_GPIO_DSADCI_CONFIG_5_SHIFT, TMC4671_GPIO_dsADCI_CONFIG, false}) +#define TMC4671_GPIO_DSADCI_CONFIG_6_MASK 0x00000040 +#define TMC4671_GPIO_DSADCI_CONFIG_6_SHIFT 6 +#define TMC4671_GPIO_DSADCI_CONFIG_6_FIELD ((RegisterField) {TMC4671_GPIO_DSADCI_CONFIG_6_MASK, TMC4671_GPIO_DSADCI_CONFIG_6_SHIFT, TMC4671_GPIO_dsADCI_CONFIG, false}) +#define TMC4671_GPO_MASK 0x00FF0000 +#define TMC4671_GPO_SHIFT 16 +#define TMC4671_GPO_FIELD ((RegisterField) {TMC4671_GPO_MASK, TMC4671_GPO_SHIFT, TMC4671_GPIO_dsADCI_CONFIG, false}) +#define TMC4671_GPI_MASK 0xFF000000 +#define TMC4671_GPI_SHIFT 24 +#define TMC4671_GPI_FIELD ((RegisterField) {TMC4671_GPI_MASK, TMC4671_GPI_SHIFT, TMC4671_GPIO_dsADCI_CONFIG, false}) + +#define TMC4671_STATUS_FLAGS_0_MASK 0x00000001 +#define TMC4671_STATUS_FLAGS_0_SHIFT 0 +#define TMC4671_STATUS_FLAGS_0_FIELD ((RegisterField) {TMC4671_STATUS_FLAGS_0_MASK, TMC4671_STATUS_FLAGS_0_SHIFT, TMC4671_STATUS_FLAGS, false}) +#define TMC4671_STATUS_FLAGS_1_MASK 0x00000002 +#define TMC4671_STATUS_FLAGS_1_SHIFT 1 +#define TMC4671_STATUS_FLAGS_1_FIELD ((RegisterField) {TMC4671_STATUS_FLAGS_1_MASK, TMC4671_STATUS_FLAGS_1_SHIFT, TMC4671_STATUS_FLAGS, false}) +#define TMC4671_STATUS_FLAGS_2_MASK 0x00000004 +#define TMC4671_STATUS_FLAGS_2_SHIFT 2 +#define TMC4671_STATUS_FLAGS_2_FIELD ((RegisterField) {TMC4671_STATUS_FLAGS_2_MASK, TMC4671_STATUS_FLAGS_2_SHIFT, TMC4671_STATUS_FLAGS, false}) +#define TMC4671_STATUS_FLAGS_3_MASK 0x00000008 +#define TMC4671_STATUS_FLAGS_3_SHIFT 3 +#define TMC4671_STATUS_FLAGS_3_FIELD ((RegisterField) {TMC4671_STATUS_FLAGS_3_MASK, TMC4671_STATUS_FLAGS_3_SHIFT, TMC4671_STATUS_FLAGS, false}) +#define TMC4671_STATUS_FLAGS_4_MASK 0x00000010 +#define TMC4671_STATUS_FLAGS_4_SHIFT 4 +#define TMC4671_STATUS_FLAGS_4_FIELD ((RegisterField) {TMC4671_STATUS_FLAGS_4_MASK, TMC4671_STATUS_FLAGS_4_SHIFT, TMC4671_STATUS_FLAGS, false}) +#define TMC4671_STATUS_FLAGS_5_MASK 0x00000020 +#define TMC4671_STATUS_FLAGS_5_SHIFT 5 +#define TMC4671_STATUS_FLAGS_5_FIELD ((RegisterField) {TMC4671_STATUS_FLAGS_5_MASK, TMC4671_STATUS_FLAGS_5_SHIFT, TMC4671_STATUS_FLAGS, false}) +#define TMC4671_STATUS_FLAGS_6_MASK 0x00000040 +#define TMC4671_STATUS_FLAGS_6_SHIFT 6 +#define TMC4671_STATUS_FLAGS_6_FIELD ((RegisterField) {TMC4671_STATUS_FLAGS_6_MASK, TMC4671_STATUS_FLAGS_6_SHIFT, TMC4671_STATUS_FLAGS, false}) +#define TMC4671_STATUS_FLAGS_7_MASK 0x00000080 +#define TMC4671_STATUS_FLAGS_7_SHIFT 7 +#define TMC4671_STATUS_FLAGS_7_FIELD ((RegisterField) {TMC4671_STATUS_FLAGS_7_MASK, TMC4671_STATUS_FLAGS_7_SHIFT, TMC4671_STATUS_FLAGS, false}) +#define TMC4671_STATUS_FLAGS_8_MASK 0x00000100 +#define TMC4671_STATUS_FLAGS_8_SHIFT 8 +#define TMC4671_STATUS_FLAGS_8_FIELD ((RegisterField) {TMC4671_STATUS_FLAGS_8_MASK, TMC4671_STATUS_FLAGS_8_SHIFT, TMC4671_STATUS_FLAGS, false}) +#define TMC4671_STATUS_FLAGS_9_MASK 0x00000200 +#define TMC4671_STATUS_FLAGS_9_SHIFT 9 +#define TMC4671_STATUS_FLAGS_9_FIELD ((RegisterField) {TMC4671_STATUS_FLAGS_9_MASK, TMC4671_STATUS_FLAGS_9_SHIFT, TMC4671_STATUS_FLAGS, false}) +#define TMC4671_STATUS_FLAGS_10_MASK 0x00000400 +#define TMC4671_STATUS_FLAGS_10_SHIFT 10 +#define TMC4671_STATUS_FLAGS_10_FIELD ((RegisterField) {TMC4671_STATUS_FLAGS_10_MASK, TMC4671_STATUS_FLAGS_10_SHIFT, TMC4671_STATUS_FLAGS, false}) +#define TMC4671_STATUS_FLAGS_11_MASK 0x00000800 +#define TMC4671_STATUS_FLAGS_11_SHIFT 11 +#define TMC4671_STATUS_FLAGS_11_FIELD ((RegisterField) {TMC4671_STATUS_FLAGS_11_MASK, TMC4671_STATUS_FLAGS_11_SHIFT, TMC4671_STATUS_FLAGS, false}) +#define TMC4671_STATUS_FLAGS_12_MASK 0x00001000 +#define TMC4671_STATUS_FLAGS_12_SHIFT 12 +#define TMC4671_STATUS_FLAGS_12_FIELD ((RegisterField) {TMC4671_STATUS_FLAGS_12_MASK, TMC4671_STATUS_FLAGS_12_SHIFT, TMC4671_STATUS_FLAGS, false}) +#define TMC4671_STATUS_FLAGS_13_MASK 0x00002000 +#define TMC4671_STATUS_FLAGS_13_SHIFT 13 +#define TMC4671_STATUS_FLAGS_13_FIELD ((RegisterField) {TMC4671_STATUS_FLAGS_13_MASK, TMC4671_STATUS_FLAGS_13_SHIFT, TMC4671_STATUS_FLAGS, false}) +#define TMC4671_STATUS_FLAGS_14_MASK 0x00004000 +#define TMC4671_STATUS_FLAGS_14_SHIFT 14 +#define TMC4671_STATUS_FLAGS_14_FIELD ((RegisterField) {TMC4671_STATUS_FLAGS_14_MASK, TMC4671_STATUS_FLAGS_14_SHIFT, TMC4671_STATUS_FLAGS, false}) +#define TMC4671_STATUS_FLAGS_15_MASK 0x00008000 +#define TMC4671_STATUS_FLAGS_15_SHIFT 15 +#define TMC4671_STATUS_FLAGS_15_FIELD ((RegisterField) {TMC4671_STATUS_FLAGS_15_MASK, TMC4671_STATUS_FLAGS_15_SHIFT, TMC4671_STATUS_FLAGS, false}) +#define TMC4671_STATUS_FLAGS_16_MASK 0x00010000 +#define TMC4671_STATUS_FLAGS_16_SHIFT 16 +#define TMC4671_STATUS_FLAGS_16_FIELD ((RegisterField) {TMC4671_STATUS_FLAGS_16_MASK, TMC4671_STATUS_FLAGS_16_SHIFT, TMC4671_STATUS_FLAGS, false}) +#define TMC4671_STATUS_FLAGS_17_MASK 0x00020000 +#define TMC4671_STATUS_FLAGS_17_SHIFT 17 +#define TMC4671_STATUS_FLAGS_17_FIELD ((RegisterField) {TMC4671_STATUS_FLAGS_17_MASK, TMC4671_STATUS_FLAGS_17_SHIFT, TMC4671_STATUS_FLAGS, false}) +#define TMC4671_STATUS_FLAGS_18_MASK 0x00040000 +#define TMC4671_STATUS_FLAGS_18_SHIFT 18 +#define TMC4671_STATUS_FLAGS_18_FIELD ((RegisterField) {TMC4671_STATUS_FLAGS_18_MASK, TMC4671_STATUS_FLAGS_18_SHIFT, TMC4671_STATUS_FLAGS, false}) +#define TMC4671_STATUS_FLAGS_19_MASK 0x00080000 +#define TMC4671_STATUS_FLAGS_19_SHIFT 19 +#define TMC4671_STATUS_FLAGS_19_FIELD ((RegisterField) {TMC4671_STATUS_FLAGS_19_MASK, TMC4671_STATUS_FLAGS_19_SHIFT, TMC4671_STATUS_FLAGS, false}) +#define TMC4671_STATUS_FLAGS_20_MASK 0x00100000 +#define TMC4671_STATUS_FLAGS_20_SHIFT 20 +#define TMC4671_STATUS_FLAGS_20_FIELD ((RegisterField) {TMC4671_STATUS_FLAGS_20_MASK, TMC4671_STATUS_FLAGS_20_SHIFT, TMC4671_STATUS_FLAGS, false}) +#define TMC4671_STATUS_FLAGS_21_MASK 0x00200000 +#define TMC4671_STATUS_FLAGS_21_SHIFT 21 +#define TMC4671_STATUS_FLAGS_21_FIELD ((RegisterField) {TMC4671_STATUS_FLAGS_21_MASK, TMC4671_STATUS_FLAGS_21_SHIFT, TMC4671_STATUS_FLAGS, false}) +#define TMC4671_STATUS_FLAGS_22_MASK 0x00400000 +#define TMC4671_STATUS_FLAGS_22_SHIFT 22 +#define TMC4671_STATUS_FLAGS_22_FIELD ((RegisterField) {TMC4671_STATUS_FLAGS_22_MASK, TMC4671_STATUS_FLAGS_22_SHIFT, TMC4671_STATUS_FLAGS, false}) +#define TMC4671_STATUS_FLAGS_23_MASK 0x00800000 +#define TMC4671_STATUS_FLAGS_23_SHIFT 23 +#define TMC4671_STATUS_FLAGS_23_FIELD ((RegisterField) {TMC4671_STATUS_FLAGS_23_MASK, TMC4671_STATUS_FLAGS_23_SHIFT, TMC4671_STATUS_FLAGS, false}) +#define TMC4671_STATUS_FLAGS_24_MASK 0x01000000 +#define TMC4671_STATUS_FLAGS_24_SHIFT 24 +#define TMC4671_STATUS_FLAGS_24_FIELD ((RegisterField) {TMC4671_STATUS_FLAGS_24_MASK, TMC4671_STATUS_FLAGS_24_SHIFT, TMC4671_STATUS_FLAGS, false}) +#define TMC4671_STATUS_FLAGS_25_MASK 0x02000000 +#define TMC4671_STATUS_FLAGS_25_SHIFT 25 +#define TMC4671_STATUS_FLAGS_25_FIELD ((RegisterField) {TMC4671_STATUS_FLAGS_25_MASK, TMC4671_STATUS_FLAGS_25_SHIFT, TMC4671_STATUS_FLAGS, false}) +#define TMC4671_STATUS_FLAGS_26_MASK 0x04000000 +#define TMC4671_STATUS_FLAGS_26_SHIFT 26 +#define TMC4671_STATUS_FLAGS_26_FIELD ((RegisterField) {TMC4671_STATUS_FLAGS_26_MASK, TMC4671_STATUS_FLAGS_26_SHIFT, TMC4671_STATUS_FLAGS, false}) +#define TMC4671_STATUS_FLAGS_27_MASK 0x08000000 +#define TMC4671_STATUS_FLAGS_27_SHIFT 27 +#define TMC4671_STATUS_FLAGS_27_FIELD ((RegisterField) {TMC4671_STATUS_FLAGS_27_MASK, TMC4671_STATUS_FLAGS_27_SHIFT, TMC4671_STATUS_FLAGS, false}) +#define TMC4671_STATUS_FLAGS_28_MASK 0x10000000 +#define TMC4671_STATUS_FLAGS_28_SHIFT 28 +#define TMC4671_STATUS_FLAGS_28_FIELD ((RegisterField) {TMC4671_STATUS_FLAGS_28_MASK, TMC4671_STATUS_FLAGS_28_SHIFT, TMC4671_STATUS_FLAGS, false}) +#define TMC4671_STATUS_FLAGS_29_MASK 0x20000000 +#define TMC4671_STATUS_FLAGS_29_SHIFT 29 +#define TMC4671_STATUS_FLAGS_29_FIELD ((RegisterField) {TMC4671_STATUS_FLAGS_29_MASK, TMC4671_STATUS_FLAGS_29_SHIFT, TMC4671_STATUS_FLAGS, false}) +#define TMC4671_STATUS_FLAGS_30_MASK 0x40000000 +#define TMC4671_STATUS_FLAGS_30_SHIFT 30 +#define TMC4671_STATUS_FLAGS_30_FIELD ((RegisterField) {TMC4671_STATUS_FLAGS_30_MASK, TMC4671_STATUS_FLAGS_30_SHIFT, TMC4671_STATUS_FLAGS, false}) +#define TMC4671_STATUS_FLAGS_31_MASK 0x80000000 +#define TMC4671_STATUS_FLAGS_31_SHIFT 31 +#define TMC4671_STATUS_FLAGS_31_FIELD ((RegisterField) {TMC4671_STATUS_FLAGS_31_MASK, TMC4671_STATUS_FLAGS_31_SHIFT, TMC4671_STATUS_FLAGS, false}) + +#define TMC4671_WARNING_MASK_MASK 0xFFFFFFFF +#define TMC4671_WARNING_MASK_SHIFT 0 +#define TMC4671_WARNING_MASK_FIELD ((RegisterField) {TMC4671_WARNING_MASK_MASK, TMC4671_WARNING_MASK_SHIFT, TMC4671_STATUS_MASK, false}) + +#endif /* TMC4671_HW_ABSTRACTION_H_ */ diff --git a/firmware/lib/tmc/ic/TMC4671/registercall_hierarchy_flowchart_SPI.svg b/firmware/lib/tmc/ic/TMC4671/registercall_hierarchy_flowchart_SPI.svg new file mode 100755 index 0000000..cbad58f --- /dev/null +++ b/firmware/lib/tmc/ic/TMC4671/registercall_hierarchy_flowchart_SPI.svg @@ -0,0 +1,3 @@ + + +

HAL

HAL

APP (Eval)

APP (Eval)

API

API
Read a register
  •  Call tmcXXXX_readRegister function
Read a register...
Returns the register read value
Returns the register read value
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
tmcXXXX.c
tmcXXXX.c
SPI.c
SPI.c
tmcXXXX_eval.c
tmcXXXX_eval.c

 Implementation of SPI_readWrite
  • Sends and receives bytes on the SPI bus
Implementation of SPI_readWrite...
Returns the raw reply data
Returns the raw reply data

Implementation of tmcXXXX_readWriteSPI
  • Sets the CSN pin to LOW
  • Takes the array of data to write
  • Calls hardware function SPI_readWrite
  • Upon completion of data transfer,
    sets CSN to 
    HIGH
Implementation of tmcXXXX_readWriteSPI...
Passes on the raw reply data to the API
Passes on the raw reply data to the API
Implementation of readRegisterSPI
  • Constructs the datagram
  • Calls HAL wrapper function 
Implementation of readRegisterSPI...
tmcXXXX_readWriteSPI
tmcXXXX_readWriteSPI
Parses the reply and returns the register value
Parses the reply and returns the register value
Implementation of tmcXXXX_readRegister 
  • Check which bus is active SPI/UART. (e.g. SPI)
  • Calls bus-specific function (e.g. readRegisterSPI)
 
Implementation of tmcXXXX_readRegister...
Returns the register read value
Returns the register read value
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC4671/uml-tmc-api.svg b/firmware/lib/tmc/ic/TMC4671/uml-tmc-api.svg new file mode 100755 index 0000000..5a5f8dd --- /dev/null +++ b/firmware/lib/tmc/ic/TMC4671/uml-tmc-api.svg @@ -0,0 +1,3 @@ + + +

TMCXXXX_HW_Abstraction.h



TMCXXXX_HW_Abstraction.h...
// Constants
#define TMCXXXX_MOTORS              
                          
// Register definitions
#define TMCXXXX_GCONF        
                          ⋮
// Register fields definitions
#define TMCXXXX_GCONF_OTPW_FIELD
                     
// Constants...

TMCXXXX.h



TMCXXXX.h...
extern void tmcXXXX_readWriteSPI();
extern void tmcXXXX_readWriteUART();
extern TMCXXXXBusType tmcXXXX_getBusType();
extern uint8_t tmcXXXX_getNodeAddress();
                                  ⋮
tmcXXXX_readRegister();
tmcXXXX_writeRegister();
                                  ⋮
extern void tmcXXXX_readWriteSPI();...

TMCXXXX.c



TMCXXXX.c...
const uint8_t tmcCRCTable_Poly7Reflected[256] = {...};
int32_t tmcXXXX_readRegister(){
/* Call tmcXXXX_getBusType();
 * Based on bus type, call readRegisterSPI/UART() that
 * further calls tmcXXXX_readWriteSPI/UART();
 * For UART it also calls tmcXXXX_getNodeAddress();
                                           ⋮
}
                                           ⋮
const uint8_t tmcCRCTable_Poly7Reflected[256] = {.....
TMC-API
TMC-API

TMCXXXX_Simple_Rotation.h


TMCXXXX_Simple_Rotation.h...
void initAllMotors();
             ⋮
  
void initAllMotors()...

TMCXXXX_Simple_Rotation.c


TMCXXXX_Simple_Rotation.c...
void initAllMotors(){

// Configuring registers to enable motor drivers etc..
tmcXXXX_writeRegister();
                    ⋮
}
                    ⋮
void initAllMotors(){...
Examples
Examples
User Project
User Project

User_Project.h


User_Project.h

User_Project.c








User_Project.c...

void tmcXXXX_readWriteSPI(){
                           ⋮
}
void tmcXXXX_readWriteUART(){
                           ⋮
}
TMCXXXXBusType tmcXXXX_getBusType(){
                           ⋮
}
uint8_t tmcXXXX_getNodeAddress(){
                           ⋮
}

// User Code
                           ⋮
void tmcXXXX_readWriteSPI(){...
#include "TMCXXXX_HW_Abstraction.h"
#include "TMCXXXX.h"
#include "TMCXXXX_Simple_Rotation.h"
                                ⋮
TMCXXXXBusType bus = IC_BUS_SPI/UART;
uint8_t nodeAddress = <nodeAddress>;
                                ⋮
#include "TMCXXXX_HW_Abstraction.h"...
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC5031/README.md b/firmware/lib/tmc/ic/TMC5031/README.md new file mode 100755 index 0000000..db39f2f --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5031/README.md @@ -0,0 +1,47 @@ +# TMC5031 + + +## How to use + +To access the TMC5031's registers, the TMC-API offers two functions: **tmc5031_readRegister** and **tmc5031_writeRegister**. +Each of these functions takes in an **icID**, which is used to identify the IC when multiple ICs are connected. This identifier is passed down to the callback functions (see How to Integrate). + +## How to integrate: overview + +1. Include all the files of the TMC-API/ic/tmc/TMC5031 folder into the custom project. +2. Include the TMC5031.h file in the custom source code. +3. Implement the necessary callback functions (see below). +4. (optional): Take a look at the Examples subfolder for ready-made examples of the TMC-API usage. + +## Accessing the TMC5031 via SPI +The following diagram depicts how to access the TMC5031 via SPI using the TMC-API. + +![screenshot](registercall_hierarchy_flowchart_SPI.svg) + +###The description of the functions, in the above flowchart, are as follows: +- The functions tmc5031_readRegister and tmc5031_writeRegister are used to read and write the registers respectively. These functions check the current active bus and calls the bus-specific function i.e readRegisterSPI or writeRegisterSPI. +- These bus specific functions constructs the datagram and further calls the bus specific callback 'tmcXXXX_readWriteSPI. +- This callback function further calls the hardware specific read/write function for SPI and needs to be implemented externally. + +### How to integrate: Callback functions +To communicate with TMC5031 IC, the TMC-API library needs to know which bus (UART, SPI) it shall use. For that, the callback function **'tmc5031_getBusType()'** needs to be implemented. +Additionally, implement the following callback functions to access the chip via SPI: +1. **tmc5031_readWriteSPI()**, which is a HAL wrapper function that provides the necessary hardware access. This function should also set the chip select pin CSN to low before starting the data transfer and set to high upon completion. Please refer to the datasheet of the IC for further details. + +### Option to use the cache logic for Write-Only registers +The chip features write-only registers that are unable to be read, necessitating the creation of a shadow copy to cache their contents. This copy is automatically updated whenever data is written to these registers. This cache logic could be enabled by setting the macro **TMC5031_CACHE** to **'1'** or disabled by setting to **'0'** respectively. If this feature is enabled then there comes another option to use **tmc5031_cache** function, which is already implemeted in the API, by defining **TMC5031_ENABLE_TMC_CACHE** macro to **'1** or one can implement their own function. The function **tmc5031_cache** works for both reading from and writing to the shadow array. It first checks whether the register has write-only access and data needs to be read from the hadow copy. On the basis of that, it returns **true** or **false**. The shadowRegisters on the premade cache implementation need to be one per chip. **TMC5031_IC_CACHE_COUNT** is set to '1' by default and is user-overwritable. If multiple chips are being used in the same project, increment its value to the number of chips connected. + + +## Further info +### Dependency graph for the ICs with new register R/W mechanism +This graph illustrates the relationships between files within the TMC-API library, highlighting dependencies and identifying the files that are essential for integrating the library into the custom projects. + +![screenshot](uml-tmc-api.svg) + +### Example usage: TMC-Evalsystem +**For a reference usage of the TMC-API**, visit the [TMC-Evalsystem](https://github.com/analogdevicesinc/TMC-EvalSystem) + +## Migration status +The TMC5031 has been reworked to the access system described above. For more infos on the status of this and other ICs, check out the [migration page](https://github.com/analogdevicesinc/TMC-API/issues/53). + + diff --git a/firmware/lib/tmc/ic/TMC5031/TMC5031.c b/firmware/lib/tmc/ic/TMC5031/TMC5031.c new file mode 100755 index 0000000..2a56da7 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5031/TMC5031.c @@ -0,0 +1,191 @@ +/******************************************************************************* +* Copyright © 2017 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#include "TMC5031.h" +/**************************************************************** Cache Implementation *************************************************************************/ + +#if TMC5031_CACHE == 0 +static inline bool tmc5031_cache(uint16_t icID, TMC5031CacheOp operation, uint8_t address, uint32_t *value) +{ + UNUSED(icID); + UNUSED(address); + UNUSED(operation); + return false; +} +#else +#if TMC5031_ENABLE_TMC_CACHE == 1 + +uint8_t tmc5031_dirtyBits[TMC5031_IC_CACHE_COUNT][TMC5031_REGISTER_COUNT/8]= {0}; +int32_t tmc5031_shadowRegister[TMC5031_IC_CACHE_COUNT][TMC5031_REGISTER_COUNT]; + +void tmc5031_setDirtyBit(uint16_t icID, uint8_t index, bool value) + { + if(index >= TMC5031_REGISTER_COUNT) + return; + + uint8_t *tmp = &tmc5031_dirtyBits[icID][index / 8]; + uint8_t shift = (index % 8); + uint8_t mask = 1 << shift; + *tmp = (((*tmp) & (~(mask))) | (((value) << (shift)) & (mask))); +} + +bool tmc5031_getDirtyBit(uint16_t icID, uint8_t index) +{ + if(index >= TMC5031_REGISTER_COUNT) + return false; + + uint8_t *tmp = &tmc5031_dirtyBits[icID][index / 8]; + uint8_t shift = (index % 8); + return ((*tmp) >> shift) & 1; +} +/* + * This function is used to cache the value written to the Write-Only registers in the form of shadow array. + * The shadow copy is then used to read these kinds of registers. + */ + +bool tmc5031_cache(uint16_t icID, TMC5031CacheOp operation, uint8_t address, uint32_t *value) +{ + if (operation == TMC5031_CACHE_READ) + { + // Check if the value should come from cache + + // Only supported chips have a cache + if (icID >= TMC5031_IC_CACHE_COUNT) + return false; + + // Only non-readable registers care about caching + // Note: This could also be used to cache i.e. RW config registers to reduce bus accesses + if (TMC5031_IS_READABLE(tmc5031_registerAccess[address])) + return false; + + // Grab the value from the cache + *value = tmc5031_shadowRegister[icID][address]; + return true; + } + else if (operation == TMC5031_CACHE_WRITE || operation == TMC5031_CACHE_FILL_DEFAULT) + { + // Fill the cache + + // only supported chips have a cache + if (icID >= TMC5031_IC_CACHE_COUNT) + return false; + + // Write to the shadow register. + tmc5031_shadowRegister[icID][address] = *value; + // For write operations, mark the register dirty + if (operation == TMC5031_CACHE_WRITE) + { + tmc5031_setDirtyBit(icID, address, true); + } + + return true; + } + return false; +} + +void tmc5031_initCache() +{ + // Check if we have constants defined + if(ARRAY_SIZE(tmc5031_RegisterConstants) == 0) + return; + + size_t i, j, id; + + for(i = 0, j = 0; i < TMC5031_REGISTER_COUNT; i++) + { + // We only need to worry about hardware preset, write-only registers + // that have not yet been written (no dirty bit) here. + if(tmc5031_registerAccess[i] != TMC5031_ACCESS_W_PRESET) + continue; + + // Search the constant list for the current address. With the constant + // list being sorted in ascended order, we can walk through the list + // until the entry with an address equal or greater than i + while(j < ARRAY_SIZE(tmc5031_RegisterConstants) && (tmc5031_RegisterConstants[j].address < i)) + j++; + + // Abort when we reach the end of the constant list + if (j == ARRAY_SIZE(tmc5031_RegisterConstants)) + break; + + // If we have an entry for our current address, write the constant + if(tmc5031_RegisterConstants[j].address == i) + { + for (id = 0; id < TMC5031_IC_CACHE_COUNT; id++) + { + uint32_t temp = tmc5031_RegisterConstants[j].value; + tmc5031_cache(id, TMC5031_CACHE_FILL_DEFAULT, i, &temp); + } + } + } +} +#else +// User must implement their own cache +extern bool tmc5031_cache(uint16_t icID, TMC5031CacheOp operation, uint8_t address, uint32_t *value); +#endif +#endif + + +/************************************************************* read / write Implementation *********************************************************************/ + + +static int32_t readRegisterSPI(uint16_t icID, uint8_t address); +static void writeRegisterSPI(uint16_t icID, uint8_t address, int32_t value); + +int32_t tmc5031_readRegister(uint16_t icID, uint8_t address) +{ + return readRegisterSPI(icID, address); + // ToDo: Error handling +} + +void tmc5031_writeRegister(uint16_t icID, uint8_t address, int32_t value) +{ + writeRegisterSPI(icID, address, value); +} + +int32_t readRegisterSPI(uint16_t icID, uint8_t address) +{ + uint32_t value; + uint8_t data[5] = { 0 }; + + // Read from cache for registers with write-only access + if (tmc5031_cache(icID, TMC5031_CACHE_READ, address, &value)) + return value; + + // clear write bit + data[0] = address & TMC5031_ADDRESS_MASK; + + // Send the read request + tmc5031_readWriteSPI(icID, &data[0], sizeof(data)); + + // Rewrite address and clear write bit + data[0] = address & TMC5031_ADDRESS_MASK; + + // Send another request to receive the read reply + tmc5031_readWriteSPI(icID, &data[0], sizeof(data)); + + return ((int32_t)data[1] << 24) | ((int32_t) data[2] << 16) | ((int32_t) data[3] << 8) | ((int32_t) data[4]); +} + +void writeRegisterSPI(uint16_t icID, uint8_t address, int32_t value) +{ + uint8_t data[5] = { 0 }; + + data[0] = address | TMC5031_WRITE_BIT; + data[1] = 0xFF & (value>>24); + data[2] = 0xFF & (value>>16); + data[3] = 0xFF & (value>>8); + data[4] = 0xFF & (value>>0); + + // Send the write request + tmc5031_readWriteSPI(icID, &data[0], sizeof(data)); + + //Cache the registers with write-only access + tmc5031_cache(icID, TMC5031_CACHE_WRITE, address, (uint32_t *)&value); +} diff --git a/firmware/lib/tmc/ic/TMC5031/TMC5031.h b/firmware/lib/tmc/ic/TMC5031/TMC5031.h new file mode 100755 index 0000000..25890f9 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5031/TMC5031.h @@ -0,0 +1,226 @@ +/******************************************************************************* +* Copyright © 2017 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#ifndef TMC_IC_TMC5031_H_ +#define TMC_IC_TMC5031_H_ + +#include +#include +#include +#include "TMC5031_HW_Abstraction.h" + +/******************************************************************************* +* API Configuration Defines +* These control optional features of the TMC-API implementation. +* These can be commented in/out here or defined from the build system. +*******************************************************************************/ + +// Uncomment if you want to save space..... +// and put the table into your own .c file +//#define TMC_API_EXTERNAL_CRC_TABLE 1 + +// To enable the cache mechanism in order to keep the copy of all registers, set TMC5031_CACHE to '1'. +// With this mechanism the value of write-only registers could be read from their shadow copies. +#ifndef TMC5031_CACHE +#define TMC5031_CACHE 1 +//#define TMC5031_CACHE 0 +#endif + +// To use the caching mechanism already implemented by the TMC-API, set TMC5031_ENABLE_TMC_CACHE to '1'. +// Set TMC5031_ENABLE_TMC_CACHE to '0' if one wants to have their own cache implementation. +#ifndef TMC5031_ENABLE_TMC_CACHE +#define TMC5031_ENABLE_TMC_CACHE 1 +//#define TMC5031_ENABLE_TMC_CACHE 0 +#endif + +/******************************************************************************/ + +/************************************************************* read / write Implementation *********************************************************************/ +// => TMC-API wrapper +extern void tmc5031_readWriteSPI(uint16_t icID, uint8_t *data, size_t dataLength); +// => TMC-API wrapper + +int32_t tmc5031_readRegister(uint16_t icID, uint8_t address); +void tmc5031_writeRegister(uint16_t icID, uint8_t address, int32_t value); + +typedef struct +{ + uint32_t mask; + uint8_t shift; + uint8_t address; + bool isSigned; +} RegisterField; + +static inline uint32_t tmc5031_fieldExtract(uint32_t data, RegisterField field) +{ + uint32_t value = (data & field.mask) >> field.shift; + + if (field.isSigned) + { + // Apply signedness conversion + uint32_t baseMask = field.mask >> field.shift; + uint32_t signMask = baseMask & (~baseMask >> 1); + value = (value ^ signMask) - signMask; + } + + return value; +} + +static inline uint32_t tmc5031_fieldRead(uint16_t icID, RegisterField field) +{ +uint32_t value = tmc5031_readRegister(icID, field.address); + + return tmc5031_fieldExtract(value, field); +} + +static inline uint32_t tmc5031_fieldUpdate(uint32_t data, RegisterField field, uint32_t value) +{ + return (data & (~field.mask)) | ((value << field.shift) & field.mask); +} + +static inline void tmc5031_fieldWrite(uint16_t icID, RegisterField field, uint32_t value) +{ + uint32_t regValue = tmc5031_readRegister(icID, field.address); + + regValue = tmc5031_fieldUpdate(regValue, field, value); + + tmc5031_writeRegister(icID, field.address, regValue); +} + +/**************************************************************** Cache Implementation *************************************************************************/ +#if TMC5031_CACHE == 1 +#ifdef TMC5031_ENABLE_TMC_CACHE + +// By default, support one IC in the cache +#ifndef TMC5031_IC_CACHE_COUNT +#define TMC5031_IC_CACHE_COUNT 1 +#endif + +typedef enum { + TMC5031_CACHE_READ, + TMC5031_CACHE_WRITE, + // Special operation: Put content into the cache without marking the entry as dirty. + // Only used to initialize the cache with hardware defaults. This will allow reading + // from write-only registers that have a value inside them on reset. When using this + // operation, a restore will *not* rewrite that filled register! + TMC5031_CACHE_FILL_DEFAULT, +} TMC5031CacheOp; + +typedef struct{ + uint8_t address; + uint32_t value; +} TMC5031RegisterConstants; + +#define TMC5031_ACCESS_DIRTY 0x08 // Register has been written since reset -> shadow register is valid for restore +#define TMC5031_ACCESS_READ 0x01 +#define TMC5031_ACCESS_W_PRESET 0x42 +#define TMC5031_IS_READABLE(x) ((x) & TMC5031_ACCESS_READ) +#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) + +// Default Register Values +#define R30 0x00071703 // IHOLD_IRUN +#define R32 0x00FFFFFF // VHIGH +#define R3A 0x00010000 // ENC_CONST +#define R6C 0x000101D5 // CHOPCONF + +// Helper define: +// Most register permission arrays are initialized with 128 values. +// In those fields its quite hard to have an easy overview of available +// registers. For that, ____ is defined to 0, since 4 underscores are +// very easy to distinguish from the 2-digit hexadecimal values. +// This way, the used registers (permission != ACCESS_NONE) are easily spotted +// amongst unused (permission == ACCESS_NONE) registers. +#define ____ 0x00 + +// Helper define: +// Default reset values are not used if the corresponding register has a +// hardware preset. Since this is not directly visible in the default +// register reset values array, N_A is used as an indicator for a preset +// value, where any value will be ignored anyways (N_A: not available). +#define N_A 0 + +// Register access permissions: +// 0x00: none (reserved) +// 0x01: read +// 0x02: write +// 0x03: read/write +// 0x13: read/write, separate functions/values for reading or writing +// 0x21: read, flag register (read to clear) +// 0x42: write, has hardware presets on reset +static const uint8_t tmc5031_registerAccess[TMC5031_REGISTER_COUNT] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0x03, 0x01, 0x01, 0x02, 0x07, 0x02, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x00 - 0x0F + 0x02, 0x01, ____, ____, ____, ____, ____, ____, 0x02, 0x01, ____, ____, ____, ____, ____, ____, // 0x10 - 0x1F + 0x03, 0x03, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, ____, ____, // 0x20 - 0x2F + 0x02, 0x02, 0x02, 0x02, 0x03, 0x01, 0x01, ____, 0x03, 0x03, 0x02, 0x01, 0x01, ____, ____, ____, // 0x30 - 0x3F + 0x03, 0x03, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, ____, ____, // 0x40 - 0x4F + 0x02, 0x02, 0x02, 0x02, 0x03, 0x01, 0x01, ____, 0x03, 0x03, 0x02, 0x01, 0x01, ____, ____, ____, // 0x50 - 0x5F + 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x01, 0x01, 0x03, 0x02, 0x02, 0x01, // 0x60 - 0x6F + 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x02, 0x42, 0x01, 0x01, 0x03, 0x02, 0x02, 0x01 // 0x70 - 0x7F +}; + +static const int32_t tmc5031_sampleRegisterPreset[TMC5031_REGISTER_COUNT] = { + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x00 - 0x0F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x10 - 0x1F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x20 - 0x2F + R30, 0, R32, 0, 0, 0, 0, 0, 0, 0, R3A, 0, 0, 0, 0, 0, // 0x30 - 0x3F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x40 - 0x4F + R30, 0, R32, 0, 0, 0, 0, 0, 0, 0, R3A, 0, 0, 0, 0, 0, // 0x50 - 0x5F + N_A, N_A, N_A, N_A, N_A, N_A, N_A, N_A, N_A, N_A, 0, 0, R6C, 0, 0, 0, // 0x60 - 0x6F + N_A, N_A, N_A, N_A, N_A, N_A, N_A, N_A, N_A, N_A, 0, 0, R6C, 0, 0, 0 // 0x70 - 0x7F + }; + + +// Undefine the default register values. +// This prevents warnings in case multiple TMC-API chip headers are included at once +#undef R30 +#undef R32 +#undef R3A +#undef R60 +#undef R61 +#undef R62 +#undef R63 +#undef R64 +#undef R65 +#undef R66 +#undef R67 +#undef R68 +#undef R69 +#undef R6C + +// Register constants (only required for 0x42 registers, since we do not have +// any way to find out the content but want to hold the actual value in the +// shadow register so an application (i.e. the TMCL IDE) can still display +// the values. This only works when the register content is constant. +static const TMC5031RegisterConstants tmc5031_RegisterConstants[] = +{ // Use ascending addresses! + { 0x60, 0xAAAAB554 }, // MSLUT[0] + { 0x61, 0x4A9554AA }, // MSLUT[1] + { 0x62, 0x24492929 }, // MSLUT[2] + { 0x63, 0x10104222 }, // MSLUT[3] + { 0x64, 0xFBFFFFFF }, // MSLUT[4] + { 0x65, 0xB5BB777D }, // MSLUT[5] + { 0x66, 0x49295556 }, // MSLUT[6] + { 0x67, 0x00404222 }, // MSLUT[7] + { 0x68, 0xFFFF8056 }, // MSLUTSEL + { 0x69, 0x00F70000 } // MSLUTSTART +}; + +extern uint8_t tmc5031_dirtyBits[TMC5031_IC_CACHE_COUNT][TMC5031_REGISTER_COUNT/8]; +extern int32_t tmc5031_shadowRegister[TMC5031_IC_CACHE_COUNT][TMC5031_REGISTER_COUNT]; +extern bool tmc5031_cache(uint16_t icID, TMC5031CacheOp operation, uint8_t address, uint32_t *value); +void tmc5031_initCache(void); +void tmc5031_setDirtyBit(uint16_t icID, uint8_t index, bool value); +bool tmc5031_getDirtyBit(uint16_t icID, uint8_t index); +#endif +#endif + +/***************************************************************************************************************************************************/ +#endif /* TMC_IC_TMC5031_H_ */ diff --git a/firmware/lib/tmc/ic/TMC5031/TMC5031_HW_Abstraction.h b/firmware/lib/tmc/ic/TMC5031/TMC5031_HW_Abstraction.h new file mode 100755 index 0000000..230cf01 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5031/TMC5031_HW_Abstraction.h @@ -0,0 +1,1167 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + +#ifndef TMC5272_HW_ABSTRACTION +#define TMC5272_HW_ABSTRACTION + +// Constants + +#define TMC5031_REGISTER_COUNT 128 // Default register count +#define TMC5031_MOTORS 2 +#define TMC5031_WRITE_BIT 0x80 +#define TMC5031_ADDRESS_MASK 0x7F +#define TMC5031_MAX_VELOCITY 8388096 +#define TMC5031_MAX_ACCELERATION (uint16_t) 65535 + +// Rampenmodi (Register TMC562_RAMPMODE) +#define TMC5031_MODE_POSITION 0 +#define TMC5031_MODE_VELPOS 1 +#define TMC5031_MODE_VELNEG 2 +#define TMC5031_MODE_HOLD 3 + +// Registers in TMC5272 + +#define TMC5031_MOTOR_ADDR(m) (0x20 << m) +#define TMC5031_MOTOR_ADDR_DRV(m) (m << 4) +#define TMC5031_MOTOR_ADDR_PWM(m) (m << 3) + +#define TMC5031_GCONF 0x00 +#define TMC5031_GSTAT 0x01 +#define TMC5031_IFCNT 0x02 +#define TMC5031_SLAVECONF 0x03 +#define TMC5031_INP_OUT 0x04 +#define TMC5031_X_COMPARE 0x05 + // motor = 0 motor = 1 +#define TMC5031_PWMCONF(motor) (0x10|TMC5031_MOTOR_ADDR_PWM(motor)) // 0x10 0x18 +#define TMC5031_PWM_STATUS(motor) (0x11|TMC5031_MOTOR_ADDR_PWM(motor)) // 0x11 0x19 + + // motor = 0 motor = 1 +#define TMC5031_RAMPMODE(motor) (0x00|TMC5031_MOTOR_ADDR(motor)) // 0x20 0x40 +#define TMC5031_XACTUAL(motor) (0x01|TMC5031_MOTOR_ADDR(motor)) // 0x21 0x41 +#define TMC5031_VACTUAL(motor) (0x02|TMC5031_MOTOR_ADDR(motor)) // 0x22 0x42 +#define TMC5031_VSTART(motor) (0x03|TMC5031_MOTOR_ADDR(motor)) // 0x23 0x43 +#define TMC5031_A1(motor) (0x04|TMC5031_MOTOR_ADDR(motor)) // 0x24 0x44 +#define TMC5031_V1(motor) (0x05|TMC5031_MOTOR_ADDR(motor)) // 0x25 0x45 +#define TMC5031_AMAX(motor) (0x06|TMC5031_MOTOR_ADDR(motor)) // 0x26 0x46 +#define TMC5031_VMAX(motor) (0x07|TMC5031_MOTOR_ADDR(motor)) // 0x27 0x47 +#define TMC5031_DMAX(motor) (0x08|TMC5031_MOTOR_ADDR(motor)) // 0x28 0x48 +#define TMC5031_D1(motor) (0x0A|TMC5031_MOTOR_ADDR(motor)) // 0x2A 0x4A +#define TMC5031_VSTOP(motor) (0x0B|TMC5031_MOTOR_ADDR(motor)) // 0x2B 0x4B +#define TMC5031_TZEROWAIT(motor) (0x0C|TMC5031_MOTOR_ADDR(motor)) // 0x2C 0x4C +#define TMC5031_XTARGET(motor) (0x0D|TMC5031_MOTOR_ADDR(motor)) // 0x2D 0x4D +#define TMC5031_IHOLD_IRUN(motor) (0x10|TMC5031_MOTOR_ADDR(motor)) // 0x30 0x50 +#define TMC5031_VCOOLTHRS(motor) (0x11|TMC5031_MOTOR_ADDR(motor)) // 0x31 0x51 +#define TMC5031_VHIGH(motor) (0x12|TMC5031_MOTOR_ADDR(motor)) // 0x32 0x52 +#define TMC5031_VDCMIN(motor) (0x13|TMC5031_MOTOR_ADDR(motor)) // 0x33 0x53 +#define TMC5031_SWMODE(motor) (0x14|TMC5031_MOTOR_ADDR(motor)) // 0x34 0x54 +#define TMC5031_RAMPSTAT(motor) (0x15|TMC5031_MOTOR_ADDR(motor)) // 0x35 0x55 +#define TMC5031_XLATCH(motor) (0x16|TMC5031_MOTOR_ADDR(motor)) // 0x36 0x56 +#define TMC5031_ENCMODE(motor) (0x18|TMC5031_MOTOR_ADDR(motor)) // 0x38 0x58 +#define TMC5031_XENC(motor) (0x19|TMC5031_MOTOR_ADDR(motor)) // 0x39 0x59 +#define TMC5031_ENC_CONST(motor) (0x1A|TMC5031_MOTOR_ADDR(motor)) // 0x3A 0x5A +#define TMC5031_ENC_STATUS(motor) (0x1B|TMC5031_MOTOR_ADDR(motor)) // 0x3B 0x5B +#define TMC5031_ENC_LATCH(motor) (0x1C|TMC5031_MOTOR_ADDR(motor)) // 0x3C 0x5C + + // motor = 0 motor = 1 +#define TMC5031_MSLUT0(motor) (0x60|TMC5031_MOTOR_ADDR_DRV(motor)) // 0x60 0x70 +#define TMC5031_MSLUT1(motor) (0x61|TMC5031_MOTOR_ADDR_DRV(motor)) // 0x61 0x71 +#define TMC5031_MSLUT2(motor) (0x62|TMC5031_MOTOR_ADDR_DRV(motor)) // 0x62 0x72 +#define TMC5031_MSLUT3(motor) (0x63|TMC5031_MOTOR_ADDR_DRV(motor)) // 0x63 0x73 +#define TMC5031_MSLUT4(motor) (0x64|TMC5031_MOTOR_ADDR_DRV(motor)) // 0x64 0x74 +#define TMC5031_MSLUT5(motor) (0x65|TMC5031_MOTOR_ADDR_DRV(motor)) // 0x65 0x75 +#define TMC5031_MSLUT6(motor) (0x66|TMC5031_MOTOR_ADDR_DRV(motor)) // 0x66 0x76 +#define TMC5031_MSLUT7(motor) (0x67|TMC5031_MOTOR_ADDR_DRV(motor)) // 0x67 0x77 +#define TMC5031_MSLUTSEL(motor) (0x68|TMC5031_MOTOR_ADDR_DRV(motor)) // 0x68 0x78 +#define TMC5031_MSLUTSTART(motor) (0x69|TMC5031_MOTOR_ADDR_DRV(motor)) // 0x69 0x79 +#define TMC5031_MSCNT(motor) (0x6A|TMC5031_MOTOR_ADDR_DRV(motor)) // 0x6A 0x7A +#define TMC5031_MSCURACT(motor) (0x6B|TMC5031_MOTOR_ADDR_DRV(motor)) // 0x6B 0x7B +#define TMC5031_CHOPCONF(motor) (0x6C|TMC5031_MOTOR_ADDR_DRV(motor)) // 0x6C 0x7C +#define TMC5031_COOLCONF(motor) (0x6D|TMC5031_MOTOR_ADDR_DRV(motor)) // 0x6D 0x7D +#define TMC5031_DCCTRL(motor) (0x6E|TMC5031_MOTOR_ADDR_DRV(motor)) // 0x6E 0x7E +#define TMC5031_DRVSTATUS(motor) (0x6F|TMC5031_MOTOR_ADDR_DRV(motor)) // 0x6F 0x7F + +// Register fields in TMC5272 + +#define TMC5031_POSCMP_ENABLE_MASK 0x00000008 +#define TMC5031_POSCMP_ENABLE_SHIFT 3 +#define TMC5031_POSCMP_ENABLE_FIELD(motor) ((RegisterField) {TMC5031_POSCMP_ENABLE_MASK, TMC5031_POSCMP_ENABLE_SHIFT, TMC5031_GCONF, false}) +#define TMC5031_TEST_MODE_MASK 0x00000080 +#define TMC5031_TEST_MODE_SHIFT 7 +#define TMC5031_TEST_MODE_FIELD(motor) ((RegisterField) {TMC5031_TEST_MODE_MASK, TMC5031_TEST_MODE_SHIFT, TMC5031_GCONF, false}) +#define TMC5031_SHAFT1_MASK 0x00000100 +#define TMC5031_SHAFT1_SHIFT 8 +#define TMC5031_SHAFT1_FIELD(motor) ((RegisterField) {TMC5031_SHAFT1_MASK, TMC5031_SHAFT1_SHIFT, TMC5031_GCONF, false}) +#define TMC5031_SHAFT2_MASK 0x00000200 +#define TMC5031_SHAFT2_SHIFT 9 +#define TMC5031_SHAFT2_FIELD(motor) ((RegisterField) {TMC5031_SHAFT2_MASK, TMC5031_SHAFT2_SHIFT, TMC5031_GCONF, false}) +#define TMC5031_LOCK_GCONF_MASK 0x00000400 +#define TMC5031_LOCK_GCONF_SHIFT 10 +#define TMC5031_LOCK_GCONF_FIELD(motor) ((RegisterField) {TMC5031_LOCK_GCONF_MASK, TMC5031_LOCK_GCONF_SHIFT, TMC5031_GCONF, false}) +#define TMC5031_RESET_MASK 0x00000001 +#define TMC5031_RESET_SHIFT 0 +#define TMC5031_RESET_FIELD(motor) ((RegisterField) {TMC5031_RESET_MASK, TMC5031_RESET_SHIFT, TMC5031_GSTAT, false}) +#define TMC5031_DRV_ERR1_MASK 0x00000002 +#define TMC5031_DRV_ERR1_SHIFT 1 +#define TMC5031_DRV_ERR1_FIELD(motor) ((RegisterField) {TMC5031_DRV_ERR1_MASK, TMC5031_DRV_ERR1_SHIFT, TMC5031_GSTAT, false}) +#define TMC5031_UV_CP_MASK 0x00000008 +#define TMC5031_UV_CP_SHIFT 3 +#define TMC5031_UV_CP_FIELD(motor) ((RegisterField) {TMC5031_UV_CP_MASK, TMC5031_UV_CP_SHIFT, TMC5031_GSTAT, false}) +#define TMC5031_TEST_SEL_MASK 0x0000000F +#define TMC5031_TEST_SEL_SHIFT 0 +#define TMC5031_TEST_SEL_FIELD(motor) ((RegisterField) {TMC5031_TEST_SEL_MASK, TMC5031_TEST_SEL_SHIFT, TMC5031_SLAVECONF, false}) +#define TMC5031_DRV_ENN_MASK 0x00000080 +#define TMC5031_DRV_ENN_SHIFT 7 +#define TMC5031_DRV_ENN_FIELD(motor) ((RegisterField) {TMC5031_DRV_ENN_MASK, TMC5031_DRV_ENN_SHIFT, TMC5031_INPUT, false}) +#define TMC5031_VERSION_MASK 0xFF000000 +#define TMC5031_VERSION_SHIFT 24 +#define TMC5031_VERSION_FIELD(motor) ((RegisterField) {TMC5031_VERSION_MASK, TMC5031_VERSION_SHIFT, TMC5031_INPUT, false}) +#define TMC5031_X_COMPARE_MASK 0xFFFFFFFF +#define TMC5031_X_COMPARE_SHIFT 0 +#define TMC5031_X_COMPARE_FIELD(motor) ((RegisterField) {TMC5031_X_COMPARE_MASK, TMC5031_X_COMPARE_SHIFT, TMC5031_X_COMPARE, false}) +#define TMC5031_RAMPMODE_MASK 0x00000003 +#define TMC5031_RAMPMODE_SHIFT 0 +#define TMC5031_RAMPMODE_FIELD(motor) ((RegisterField) {TMC5031_RAMPMODE_MASK, TMC5031_RAMPMODE_SHIFT, TMC5031_RAMPMODE(motor), false}) +#define TMC5031_XACTUAL_MASK 0xFFFFFFFF +#define TMC5031_XACTUAL_SHIFT 0 +#define TMC5031_XACTUAL_FIELD(motor) ((RegisterField) {TMC5031_XACTUAL_MASK, TMC5031_XACTUAL_SHIFT, TMC5031_XACTUAL(motor), true}) +#define TMC5031_VACTUAL_MASK 0x00FFFFFF +#define TMC5031_VACTUAL_SHIFT 0 +#define TMC5031_VACTUAL_FIELD(motor) ((RegisterField) {TMC5031_VACTUAL_MASK, TMC5031_VACTUAL_SHIFT, TMC5031_VACTUAL(motor), true}) +#define TMC5031_VSTART_MASK 0x0003FFFF +#define TMC5031_VSTART_SHIFT 0 +#define TMC5031_VSTART_FIELD(motor) ((RegisterField) {TMC5031_VSTART_MASK, TMC5031_VSTART_SHIFT, TMC5031_VSTART(motor), false}) +#define TMC5031_A1_MASK 0x0000FFFF +#define TMC5031_A1_SHIFT 0 +#define TMC5031_A1_FIELD(motor) ((RegisterField) {TMC5031_A1_MASK, TMC5031_A1_SHIFT, TMC5031_A1(motor), false}) +#define TMC5031_V1__MASK 0x000FFFFF +#define TMC5031_V1__SHIFT 0 +#define TMC5031_V1__FIELD(motor) ((RegisterField) {TMC5031_V1__MASK, TMC5031_V1__SHIFT, TMC5031_V1(motor), false}) +#define TMC5031_AMAX_MASK 0x0000FFFF +#define TMC5031_AMAX_SHIFT 0 +#define TMC5031_AMAX_FIELD(motor) ((RegisterField) {TMC5031_AMAX_MASK, TMC5031_AMAX_SHIFT, TMC5031_AMAX(motor), false}) +#define TMC5031_VMAX_MASK 0x007FFFFF +#define TMC5031_VMAX_SHIFT 0 +#define TMC5031_VMAX_FIELD(motor) ((RegisterField) {TMC5031_VMAX_MASK, TMC5031_VMAX_SHIFT, TMC5031_VMAX(motor), false}) +#define TMC5031_DMAX_MASK 0x0000FFFF +#define TMC5031_DMAX_SHIFT 0 +#define TMC5031_DMAX_FIELD(motor) ((RegisterField) {TMC5031_DMAX_MASK, TMC5031_DMAX_SHIFT, TMC5031_DMAX(motor), false}) +#define TMC5031_D1_MASK 0x0000FFFF +#define TMC5031_D1_SHIFT 0 +#define TMC5031_D1_FIELD(motor) ((RegisterField) {TMC5031_D1_MASK, TMC5031_D1_SHIFT, TMC5031_D1(motor), false}) +#define TMC5031_VSTOP_MASK 0x0003FFFF +#define TMC5031_VSTOP_SHIFT 0 +#define TMC5031_VSTOP_FIELD(motor) ((RegisterField) {TMC5031_VSTOP_MASK, TMC5031_VSTOP_SHIFT, TMC5031_VSTOP(motor), false}) +#define TMC5031_TZEROWAIT_MASK 0x0000FFFF +#define TMC5031_TZEROWAIT_SHIFT 0 +#define TMC5031_TZEROWAIT_FIELD(motor) ((RegisterField) {TMC5031_TZEROWAIT_MASK, TMC5031_TZEROWAIT_SHIFT, TMC5031_TZEROWAIT(motor), false}) +#define TMC5031_XTARGET_MASK 0xFFFFFFFF +#define TMC5031_XTARGET_SHIFT 0 +#define TMC5031_XTARGET_FIELD(motor) ((RegisterField) {TMC5031_XTARGET_MASK, TMC5031_XTARGET_SHIFT, TMC5031_XTARGET(motor), true}) +#define TMC5031_IHOLD_MASK 0x0000001F +#define TMC5031_IHOLD_SHIFT 0 +#define TMC5031_IHOLD_FIELD(motor) ((RegisterField) {TMC5031_IHOLD_MASK, TMC5031_IHOLD_SHIFT, TMC5031_IHOLD_IRUN(motor), false}) +#define TMC5031_IRUN_MASK 0x00001F00 +#define TMC5031_IRUN_SHIFT 8 +#define TMC5031_IRUN_FIELD(motor) ((RegisterField) {TMC5031_IRUN_MASK, TMC5031_IRUN_SHIFT, TMC5031_IHOLD_IRUN(motor), false}) +#define TMC5031_IHOLDDELAY_MASK 0x000F0000 +#define TMC5031_IHOLDDELAY_SHIFT 16 +#define TMC5031_IHOLDDELAY_FIELD(motor) ((RegisterField) {TMC5031_IHOLDDELAY_MASK, TMC5031_IHOLDDELAY_SHIFT, TMC5031_IHOLD_IRUN(motor), false}) +#define TMC5031_VCOOLTHRS_MASK 0x007FFFFF +#define TMC5031_VCOOLTHRS_SHIFT 0 +#define TMC5031_VCOOLTHRS_FIELD(motor) ((RegisterField) {TMC5031_VCOOLTHRS_MASK, TMC5031_VCOOLTHRS_SHIFT, TMC5031_VCOOLTHRS(motor), false}) +#define TMC5031_VHIGH_MASK 0x007FFFFF +#define TMC5031_VHIGH_SHIFT 0 +#define TMC5031_VHIGH_FIELD(motor) ((RegisterField) {TMC5031_VHIGH_MASK, TMC5031_VHIGH_SHIFT, TMC5031_VHIGH(motor), false}) +#define TMC5031_STOP_L_ENABLE_MASK 0x00000001 +#define TMC5031_STOP_L_ENABLE_SHIFT 0 +#define TMC5031_STOP_L_ENABLE_FIELD(motor) ((RegisterField) {TMC5031_STOP_L_ENABLE_MASK, TMC5031_STOP_L_ENABLE_SHIFT, TMC5031_SWMODE(motor), false}) +#define TMC5031_STOP_R_ENABLE_MASK 0x00000002 +#define TMC5031_STOP_R_ENABLE_SHIFT 1 +#define TMC5031_STOP_R_ENABLE_FIELD(motor) ((RegisterField) {TMC5031_STOP_R_ENABLE_MASK, TMC5031_STOP_R_ENABLE_SHIFT, TMC5031_SWMODE(motor), false}) +#define TMC5031_POL_STOP_L_MASK 0x00000004 +#define TMC5031_POL_STOP_L_SHIFT 2 +#define TMC5031_POL_STOP_L_FIELD(motor) ((RegisterField) {TMC5031_POL_STOP_L_MASK, TMC5031_POL_STOP_L_SHIFT, TMC5031_SWMODE(motor), false}) +#define TMC5031_POL_STOP_R_MASK 0x00000008 +#define TMC5031_POL_STOP_R_SHIFT 3 +#define TMC5031_POL_STOP_R_FIELD(motor) ((RegisterField) {TMC5031_POL_STOP_R_MASK, TMC5031_POL_STOP_R_SHIFT, TMC5031_SWMODE(motor), false}) +#define TMC5031_SWAP_LR_MASK 0x00000010 +#define TMC5031_SWAP_LR_SHIFT 4 +#define TMC5031_SWAP_LR_FIELD(motor) ((RegisterField) {TMC5031_SWAP_LR_MASK, TMC5031_SWAP_LR_SHIFT, TMC5031_SWMODE(motor), false}) +#define TMC5031_LATCH_L_ACTIVE_MASK 0x00000020 +#define TMC5031_LATCH_L_ACTIVE_SHIFT 5 +#define TMC5031_LATCH_L_ACTIVE_FIELD(motor) ((RegisterField) {TMC5031_LATCH_L_ACTIVE_MASK, TMC5031_LATCH_L_ACTIVE_SHIFT, TMC5031_SWMODE(motor), false}) +#define TMC5031_LATCH_L_INACTIVE_MASK 0x00000040 +#define TMC5031_LATCH_L_INACTIVE_SHIFT 6 +#define TMC5031_LATCH_L_INACTIVE_FIELD(motor) ((RegisterField) {TMC5031_LATCH_L_INACTIVE_MASK, TMC5031_LATCH_L_INACTIVE_SHIFT, TMC5031_SWMODE(motor), false}) +#define TMC5031_LATCH_R_ACTIVE_MASK 0x00000080 +#define TMC5031_LATCH_R_ACTIVE_SHIFT 7 +#define TMC5031_LATCH_R_ACTIVE_FIELD(motor) ((RegisterField) {TMC5031_LATCH_R_ACTIVE_MASK, TMC5031_LATCH_R_ACTIVE_SHIFT, TMC5031_SWMODE(motor), false}) +#define TMC5031_LATCH_R_INACTIVE_MASK 0x00000100 +#define TMC5031_LATCH_R_INACTIVE_SHIFT 8 +#define TMC5031_LATCH_R_INACTIVE_FIELD(motor) ((RegisterField) {TMC5031_LATCH_R_INACTIVE_MASK, TMC5031_LATCH_R_INACTIVE_SHIFT, TMC5031_SWMODE(motor), false}) +#define TMC5031_SG_STOP_MASK 0x00000400 +#define TMC5031_SG_STOP_SHIFT 10 +#define TMC5031_SG_STOP_FIELD(motor) ((RegisterField) {TMC5031_SG_STOP_MASK, TMC5031_SG_STOP_SHIFT, TMC5031_SWMODE(motor), false}) +#define TMC5031_EN_SOFTSTOP_MASK 0x00000800 +#define TMC5031_EN_SOFTSTOP_SHIFT 11 +#define TMC5031_EN_SOFTSTOP_FIELD(motor) ((RegisterField) {TMC5031_EN_SOFTSTOP_MASK, TMC5031_EN_SOFTSTOP_SHIFT, TMC5031_SWMODE(motor), false}) +#define TMC5031_STATUS_STOP_L_MASK 0x00000001 +#define TMC5031_STATUS_STOP_L_SHIFT 0 +#define TMC5031_STATUS_STOP_L_FIELD(motor) ((RegisterField) {TMC5031_STATUS_STOP_L_MASK, TMC5031_STATUS_STOP_L_SHIFT, TMC5031_RAMPSTAT(motor), false}) +#define TMC5031_STATUS_STOP_R_MASK 0x00000002 +#define TMC5031_STATUS_STOP_R_SHIFT 1 +#define TMC5031_STATUS_STOP_R_FIELD(motor) ((RegisterField) {TMC5031_STATUS_STOP_R_MASK, TMC5031_STATUS_STOP_R_SHIFT, TMC5031_RAMPSTAT(motor), false}) +#define TMC5031_STATUS_LATCH_L_MASK 0x00000004 +#define TMC5031_STATUS_LATCH_L_SHIFT 2 +#define TMC5031_STATUS_LATCH_L_FIELD(motor) ((RegisterField) {TMC5031_STATUS_LATCH_L_MASK, TMC5031_STATUS_LATCH_L_SHIFT, TMC5031_RAMPSTAT(motor), false}) +#define TMC5031_STATUS_LATCH_R_MASK 0x00000008 +#define TMC5031_STATUS_LATCH_R_SHIFT 3 +#define TMC5031_STATUS_LATCH_R_FIELD(motor) ((RegisterField) {TMC5031_STATUS_LATCH_R_MASK, TMC5031_STATUS_LATCH_R_SHIFT, TMC5031_RAMPSTAT(motor), false}) +#define TMC5031_EVENT_STOP_L_MASK 0x00000010 +#define TMC5031_EVENT_STOP_L_SHIFT 4 +#define TMC5031_EVENT_STOP_L_FIELD(motor) ((RegisterField) {TMC5031_EVENT_STOP_L_MASK, TMC5031_EVENT_STOP_L_SHIFT, TMC5031_RAMPSTAT(motor), false}) +#define TMC5031_EVENT_STOP_R_MASK 0x00000020 +#define TMC5031_EVENT_STOP_R_SHIFT 5 +#define TMC5031_EVENT_STOP_R_FIELD(motor) ((RegisterField) {TMC5031_EVENT_STOP_R_MASK, TMC5031_EVENT_STOP_R_SHIFT, TMC5031_RAMPSTAT(motor), false}) +#define TMC5031_EVENT_STOP_SG_MASK 0x00000040 +#define TMC5031_EVENT_STOP_SG_SHIFT 6 +#define TMC5031_EVENT_STOP_SG_FIELD(motor) ((RegisterField) {TMC5031_EVENT_STOP_SG_MASK, TMC5031_EVENT_STOP_SG_SHIFT, TMC5031_RAMPSTAT(motor), false}) +#define TMC5031_EVENT_POS_REACHED_MASK 0x00000080 +#define TMC5031_EVENT_POS_REACHED_SHIFT 7 +#define TMC5031_EVENT_POS_REACHED_FIELD(motor) ((RegisterField) {TMC5031_EVENT_POS_REACHED_MASK, TMC5031_EVENT_POS_REACHED_SHIFT, TMC5031_RAMPSTAT(motor), false}) +#define TMC5031_VELOCITY_REACHED_MASK 0x00000100 +#define TMC5031_VELOCITY_REACHED_SHIFT 8 +#define TMC5031_VELOCITY_REACHED_FIELD(motor) ((RegisterField) {TMC5031_VELOCITY_REACHED_MASK, TMC5031_VELOCITY_REACHED_SHIFT, TMC5031_RAMPSTAT(motor), false}) +#define TMC5031_POSITION_REACHED_MASK 0x00000200 +#define TMC5031_POSITION_REACHED_SHIFT 9 +#define TMC5031_POSITION_REACHED_FIELD(motor) ((RegisterField) {TMC5031_POSITION_REACHED_MASK, TMC5031_POSITION_REACHED_SHIFT, TMC5031_RAMPSTAT(motor), false}) +#define TMC5031_VZERO_MASK 0x00000400 +#define TMC5031_VZERO_SHIFT 10 +#define TMC5031_VZERO_FIELD(motor) ((RegisterField) {TMC5031_VZERO_MASK, TMC5031_VZERO_SHIFT, TMC5031_RAMPSTAT(motor), false}) +#define TMC5031_T_ZEROWAIT_ACTIVE_MASK 0x00000800 +#define TMC5031_T_ZEROWAIT_ACTIVE_SHIFT 11 +#define TMC5031_T_ZEROWAIT_ACTIVE_FIELD(motor) ((RegisterField) {TMC5031_T_ZEROWAIT_ACTIVE_MASK, TMC5031_T_ZEROWAIT_ACTIVE_SHIFT, TMC5031_RAMPSTAT(motor), false}) +#define TMC5031_SECOND_MOVE_MASK 0x00001000 +#define TMC5031_SECOND_MOVE_SHIFT 12 +#define TMC5031_SECOND_MOVE_FIELD(motor) ((RegisterField) {TMC5031_SECOND_MOVE_MASK, TMC5031_SECOND_MOVE_SHIFT, TMC5031_RAMPSTAT(motor), false}) +#define TMC5031_STATUS_SG_MASK 0x00002000 +#define TMC5031_STATUS_SG_SHIFT 13 +#define TMC5031_STATUS_SG_FIELD(motor) ((RegisterField) {TMC5031_STATUS_SG_MASK, TMC5031_STATUS_SG_SHIFT, TMC5031_RAMPSTAT(motor), false}) +#define TMC5031_XLATCH_MASK 0xFFFFFFFF +#define TMC5031_XLATCH_SHIFT 0 +#define TMC5031_XLATCH_FIELD(motor) ((RegisterField) {TMC5031_XLATCH_MASK, TMC5031_XLATCH_SHIFT, TMC5031_XLATCH(motor), false}) +#define TMC5031_OFS0_MASK 0x00000001 +#define TMC5031_OFS0_SHIFT 0 +#define TMC5031_OFS0_FIELD(motor) ((RegisterField) {TMC5031_OFS0_MASK, TMC5031_OFS0_SHIFT, TMC5031_MSLUT[0](motor), false}) +#define TMC5031_OFS1_MASK 0x00000002 +#define TMC5031_OFS1_SHIFT 1 +#define TMC5031_OFS1_FIELD(motor) ((RegisterField) {TMC5031_OFS1_MASK, TMC5031_OFS1_SHIFT, TMC5031_MSLUT[0](motor), false}) +#define TMC5031_OFS2_MASK 0x00000004 +#define TMC5031_OFS2_SHIFT 2 +#define TMC5031_OFS2_FIELD(motor) ((RegisterField) {TMC5031_OFS2_MASK, TMC5031_OFS2_SHIFT, TMC5031_MSLUT[0](motor), false}) +#define TMC5031_OFS3_MASK 0x00000008 +#define TMC5031_OFS3_SHIFT 3 +#define TMC5031_OFS3_FIELD(motor) ((RegisterField) {TMC5031_OFS3_MASK, TMC5031_OFS3_SHIFT, TMC5031_MSLUT[0](motor), false}) +#define TMC5031_OFS4_MASK 0x00000010 +#define TMC5031_OFS4_SHIFT 4 +#define TMC5031_OFS4_FIELD(motor) ((RegisterField) {TMC5031_OFS4_MASK, TMC5031_OFS4_SHIFT, TMC5031_MSLUT[0](motor), false}) +#define TMC5031_OFS5_MASK 0x00000020 +#define TMC5031_OFS5_SHIFT 5 +#define TMC5031_OFS5_FIELD(motor) ((RegisterField) {TMC5031_OFS5_MASK, TMC5031_OFS5_SHIFT, TMC5031_MSLUT[0](motor), false}) +#define TMC5031_OFS6_MASK 0x00000040 +#define TMC5031_OFS6_SHIFT 6 +#define TMC5031_OFS6_FIELD(motor) ((RegisterField) {TMC5031_OFS6_MASK, TMC5031_OFS6_SHIFT, TMC5031_MSLUT[0](motor), false}) +#define TMC5031_OFS7_MASK 0x00000080 +#define TMC5031_OFS7_SHIFT 7 +#define TMC5031_OFS7_FIELD(motor) ((RegisterField) {TMC5031_OFS7_MASK, TMC5031_OFS7_SHIFT, TMC5031_MSLUT[0](motor), false}) +#define TMC5031_OFS8_MASK 0x00000100 +#define TMC5031_OFS8_SHIFT 8 +#define TMC5031_OFS8_FIELD(motor) ((RegisterField) {TMC5031_OFS8_MASK, TMC5031_OFS8_SHIFT, TMC5031_MSLUT[0](motor), false}) +#define TMC5031_OFS9_MASK 0x00000200 +#define TMC5031_OFS9_SHIFT 9 +#define TMC5031_OFS9_FIELD(motor) ((RegisterField) {TMC5031_OFS9_MASK, TMC5031_OFS9_SHIFT, TMC5031_MSLUT[0](motor), false}) +#define TMC5031_OFS10_MASK 0x00000400 +#define TMC5031_OFS10_SHIFT 10 +#define TMC5031_OFS10_FIELD(motor) ((RegisterField) {TMC5031_OFS10_MASK, TMC5031_OFS10_SHIFT, TMC5031_MSLUT[0](motor), false}) +#define TMC5031_OFS11_MASK 0x00000800 +#define TMC5031_OFS11_SHIFT 11 +#define TMC5031_OFS11_FIELD(motor) ((RegisterField) {TMC5031_OFS11_MASK, TMC5031_OFS11_SHIFT, TMC5031_MSLUT[0](motor), false}) +#define TMC5031_OFS12_MASK 0x00001000 +#define TMC5031_OFS12_SHIFT 12 +#define TMC5031_OFS12_FIELD(motor) ((RegisterField) {TMC5031_OFS12_MASK, TMC5031_OFS12_SHIFT, TMC5031_MSLUT[0](motor), false}) +#define TMC5031_OFS13_MASK 0x00002000 +#define TMC5031_OFS13_SHIFT 13 +#define TMC5031_OFS13_FIELD(motor) ((RegisterField) {TMC5031_OFS13_MASK, TMC5031_OFS13_SHIFT, TMC5031_MSLUT[0](motor), false}) +#define TMC5031_OFS14_MASK 0x00004000 +#define TMC5031_OFS14_SHIFT 14 +#define TMC5031_OFS14_FIELD(motor) ((RegisterField) {TMC5031_OFS14_MASK, TMC5031_OFS14_SHIFT, TMC5031_MSLUT[0](motor), false}) +#define TMC5031_OFS15_MASK 0x00008000 +#define TMC5031_OFS15_SHIFT 15 +#define TMC5031_OFS15_FIELD(motor) ((RegisterField) {TMC5031_OFS15_MASK, TMC5031_OFS15_SHIFT, TMC5031_MSLUT[0](motor), false}) +#define TMC5031_OFS16_MASK 0x00010000 +#define TMC5031_OFS16_SHIFT 16 +#define TMC5031_OFS16_FIELD(motor) ((RegisterField) {TMC5031_OFS16_MASK, TMC5031_OFS16_SHIFT, TMC5031_MSLUT[0](motor), false}) +#define TMC5031_OFS17_MASK 0x00020000 +#define TMC5031_OFS17_SHIFT 17 +#define TMC5031_OFS17_FIELD(motor) ((RegisterField) {TMC5031_OFS17_MASK, TMC5031_OFS17_SHIFT, TMC5031_MSLUT[0](motor), false}) +#define TMC5031_OFS18_MASK 0x00040000 +#define TMC5031_OFS18_SHIFT 18 +#define TMC5031_OFS18_FIELD(motor) ((RegisterField) {TMC5031_OFS18_MASK, TMC5031_OFS18_SHIFT, TMC5031_MSLUT[0](motor), false}) +#define TMC5031_OFS19_MASK 0x00080000 +#define TMC5031_OFS19_SHIFT 19 +#define TMC5031_OFS19_FIELD(motor) ((RegisterField) {TMC5031_OFS19_MASK, TMC5031_OFS19_SHIFT, TMC5031_MSLUT[0](motor), false}) +#define TMC5031_OFS20_MASK 0x00100000 +#define TMC5031_OFS20_SHIFT 20 +#define TMC5031_OFS20_FIELD(motor) ((RegisterField) {TMC5031_OFS20_MASK, TMC5031_OFS20_SHIFT, TMC5031_MSLUT[0](motor), false}) +#define TMC5031_OFS21_MASK 0x00200000 +#define TMC5031_OFS21_SHIFT 21 +#define TMC5031_OFS21_FIELD(motor) ((RegisterField) {TMC5031_OFS21_MASK, TMC5031_OFS21_SHIFT, TMC5031_MSLUT[0](motor), false}) +#define TMC5031_OFS22_MASK 0x00400000 +#define TMC5031_OFS22_SHIFT 22 +#define TMC5031_OFS22_FIELD(motor) ((RegisterField) {TMC5031_OFS22_MASK, TMC5031_OFS22_SHIFT, TMC5031_MSLUT[0](motor), false}) +#define TMC5031_OFS23_MASK 0x00800000 +#define TMC5031_OFS23_SHIFT 23 +#define TMC5031_OFS23_FIELD(motor) ((RegisterField) {TMC5031_OFS23_MASK, TMC5031_OFS23_SHIFT, TMC5031_MSLUT[0](motor), false}) +#define TMC5031_OFS24_MASK 0x01000000 +#define TMC5031_OFS24_SHIFT 24 +#define TMC5031_OFS24_FIELD(motor) ((RegisterField) {TMC5031_OFS24_MASK, TMC5031_OFS24_SHIFT, TMC5031_MSLUT[0](motor), false}) +#define TMC5031_OFS25_MASK 0x02000000 +#define TMC5031_OFS25_SHIFT 25 +#define TMC5031_OFS25_FIELD(motor) ((RegisterField) {TMC5031_OFS25_MASK, TMC5031_OFS25_SHIFT, TMC5031_MSLUT[0](motor), false}) +#define TMC5031_OFS26_MASK 0x04000000 +#define TMC5031_OFS26_SHIFT 26 +#define TMC5031_OFS26_FIELD(motor) ((RegisterField) {TMC5031_OFS26_MASK, TMC5031_OFS26_SHIFT, TMC5031_MSLUT[0](motor), false}) +#define TMC5031_OFS27_MASK 0x08000000 +#define TMC5031_OFS27_SHIFT 27 +#define TMC5031_OFS27_FIELD(motor) ((RegisterField) {TMC5031_OFS27_MASK, TMC5031_OFS27_SHIFT, TMC5031_MSLUT[0](motor), false}) +#define TMC5031_OFS28_MASK 0x10000000 +#define TMC5031_OFS28_SHIFT 28 +#define TMC5031_OFS28_FIELD(motor) ((RegisterField) {TMC5031_OFS28_MASK, TMC5031_OFS28_SHIFT, TMC5031_MSLUT[0](motor), false}) +#define TMC5031_OFS29_MASK 0x20000000 +#define TMC5031_OFS29_SHIFT 29 +#define TMC5031_OFS29_FIELD(motor) ((RegisterField) {TMC5031_OFS29_MASK, TMC5031_OFS29_SHIFT, TMC5031_MSLUT[0](motor), false}) +#define TMC5031_OFS30_MASK 0x40000000 +#define TMC5031_OFS30_SHIFT 30 +#define TMC5031_OFS30_FIELD(motor) ((RegisterField) {TMC5031_OFS30_MASK, TMC5031_OFS30_SHIFT, TMC5031_MSLUT[0](motor), false}) +#define TMC5031_OFS31_MASK 0x80000000 +#define TMC5031_OFS31_SHIFT 31 +#define TMC5031_OFS31_FIELD(motor) ((RegisterField) {TMC5031_OFS31_MASK, TMC5031_OFS31_SHIFT, TMC5031_MSLUT[0](motor), false}) +#define TMC5031_OFS32_MASK 0x00000001 +#define TMC5031_OFS32_SHIFT 0 +#define TMC5031_OFS32_FIELD(motor) ((RegisterField) {TMC5031_OFS32_MASK, TMC5031_OFS32_SHIFT, TMC5031_MSLUT[1](motor), false}) +#define TMC5031_OFS33_MASK 0x00000002 +#define TMC5031_OFS33_SHIFT 1 +#define TMC5031_OFS33_FIELD(motor) ((RegisterField) {TMC5031_OFS33_MASK, TMC5031_OFS33_SHIFT, TMC5031_MSLUT[1](motor), false}) +#define TMC5031_OFS34_MASK 0x00000004 +#define TMC5031_OFS34_SHIFT 2 +#define TMC5031_OFS34_FIELD(motor) ((RegisterField) {TMC5031_OFS34_MASK, TMC5031_OFS34_SHIFT, TMC5031_MSLUT[1](motor), false}) +#define TMC5031_OFS35_MASK 0x00000008 +#define TMC5031_OFS35_SHIFT 3 +#define TMC5031_OFS35_FIELD(motor) ((RegisterField) {TMC5031_OFS35_MASK, TMC5031_OFS35_SHIFT, TMC5031_MSLUT[1](motor), false}) +#define TMC5031_OFS36_MASK 0x00000010 +#define TMC5031_OFS36_SHIFT 4 +#define TMC5031_OFS36_FIELD(motor) ((RegisterField) {TMC5031_OFS36_MASK, TMC5031_OFS36_SHIFT, TMC5031_MSLUT[1](motor), false}) +#define TMC5031_OFS37_MASK 0x00000020 +#define TMC5031_OFS37_SHIFT 5 +#define TMC5031_OFS37_FIELD(motor) ((RegisterField) {TMC5031_OFS37_MASK, TMC5031_OFS37_SHIFT, TMC5031_MSLUT[1](motor), false}) +#define TMC5031_OFS38_MASK 0x00000040 +#define TMC5031_OFS38_SHIFT 6 +#define TMC5031_OFS38_FIELD(motor) ((RegisterField) {TMC5031_OFS38_MASK, TMC5031_OFS38_SHIFT, TMC5031_MSLUT[1](motor), false}) +#define TMC5031_OFS39_MASK 0x00000080 +#define TMC5031_OFS39_SHIFT 7 +#define TMC5031_OFS39_FIELD(motor) ((RegisterField) {TMC5031_OFS39_MASK, TMC5031_OFS39_SHIFT, TMC5031_MSLUT[1](motor), false}) +#define TMC5031_OFS40_MASK 0x00000100 +#define TMC5031_OFS40_SHIFT 8 +#define TMC5031_OFS40_FIELD(motor) ((RegisterField) {TMC5031_OFS40_MASK, TMC5031_OFS40_SHIFT, TMC5031_MSLUT[1](motor), false}) +#define TMC5031_OFS41_MASK 0x00000200 +#define TMC5031_OFS41_SHIFT 9 +#define TMC5031_OFS41_FIELD(motor) ((RegisterField) {TMC5031_OFS41_MASK, TMC5031_OFS41_SHIFT, TMC5031_MSLUT[1](motor), false}) +#define TMC5031_OFS42_MASK 0x00000400 +#define TMC5031_OFS42_SHIFT 10 +#define TMC5031_OFS42_FIELD(motor) ((RegisterField) {TMC5031_OFS42_MASK, TMC5031_OFS42_SHIFT, TMC5031_MSLUT[1](motor), false}) +#define TMC5031_OFS43_MASK 0x00000800 +#define TMC5031_OFS43_SHIFT 11 +#define TMC5031_OFS43_FIELD(motor) ((RegisterField) {TMC5031_OFS43_MASK, TMC5031_OFS43_SHIFT, TMC5031_MSLUT[1](motor), false}) +#define TMC5031_OFS44_MASK 0x00001000 +#define TMC5031_OFS44_SHIFT 12 +#define TMC5031_OFS44_FIELD(motor) ((RegisterField) {TMC5031_OFS44_MASK, TMC5031_OFS44_SHIFT, TMC5031_MSLUT[1](motor), false}) +#define TMC5031_OFS45_MASK 0x00002000 +#define TMC5031_OFS45_SHIFT 13 +#define TMC5031_OFS45_FIELD(motor) ((RegisterField) {TMC5031_OFS45_MASK, TMC5031_OFS45_SHIFT, TMC5031_MSLUT[1](motor), false}) +#define TMC5031_OFS46_MASK 0x00004000 +#define TMC5031_OFS46_SHIFT 14 +#define TMC5031_OFS46_FIELD(motor) ((RegisterField) {TMC5031_OFS46_MASK, TMC5031_OFS46_SHIFT, TMC5031_MSLUT[1](motor), false}) +#define TMC5031_OFS47_MASK 0x00008000 +#define TMC5031_OFS47_SHIFT 15 +#define TMC5031_OFS47_FIELD(motor) ((RegisterField) {TMC5031_OFS47_MASK, TMC5031_OFS47_SHIFT, TMC5031_MSLUT[1](motor), false}) +#define TMC5031_OFS48_MASK 0x00010000 +#define TMC5031_OFS48_SHIFT 16 +#define TMC5031_OFS48_FIELD(motor) ((RegisterField) {TMC5031_OFS48_MASK, TMC5031_OFS48_SHIFT, TMC5031_MSLUT[1](motor), false}) +#define TMC5031_OFS49_MASK 0x00020000 +#define TMC5031_OFS49_SHIFT 17 +#define TMC5031_OFS49_FIELD(motor) ((RegisterField) {TMC5031_OFS49_MASK, TMC5031_OFS49_SHIFT, TMC5031_MSLUT[1](motor), false}) +#define TMC5031_OFS50_MASK 0x00040000 +#define TMC5031_OFS50_SHIFT 18 +#define TMC5031_OFS50_FIELD(motor) ((RegisterField) {TMC5031_OFS50_MASK, TMC5031_OFS50_SHIFT, TMC5031_MSLUT[1](motor), false}) +#define TMC5031_OFS51_MASK 0x00080000 +#define TMC5031_OFS51_SHIFT 19 +#define TMC5031_OFS51_FIELD(motor) ((RegisterField) {TMC5031_OFS51_MASK, TMC5031_OFS51_SHIFT, TMC5031_MSLUT[1](motor), false}) +#define TMC5031_OFS52_MASK 0x00100000 +#define TMC5031_OFS52_SHIFT 20 +#define TMC5031_OFS52_FIELD(motor) ((RegisterField) {TMC5031_OFS52_MASK, TMC5031_OFS52_SHIFT, TMC5031_MSLUT[1](motor), false}) +#define TMC5031_OFS53_MASK 0x00200000 +#define TMC5031_OFS53_SHIFT 21 +#define TMC5031_OFS53_FIELD(motor) ((RegisterField) {TMC5031_OFS53_MASK, TMC5031_OFS53_SHIFT, TMC5031_MSLUT[1](motor), false}) +#define TMC5031_OFS54_MASK 0x00400000 +#define TMC5031_OFS54_SHIFT 22 +#define TMC5031_OFS54_FIELD(motor) ((RegisterField) {TMC5031_OFS54_MASK, TMC5031_OFS54_SHIFT, TMC5031_MSLUT[1](motor), false}) +#define TMC5031_OFS55_MASK 0x00800000 +#define TMC5031_OFS55_SHIFT 23 +#define TMC5031_OFS55_FIELD(motor) ((RegisterField) {TMC5031_OFS55_MASK, TMC5031_OFS55_SHIFT, TMC5031_MSLUT[1](motor), false}) +#define TMC5031_OFS56_MASK 0x01000000 +#define TMC5031_OFS56_SHIFT 24 +#define TMC5031_OFS56_FIELD(motor) ((RegisterField) {TMC5031_OFS56_MASK, TMC5031_OFS56_SHIFT, TMC5031_MSLUT[1](motor), false}) +#define TMC5031_OFS57_MASK 0x02000000 +#define TMC5031_OFS57_SHIFT 25 +#define TMC5031_OFS57_FIELD(motor) ((RegisterField) {TMC5031_OFS57_MASK, TMC5031_OFS57_SHIFT, TMC5031_MSLUT[1](motor), false}) +#define TMC5031_OFS58_MASK 0x04000000 +#define TMC5031_OFS58_SHIFT 26 +#define TMC5031_OFS58_FIELD(motor) ((RegisterField) {TMC5031_OFS58_MASK, TMC5031_OFS58_SHIFT, TMC5031_MSLUT[1](motor), false}) +#define TMC5031_OFS59_MASK 0x08000000 +#define TMC5031_OFS59_SHIFT 27 +#define TMC5031_OFS59_FIELD(motor) ((RegisterField) {TMC5031_OFS59_MASK, TMC5031_OFS59_SHIFT, TMC5031_MSLUT[1](motor), false}) +#define TMC5031_OFS60_MASK 0x10000000 +#define TMC5031_OFS60_SHIFT 28 +#define TMC5031_OFS60_FIELD(motor) ((RegisterField) {TMC5031_OFS60_MASK, TMC5031_OFS60_SHIFT, TMC5031_MSLUT[1](motor), false}) +#define TMC5031_OFS61_MASK 0x20000000 +#define TMC5031_OFS61_SHIFT 29 +#define TMC5031_OFS61_FIELD(motor) ((RegisterField) {TMC5031_OFS61_MASK, TMC5031_OFS61_SHIFT, TMC5031_MSLUT[1](motor), false}) +#define TMC5031_OFS62_MASK 0x40000000 +#define TMC5031_OFS62_SHIFT 30 +#define TMC5031_OFS62_FIELD(motor) ((RegisterField) {TMC5031_OFS62_MASK, TMC5031_OFS62_SHIFT, TMC5031_MSLUT[1](motor), false}) +#define TMC5031_OFS63_MASK 0x80000000 +#define TMC5031_OFS63_SHIFT 31 +#define TMC5031_OFS63_FIELD(motor) ((RegisterField) {TMC5031_OFS63_MASK, TMC5031_OFS63_SHIFT, TMC5031_MSLUT[1](motor), false}) +#define TMC5031_OFS64_MASK 0x00000001 +#define TMC5031_OFS64_SHIFT 0 +#define TMC5031_OFS64_FIELD(motor) ((RegisterField) {TMC5031_OFS64_MASK, TMC5031_OFS64_SHIFT, TMC5031_MSLUT[2](motor), false}) +#define TMC5031_OFS65_MASK 0x00000002 +#define TMC5031_OFS65_SHIFT 1 +#define TMC5031_OFS65_FIELD(motor) ((RegisterField) {TMC5031_OFS65_MASK, TMC5031_OFS65_SHIFT, TMC5031_MSLUT[2](motor), false}) +#define TMC5031_OFS66_MASK 0x00000004 +#define TMC5031_OFS66_SHIFT 2 +#define TMC5031_OFS66_FIELD(motor) ((RegisterField) {TMC5031_OFS66_MASK, TMC5031_OFS66_SHIFT, TMC5031_MSLUT[2](motor), false}) +#define TMC5031_OFS67_MASK 0x00000008 +#define TMC5031_OFS67_SHIFT 3 +#define TMC5031_OFS67_FIELD(motor) ((RegisterField) {TMC5031_OFS67_MASK, TMC5031_OFS67_SHIFT, TMC5031_MSLUT[2](motor), false}) +#define TMC5031_OFS68_MASK 0x00000010 +#define TMC5031_OFS68_SHIFT 4 +#define TMC5031_OFS68_FIELD(motor) ((RegisterField) {TMC5031_OFS68_MASK, TMC5031_OFS68_SHIFT, TMC5031_MSLUT[2](motor), false}) +#define TMC5031_OFS69_MASK 0x00000020 +#define TMC5031_OFS69_SHIFT 5 +#define TMC5031_OFS69_FIELD(motor) ((RegisterField) {TMC5031_OFS69_MASK, TMC5031_OFS69_SHIFT, TMC5031_MSLUT[2](motor), false}) +#define TMC5031_OFS70_MASK 0x00000040 +#define TMC5031_OFS70_SHIFT 6 +#define TMC5031_OFS70_FIELD(motor) ((RegisterField) {TMC5031_OFS70_MASK, TMC5031_OFS70_SHIFT, TMC5031_MSLUT[2](motor), false}) +#define TMC5031_OFS71_MASK 0x00000080 +#define TMC5031_OFS71_SHIFT 7 +#define TMC5031_OFS71_FIELD(motor) ((RegisterField) {TMC5031_OFS71_MASK, TMC5031_OFS71_SHIFT, TMC5031_MSLUT[2](motor), false}) +#define TMC5031_OFS72_MASK 0x00000100 +#define TMC5031_OFS72_SHIFT 8 +#define TMC5031_OFS72_FIELD(motor) ((RegisterField) {TMC5031_OFS72_MASK, TMC5031_OFS72_SHIFT, TMC5031_MSLUT[2](motor), false}) +#define TMC5031_OFS73_MASK 0x00000200 +#define TMC5031_OFS73_SHIFT 9 +#define TMC5031_OFS73_FIELD(motor) ((RegisterField) {TMC5031_OFS73_MASK, TMC5031_OFS73_SHIFT, TMC5031_MSLUT[2](motor), false}) +#define TMC5031_OFS74_MASK 0x00000400 +#define TMC5031_OFS74_SHIFT 10 +#define TMC5031_OFS74_FIELD(motor) ((RegisterField) {TMC5031_OFS74_MASK, TMC5031_OFS74_SHIFT, TMC5031_MSLUT[2](motor), false}) +#define TMC5031_OFS75_MASK 0x00000800 +#define TMC5031_OFS75_SHIFT 11 +#define TMC5031_OFS75_FIELD(motor) ((RegisterField) {TMC5031_OFS75_MASK, TMC5031_OFS75_SHIFT, TMC5031_MSLUT[2](motor), false}) +#define TMC5031_OFS76_MASK 0x00001000 +#define TMC5031_OFS76_SHIFT 12 +#define TMC5031_OFS76_FIELD(motor) ((RegisterField) {TMC5031_OFS76_MASK, TMC5031_OFS76_SHIFT, TMC5031_MSLUT[2](motor), false}) +#define TMC5031_OFS77_MASK 0x00002000 +#define TMC5031_OFS77_SHIFT 13 +#define TMC5031_OFS77_FIELD(motor) ((RegisterField) {TMC5031_OFS77_MASK, TMC5031_OFS77_SHIFT, TMC5031_MSLUT[2](motor), false}) +#define TMC5031_OFS78_MASK 0x00004000 +#define TMC5031_OFS78_SHIFT 14 +#define TMC5031_OFS78_FIELD(motor) ((RegisterField) {TMC5031_OFS78_MASK, TMC5031_OFS78_SHIFT, TMC5031_MSLUT[2](motor), false}) +#define TMC5031_OFS79_MASK 0x00008000 +#define TMC5031_OFS79_SHIFT 15 +#define TMC5031_OFS79_FIELD(motor) ((RegisterField) {TMC5031_OFS79_MASK, TMC5031_OFS79_SHIFT, TMC5031_MSLUT[2](motor), false}) +#define TMC5031_OFS80_MASK 0x00010000 +#define TMC5031_OFS80_SHIFT 16 +#define TMC5031_OFS80_FIELD(motor) ((RegisterField) {TMC5031_OFS80_MASK, TMC5031_OFS80_SHIFT, TMC5031_MSLUT[2](motor), false}) +#define TMC5031_OFS81_MASK 0x00020000 +#define TMC5031_OFS81_SHIFT 17 +#define TMC5031_OFS81_FIELD(motor) ((RegisterField) {TMC5031_OFS81_MASK, TMC5031_OFS81_SHIFT, TMC5031_MSLUT[2](motor), false}) +#define TMC5031_OFS82_MASK 0x00040000 +#define TMC5031_OFS82_SHIFT 18 +#define TMC5031_OFS82_FIELD(motor) ((RegisterField) {TMC5031_OFS82_MASK, TMC5031_OFS82_SHIFT, TMC5031_MSLUT[2](motor), false}) +#define TMC5031_OFS83_MASK 0x00080000 +#define TMC5031_OFS83_SHIFT 19 +#define TMC5031_OFS83_FIELD(motor) ((RegisterField) {TMC5031_OFS83_MASK, TMC5031_OFS83_SHIFT, TMC5031_MSLUT[2](motor), false}) +#define TMC5031_OFS84_MASK 0x00100000 +#define TMC5031_OFS84_SHIFT 20 +#define TMC5031_OFS84_FIELD(motor) ((RegisterField) {TMC5031_OFS84_MASK, TMC5031_OFS84_SHIFT, TMC5031_MSLUT[2](motor), false}) +#define TMC5031_OFS85_MASK 0x00200000 +#define TMC5031_OFS85_SHIFT 21 +#define TMC5031_OFS85_FIELD(motor) ((RegisterField) {TMC5031_OFS85_MASK, TMC5031_OFS85_SHIFT, TMC5031_MSLUT[2](motor), false}) +#define TMC5031_OFS86_MASK 0x00400000 +#define TMC5031_OFS86_SHIFT 22 +#define TMC5031_OFS86_FIELD(motor) ((RegisterField) {TMC5031_OFS86_MASK, TMC5031_OFS86_SHIFT, TMC5031_MSLUT[2](motor), false}) +#define TMC5031_OFS87_MASK 0x00800000 +#define TMC5031_OFS87_SHIFT 23 +#define TMC5031_OFS87_FIELD(motor) ((RegisterField) {TMC5031_OFS87_MASK, TMC5031_OFS87_SHIFT, TMC5031_MSLUT[2](motor), false}) +#define TMC5031_OFS88_MASK 0x01000000 +#define TMC5031_OFS88_SHIFT 24 +#define TMC5031_OFS88_FIELD(motor) ((RegisterField) {TMC5031_OFS88_MASK, TMC5031_OFS88_SHIFT, TMC5031_MSLUT[2](motor), false}) +#define TMC5031_OFS89_MASK 0x02000000 +#define TMC5031_OFS89_SHIFT 25 +#define TMC5031_OFS89_FIELD(motor) ((RegisterField) {TMC5031_OFS89_MASK, TMC5031_OFS89_SHIFT, TMC5031_MSLUT[2](motor), false}) +#define TMC5031_OFS90_MASK 0x04000000 +#define TMC5031_OFS90_SHIFT 26 +#define TMC5031_OFS90_FIELD(motor) ((RegisterField) {TMC5031_OFS90_MASK, TMC5031_OFS90_SHIFT, TMC5031_MSLUT[2](motor), false}) +#define TMC5031_OFS91_MASK 0x08000000 +#define TMC5031_OFS91_SHIFT 27 +#define TMC5031_OFS91_FIELD(motor) ((RegisterField) {TMC5031_OFS91_MASK, TMC5031_OFS91_SHIFT, TMC5031_MSLUT[2](motor), false}) +#define TMC5031_OFS92_MASK 0x10000000 +#define TMC5031_OFS92_SHIFT 28 +#define TMC5031_OFS92_FIELD(motor) ((RegisterField) {TMC5031_OFS92_MASK, TMC5031_OFS92_SHIFT, TMC5031_MSLUT[2](motor), false}) +#define TMC5031_OFS93_MASK 0x20000000 +#define TMC5031_OFS93_SHIFT 29 +#define TMC5031_OFS93_FIELD(motor) ((RegisterField) {TMC5031_OFS93_MASK, TMC5031_OFS93_SHIFT, TMC5031_MSLUT[2](motor), false}) +#define TMC5031_OFS94_MASK 0x40000000 +#define TMC5031_OFS94_SHIFT 30 +#define TMC5031_OFS94_FIELD(motor) ((RegisterField) {TMC5031_OFS94_MASK, TMC5031_OFS94_SHIFT, TMC5031_MSLUT[2](motor), false}) +#define TMC5031_OFS95_MASK 0x80000000 +#define TMC5031_OFS95_SHIFT 31 +#define TMC5031_OFS95_FIELD(motor) ((RegisterField) {TMC5031_OFS95_MASK, TMC5031_OFS95_SHIFT, TMC5031_MSLUT[2](motor), false}) +#define TMC5031_OFS96_MASK 0x00000001 +#define TMC5031_OFS96_SHIFT 0 +#define TMC5031_OFS96_FIELD(motor) ((RegisterField) {TMC5031_OFS96_MASK, TMC5031_OFS96_SHIFT, TMC5031_MSLUT[3](motor), false}) +#define TMC5031_OFS97_MASK 0x00000002 +#define TMC5031_OFS97_SHIFT 1 +#define TMC5031_OFS97_FIELD(motor) ((RegisterField) {TMC5031_OFS97_MASK, TMC5031_OFS97_SHIFT, TMC5031_MSLUT[3](motor), false}) +#define TMC5031_OFS98_MASK 0x00000004 +#define TMC5031_OFS98_SHIFT 2 +#define TMC5031_OFS98_FIELD(motor) ((RegisterField) {TMC5031_OFS98_MASK, TMC5031_OFS98_SHIFT, TMC5031_MSLUT[3](motor), false}) +#define TMC5031_OFS99_MASK 0x00000008 +#define TMC5031_OFS99_SHIFT 3 +#define TMC5031_OFS99_FIELD(motor) ((RegisterField) {TMC5031_OFS99_MASK, TMC5031_OFS99_SHIFT, TMC5031_MSLUT[3](motor), false}) +#define TMC5031_OFS100_MASK 0x00000010 +#define TMC5031_OFS100_SHIFT 4 +#define TMC5031_OFS100_FIELD(motor) ((RegisterField) {TMC5031_OFS100_MASK, TMC5031_OFS100_SHIFT, TMC5031_MSLUT[3](motor), false}) +#define TMC5031_OFS101_MASK 0x00000020 +#define TMC5031_OFS101_SHIFT 5 +#define TMC5031_OFS101_FIELD(motor) ((RegisterField) {TMC5031_OFS101_MASK, TMC5031_OFS101_SHIFT, TMC5031_MSLUT[3](motor), false}) +#define TMC5031_OFS102_MASK 0x00000040 +#define TMC5031_OFS102_SHIFT 6 +#define TMC5031_OFS102_FIELD(motor) ((RegisterField) {TMC5031_OFS102_MASK, TMC5031_OFS102_SHIFT, TMC5031_MSLUT[3](motor), false}) +#define TMC5031_OFS103_MASK 0x00000080 +#define TMC5031_OFS103_SHIFT 7 +#define TMC5031_OFS103_FIELD(motor) ((RegisterField) {TMC5031_OFS103_MASK, TMC5031_OFS103_SHIFT, TMC5031_MSLUT[3](motor), false}) +#define TMC5031_OFS104_MASK 0x00000100 +#define TMC5031_OFS104_SHIFT 8 +#define TMC5031_OFS104_FIELD(motor) ((RegisterField) {TMC5031_OFS104_MASK, TMC5031_OFS104_SHIFT, TMC5031_MSLUT[3](motor), false}) +#define TMC5031_OFS105_MASK 0x00000200 +#define TMC5031_OFS105_SHIFT 9 +#define TMC5031_OFS105_FIELD(motor) ((RegisterField) {TMC5031_OFS105_MASK, TMC5031_OFS105_SHIFT, TMC5031_MSLUT[3](motor), false}) +#define TMC5031_OFS106_MASK 0x00000400 +#define TMC5031_OFS106_SHIFT 10 +#define TMC5031_OFS106_FIELD(motor) ((RegisterField) {TMC5031_OFS106_MASK, TMC5031_OFS106_SHIFT, TMC5031_MSLUT[3](motor), false}) +#define TMC5031_OFS107_MASK 0x00000800 +#define TMC5031_OFS107_SHIFT 11 +#define TMC5031_OFS107_FIELD(motor) ((RegisterField) {TMC5031_OFS107_MASK, TMC5031_OFS107_SHIFT, TMC5031_MSLUT[3](motor), false}) +#define TMC5031_OFS108_MASK 0x00001000 +#define TMC5031_OFS108_SHIFT 12 +#define TMC5031_OFS108_FIELD(motor) ((RegisterField) {TMC5031_OFS108_MASK, TMC5031_OFS108_SHIFT, TMC5031_MSLUT[3](motor), false}) +#define TMC5031_OFS109_MASK 0x00002000 +#define TMC5031_OFS109_SHIFT 13 +#define TMC5031_OFS109_FIELD(motor) ((RegisterField) {TMC5031_OFS109_MASK, TMC5031_OFS109_SHIFT, TMC5031_MSLUT[3](motor), false}) +#define TMC5031_OFS110_MASK 0x00004000 +#define TMC5031_OFS110_SHIFT 14 +#define TMC5031_OFS110_FIELD(motor) ((RegisterField) {TMC5031_OFS110_MASK, TMC5031_OFS110_SHIFT, TMC5031_MSLUT[3](motor), false}) +#define TMC5031_OFS111_MASK 0x00008000 +#define TMC5031_OFS111_SHIFT 15 +#define TMC5031_OFS111_FIELD(motor) ((RegisterField) {TMC5031_OFS111_MASK, TMC5031_OFS111_SHIFT, TMC5031_MSLUT[3](motor), false}) +#define TMC5031_OFS112_MASK 0x00010000 +#define TMC5031_OFS112_SHIFT 16 +#define TMC5031_OFS112_FIELD(motor) ((RegisterField) {TMC5031_OFS112_MASK, TMC5031_OFS112_SHIFT, TMC5031_MSLUT[3](motor), false}) +#define TMC5031_OFS113_MASK 0x00020000 +#define TMC5031_OFS113_SHIFT 17 +#define TMC5031_OFS113_FIELD(motor) ((RegisterField) {TMC5031_OFS113_MASK, TMC5031_OFS113_SHIFT, TMC5031_MSLUT[3](motor), false}) +#define TMC5031_OFS114_MASK 0x00040000 +#define TMC5031_OFS114_SHIFT 18 +#define TMC5031_OFS114_FIELD(motor) ((RegisterField) {TMC5031_OFS114_MASK, TMC5031_OFS114_SHIFT, TMC5031_MSLUT[3](motor), false}) +#define TMC5031_OFS115_MASK 0x00080000 +#define TMC5031_OFS115_SHIFT 19 +#define TMC5031_OFS115_FIELD(motor) ((RegisterField) {TMC5031_OFS115_MASK, TMC5031_OFS115_SHIFT, TMC5031_MSLUT[3](motor), false}) +#define TMC5031_OFS116_MASK 0x00100000 +#define TMC5031_OFS116_SHIFT 20 +#define TMC5031_OFS116_FIELD(motor) ((RegisterField) {TMC5031_OFS116_MASK, TMC5031_OFS116_SHIFT, TMC5031_MSLUT[3](motor), false}) +#define TMC5031_OFS117_MASK 0x00200000 +#define TMC5031_OFS117_SHIFT 21 +#define TMC5031_OFS117_FIELD(motor) ((RegisterField) {TMC5031_OFS117_MASK, TMC5031_OFS117_SHIFT, TMC5031_MSLUT[3](motor), false}) +#define TMC5031_OFS118_MASK 0x00400000 +#define TMC5031_OFS118_SHIFT 22 +#define TMC5031_OFS118_FIELD(motor) ((RegisterField) {TMC5031_OFS118_MASK, TMC5031_OFS118_SHIFT, TMC5031_MSLUT[3](motor), false}) +#define TMC5031_OFS119_MASK 0x00800000 +#define TMC5031_OFS119_SHIFT 23 +#define TMC5031_OFS119_FIELD(motor) ((RegisterField) {TMC5031_OFS119_MASK, TMC5031_OFS119_SHIFT, TMC5031_MSLUT[3](motor), false}) +#define TMC5031_OFS120_MASK 0x01000000 +#define TMC5031_OFS120_SHIFT 24 +#define TMC5031_OFS120_FIELD(motor) ((RegisterField) {TMC5031_OFS120_MASK, TMC5031_OFS120_SHIFT, TMC5031_MSLUT[3](motor), false}) +#define TMC5031_OFS121_MASK 0x02000000 +#define TMC5031_OFS121_SHIFT 25 +#define TMC5031_OFS121_FIELD(motor) ((RegisterField) {TMC5031_OFS121_MASK, TMC5031_OFS121_SHIFT, TMC5031_MSLUT[3](motor), false}) +#define TMC5031_OFS122_MASK 0x04000000 +#define TMC5031_OFS122_SHIFT 26 +#define TMC5031_OFS122_FIELD(motor) ((RegisterField) {TMC5031_OFS122_MASK, TMC5031_OFS122_SHIFT, TMC5031_MSLUT[3](motor), false}) +#define TMC5031_OFS123_MASK 0x08000000 +#define TMC5031_OFS123_SHIFT 27 +#define TMC5031_OFS123_FIELD(motor) ((RegisterField) {TMC5031_OFS123_MASK, TMC5031_OFS123_SHIFT, TMC5031_MSLUT[3](motor), false}) +#define TMC5031_OFS124_MASK 0x10000000 +#define TMC5031_OFS124_SHIFT 28 +#define TMC5031_OFS124_FIELD(motor) ((RegisterField) {TMC5031_OFS124_MASK, TMC5031_OFS124_SHIFT, TMC5031_MSLUT[3](motor), false}) +#define TMC5031_OFS125_MASK 0x20000000 +#define TMC5031_OFS125_SHIFT 29 +#define TMC5031_OFS125_FIELD(motor) ((RegisterField) {TMC5031_OFS125_MASK, TMC5031_OFS125_SHIFT, TMC5031_MSLUT[3](motor), false}) +#define TMC5031_OFS126_MASK 0x40000000 +#define TMC5031_OFS126_SHIFT 30 +#define TMC5031_OFS126_FIELD(motor) ((RegisterField) {TMC5031_OFS126_MASK, TMC5031_OFS126_SHIFT, TMC5031_MSLUT[3](motor), false}) +#define TMC5031_OFS127_MASK 0x80000000 +#define TMC5031_OFS127_SHIFT 31 +#define TMC5031_OFS127_FIELD(motor) ((RegisterField) {TMC5031_OFS127_MASK, TMC5031_OFS127_SHIFT, TMC5031_MSLUT[3](motor), false}) +#define TMC5031_OFS128_MASK 0x00000001 +#define TMC5031_OFS128_SHIFT 0 +#define TMC5031_OFS128_FIELD(motor) ((RegisterField) {TMC5031_OFS128_MASK, TMC5031_OFS128_SHIFT, TMC5031_MSLUT[4](motor), false}) +#define TMC5031_OFS129_MASK 0x00000002 +#define TMC5031_OFS129_SHIFT 1 +#define TMC5031_OFS129_FIELD(motor) ((RegisterField) {TMC5031_OFS129_MASK, TMC5031_OFS129_SHIFT, TMC5031_MSLUT[4](motor), false}) +#define TMC5031_OFS130_MASK 0x00000004 +#define TMC5031_OFS130_SHIFT 2 +#define TMC5031_OFS130_FIELD(motor) ((RegisterField) {TMC5031_OFS130_MASK, TMC5031_OFS130_SHIFT, TMC5031_MSLUT[4](motor), false}) +#define TMC5031_OFS131_MASK 0x00000008 +#define TMC5031_OFS131_SHIFT 3 +#define TMC5031_OFS131_FIELD(motor) ((RegisterField) {TMC5031_OFS131_MASK, TMC5031_OFS131_SHIFT, TMC5031_MSLUT[4](motor), false}) +#define TMC5031_OFS132_MASK 0x00000010 +#define TMC5031_OFS132_SHIFT 4 +#define TMC5031_OFS132_FIELD(motor) ((RegisterField) {TMC5031_OFS132_MASK, TMC5031_OFS132_SHIFT, TMC5031_MSLUT[4](motor), false}) +#define TMC5031_OFS133_MASK 0x00000020 +#define TMC5031_OFS133_SHIFT 5 +#define TMC5031_OFS133_FIELD(motor) ((RegisterField) {TMC5031_OFS133_MASK, TMC5031_OFS133_SHIFT, TMC5031_MSLUT[4](motor), false}) +#define TMC5031_OFS134_MASK 0x00000040 +#define TMC5031_OFS134_SHIFT 6 +#define TMC5031_OFS134_FIELD(motor) ((RegisterField) {TMC5031_OFS134_MASK, TMC5031_OFS134_SHIFT, TMC5031_MSLUT[4](motor), false}) +#define TMC5031_OFS135_MASK 0x00000080 +#define TMC5031_OFS135_SHIFT 7 +#define TMC5031_OFS135_FIELD(motor) ((RegisterField) {TMC5031_OFS135_MASK, TMC5031_OFS135_SHIFT, TMC5031_MSLUT[4](motor), false}) +#define TMC5031_OFS136_MASK 0x00000100 +#define TMC5031_OFS136_SHIFT 8 +#define TMC5031_OFS136_FIELD(motor) ((RegisterField) {TMC5031_OFS136_MASK, TMC5031_OFS136_SHIFT, TMC5031_MSLUT[4](motor), false}) +#define TMC5031_OFS137_MASK 0x00000200 +#define TMC5031_OFS137_SHIFT 9 +#define TMC5031_OFS137_FIELD(motor) ((RegisterField) {TMC5031_OFS137_MASK, TMC5031_OFS137_SHIFT, TMC5031_MSLUT[4](motor), false}) +#define TMC5031_OFS138_MASK 0x00000400 +#define TMC5031_OFS138_SHIFT 10 +#define TMC5031_OFS138_FIELD(motor) ((RegisterField) {TMC5031_OFS138_MASK, TMC5031_OFS138_SHIFT, TMC5031_MSLUT[4](motor), false}) +#define TMC5031_OFS139_MASK 0x00000800 +#define TMC5031_OFS139_SHIFT 11 +#define TMC5031_OFS139_FIELD(motor) ((RegisterField) {TMC5031_OFS139_MASK, TMC5031_OFS139_SHIFT, TMC5031_MSLUT[4](motor), false}) +#define TMC5031_OFS140_MASK 0x00001000 +#define TMC5031_OFS140_SHIFT 12 +#define TMC5031_OFS140_FIELD(motor) ((RegisterField) {TMC5031_OFS140_MASK, TMC5031_OFS140_SHIFT, TMC5031_MSLUT[4](motor), false}) +#define TMC5031_OFS141_MASK 0x00002000 +#define TMC5031_OFS141_SHIFT 13 +#define TMC5031_OFS141_FIELD(motor) ((RegisterField) {TMC5031_OFS141_MASK, TMC5031_OFS141_SHIFT, TMC5031_MSLUT[4](motor), false}) +#define TMC5031_OFS142_MASK 0x00004000 +#define TMC5031_OFS142_SHIFT 14 +#define TMC5031_OFS142_FIELD(motor) ((RegisterField) {TMC5031_OFS142_MASK, TMC5031_OFS142_SHIFT, TMC5031_MSLUT[4](motor), false}) +#define TMC5031_OFS143_MASK 0x00008000 +#define TMC5031_OFS143_SHIFT 15 +#define TMC5031_OFS143_FIELD(motor) ((RegisterField) {TMC5031_OFS143_MASK, TMC5031_OFS143_SHIFT, TMC5031_MSLUT[4](motor), false}) +#define TMC5031_OFS144_MASK 0x00010000 +#define TMC5031_OFS144_SHIFT 16 +#define TMC5031_OFS144_FIELD(motor) ((RegisterField) {TMC5031_OFS144_MASK, TMC5031_OFS144_SHIFT, TMC5031_MSLUT[4](motor), false}) +#define TMC5031_OFS145_MASK 0x00020000 +#define TMC5031_OFS145_SHIFT 17 +#define TMC5031_OFS145_FIELD(motor) ((RegisterField) {TMC5031_OFS145_MASK, TMC5031_OFS145_SHIFT, TMC5031_MSLUT[4](motor), false}) +#define TMC5031_OFS146_MASK 0x00040000 +#define TMC5031_OFS146_SHIFT 18 +#define TMC5031_OFS146_FIELD(motor) ((RegisterField) {TMC5031_OFS146_MASK, TMC5031_OFS146_SHIFT, TMC5031_MSLUT[4](motor), false}) +#define TMC5031_OFS147_MASK 0x00080000 +#define TMC5031_OFS147_SHIFT 19 +#define TMC5031_OFS147_FIELD(motor) ((RegisterField) {TMC5031_OFS147_MASK, TMC5031_OFS147_SHIFT, TMC5031_MSLUT[4](motor), false}) +#define TMC5031_OFS148_MASK 0x00100000 +#define TMC5031_OFS148_SHIFT 20 +#define TMC5031_OFS148_FIELD(motor) ((RegisterField) {TMC5031_OFS148_MASK, TMC5031_OFS148_SHIFT, TMC5031_MSLUT[4](motor), false}) +#define TMC5031_OFS149_MASK 0x00200000 +#define TMC5031_OFS149_SHIFT 21 +#define TMC5031_OFS149_FIELD(motor) ((RegisterField) {TMC5031_OFS149_MASK, TMC5031_OFS149_SHIFT, TMC5031_MSLUT[4](motor), false}) +#define TMC5031_OFS150_MASK 0x00400000 +#define TMC5031_OFS150_SHIFT 22 +#define TMC5031_OFS150_FIELD(motor) ((RegisterField) {TMC5031_OFS150_MASK, TMC5031_OFS150_SHIFT, TMC5031_MSLUT[4](motor), false}) +#define TMC5031_OFS151_MASK 0x00800000 +#define TMC5031_OFS151_SHIFT 23 +#define TMC5031_OFS151_FIELD(motor) ((RegisterField) {TMC5031_OFS151_MASK, TMC5031_OFS151_SHIFT, TMC5031_MSLUT[4](motor), false}) +#define TMC5031_OFS152_MASK 0x01000000 +#define TMC5031_OFS152_SHIFT 24 +#define TMC5031_OFS152_FIELD(motor) ((RegisterField) {TMC5031_OFS152_MASK, TMC5031_OFS152_SHIFT, TMC5031_MSLUT[4](motor), false}) +#define TMC5031_OFS153_MASK 0x02000000 +#define TMC5031_OFS153_SHIFT 25 +#define TMC5031_OFS153_FIELD(motor) ((RegisterField) {TMC5031_OFS153_MASK, TMC5031_OFS153_SHIFT, TMC5031_MSLUT[4](motor), false}) +#define TMC5031_OFS154_MASK 0x04000000 +#define TMC5031_OFS154_SHIFT 26 +#define TMC5031_OFS154_FIELD(motor) ((RegisterField) {TMC5031_OFS154_MASK, TMC5031_OFS154_SHIFT, TMC5031_MSLUT[4](motor), false}) +#define TMC5031_OFS155_MASK 0x08000000 +#define TMC5031_OFS155_SHIFT 27 +#define TMC5031_OFS155_FIELD(motor) ((RegisterField) {TMC5031_OFS155_MASK, TMC5031_OFS155_SHIFT, TMC5031_MSLUT[4](motor), false}) +#define TMC5031_OFS156_MASK 0x10000000 +#define TMC5031_OFS156_SHIFT 28 +#define TMC5031_OFS156_FIELD(motor) ((RegisterField) {TMC5031_OFS156_MASK, TMC5031_OFS156_SHIFT, TMC5031_MSLUT[4](motor), false}) +#define TMC5031_OFS157_MASK 0x20000000 +#define TMC5031_OFS157_SHIFT 29 +#define TMC5031_OFS157_FIELD(motor) ((RegisterField) {TMC5031_OFS157_MASK, TMC5031_OFS157_SHIFT, TMC5031_MSLUT[4](motor), false}) +#define TMC5031_OFS158_MASK 0x40000000 +#define TMC5031_OFS158_SHIFT 30 +#define TMC5031_OFS158_FIELD(motor) ((RegisterField) {TMC5031_OFS158_MASK, TMC5031_OFS158_SHIFT, TMC5031_MSLUT[4](motor), false}) +#define TMC5031_OFS159_MASK 0x80000000 +#define TMC5031_OFS159_SHIFT 31 +#define TMC5031_OFS159_FIELD(motor) ((RegisterField) {TMC5031_OFS159_MASK, TMC5031_OFS159_SHIFT, TMC5031_MSLUT[4](motor), false}) +#define TMC5031_OFS160_MASK 0x00000001 +#define TMC5031_OFS160_SHIFT 0 +#define TMC5031_OFS160_FIELD(motor) ((RegisterField) {TMC5031_OFS160_MASK, TMC5031_OFS160_SHIFT, TMC5031_MSLUT[5](motor), false}) +#define TMC5031_OFS161_MASK 0x00000002 +#define TMC5031_OFS161_SHIFT 1 +#define TMC5031_OFS161_FIELD(motor) ((RegisterField) {TMC5031_OFS161_MASK, TMC5031_OFS161_SHIFT, TMC5031_MSLUT[5](motor), false}) +#define TMC5031_OFS162_MASK 0x00000004 +#define TMC5031_OFS162_SHIFT 2 +#define TMC5031_OFS162_FIELD(motor) ((RegisterField) {TMC5031_OFS162_MASK, TMC5031_OFS162_SHIFT, TMC5031_MSLUT[5](motor), false}) +#define TMC5031_OFS163_MASK 0x00000008 +#define TMC5031_OFS163_SHIFT 3 +#define TMC5031_OFS163_FIELD(motor) ((RegisterField) {TMC5031_OFS163_MASK, TMC5031_OFS163_SHIFT, TMC5031_MSLUT[5](motor), false}) +#define TMC5031_OFS164_MASK 0x00000010 +#define TMC5031_OFS164_SHIFT 4 +#define TMC5031_OFS164_FIELD(motor) ((RegisterField) {TMC5031_OFS164_MASK, TMC5031_OFS164_SHIFT, TMC5031_MSLUT[5](motor), false}) +#define TMC5031_OFS165_MASK 0x00000020 +#define TMC5031_OFS165_SHIFT 5 +#define TMC5031_OFS165_FIELD(motor) ((RegisterField) {TMC5031_OFS165_MASK, TMC5031_OFS165_SHIFT, TMC5031_MSLUT[5](motor), false}) +#define TMC5031_OFS166_MASK 0x00000040 +#define TMC5031_OFS166_SHIFT 6 +#define TMC5031_OFS166_FIELD(motor) ((RegisterField) {TMC5031_OFS166_MASK, TMC5031_OFS166_SHIFT, TMC5031_MSLUT[5](motor), false}) +#define TMC5031_OFS167_MASK 0x00000080 +#define TMC5031_OFS167_SHIFT 7 +#define TMC5031_OFS167_FIELD(motor) ((RegisterField) {TMC5031_OFS167_MASK, TMC5031_OFS167_SHIFT, TMC5031_MSLUT[5](motor), false}) +#define TMC5031_OFS168_MASK 0x00000100 +#define TMC5031_OFS168_SHIFT 8 +#define TMC5031_OFS168_FIELD(motor) ((RegisterField) {TMC5031_OFS168_MASK, TMC5031_OFS168_SHIFT, TMC5031_MSLUT[5](motor), false}) +#define TMC5031_OFS169_MASK 0x00000200 +#define TMC5031_OFS169_SHIFT 9 +#define TMC5031_OFS169_FIELD(motor) ((RegisterField) {TMC5031_OFS169_MASK, TMC5031_OFS169_SHIFT, TMC5031_MSLUT[5](motor), false}) +#define TMC5031_OFS170_MASK 0x00000400 +#define TMC5031_OFS170_SHIFT 10 +#define TMC5031_OFS170_FIELD(motor) ((RegisterField) {TMC5031_OFS170_MASK, TMC5031_OFS170_SHIFT, TMC5031_MSLUT[5](motor), false}) +#define TMC5031_OFS171_MASK 0x00000800 +#define TMC5031_OFS171_SHIFT 11 +#define TMC5031_OFS171_FIELD(motor) ((RegisterField) {TMC5031_OFS171_MASK, TMC5031_OFS171_SHIFT, TMC5031_MSLUT[5](motor), false}) +#define TMC5031_OFS172_MASK 0x00001000 +#define TMC5031_OFS172_SHIFT 12 +#define TMC5031_OFS172_FIELD(motor) ((RegisterField) {TMC5031_OFS172_MASK, TMC5031_OFS172_SHIFT, TMC5031_MSLUT[5](motor), false}) +#define TMC5031_OFS173_MASK 0x00002000 +#define TMC5031_OFS173_SHIFT 13 +#define TMC5031_OFS173_FIELD(motor) ((RegisterField) {TMC5031_OFS173_MASK, TMC5031_OFS173_SHIFT, TMC5031_MSLUT[5](motor), false}) +#define TMC5031_OFS174_MASK 0x00004000 +#define TMC5031_OFS174_SHIFT 14 +#define TMC5031_OFS174_FIELD(motor) ((RegisterField) {TMC5031_OFS174_MASK, TMC5031_OFS174_SHIFT, TMC5031_MSLUT[5](motor), false}) +#define TMC5031_OFS175_MASK 0x00008000 +#define TMC5031_OFS175_SHIFT 15 +#define TMC5031_OFS175_FIELD(motor) ((RegisterField) {TMC5031_OFS175_MASK, TMC5031_OFS175_SHIFT, TMC5031_MSLUT[5](motor), false}) +#define TMC5031_OFS176_MASK 0x00010000 +#define TMC5031_OFS176_SHIFT 16 +#define TMC5031_OFS176_FIELD(motor) ((RegisterField) {TMC5031_OFS176_MASK, TMC5031_OFS176_SHIFT, TMC5031_MSLUT[5](motor), false}) +#define TMC5031_OFS177_MASK 0x00020000 +#define TMC5031_OFS177_SHIFT 17 +#define TMC5031_OFS177_FIELD(motor) ((RegisterField) {TMC5031_OFS177_MASK, TMC5031_OFS177_SHIFT, TMC5031_MSLUT[5](motor), false}) +#define TMC5031_OFS178_MASK 0x00040000 +#define TMC5031_OFS178_SHIFT 18 +#define TMC5031_OFS178_FIELD(motor) ((RegisterField) {TMC5031_OFS178_MASK, TMC5031_OFS178_SHIFT, TMC5031_MSLUT[5](motor), false}) +#define TMC5031_OFS179_MASK 0x00080000 +#define TMC5031_OFS179_SHIFT 19 +#define TMC5031_OFS179_FIELD(motor) ((RegisterField) {TMC5031_OFS179_MASK, TMC5031_OFS179_SHIFT, TMC5031_MSLUT[5](motor), false}) +#define TMC5031_OFS180_MASK 0x00100000 +#define TMC5031_OFS180_SHIFT 20 +#define TMC5031_OFS180_FIELD(motor) ((RegisterField) {TMC5031_OFS180_MASK, TMC5031_OFS180_SHIFT, TMC5031_MSLUT[5](motor), false}) +#define TMC5031_OFS181_MASK 0x00200000 +#define TMC5031_OFS181_SHIFT 21 +#define TMC5031_OFS181_FIELD(motor) ((RegisterField) {TMC5031_OFS181_MASK, TMC5031_OFS181_SHIFT, TMC5031_MSLUT[5](motor), false}) +#define TMC5031_OFS182_MASK 0x00400000 +#define TMC5031_OFS182_SHIFT 22 +#define TMC5031_OFS182_FIELD(motor) ((RegisterField) {TMC5031_OFS182_MASK, TMC5031_OFS182_SHIFT, TMC5031_MSLUT[5](motor), false}) +#define TMC5031_OFS183_MASK 0x00800000 +#define TMC5031_OFS183_SHIFT 23 +#define TMC5031_OFS183_FIELD(motor) ((RegisterField) {TMC5031_OFS183_MASK, TMC5031_OFS183_SHIFT, TMC5031_MSLUT[5](motor), false}) +#define TMC5031_OFS184_MASK 0x01000000 +#define TMC5031_OFS184_SHIFT 24 +#define TMC5031_OFS184_FIELD(motor) ((RegisterField) {TMC5031_OFS184_MASK, TMC5031_OFS184_SHIFT, TMC5031_MSLUT[5](motor), false}) +#define TMC5031_OFS185_MASK 0x02000000 +#define TMC5031_OFS185_SHIFT 25 +#define TMC5031_OFS185_FIELD(motor) ((RegisterField) {TMC5031_OFS185_MASK, TMC5031_OFS185_SHIFT, TMC5031_MSLUT[5](motor), false}) +#define TMC5031_OFS186_MASK 0x04000000 +#define TMC5031_OFS186_SHIFT 26 +#define TMC5031_OFS186_FIELD(motor) ((RegisterField) {TMC5031_OFS186_MASK, TMC5031_OFS186_SHIFT, TMC5031_MSLUT[5](motor), false}) +#define TMC5031_OFS187_MASK 0x08000000 +#define TMC5031_OFS187_SHIFT 27 +#define TMC5031_OFS187_FIELD(motor) ((RegisterField) {TMC5031_OFS187_MASK, TMC5031_OFS187_SHIFT, TMC5031_MSLUT[5](motor), false}) +#define TMC5031_OFS188_MASK 0x10000000 +#define TMC5031_OFS188_SHIFT 28 +#define TMC5031_OFS188_FIELD(motor) ((RegisterField) {TMC5031_OFS188_MASK, TMC5031_OFS188_SHIFT, TMC5031_MSLUT[5](motor), false}) +#define TMC5031_OFS189_MASK 0x20000000 +#define TMC5031_OFS189_SHIFT 29 +#define TMC5031_OFS189_FIELD(motor) ((RegisterField) {TMC5031_OFS189_MASK, TMC5031_OFS189_SHIFT, TMC5031_MSLUT[5](motor), false}) +#define TMC5031_OFS190_MASK 0x40000000 +#define TMC5031_OFS190_SHIFT 30 +#define TMC5031_OFS190_FIELD(motor) ((RegisterField) {TMC5031_OFS190_MASK, TMC5031_OFS190_SHIFT, TMC5031_MSLUT[5](motor), false}) +#define TMC5031_OFS191_MASK 0x80000000 +#define TMC5031_OFS191_SHIFT 31 +#define TMC5031_OFS191_FIELD(motor) ((RegisterField) {TMC5031_OFS191_MASK, TMC5031_OFS191_SHIFT, TMC5031_MSLUT[5](motor), false}) +#define TMC5031_OFS192_MASK 0x00000001 +#define TMC5031_OFS192_SHIFT 0 +#define TMC5031_OFS192_FIELD(motor) ((RegisterField) {TMC5031_OFS192_MASK, TMC5031_OFS192_SHIFT, TMC5031_MSLUT[6](motor), false}) +#define TMC5031_OFS193_MASK 0x00000002 +#define TMC5031_OFS193_SHIFT 1 +#define TMC5031_OFS193_FIELD(motor) ((RegisterField) {TMC5031_OFS193_MASK, TMC5031_OFS193_SHIFT, TMC5031_MSLUT[6](motor), false}) +#define TMC5031_OFS194_MASK 0x00000004 +#define TMC5031_OFS194_SHIFT 2 +#define TMC5031_OFS194_FIELD(motor) ((RegisterField) {TMC5031_OFS194_MASK, TMC5031_OFS194_SHIFT, TMC5031_MSLUT[6](motor), false}) +#define TMC5031_OFS195_MASK 0x00000008 +#define TMC5031_OFS195_SHIFT 3 +#define TMC5031_OFS195_FIELD(motor) ((RegisterField) {TMC5031_OFS195_MASK, TMC5031_OFS195_SHIFT, TMC5031_MSLUT[6](motor), false}) +#define TMC5031_OFS196_MASK 0x00000010 +#define TMC5031_OFS196_SHIFT 4 +#define TMC5031_OFS196_FIELD(motor) ((RegisterField) {TMC5031_OFS196_MASK, TMC5031_OFS196_SHIFT, TMC5031_MSLUT[6](motor), false}) +#define TMC5031_OFS197_MASK 0x00000020 +#define TMC5031_OFS197_SHIFT 5 +#define TMC5031_OFS197_FIELD(motor) ((RegisterField) {TMC5031_OFS197_MASK, TMC5031_OFS197_SHIFT, TMC5031_MSLUT[6](motor), false}) +#define TMC5031_OFS198_MASK 0x00000040 +#define TMC5031_OFS198_SHIFT 6 +#define TMC5031_OFS198_FIELD(motor) ((RegisterField) {TMC5031_OFS198_MASK, TMC5031_OFS198_SHIFT, TMC5031_MSLUT[6](motor), false}) +#define TMC5031_OFS199_MASK 0x00000080 +#define TMC5031_OFS199_SHIFT 7 +#define TMC5031_OFS199_FIELD(motor) ((RegisterField) {TMC5031_OFS199_MASK, TMC5031_OFS199_SHIFT, TMC5031_MSLUT[6](motor), false}) +#define TMC5031_OFS200_MASK 0x00000100 +#define TMC5031_OFS200_SHIFT 8 +#define TMC5031_OFS200_FIELD(motor) ((RegisterField) {TMC5031_OFS200_MASK, TMC5031_OFS200_SHIFT, TMC5031_MSLUT[6](motor), false}) +#define TMC5031_OFS201_MASK 0x00000200 +#define TMC5031_OFS201_SHIFT 9 +#define TMC5031_OFS201_FIELD(motor) ((RegisterField) {TMC5031_OFS201_MASK, TMC5031_OFS201_SHIFT, TMC5031_MSLUT[6](motor), false}) +#define TMC5031_OFS202_MASK 0x00000400 +#define TMC5031_OFS202_SHIFT 10 +#define TMC5031_OFS202_FIELD(motor) ((RegisterField) {TMC5031_OFS202_MASK, TMC5031_OFS202_SHIFT, TMC5031_MSLUT[6](motor), false}) +#define TMC5031_OFS203_MASK 0x00000800 +#define TMC5031_OFS203_SHIFT 11 +#define TMC5031_OFS203_FIELD(motor) ((RegisterField) {TMC5031_OFS203_MASK, TMC5031_OFS203_SHIFT, TMC5031_MSLUT[6](motor), false}) +#define TMC5031_OFS204_MASK 0x00001000 +#define TMC5031_OFS204_SHIFT 12 +#define TMC5031_OFS204_FIELD(motor) ((RegisterField) {TMC5031_OFS204_MASK, TMC5031_OFS204_SHIFT, TMC5031_MSLUT[6](motor), false}) +#define TMC5031_OFS205_MASK 0x00002000 +#define TMC5031_OFS205_SHIFT 13 +#define TMC5031_OFS205_FIELD(motor) ((RegisterField) {TMC5031_OFS205_MASK, TMC5031_OFS205_SHIFT, TMC5031_MSLUT[6](motor), false}) +#define TMC5031_OFS206_MASK 0x00004000 +#define TMC5031_OFS206_SHIFT 14 +#define TMC5031_OFS206_FIELD(motor) ((RegisterField) {TMC5031_OFS206_MASK, TMC5031_OFS206_SHIFT, TMC5031_MSLUT[6](motor), false}) +#define TMC5031_OFS207_MASK 0x00008000 +#define TMC5031_OFS207_SHIFT 15 +#define TMC5031_OFS207_FIELD(motor) ((RegisterField) {TMC5031_OFS207_MASK, TMC5031_OFS207_SHIFT, TMC5031_MSLUT[6](motor), false}) +#define TMC5031_OFS208_MASK 0x00010000 +#define TMC5031_OFS208_SHIFT 16 +#define TMC5031_OFS208_FIELD(motor) ((RegisterField) {TMC5031_OFS208_MASK, TMC5031_OFS208_SHIFT, TMC5031_MSLUT[6](motor), false}) +#define TMC5031_OFS209_MASK 0x00020000 +#define TMC5031_OFS209_SHIFT 17 +#define TMC5031_OFS209_FIELD(motor) ((RegisterField) {TMC5031_OFS209_MASK, TMC5031_OFS209_SHIFT, TMC5031_MSLUT[6](motor), false}) +#define TMC5031_OFS210_MASK 0x00040000 +#define TMC5031_OFS210_SHIFT 18 +#define TMC5031_OFS210_FIELD(motor) ((RegisterField) {TMC5031_OFS210_MASK, TMC5031_OFS210_SHIFT, TMC5031_MSLUT[6](motor), false}) +#define TMC5031_OFS211_MASK 0x00080000 +#define TMC5031_OFS211_SHIFT 19 +#define TMC5031_OFS211_FIELD(motor) ((RegisterField) {TMC5031_OFS211_MASK, TMC5031_OFS211_SHIFT, TMC5031_MSLUT[6](motor), false}) +#define TMC5031_OFS212_MASK 0x00100000 +#define TMC5031_OFS212_SHIFT 20 +#define TMC5031_OFS212_FIELD(motor) ((RegisterField) {TMC5031_OFS212_MASK, TMC5031_OFS212_SHIFT, TMC5031_MSLUT[6](motor), false}) +#define TMC5031_OFS213_MASK 0x00200000 +#define TMC5031_OFS213_SHIFT 21 +#define TMC5031_OFS213_FIELD(motor) ((RegisterField) {TMC5031_OFS213_MASK, TMC5031_OFS213_SHIFT, TMC5031_MSLUT[6](motor), false}) +#define TMC5031_OFS214_MASK 0x00400000 +#define TMC5031_OFS214_SHIFT 22 +#define TMC5031_OFS214_FIELD(motor) ((RegisterField) {TMC5031_OFS214_MASK, TMC5031_OFS214_SHIFT, TMC5031_MSLUT[6](motor), false}) +#define TMC5031_OFS215_MASK 0x00800000 +#define TMC5031_OFS215_SHIFT 23 +#define TMC5031_OFS215_FIELD(motor) ((RegisterField) {TMC5031_OFS215_MASK, TMC5031_OFS215_SHIFT, TMC5031_MSLUT[6](motor), false}) +#define TMC5031_OFS216_MASK 0x01000000 +#define TMC5031_OFS216_SHIFT 24 +#define TMC5031_OFS216_FIELD(motor) ((RegisterField) {TMC5031_OFS216_MASK, TMC5031_OFS216_SHIFT, TMC5031_MSLUT[6](motor), false}) +#define TMC5031_OFS217_MASK 0x02000000 +#define TMC5031_OFS217_SHIFT 25 +#define TMC5031_OFS217_FIELD(motor) ((RegisterField) {TMC5031_OFS217_MASK, TMC5031_OFS217_SHIFT, TMC5031_MSLUT[6](motor), false}) +#define TMC5031_OFS218_MASK 0x04000000 +#define TMC5031_OFS218_SHIFT 26 +#define TMC5031_OFS218_FIELD(motor) ((RegisterField) {TMC5031_OFS218_MASK, TMC5031_OFS218_SHIFT, TMC5031_MSLUT[6](motor), false}) +#define TMC5031_OFS219_MASK 0x08000000 +#define TMC5031_OFS219_SHIFT 27 +#define TMC5031_OFS219_FIELD(motor) ((RegisterField) {TMC5031_OFS219_MASK, TMC5031_OFS219_SHIFT, TMC5031_MSLUT[6](motor), false}) +#define TMC5031_OFS220_MASK 0x10000000 +#define TMC5031_OFS220_SHIFT 28 +#define TMC5031_OFS220_FIELD(motor) ((RegisterField) {TMC5031_OFS220_MASK, TMC5031_OFS220_SHIFT, TMC5031_MSLUT[6](motor), false}) +#define TMC5031_OFS221_MASK 0x20000000 +#define TMC5031_OFS221_SHIFT 29 +#define TMC5031_OFS221_FIELD(motor) ((RegisterField) {TMC5031_OFS221_MASK, TMC5031_OFS221_SHIFT, TMC5031_MSLUT[6](motor), false}) +#define TMC5031_OFS222_MASK 0x40000000 +#define TMC5031_OFS222_SHIFT 30 +#define TMC5031_OFS222_FIELD(motor) ((RegisterField) {TMC5031_OFS222_MASK, TMC5031_OFS222_SHIFT, TMC5031_MSLUT[6](motor), false}) +#define TMC5031_OFS223_MASK 0x80000000 +#define TMC5031_OFS223_SHIFT 31 +#define TMC5031_OFS223_FIELD(motor) ((RegisterField) {TMC5031_OFS223_MASK, TMC5031_OFS223_SHIFT, TMC5031_MSLUT[6](motor), false}) +#define TMC5031_OFS224_MASK 0x00000001 +#define TMC5031_OFS224_SHIFT 0 +#define TMC5031_OFS224_FIELD(motor) ((RegisterField) {TMC5031_OFS224_MASK, TMC5031_OFS224_SHIFT, TMC5031_MSLUT[7](motor), false}) +#define TMC5031_OFS225_MASK 0x00000002 +#define TMC5031_OFS225_SHIFT 1 +#define TMC5031_OFS225_FIELD(motor) ((RegisterField) {TMC5031_OFS225_MASK, TMC5031_OFS225_SHIFT, TMC5031_MSLUT[7](motor), false}) +#define TMC5031_OFS226_MASK 0x00000004 +#define TMC5031_OFS226_SHIFT 2 +#define TMC5031_OFS226_FIELD(motor) ((RegisterField) {TMC5031_OFS226_MASK, TMC5031_OFS226_SHIFT, TMC5031_MSLUT[7](motor), false}) +#define TMC5031_OFS227_MASK 0x00000008 +#define TMC5031_OFS227_SHIFT 3 +#define TMC5031_OFS227_FIELD(motor) ((RegisterField) {TMC5031_OFS227_MASK, TMC5031_OFS227_SHIFT, TMC5031_MSLUT[7](motor), false}) +#define TMC5031_OFS228_MASK 0x00000010 +#define TMC5031_OFS228_SHIFT 4 +#define TMC5031_OFS228_FIELD(motor) ((RegisterField) {TMC5031_OFS228_MASK, TMC5031_OFS228_SHIFT, TMC5031_MSLUT[7](motor), false}) +#define TMC5031_OFS229_MASK 0x00000020 +#define TMC5031_OFS229_SHIFT 5 +#define TMC5031_OFS229_FIELD(motor) ((RegisterField) {TMC5031_OFS229_MASK, TMC5031_OFS229_SHIFT, TMC5031_MSLUT[7](motor), false}) +#define TMC5031_OFS230_MASK 0x00000040 +#define TMC5031_OFS230_SHIFT 6 +#define TMC5031_OFS230_FIELD(motor) ((RegisterField) {TMC5031_OFS230_MASK, TMC5031_OFS230_SHIFT, TMC5031_MSLUT[7](motor), false}) +#define TMC5031_OFS231_MASK 0x00000080 +#define TMC5031_OFS231_SHIFT 7 +#define TMC5031_OFS231_FIELD(motor) ((RegisterField) {TMC5031_OFS231_MASK, TMC5031_OFS231_SHIFT, TMC5031_MSLUT[7](motor), false}) +#define TMC5031_OFS232_MASK 0x00000100 +#define TMC5031_OFS232_SHIFT 8 +#define TMC5031_OFS232_FIELD(motor) ((RegisterField) {TMC5031_OFS232_MASK, TMC5031_OFS232_SHIFT, TMC5031_MSLUT[7](motor), false}) +#define TMC5031_OFS233_MASK 0x00000200 +#define TMC5031_OFS233_SHIFT 9 +#define TMC5031_OFS233_FIELD(motor) ((RegisterField) {TMC5031_OFS233_MASK, TMC5031_OFS233_SHIFT, TMC5031_MSLUT[7](motor), false}) +#define TMC5031_OFS234_MASK 0x00000400 +#define TMC5031_OFS234_SHIFT 10 +#define TMC5031_OFS234_FIELD(motor) ((RegisterField) {TMC5031_OFS234_MASK, TMC5031_OFS234_SHIFT, TMC5031_MSLUT[7](motor), false}) +#define TMC5031_OFS235_MASK 0x00000800 +#define TMC5031_OFS235_SHIFT 11 +#define TMC5031_OFS235_FIELD(motor) ((RegisterField) {TMC5031_OFS235_MASK, TMC5031_OFS235_SHIFT, TMC5031_MSLUT[7](motor), false}) +#define TMC5031_OFS236_MASK 0x00001000 +#define TMC5031_OFS236_SHIFT 12 +#define TMC5031_OFS236_FIELD(motor) ((RegisterField) {TMC5031_OFS236_MASK, TMC5031_OFS236_SHIFT, TMC5031_MSLUT[7](motor), false}) +#define TMC5031_OFS237_MASK 0x00002000 +#define TMC5031_OFS237_SHIFT 13 +#define TMC5031_OFS237_FIELD(motor) ((RegisterField) {TMC5031_OFS237_MASK, TMC5031_OFS237_SHIFT, TMC5031_MSLUT[7](motor), false}) +#define TMC5031_OFS238_MASK 0x00004000 +#define TMC5031_OFS238_SHIFT 14 +#define TMC5031_OFS238_FIELD(motor) ((RegisterField) {TMC5031_OFS238_MASK, TMC5031_OFS238_SHIFT, TMC5031_MSLUT[7](motor), false}) +#define TMC5031_OFS239_MASK 0x00008000 +#define TMC5031_OFS239_SHIFT 15 +#define TMC5031_OFS239_FIELD(motor) ((RegisterField) {TMC5031_OFS239_MASK, TMC5031_OFS239_SHIFT, TMC5031_MSLUT[7](motor), false}) +#define TMC5031_OFS240_MASK 0x00010000 +#define TMC5031_OFS240_SHIFT 16 +#define TMC5031_OFS240_FIELD(motor) ((RegisterField) {TMC5031_OFS240_MASK, TMC5031_OFS240_SHIFT, TMC5031_MSLUT[7](motor), false}) +#define TMC5031_OFS241_MASK 0x00020000 +#define TMC5031_OFS241_SHIFT 17 +#define TMC5031_OFS241_FIELD(motor) ((RegisterField) {TMC5031_OFS241_MASK, TMC5031_OFS241_SHIFT, TMC5031_MSLUT[7](motor), false}) +#define TMC5031_OFS242_MASK 0x00040000 +#define TMC5031_OFS242_SHIFT 18 +#define TMC5031_OFS242_FIELD(motor) ((RegisterField) {TMC5031_OFS242_MASK, TMC5031_OFS242_SHIFT, TMC5031_MSLUT[7](motor), false}) +#define TMC5031_OFS243_MASK 0x00080000 +#define TMC5031_OFS243_SHIFT 19 +#define TMC5031_OFS243_FIELD(motor) ((RegisterField) {TMC5031_OFS243_MASK, TMC5031_OFS243_SHIFT, TMC5031_MSLUT[7](motor), false}) +#define TMC5031_OFS244_MASK 0x00100000 +#define TMC5031_OFS244_SHIFT 20 +#define TMC5031_OFS244_FIELD(motor) ((RegisterField) {TMC5031_OFS244_MASK, TMC5031_OFS244_SHIFT, TMC5031_MSLUT[7](motor), false}) +#define TMC5031_OFS245_MASK 0x00200000 +#define TMC5031_OFS245_SHIFT 21 +#define TMC5031_OFS245_FIELD(motor) ((RegisterField) {TMC5031_OFS245_MASK, TMC5031_OFS245_SHIFT, TMC5031_MSLUT[7](motor), false}) +#define TMC5031_OFS246_MASK 0x00400000 +#define TMC5031_OFS246_SHIFT 22 +#define TMC5031_OFS246_FIELD(motor) ((RegisterField) {TMC5031_OFS246_MASK, TMC5031_OFS246_SHIFT, TMC5031_MSLUT[7](motor), false}) +#define TMC5031_OFS247_MASK 0x00800000 +#define TMC5031_OFS247_SHIFT 23 +#define TMC5031_OFS247_FIELD(motor) ((RegisterField) {TMC5031_OFS247_MASK, TMC5031_OFS247_SHIFT, TMC5031_MSLUT[7](motor), false}) +#define TMC5031_OFS248_MASK 0x01000000 +#define TMC5031_OFS248_SHIFT 24 +#define TMC5031_OFS248_FIELD(motor) ((RegisterField) {TMC5031_OFS248_MASK, TMC5031_OFS248_SHIFT, TMC5031_MSLUT[7](motor), false}) +#define TMC5031_OFS249_MASK 0x02000000 +#define TMC5031_OFS249_SHIFT 25 +#define TMC5031_OFS249_FIELD(motor) ((RegisterField) {TMC5031_OFS249_MASK, TMC5031_OFS249_SHIFT, TMC5031_MSLUT[7](motor), false}) +#define TMC5031_OFS250_MASK 0x04000000 +#define TMC5031_OFS250_SHIFT 26 +#define TMC5031_OFS250_FIELD(motor) ((RegisterField) {TMC5031_OFS250_MASK, TMC5031_OFS250_SHIFT, TMC5031_MSLUT[7](motor), false}) +#define TMC5031_OFS251_MASK 0x08000000 +#define TMC5031_OFS251_SHIFT 27 +#define TMC5031_OFS251_FIELD(motor) ((RegisterField) {TMC5031_OFS251_MASK, TMC5031_OFS251_SHIFT, TMC5031_MSLUT[7](motor), false}) +#define TMC5031_OFS252_MASK 0x10000000 +#define TMC5031_OFS252_SHIFT 28 +#define TMC5031_OFS252_FIELD(motor) ((RegisterField) {TMC5031_OFS252_MASK, TMC5031_OFS252_SHIFT, TMC5031_MSLUT[7](motor), false}) +#define TMC5031_OFS253_MASK 0x20000000 +#define TMC5031_OFS253_SHIFT 29 +#define TMC5031_OFS253_FIELD(motor) ((RegisterField) {TMC5031_OFS253_MASK, TMC5031_OFS253_SHIFT, TMC5031_MSLUT[7](motor), false}) +#define TMC5031_OFS254_MASK 0x40000000 +#define TMC5031_OFS254_SHIFT 30 +#define TMC5031_OFS254_FIELD(motor) ((RegisterField) {TMC5031_OFS254_MASK, TMC5031_OFS254_SHIFT, TMC5031_MSLUT[7](motor), false}) +#define TMC5031_OFS255_MASK 0x80000000 +#define TMC5031_OFS255_SHIFT 31 +#define TMC5031_OFS255_FIELD(motor) ((RegisterField) {TMC5031_OFS255_MASK, TMC5031_OFS255_SHIFT, TMC5031_MSLUT[7](motor), false}) +#define TMC5031_W0_MASK 0x00000003 +#define TMC5031_W0_SHIFT 0 +#define TMC5031_W0_FIELD(motor) ((RegisterField) {TMC5031_W0_MASK, TMC5031_W0_SHIFT, TMC5031_MSLUTSEL(motor), false}) +#define TMC5031_W1_MASK 0x0000000C +#define TMC5031_W1_SHIFT 2 +#define TMC5031_W1_FIELD(motor) ((RegisterField) {TMC5031_W1_MASK, TMC5031_W1_SHIFT, TMC5031_MSLUTSEL(motor), false}) +#define TMC5031_W2_MASK 0x00000030 +#define TMC5031_W2_SHIFT 4 +#define TMC5031_W2_FIELD(motor) ((RegisterField) {TMC5031_W2_MASK, TMC5031_W2_SHIFT, TMC5031_MSLUTSEL(motor), false}) +#define TMC5031_W3_MASK 0x000000C0 +#define TMC5031_W3_SHIFT 6 +#define TMC5031_W3_FIELD(motor) ((RegisterField) {TMC5031_W3_MASK, TMC5031_W3_SHIFT, TMC5031_MSLUTSEL(motor), false}) +#define TMC5031_X1_MASK 0x0000FF00 +#define TMC5031_X1_SHIFT 8 +#define TMC5031_X1_FIELD(motor) ((RegisterField) {TMC5031_X1_MASK, TMC5031_X1_SHIFT, TMC5031_MSLUTSEL(motor), false}) +#define TMC5031_X2_MASK 0x00FF0000 +#define TMC5031_X2_SHIFT 16 +#define TMC5031_X2_FIELD(motor) ((RegisterField) {TMC5031_X2_MASK, TMC5031_X2_SHIFT, TMC5031_MSLUTSEL(motor), false}) +#define TMC5031_X3_MASK 0xFF000000 +#define TMC5031_X3_SHIFT 24 +#define TMC5031_X3_FIELD(motor) ((RegisterField) {TMC5031_X3_MASK, TMC5031_X3_SHIFT, TMC5031_MSLUTSEL(motor), false}) +#define TMC5031_START_SIN_MASK 0x000000FF +#define TMC5031_START_SIN_SHIFT 0 +#define TMC5031_START_SIN_FIELD(motor) ((RegisterField) {TMC5031_START_SIN_MASK, TMC5031_START_SIN_SHIFT, TMC5031_MSLUTSTART(motor), false}) +#define TMC5031_START_SIN90_MASK 0x00FF0000 +#define TMC5031_START_SIN90_SHIFT 16 +#define TMC5031_START_SIN90_FIELD(motor) ((RegisterField) {TMC5031_START_SIN90_MASK, TMC5031_START_SIN90_SHIFT, TMC5031_MSLUTSTART(motor), false}) +#define TMC5031_MSCNT_MASK 0x000003FF +#define TMC5031_MSCNT_SHIFT 0 +#define TMC5031_MSCNT_FIELD(motor) ((RegisterField) {TMC5031_MSCNT_MASK, TMC5031_MSCNT_SHIFT, TMC5031_MSCNT(motor), false}) +#define TMC5031_CUR_A_MASK 0x000001FF +#define TMC5031_CUR_A_SHIFT 0 +#define TMC5031_CUR_A_FIELD(motor) ((RegisterField) {TMC5031_CUR_A_MASK, TMC5031_CUR_A_SHIFT, TMC5031_MSCURACT(motor), true}) +#define TMC5031_CUR_B_MASK 0x01FF0000 +#define TMC5031_CUR_B_SHIFT 16 +#define TMC5031_CUR_B_FIELD(motor) ((RegisterField) {TMC5031_CUR_B_MASK, TMC5031_CUR_B_SHIFT, TMC5031_MSCURACT(motor), true}) +#define TMC5031_TOFF_MASK 0x0000000F +#define TMC5031_TOFF_SHIFT 0 +#define TMC5031_TOFF_FIELD(motor) ((RegisterField) {TMC5031_TOFF_MASK, TMC5031_TOFF_SHIFT, TMC5031_CHOPCONF(motor), false}) +#define TMC5031_TFD_2__0__MASK 0x00000070 +#define TMC5031_TFD_2__0__SHIFT 4 +#define TMC5031_TFD_2__0__FIELD(motor) ((RegisterField) {TMC5031_TFD_2__0__MASK, TMC5031_TFD_2__0__SHIFT, TMC5031_CHOPCONF(motor), false}) +#define TMC5031_OFFSET_MASK 0x00000780 +#define TMC5031_OFFSET_SHIFT 7 +#define TMC5031_OFFSET_FIELD(motor) ((RegisterField) {TMC5031_OFFSET_MASK, TMC5031_OFFSET_SHIFT, TMC5031_CHOPCONF(motor), false}) +#define TMC5031_TFD___MASK 0x00000800 +#define TMC5031_TFD___SHIFT 11 +#define TMC5031_TFD___FIELD(motor) ((RegisterField) {TMC5031_TFD___MASK, TMC5031_TFD___SHIFT, TMC5031_CHOPCONF(motor), false}) +#define TMC5031_DISFDCC_MASK 0x00001000 +#define TMC5031_DISFDCC_SHIFT 12 +#define TMC5031_DISFDCC_FIELD(motor) ((RegisterField) {TMC5031_DISFDCC_MASK, TMC5031_DISFDCC_SHIFT, TMC5031_CHOPCONF(motor), false}) +#define TMC5031_RNDTF_MASK 0x00002000 +#define TMC5031_RNDTF_SHIFT 13 +#define TMC5031_RNDTF_FIELD(motor) ((RegisterField) {TMC5031_RNDTF_MASK, TMC5031_RNDTF_SHIFT, TMC5031_CHOPCONF(motor), false}) +#define TMC5031_CHM_MASK 0x00004000 +#define TMC5031_CHM_SHIFT 14 +#define TMC5031_CHM_FIELD(motor) ((RegisterField) {TMC5031_CHM_MASK, TMC5031_CHM_SHIFT, TMC5031_CHOPCONF(motor), false}) +#define TMC5031_TBL_MASK 0x00018000 +#define TMC5031_TBL_SHIFT 15 +#define TMC5031_TBL_FIELD(motor) ((RegisterField) {TMC5031_TBL_MASK, TMC5031_TBL_SHIFT, TMC5031_CHOPCONF(motor), false}) +#define TMC5031_VSENSE_MASK 0x00020000 +#define TMC5031_VSENSE_SHIFT 17 +#define TMC5031_VSENSE_FIELD(motor) ((RegisterField) {TMC5031_VSENSE_MASK, TMC5031_VSENSE_SHIFT, TMC5031_CHOPCONF(motor), false}) +#define TMC5031_VHIGHFS_MASK 0x00040000 +#define TMC5031_VHIGHFS_SHIFT 18 +#define TMC5031_VHIGHFS_FIELD(motor) ((RegisterField) {TMC5031_VHIGHFS_MASK, TMC5031_VHIGHFS_SHIFT, TMC5031_CHOPCONF(motor), false}) +#define TMC5031_VHIGHCHM_MASK 0x00080000 +#define TMC5031_VHIGHCHM_SHIFT 19 +#define TMC5031_VHIGHCHM_FIELD(motor) ((RegisterField) {TMC5031_VHIGHCHM_MASK, TMC5031_VHIGHCHM_SHIFT, TMC5031_CHOPCONF(motor), false}) +#define TMC5031_SYNC_MASK 0x00F00000 +#define TMC5031_SYNC_SHIFT 20 +#define TMC5031_SYNC_FIELD(motor) ((RegisterField) {TMC5031_SYNC_MASK, TMC5031_SYNC_SHIFT, TMC5031_CHOPCONF(motor), false}) +#define TMC5031_DISS2G_MASK 0x40000000 +#define TMC5031_DISS2G_SHIFT 30 +#define TMC5031_DISS2G_FIELD(motor) ((RegisterField) {TMC5031_DISS2G_MASK, TMC5031_DISS2G_SHIFT, TMC5031_CHOPCONF(motor), false}) +#define TMC5031_HSTRT_MASK 0x00000070 +#define TMC5031_HSTRT_SHIFT 4 +#define TMC5031_HSTRT_FIELD(motor) ((RegisterField) {TMC5031_HSTRT_MASK, TMC5031_HSTRT_SHIFT, TMC5031_CHOPCONF(motor), false}) +#define TMC5031_HEND_MASK 0x00000780 +#define TMC5031_HEND_SHIFT 7 +#define TMC5031_HEND_FIELD(motor) ((RegisterField) {TMC5031_HEND_MASK, TMC5031_HEND_SHIFT, TMC5031_CHOPCONF(motor), false}) +#define TMC5031_SEMIN_MASK 0x0000000F +#define TMC5031_SEMIN_SHIFT 0 +#define TMC5031_SEMIN_FIELD(motor) ((RegisterField) {TMC5031_SEMIN_MASK, TMC5031_SEMIN_SHIFT, TMC5031_COOLCONF(motor), false}) +#define TMC5031_SEUP_MASK 0x00000060 +#define TMC5031_SEUP_SHIFT 5 +#define TMC5031_SEUP_FIELD(motor) ((RegisterField) {TMC5031_SEUP_MASK, TMC5031_SEUP_SHIFT, TMC5031_COOLCONF(motor), false}) +#define TMC5031_SEMAX_MASK 0x00000F00 +#define TMC5031_SEMAX_SHIFT 8 +#define TMC5031_SEMAX_FIELD(motor) ((RegisterField) {TMC5031_SEMAX_MASK, TMC5031_SEMAX_SHIFT, TMC5031_COOLCONF(motor), false}) +#define TMC5031_SEDN_MASK 0x00006000 +#define TMC5031_SEDN_SHIFT 13 +#define TMC5031_SEDN_FIELD(motor) ((RegisterField) {TMC5031_SEDN_MASK, TMC5031_SEDN_SHIFT, TMC5031_COOLCONF(motor), false}) +#define TMC5031_SEIMIN_MASK 0x00008000 +#define TMC5031_SEIMIN_SHIFT 15 +#define TMC5031_SEIMIN_FIELD(motor) ((RegisterField) {TMC5031_SEIMIN_MASK, TMC5031_SEIMIN_SHIFT, TMC5031_COOLCONF(motor), false}) +#define TMC5031_SGT_MASK 0x007F0000 +#define TMC5031_SGT_SHIFT 16 +#define TMC5031_SGT_FIELD(motor) ((RegisterField) {TMC5031_SGT_MASK, TMC5031_SGT_SHIFT, TMC5031_COOLCONF(motor), true}) +#define TMC5031_SFILT_MASK 0x01000000 +#define TMC5031_SFILT_SHIFT 24 +#define TMC5031_SFILT_FIELD(motor) ((RegisterField) {TMC5031_SFILT_MASK, TMC5031_SFILT_SHIFT, TMC5031_COOLCONF(motor), false}) +#define TMC5031_MRES_MASK 0x0F000000 // CHOPCONF_M1 // Microstep Resolution (manually added) +#define TMC5031_MRES_SHIFT 24 // min.: 1, max.: 256, default: 256 +#define TMC5031_MRES_FIELD(motor) ((RegisterField) {TMC5031_MRES_MASK, TMC5031_MRES_SHIFT, TMC5031_COOLCONF(motor), false}) +#define TMC5031_SG_RESULT_MASK 0x000003FF +#define TMC5031_SG_RESULT_SHIFT 0 +#define TMC5031_SG_RESULT_FIELD(motor) ((RegisterField) {TMC5031_SG_RESULT_MASK, TMC5031_SG_RESULT_SHIFT, TMC5031_DRVSTATUS(motor), false}) +#define TMC5031_FSACTIVE_MASK 0x00008000 +#define TMC5031_FSACTIVE_SHIFT 15 +#define TMC5031_FSACTIVE_FIELD(motor) ((RegisterField) {TMC5031_FSACTIVE_MASK, TMC5031_FSACTIVE_SHIFT, TMC5031_DRVSTATUS(motor), false}) +#define TMC5031_CS_ACTUAL_MASK 0x001F0000 +#define TMC5031_CS_ACTUAL_SHIFT 16 +#define TMC5031_CS_ACTUAL_FIELD(motor) ((RegisterField) {TMC5031_CS_ACTUAL_MASK, TMC5031_CS_ACTUAL_SHIFT, TMC5031_DRVSTATUS(motor), false}) +#define TMC5031_STALLGUARD_MASK 0x01000000 +#define TMC5031_STALLGUARD_SHIFT 24 +#define TMC5031_STALLGUARD_FIELD(motor) ((RegisterField) {TMC5031_STALLGUARD_MASK, TMC5031_STALLGUARD_SHIFT, TMC5031_DRVSTATUS(motor), false}) +#define TMC5031_OT_MASK 0x02000000 +#define TMC5031_OT_SHIFT 25 +#define TMC5031_OT_FIELD(motor) ((RegisterField) {TMC5031_OT_MASK, TMC5031_OT_SHIFT, TMC5031_DRVSTATUS(motor), false}) +#define TMC5031_OTPW_MASK 0x04000000 +#define TMC5031_OTPW_SHIFT 26 +#define TMC5031_OTPW_FIELD(motor) ((RegisterField) {TMC5031_OTPW_MASK, TMC5031_OTPW_SHIFT, TMC5031_DRVSTATUS(motor), false}) +#define TMC5031_S2GA_MASK 0x08000000 +#define TMC5031_S2GA_SHIFT 27 +#define TMC5031_S2GA_FIELD(motor) ((RegisterField) {TMC5031_S2GA_MASK, TMC5031_S2GA_SHIFT, TMC5031_DRVSTATUS(motor), false}) +#define TMC5031_S2GB_MASK 0x10000000 +#define TMC5031_S2GB_SHIFT 28 +#define TMC5031_S2GB_FIELD(motor) ((RegisterField) {TMC5031_S2GB_MASK, TMC5031_S2GB_SHIFT, TMC5031_DRVSTATUS(motor), false}) +#define TMC5031_OLA_MASK 0x20000000 +#define TMC5031_OLA_SHIFT 29 +#define TMC5031_OLA_FIELD(motor) ((RegisterField) {TMC5031_OLA_MASK, TMC5031_OLA_SHIFT, TMC5031_DRVSTATUS(motor), false}) +#define TMC5031_OLB_MASK 0x40000000 +#define TMC5031_OLB_SHIFT 30 +#define TMC5031_OLB_FIELD(motor) ((RegisterField) {TMC5031_OLB_MASK, TMC5031_OLB_SHIFT, TMC5031_DRVSTATUS(motor), false}) +#define TMC5031_STST_MASK 0x80000000 +#define TMC5031_STST_SHIFT 31 +#define TMC5031_STST_FIELD(motor) ((RegisterField) {TMC5031_STST_MASK, TMC5031_STST_SHIFT, TMC5031_DRVSTATUS(motor), false}) + + + +#endif diff --git a/firmware/lib/tmc/ic/TMC5031/registercall_hierarchy_flowchart_SPI.svg b/firmware/lib/tmc/ic/TMC5031/registercall_hierarchy_flowchart_SPI.svg new file mode 100755 index 0000000..cbad58f --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5031/registercall_hierarchy_flowchart_SPI.svg @@ -0,0 +1,3 @@ + + +

HAL

HAL

APP (Eval)

APP (Eval)

API

API
Read a register
  •  Call tmcXXXX_readRegister function
Read a register...
Returns the register read value
Returns the register read value
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
tmcXXXX.c
tmcXXXX.c
SPI.c
SPI.c
tmcXXXX_eval.c
tmcXXXX_eval.c

 Implementation of SPI_readWrite
  • Sends and receives bytes on the SPI bus
Implementation of SPI_readWrite...
Returns the raw reply data
Returns the raw reply data

Implementation of tmcXXXX_readWriteSPI
  • Sets the CSN pin to LOW
  • Takes the array of data to write
  • Calls hardware function SPI_readWrite
  • Upon completion of data transfer,
    sets CSN to 
    HIGH
Implementation of tmcXXXX_readWriteSPI...
Passes on the raw reply data to the API
Passes on the raw reply data to the API
Implementation of readRegisterSPI
  • Constructs the datagram
  • Calls HAL wrapper function 
Implementation of readRegisterSPI...
tmcXXXX_readWriteSPI
tmcXXXX_readWriteSPI
Parses the reply and returns the register value
Parses the reply and returns the register value
Implementation of tmcXXXX_readRegister 
  • Check which bus is active SPI/UART. (e.g. SPI)
  • Calls bus-specific function (e.g. readRegisterSPI)
 
Implementation of tmcXXXX_readRegister...
Returns the register read value
Returns the register read value
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC5031/uml-tmc-api.svg b/firmware/lib/tmc/ic/TMC5031/uml-tmc-api.svg new file mode 100755 index 0000000..5a5f8dd --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5031/uml-tmc-api.svg @@ -0,0 +1,3 @@ + + +

TMCXXXX_HW_Abstraction.h



TMCXXXX_HW_Abstraction.h...
// Constants
#define TMCXXXX_MOTORS              
                          
// Register definitions
#define TMCXXXX_GCONF        
                          ⋮
// Register fields definitions
#define TMCXXXX_GCONF_OTPW_FIELD
                     
// Constants...

TMCXXXX.h



TMCXXXX.h...
extern void tmcXXXX_readWriteSPI();
extern void tmcXXXX_readWriteUART();
extern TMCXXXXBusType tmcXXXX_getBusType();
extern uint8_t tmcXXXX_getNodeAddress();
                                  ⋮
tmcXXXX_readRegister();
tmcXXXX_writeRegister();
                                  ⋮
extern void tmcXXXX_readWriteSPI();...

TMCXXXX.c



TMCXXXX.c...
const uint8_t tmcCRCTable_Poly7Reflected[256] = {...};
int32_t tmcXXXX_readRegister(){
/* Call tmcXXXX_getBusType();
 * Based on bus type, call readRegisterSPI/UART() that
 * further calls tmcXXXX_readWriteSPI/UART();
 * For UART it also calls tmcXXXX_getNodeAddress();
                                           ⋮
}
                                           ⋮
const uint8_t tmcCRCTable_Poly7Reflected[256] = {.....
TMC-API
TMC-API

TMCXXXX_Simple_Rotation.h


TMCXXXX_Simple_Rotation.h...
void initAllMotors();
             ⋮
  
void initAllMotors()...

TMCXXXX_Simple_Rotation.c


TMCXXXX_Simple_Rotation.c...
void initAllMotors(){

// Configuring registers to enable motor drivers etc..
tmcXXXX_writeRegister();
                    ⋮
}
                    ⋮
void initAllMotors(){...
Examples
Examples
User Project
User Project

User_Project.h


User_Project.h

User_Project.c








User_Project.c...

void tmcXXXX_readWriteSPI(){
                           ⋮
}
void tmcXXXX_readWriteUART(){
                           ⋮
}
TMCXXXXBusType tmcXXXX_getBusType(){
                           ⋮
}
uint8_t tmcXXXX_getNodeAddress(){
                           ⋮
}

// User Code
                           ⋮
void tmcXXXX_readWriteSPI(){...
#include "TMCXXXX_HW_Abstraction.h"
#include "TMCXXXX.h"
#include "TMCXXXX_Simple_Rotation.h"
                                ⋮
TMCXXXXBusType bus = IC_BUS_SPI/UART;
uint8_t nodeAddress = <nodeAddress>;
                                ⋮
#include "TMCXXXX_HW_Abstraction.h"...
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC5041/README.md b/firmware/lib/tmc/ic/TMC5041/README.md new file mode 100755 index 0000000..9ea60ee --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5041/README.md @@ -0,0 +1,46 @@ +# TMC5041 + + +## How to use + +To access the TMC5041's registers, the TMC-API offers two functions: **tmc5041_readRegister** and **tmc5041_writeRegister**. +Each of these functions takes in an **icID**, which is used to identify the IC when multiple ICs are connected. This identifier is passed down to the callback functions (see How to Integrate). + +## How to integrate: overview + +1. Include all the files of the TMC-API/ic/tmc/TMC5041 folder into the custom project. +2. Include the TMC5041.h file in the custom source code. +3. Implement the necessary callback functions (see below). +4. (optional): Take a look at the Examples subfolder for ready-made examples of the TMC-API usage. + +## Accessing the TMC5041 via SPI +The following diagram depicts how to access the TMC5041 via SPI using the TMC-API. + +![screenshot](registercall_hierarchy_flowchart_SPI.svg) + +The description of the functions, in the above flowchart, are as follows: +- The functions tmc5041_readRegister and tmc5041_writeRegister are used to read and write the registers respectively. These functions check the current active bus and calls the bus-specific function i.e readRegisterSPI or writeRegisterSPI. +- These bus specific functions constructs the datagram and further calls the bus specific callback 'tmcXXXX_readWriteSPI. +- This callback function further calls the hardware specific read/write function for SPI and needs to be implemented externally. + +### How to integrate: Callback functions +To communicate with TMC5041 IC, the TMC-API library needs to know which bus (UART, SPI) it shall use. For that, the callback function **'tmc5041_getBusType()'** needs to be implemented. +Additionally, implement the following callback functions to access the chip via SPI: +1. **tmc5041_readWriteSPI()**, which is a HAL wrapper function that provides the necessary hardware access. This function should also set the chip select pin CSN to low before starting the data transfer and set to high upon completion. Please refer to the datasheet of the IC for further details. + +### Option to use the cache logic for Write-Only registers +The chip features write-only registers that are unable to be read, necessitating the creation of a shadow copy to cache their contents. This copy is automatically updated whenever data is written to these registers. This cache logic could be enabled by setting the macro **TMC5041_CACHE** to **'1'** or disabled by setting to **'0'** respectively. If this feature is enabled then there comes another option to use **tmc5041_cache** function, which is already implemeted in the API, by defining **TMC5041_ENABLE_TMC_CACHE** macro to **'1** or one can implement their own function. The function **tmc5041_cache** works for both reading from and writing to the shadow array. It first checks whether the register has write-only access and data needs to be read from the hadow copy. On the basis of that, it returns **true** or **false**. The shadowRegisters on the premade cache implementation need to be one per chip. **TMC5041_IC_CACHE_COUNT** is set to '1' by default and is user-overwritable. If multiple chips are being used in the same project, increment its value to the number of chips connected. + +## Further info +### Dependency graph for the ICs with new register R/W mechanism +This graph illustrates the relationships between files within the TMC-API library, highlighting dependencies and identifying the files that are essential for integrating the library into the custom projects. + +![screenshot](uml-tmc-api.svg) + +### Example usage: TMC-Evalsystem +**For a reference usage of the TMC-API**, visit the [TMC-Evalsystem](https://github.com/analogdevicesinc/TMC-EvalSystem) + +## Migration status +The TMC5041 has been reworked to the access system described above. For more infos on the status of this and other ICs, check out the [migration page](https://github.com/analogdevicesinc/TMC-API/issues/53). + + diff --git a/firmware/lib/tmc/ic/TMC5041/TMC5041.c b/firmware/lib/tmc/ic/TMC5041/TMC5041.c new file mode 100755 index 0000000..bf78bb6 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5041/TMC5041.c @@ -0,0 +1,194 @@ +/******************************************************************************* +* Copyright © 2017 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#include "TMC5041.h" + + +/**************************************************************** Cache Implementation *************************************************************************/ + +#if TMC5041_CACHE == 0 +static inline bool tmc5041_cache(uint16_t icID, TMC5041CacheOp operation, uint8_t address, uint32_t *value) +{ + UNUSED(icID); + UNUSED(address); + UNUSED(operation); + return false; +} +#else +#if TMC5041_ENABLE_TMC_CACHE == 1 + +uint8_t tmc5041_dirtyBits[TMC5041_IC_CACHE_COUNT][TMC5041_REGISTER_COUNT/8]= {0}; +int32_t tmc5041_shadowRegister[TMC5041_IC_CACHE_COUNT][TMC5041_REGISTER_COUNT]; + +void tmc5041_setDirtyBit(uint16_t icID, uint8_t index, bool value) + { + if(index >= TMC5041_REGISTER_COUNT) + return; + + uint8_t *tmp = &tmc5041_dirtyBits[icID][index / 8]; + uint8_t shift = (index % 8); + uint8_t mask = 1 << shift; + *tmp = (((*tmp) & (~(mask))) | (((value) << (shift)) & (mask))); +} + +bool tmc5041_getDirtyBit(uint16_t icID, uint8_t index) +{ + if(index >= TMC5041_REGISTER_COUNT) + return false; + + uint8_t *tmp = &tmc5041_dirtyBits[icID][index / 8]; + uint8_t shift = (index % 8); + return ((*tmp) >> shift) & 1; +} +/* + * This function is used to cache the value written to the Write-Only registers in the form of shadow array. + * The shadow copy is then used to read these kinds of registers. + */ + +bool tmc5041_cache(uint16_t icID, TMC5041CacheOp operation, uint8_t address, uint32_t *value) +{ + if (operation == TMC5041_CACHE_READ) + { + // Check if the value should come from cache + + // Only supported chips have a cache + if (icID >= TMC5041_IC_CACHE_COUNT) + return false; + + // Only non-readable registers care about caching + // Note: This could also be used to cache i.e. RW config registers to reduce bus accesses + if (TMC5041_IS_READABLE(tmc5041_registerAccess[address])) + return false; + + // Grab the value from the cache + *value = tmc5041_shadowRegister[icID][address]; + return true; + } + else if (operation == TMC5041_CACHE_WRITE || operation == TMC5041_CACHE_FILL_DEFAULT) + { + // Fill the cache + + // only supported chips have a cache + if (icID >= TMC5041_IC_CACHE_COUNT) + return false; + + // Write to the shadow register. + tmc5041_shadowRegister[icID][address] = *value; + // For write operations, mark the register dirty + if (operation == TMC5041_CACHE_WRITE) + { + tmc5041_setDirtyBit(icID, address, true); + } + + return true; + } + return false; +} + +void tmc5041_initCache() +{ + // Check if we have constants defined + if(ARRAY_SIZE(tmc5041_RegisterConstants) == 0) + return; + + size_t i, j, id; + + for(i = 0, j = 0; i < TMC5041_REGISTER_COUNT; i++) + { + // We only need to worry about hardware preset, write-only registers + // that have not yet been written (no dirty bit) here. + if(tmc5041_registerAccess[i] != TMC5041_ACCESS_W_PRESET) + continue; + + // Search the constant list for the current address. With the constant + // list being sorted in ascended order, we can walk through the list + // until the entry with an address equal or greater than i + while(j < ARRAY_SIZE(tmc5041_RegisterConstants) && (tmc5041_RegisterConstants[j].address < i)) + j++; + + // Abort when we reach the end of the constant list + if (j == ARRAY_SIZE(tmc5041_RegisterConstants)) + break; + + // If we have an entry for our current address, write the constant + if(tmc5041_RegisterConstants[j].address == i) + { + for (id = 0; id < TMC5041_IC_CACHE_COUNT; id++) + { + uint32_t temp = tmc5041_RegisterConstants[j].value; + tmc5041_cache(id, TMC5041_CACHE_FILL_DEFAULT, i, &temp); + } + } + } +} +#else +// User must implement their own cache +extern bool tmc5041_cache(uint16_t icID, TMC5041CacheOp operation, uint8_t address, uint32_t *value); +#endif +#endif + +/************************************************************* read / write Implementation *********************************************************************/ + + + +static int32_t readRegisterSPI(uint16_t icID, uint8_t address); +static void writeRegisterSPI(uint16_t icID, uint8_t address, int32_t value); + +int32_t tmc5041_readRegister(uint16_t icID, uint8_t address) +{ + return readRegisterSPI(icID, address); + // ToDo: Error handling +} + +void tmc5041_writeRegister(uint16_t icID, uint8_t address, int32_t value) +{ + writeRegisterSPI(icID, address, value); +} + +int32_t readRegisterSPI(uint16_t icID, uint8_t address) +{ + uint8_t data[5] = { 0 }; + + uint32_t value; + + // Read from cache for registers with write-only access + if (tmc5041_cache(icID, TMC5041_CACHE_READ, address, &value)) + return value; + + // clear write bit + data[0] = address & TMC5041_ADDRESS_MASK; + + // Send the read request + tmc5041_readWriteSPI(icID, &data[0], sizeof(data)); + + // Rewrite address and clear write bit + data[0] = address & TMC5041_ADDRESS_MASK; + + // Send another request to receive the read reply + tmc5041_readWriteSPI(icID, &data[0], sizeof(data)); + + return ((int32_t)data[1] << 24) | ((int32_t) data[2] << 16) | ((int32_t) data[3] << 8) | ((int32_t) data[4]); +} + +void writeRegisterSPI(uint16_t icID, uint8_t address, int32_t value) +{ + uint8_t data[5] = { 0 }; + + data[0] = address | TMC5041_WRITE_BIT; + data[1] = 0xFF & (value>>24); + data[2] = 0xFF & (value>>16); + data[3] = 0xFF & (value>>8); + data[4] = 0xFF & (value>>0); + + // Send the write request + tmc5041_readWriteSPI(icID, &data[0], sizeof(data)); + + //Cache the registers with write-only access + tmc5041_cache(icID, TMC5041_CACHE_WRITE, address, (uint32_t *)&value); +} diff --git a/firmware/lib/tmc/ic/TMC5041/TMC5041.h b/firmware/lib/tmc/ic/TMC5041/TMC5041.h new file mode 100755 index 0000000..695f5f8 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5041/TMC5041.h @@ -0,0 +1,218 @@ +/******************************************************************************* +* Copyright © 2017 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#ifndef TMC_IC_TMC5041_H_ +#define TMC_IC_TMC5041_H_ +#include +#include +#include +#include "TMC5041_HW_Abstraction.h" + +/******************************************************************************* +* API Configuration Defines +* These control optional features of the TMC-API implementation. +* These can be commented in/out here or defined from the build system. +*******************************************************************************/ + +// Uncomment if you want to save space..... +// and put the table into your own .c file +//#define TMC_API_EXTERNAL_CRC_TABLE 1 + +// To enable the cache mechanism in order to keep the copy of all registers, set TMC5041_CACHE to '1'. +// With this mechanism the value of write-only registers could be read from their shadow copies. +#ifndef TMC5041_CACHE +#define TMC5041_CACHE 1 +//#define TMC5041_CACHE 0 +#endif + +// To use the caching mechanism already implemented by the TMC-API, set TMC5041_ENABLE_TMC_CACHE to '1'. +// Set TMC5041_ENABLE_TMC_CACHE to '0' if one wants to have their own cache implementation. +#ifndef TMC5041_ENABLE_TMC_CACHE +#define TMC5041_ENABLE_TMC_CACHE 1 +//#define TMC5041_ENABLE_TMC_CACHE 0 +#endif + +/******************************************************************************/ +extern void tmc5041_readWriteSPI(uint16_t icID, uint8_t *data, size_t dataLength); + +/************************************************************* read / write Implementation *********************************************************************/ +int32_t tmc5041_readRegister(uint16_t icID, uint8_t address); +void tmc5041_writeRegister(uint16_t icID, uint8_t address, int32_t value); + +typedef struct +{ + uint32_t mask; + uint8_t shift; + uint8_t address; + bool isSigned; +} RegisterField; + +static inline uint32_t tmc5041_fieldExtract(uint32_t data, RegisterField field) +{ + uint32_t value = (data & field.mask) >> field.shift; + + if (field.isSigned) + { + // Apply signedness conversion + uint32_t baseMask = field.mask >> field.shift; + uint32_t signMask = baseMask & (~baseMask >> 1); + value = (value ^ signMask) - signMask; + } + + return value; +} + +static inline uint32_t tmc5041_fieldRead(uint16_t icID, RegisterField field) +{ + uint32_t value = tmc5041_readRegister(icID, field.address); + + return tmc5041_fieldExtract(value, field); +} + +static inline uint32_t tmc5041_fieldUpdate(uint32_t data, RegisterField field, uint32_t value) +{ + return (data & (~field.mask)) | ((value << field.shift) & field.mask); +} + +static inline void tmc5041_fieldWrite(uint16_t icID, RegisterField field, uint32_t value) +{ + uint32_t regValue = tmc5041_readRegister(icID, field.address); + + regValue = tmc5041_fieldUpdate(regValue, field, value); + + tmc5041_writeRegister(icID, field.address, regValue); +} + +/**************************************************************** Cache Implementation *************************************************************************/ +#if TMC5041_CACHE == 1 +#ifdef TMC5041_ENABLE_TMC_CACHE +// By default, support one IC in the cache +#ifndef TMC5041_IC_CACHE_COUNT +#define TMC5041_IC_CACHE_COUNT 1 +#endif + +/***************** The following code is TMC-EvalSystem specific and needs to be commented out when working with other MCUs e.g Arduino*****************************/ + +typedef enum { + TMC5041_CACHE_READ, + TMC5041_CACHE_WRITE, + // Special operation: Put content into the cache without marking the entry as dirty. + // Only used to initialize the cache with hardware defaults. This will allow reading + // from write-only registers that have a value inside them on reset. When using this + // operation, a restore will *not* rewrite that filled register! + TMC5041_CACHE_FILL_DEFAULT, +} TMC5041CacheOp; + +typedef struct{ + uint8_t address; + uint32_t value; +} TMC5041RegisterConstants; + +#define TMC5041_ACCESS_DIRTY 0x08 // Register has been written since reset -> shadow register is valid for restore +#define TMC5041_ACCESS_READ 0x01 +#define TMC5041_ACCESS_W_PRESET 0x42 +#define TMC5041_IS_READABLE(x) ((x) & TMC5041_ACCESS_READ) +#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) + +#define R30 0x00071703 // IHOLD_IRUN (Motor 1) +#define R32 0x00FFFFFF // VHIGH (Motor 1) +#define R50 0x00071703 // IHOLD_IRUN (Motor 2) +#define R52 0x00FFFFFF // VHIGH (Motor 2) + +#define R6C 0x000101D5 // CHOPCONF (Motor 1) +#define R7C 0x000101D5 // CHOPCONF (Motor 2) + +// Helper define: +// Most register permission arrays are initialized with 128 values. +// In those fields its quite hard to have an easy overview of available +// registers. For that, ____ is defined to 0, since 4 underscores are +// very easy to distinguish from the 2-digit hexadecimal values. +// This way, the used registers (permission != ACCESS_NONE) are easily spotted +// amongst unused (permission == ACCESS_NONE) registers. +#define ____ 0x00 + +// Helper define: +// Default reset values are not used if the corresponding register has a +// hardware preset. Since this is not directly visible in the default +// register reset values array, N_A is used as an indicator for a preset +// value, where any value will be ignored anyways (N_A: not available). +#define N_A 0 + + +// Register access permissions: +// 0x00: none (reserved) +// 0x01: read +// 0x02: write +// 0x03: read/write +// 0x13: read/write, separate functions/values for reading or writing +// 0x21: read, flag register (read to clear) +// 0x42: write, has hardware presets on reset +static const uint8_t tmc5041_registerAccess[TMC5041_REGISTER_COUNT] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0x03, 0x01, ____, 0x02, 0x01, 0x02, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x00 - 0x0F + 0x02, 0x01, ____, ____, ____, ____, ____, ____, 0x02, 0x01, ____, ____, ____, ____, ____, ____, // 0x10 - 0x1F + 0x03, 0x03, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, ____, 0x02, 0x02, 0x02, 0x03, ____, ____, // 0x20 - 0x2F + 0x02, 0x02, 0x02, ____, 0x03, 0x01, 0x01, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x30 - 0x3F + 0x03, 0x03, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, ____, 0x02, 0x02, 0x02, 0x03, ____, ____, // 0x40 - 0x4F + 0x02, 0x02, 0x02, ____, 0x03, 0x01, 0x01, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x50 - 0x5F + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x03, 0x02, ____, 0x01, // 0x60 - 0x6F + ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, 0x01, 0x01, 0x03, 0x02, ____, 0x01 // 0x70 - 0x7F +}; + +static const int32_t tmc5041_sampleRegisterPreset[TMC5041_REGISTER_COUNT] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 00 - 0F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 10 - 1F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20 - 2F + R30, 0, R32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 30 - 3F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 40 - 4F + R50, 0, R52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 50 - 5F + N_A, N_A, N_A, N_A, N_A, N_A, N_A, N_A, N_A, N_A, 0, 0, R6C, 0, 0, 0, // 60 - 6F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, R7C, 0, 0, 0 // 70 - 7F +}; + +// Undefine the default register values. +// This prevents warnings in case multiple TMC-API chip headers are included at once +#undef R30 +#undef R32 +#undef R50 +#undef R52 +#undef R6C +#undef R7C + +// Register constants (only required for 0x42 registers, since we do not have +// any way to find out the content but want to hold the actual value in the +// shadow register so an application (i.e. the TMCL IDE) can still display +// the values. This only works when the register content is constant. +static const TMC5041RegisterConstants tmc5041_RegisterConstants[] = + { // Use ascending addresses! + { 0x60, 0xAAAAB554 }, // MSLUT[0] + { 0x61, 0x4A9554AA }, // MSLUT[1] + { 0x62, 0x24492929 }, // MSLUT[2] + { 0x63, 0x10104222 }, // MSLUT[3] + { 0x64, 0xFBFFFFFF }, // MSLUT[4] + { 0x65, 0xB5BB777D }, // MSLUT[5] + { 0x66, 0x49295556 }, // MSLUT[6] + { 0x67, 0x00404222 }, // MSLUT[7] + { 0x68, 0xFFFF8056 }, // MSLUTSEL + { 0x69, 0x00F70000 } // MSLUTSTART + }; + + +extern uint8_t tmc5041_dirtyBits[TMC5041_IC_CACHE_COUNT][TMC5041_REGISTER_COUNT/8]; +extern int32_t tmc5041_shadowRegister[TMC5041_IC_CACHE_COUNT][TMC5041_REGISTER_COUNT]; +extern bool tmc5041_cache(uint16_t icID, TMC5041CacheOp operation, uint8_t address, uint32_t *value); +extern void tmc5041_initCache(void); +void tmc5041_setDirtyBit(uint16_t icID, uint8_t index, bool value); +bool tmc5041_getDirtyBit(uint16_t icID, uint8_t index); +#endif +#endif +/***************************************************************************************************************************************************/ + +#endif /* TMC_IC_TMC5041_H_ */ diff --git a/firmware/lib/tmc/ic/TMC5041/TMC5041_HW_Abstraction.h b/firmware/lib/tmc/ic/TMC5041/TMC5041_HW_Abstraction.h new file mode 100755 index 0000000..1717b54 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5041/TMC5041_HW_Abstraction.h @@ -0,0 +1,1199 @@ +/******************************************************************************* +* Copyright © 2018 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + +#ifndef TMC5272_HW_ABSTRACTION +#define TMC5272_HW_ABSTRACTION + + +// Constants + +#define TMC5041_REGISTER_COUNT 128 // Default register count +#define TMC5041_MOTORS 2 +#define TMC5041_WRITE_BIT 0x80 +#define TMC5041_ADDRESS_MASK 0x7F +#define TMC5041_MAX_VELOCITY 8388096 +#define TMC5041_MAX_ACCELERATION 65535 + +// Rampenmodi (Register TMC562_RAMPMODE) +#define TMC5041_MODE_POSITION 0 +#define TMC5041_MODE_VELPOS 1 +#define TMC5041_MODE_VELNEG 2 +#define TMC5041_MODE_HOLD 3 + + +// Register + +#define TMC5041_MOTOR_ADDR(m) (0x20 << m) +#define TMC5041_MOTOR_ADDR_DRV(m) (m << 4) +#define TMC5041_MOTOR_ADDR_PWM(m) (m << 3) + +#define TMC5041_GCONF 0x00 +#define TMC5041_GSTAT 0x01 +#define TMC5041_IFCNT 0x02 +#define TMC5041_SLAVECONF 0x03 +#define TMC5041_INPUT 0x04 +#define TMC5041_X_COMPARE 0x05 + // motor = 0 motor = 1 +#define TMC5041_PWMCONF(motor) (0x10|TMC5041_MOTOR_ADDR_PWM(motor)) // 0x10 0x18 +#define TMC5041_PWM_STATUS(motor) (0x11|TMC5041_MOTOR_ADDR_PWM(motor)) // 0x11 0x19 + + // motor = 0 motor = 1 +#define TMC5041_RAMPMODE(motor) (0x00|TMC5041_MOTOR_ADDR(motor)) // 0x20 0x40 +#define TMC5041_XACTUAL(motor) (0x01|TMC5041_MOTOR_ADDR(motor)) // 0x21 0x41 +#define TMC5041_VACTUAL(motor) (0x02|TMC5041_MOTOR_ADDR(motor)) // 0x22 0x42 +#define TMC5041_VSTART(motor) (0x03|TMC5041_MOTOR_ADDR(motor)) // 0x23 0x43 +#define TMC5041_A1(motor) (0x04|TMC5041_MOTOR_ADDR(motor)) // 0x24 0x44 +#define TMC5041_V1(motor) (0x05|TMC5041_MOTOR_ADDR(motor)) // 0x25 0x45 +#define TMC5041_AMAX(motor) (0x06|TMC5041_MOTOR_ADDR(motor)) // 0x26 0x46 +#define TMC5041_VMAX(motor) (0x07|TMC5041_MOTOR_ADDR(motor)) // 0x27 0x47 +#define TMC5041_DMAX(motor) (0x08|TMC5041_MOTOR_ADDR(motor)) // 0x28 0x48 +#define TMC5041_D1(motor) (0x0A|TMC5041_MOTOR_ADDR(motor)) // 0x2A 0x4A +#define TMC5041_VSTOP(motor) (0x0B|TMC5041_MOTOR_ADDR(motor)) // 0x2B 0x4B +#define TMC5041_TZEROWAIT(motor) (0x0C|TMC5041_MOTOR_ADDR(motor)) // 0x2C 0x4C +#define TMC5041_XTARGET(motor) (0x0D|TMC5041_MOTOR_ADDR(motor)) // 0x2D 0x4D +#define TMC5041_IHOLD_IRUN(motor) (0x10|TMC5041_MOTOR_ADDR(motor)) // 0x30 0x50 +#define TMC5041_VCOOLTHRS(motor) (0x11|TMC5041_MOTOR_ADDR(motor)) // 0x31 0x51 +#define TMC5041_VHIGH(motor) (0x12|TMC5041_MOTOR_ADDR(motor)) // 0x32 0x52 +#define TMC5041_VDCMIN(motor) (0x13|TMC5041_MOTOR_ADDR(motor)) // 0x33 0x53 +#define TMC5041_SWMODE(motor) (0x14|TMC5041_MOTOR_ADDR(motor)) // 0x34 0x54 +#define TMC5041_RAMPSTAT(motor) (0x15|TMC5041_MOTOR_ADDR(motor)) // 0x35 0x55 +#define TMC5041_XLATCH(motor) (0x16|TMC5041_MOTOR_ADDR(motor)) // 0x36 0x56 +#define TMC5041_ENC_CONST(motor) (0x1A|TMC5041_MOTOR_ADDR(motor)) // 0x3A 0x5A // todo CHECK REM 3: should be removable, TMC5041 doesn't have encoder features. Still used though (LH) + + // motor = 0 motor = 1 +#define TMC5041_MSLUT0(motor) (0x60|TMC5041_MOTOR_ADDR_DRV(motor)) // 0x60 0x70 +#define TMC5041_MSLUT1(motor) (0x61|TMC5041_MOTOR_ADDR_DRV(motor)) // 0x61 0x71 +#define TMC5041_MSLUT2(motor) (0x62|TMC5041_MOTOR_ADDR_DRV(motor)) // 0x62 0x72 +#define TMC5041_MSLUT3(motor) (0x63|TMC5041_MOTOR_ADDR_DRV(motor)) // 0x63 0x73 +#define TMC5041_MSLUT4(motor) (0x64|TMC5041_MOTOR_ADDR_DRV(motor)) // 0x64 0x74 +#define TMC5041_MSLUT5(motor) (0x65|TMC5041_MOTOR_ADDR_DRV(motor)) // 0x65 0x75 +#define TMC5041_MSLUT6(motor) (0x66|TMC5041_MOTOR_ADDR_DRV(motor)) // 0x66 0x76 +#define TMC5041_MSLUT7(motor) (0x67|TMC5041_MOTOR_ADDR_DRV(motor)) // 0x67 0x77 +#define TMC5041_MSLUTSEL(motor) (0x68|TMC5041_MOTOR_ADDR_DRV(motor)) // 0x68 0x78 +#define TMC5041_MSLUTSTART(motor) (0x69|TMC5041_MOTOR_ADDR_DRV(motor)) // 0x69 0x79 +#define TMC5041_MSCNT(motor) (0x6A|TMC5041_MOTOR_ADDR_DRV(motor)) // 0x6A 0x7A +#define TMC5041_MSCURACT(motor) (0x6B|TMC5041_MOTOR_ADDR_DRV(motor)) // 0x6B 0x7B +#define TMC5041_CHOPCONF(motor) (0x6C|TMC5041_MOTOR_ADDR_DRV(motor)) // 0x6C 0x7C +#define TMC5041_COOLCONF(motor) (0x6D|TMC5041_MOTOR_ADDR_DRV(motor)) // 0x6D 0x7D +#define TMC5041_DRVSTATUS(motor) (0x6F|TMC5041_MOTOR_ADDR_DRV(motor)) // 0x6F 0x7F + + +// Register fields + +#define TMC5041_POSCMP_ENABLE_MASK 0x00000008 +#define TMC5041_POSCMP_ENABLE_SHIFT 3 +#define TMC5041_POSCMP_ENABLE_FIELD(motor) ((RegisterField) {TMC5041_POSCMP_ENABLE_MASK, TMC5041_POSCMP_ENABLE_SHIFT, TMC5041_GCONF, false}) +#define TMC5041_TEST_MODE_MASK 0x00000080 +#define TMC5041_TEST_MODE_SHIFT 7 +#define TMC5041_TEST_MODE_FIELD(motor) ((RegisterField) {TMC5041_TEST_MODE_MASK, TMC5041_TEST_MODE_SHIFT, TMC5041_GCONF, false}) +#define TMC5041_SHAFT1_MASK 0x00000100 +#define TMC5041_SHAFT1_SHIFT 8 +#define TMC5041_SHAFT1_FIELD(motor) ((RegisterField) {TMC5041_SHAFT1_MASK, TMC5041_SHAFT1_SHIFT, TMC5041_GCONF, false}) +#define TMC5041_SHAFT2_MASK 0x00000200 +#define TMC5041_SHAFT2_SHIFT 9 +#define TMC5041_SHAFT2_FIELD(motor) ((RegisterField) {TMC5041_SHAFT2_MASK, TMC5041_SHAFT2_SHIFT, TMC5041_GCONF, false}) +#define TMC5041_LOCK_GCONF_MASK 0x00000400 +#define TMC5041_LOCK_GCONF_SHIFT 10 +#define TMC5041_LOCK_GCONF_FIELD(motor) ((RegisterField) {TMC5041_LOCK_GCONF_MASK, TMC5041_LOCK_GCONF_SHIFT, TMC5041_GCONF, false}) +#define TMC5041_RESET_MASK 0x00000001 +#define TMC5041_RESET_SHIFT 0 +#define TMC5041_RESET_FIELD(motor) ((RegisterField) {TMC5041_RESET_MASK, TMC5041_RESET_SHIFT, TMC5041_GSTAT, false}) +#define TMC5041_DRV_ERR1_MASK 0x00000002 +#define TMC5041_DRV_ERR1_SHIFT 1 +#define TMC5041_DRV_ERR1_FIELD(motor) ((RegisterField) {TMC5041_DRV_ERR1_MASK, TMC5041_DRV_ERR1_SHIFT, TMC5041_GSTAT, false}) +#define TMC5041_DRV_ERR2_MASK 0x00000004 +#define TMC5041_DRV_ERR2_SHIFT 2 +#define TMC5041_DRV_ERR2_FIELD(motor) ((RegisterField) {TMC5041_DRV_ERR2_MASK, TMC5041_DRV_ERR2_SHIFT, TMC5041_GSTAT, false}) +#define TMC5041_UV_CP_MASK 0x00000008 +#define TMC5041_UV_CP_SHIFT 3 +#define TMC5041_UV_CP_FIELD(motor) ((RegisterField) {TMC5041_UV_CP_MASK, TMC5041_UV_CP_SHIFT, TMC5041_GSTAT, false}) +#define TMC5041_IFCNT_MASK 0x000000FF +#define TMC5041_IFCNT_SHIFT 0 +#define TMC5041_IFCNT_FIELD(motor) ((RegisterField) {TMC5041_IFCNT_MASK, TMC5041_IFCNT_SHIFT, TMC5041_IFCNT, false}) +#define TMC5041_TEST_SEL_MASK 0x0000000F +#define TMC5041_TEST_SEL_SHIFT 0 +#define TMC5041_TEST_SEL_FIELD(motor) ((RegisterField) {TMC5041_TEST_SEL_MASK, TMC5041_TEST_SEL_SHIFT, TMC5041_TEST_SEL, false}) +#define TMC5041_DRV_ENN_MASK 0x00000080 +#define TMC5041_DRV_ENN_SHIFT 7 +#define TMC5041_DRV_ENN_FIELD(motor) ((RegisterField) {TMC5041_DRV_ENN_MASK, TMC5041_DRV_ENN_SHIFT, TMC5041_INPUT, false}) +#define TMC5041_VERSION_MASK 0xFF000000 +#define TMC5041_VERSION_SHIFT 24 +#define TMC5041_VERSION_FIELD(motor) ((RegisterField) {TMC5041_VERSION_MASK, TMC5041_VERSION_SHIFT, TMC5041_INPUT, false}) +#define TMC5041_X_COMPARE_MASK 0xFFFFFFFF +#define TMC5041_X_COMPARE_SHIFT 0 +#define TMC5041_X_COMPARE_FIELD(motor) ((RegisterField) {TMC5041_X_COMPARE_MASK, TMC5041_X_COMPARE_SHIFT, TMC5041_X_COMPARE, false}) +#define TMC5041_PWM_AMPL_MASK 0x000000FF +#define TMC5041_PWM_AMPL_SHIFT 0 +#define TMC5041_PWM_AMPL_FIELD(motor) ((RegisterField) {TMC5041_PWM_AMPL_MASK, TMC5041_PWM_AMPL_SHIFT, TMC5041_PWMCONF(motor), false}) +#define TMC5041_PWM_GRAD_MASK 0x0000FF00 +#define TMC5041_PWM_GRAD_SHIFT 8 +#define TMC5041_PWM_GRAD_FIELD(motor) ((RegisterField) {TMC5041_PWM_GRAD_MASK, TMC5041_PWM_GRAD_SHIFT, TMC5041_PWMCONF(motor), false}) +#define TMC5041_PWM_FREQ_MASK 0x00030000 +#define TMC5041_PWM_FREQ_SHIFT 16 +#define TMC5041_PWM_FREQ_FIELD(motor) ((RegisterField) {TMC5041_PWM_FREQ_MASK, TMC5041_PWM_FREQ_SHIFT, TMC5041_PWMCONF(motor), false}) +#define TMC5041_PWM_AUTOSCALE_MASK 0x00040000 +#define TMC5041_PWM_AUTOSCALE_SHIFT 18 +#define TMC5041_PWM_AUTOSCALE_FIELD(motor) ((RegisterField) {TMC5041_PWM_AUTOSCALE_MASK, TMC5041_PWM_AUTOSCALE_SHIFT, TMC5041_PWMCONF(motor), false}) +#define TMC5041_PWM_SYMMETRIC_MASK 0x00080000 +#define TMC5041_PWM_SYMMETRIC_SHIFT 19 +#define TMC5041_PWM_SYMMETRIC_FIELD(motor) ((RegisterField) {TMC5041_PWM_SYMMETRIC_MASK, TMC5041_PWM_SYMMETRIC_SHIFT, TMC5041_PWMCONF(motor), false}) +#define TMC5041_FREEWHEEL_MASK 0x00300000 +#define TMC5041_FREEWHEEL_SHIFT 20 +#define TMC5041_FREEWHEEL_FIELD(motor) ((RegisterField) {TMC5041_FREEWHEEL_MASK, TMC5041_FREEWHEEL_SHIFT, TMC5041_PWMCONF(motor), false}) +#define TMC5041_PWM__STATUS_MASK 0x000000FF +#define TMC5041_PWM__STATUS_SHIFT 0 +#define TMC5041_PWM__STATUS_FIELD(motor) ((RegisterField) {TMC5041_PWM__STATUS_MASK, TMC5041_PWM__STATUS_SHIFT, TMC5041_PWM_STATUS(motor), false}) +#define TMC5041_RAMPMODE_MASK 0x00000003 +#define TMC5041_RAMPMODE_SHIFT 0 +#define TMC5041_RAMPMODE_FIELD(motor) ((RegisterField) {TMC5041_RAMPMODE_MASK, TMC5041_RAMPMODE_SHIFT, TMC5041_RAMPMODE(motor), false}) +#define TMC5041_XACTUAL_MASK 0xFFFFFFFF +#define TMC5041_XACTUAL_SHIFT 0 +#define TMC5041_XACTUAL_FIELD(motor) ((RegisterField) {TMC5041_XACTUAL_MASK, TMC5041_XACTUAL_SHIFT, TMC5041_XACTUAL(motor), true}) +#define TMC5041_VACTUAL_MASK 0x00FFFFFF +#define TMC5041_VACTUAL_SHIFT 0 +#define TMC5041_VACTUAL_FIELD(motor) ((RegisterField) {TMC5041_VACTUAL_MASK, TMC5041_VACTUAL_SHIFT, TMC5041_VACTUAL(motor), true}) +#define TMC5041_VSTART_MASK 0x0003FFFF +#define TMC5041_VSTART_SHIFT 0 +#define TMC5041_VSTART_FIELD(motor) ((RegisterField) {TMC5041_VSTART_MASK, TMC5041_VSTART_SHIFT, TMC5041_VSTART(motor), false}) +#define TMC5041_A1_MASK 0x0000FFFF +#define TMC5041_A1_SHIFT 0 +#define TMC5041_A1_FIELD(motor) ((RegisterField) {TMC5041_A1_MASK, TMC5041_A1_SHIFT, TMC5041_A1(motor), false}) +#define TMC5041_V1__MASK 0x000FFFFF +#define TMC5041_V1__SHIFT 0 +#define TMC5041_V1__FIELD(motor) ((RegisterField) {TMC5041_V1__MASK, TMC5041_V1__SHIFT, TMC5041_V1(motor), false}) +#define TMC5041_AMAX_MASK 0x0000FFFF +#define TMC5041_AMAX_SHIFT 0 +#define TMC5041_AMAX_FIELD(motor) ((RegisterField) {TMC5041_AMAX_MASK, TMC5041_AMAX_SHIFT, TMC5041_AMAX(motor), false}) +#define TMC5041_VMAX_MASK 0x007FFFFF +#define TMC5041_VMAX_SHIFT 0 +#define TMC5041_VMAX_FIELD(motor) ((RegisterField) {TMC5041_VMAX_MASK, TMC5041_VMAX_SHIFT, TMC5041_VMAX(motor), false}) +#define TMC5041_DMAX_MASK 0x0000FFFF +#define TMC5041_DMAX_SHIFT 0 +#define TMC5041_DMAX_FIELD(motor) ((RegisterField) {TMC5041_DMAX_MASK, TMC5041_DMAX_SHIFT, TMC5041_DMAX(motor), false}) +#define TMC5041_D1_MASK 0x0000FFFF +#define TMC5041_D1_SHIFT 0 +#define TMC5041_D1_FIELD(motor) ((RegisterField) {TMC5041_D1_MASK, TMC5041_D1_SHIFT, TMC5041_D1(motor), false}) +#define TMC5041_VSTOP_MASK 0x0003FFFF +#define TMC5041_VSTOP_SHIFT 0 +#define TMC5041_VSTOP_FIELD(motor) ((RegisterField) {TMC5041_VSTOP_MASK, TMC5041_VSTOP_SHIFT, TMC5041_VSTOP(motor), false}) +#define TMC5041_TZEROWAIT_MASK 0x0000FFFF +#define TMC5041_TZEROWAIT_SHIFT 0 +#define TMC5041_TZEROWAIT_FIELD(motor) ((RegisterField) {TMC5041_TZEROWAIT_MASK, TMC5041_TZEROWAIT_SHIFT, TMC5041_TZEROWAIT(motor), false}) +#define TMC5041_XTARGET_MASK 0xFFFFFFFF +#define TMC5041_XTARGET_SHIFT 0 +#define TMC5041_XTARGET_FIELD(motor) ((RegisterField) {TMC5041_XTARGET_MASK, TMC5041_XTARGET_SHIFT, TMC5041_XTARGET(motor), true}) +#define TMC5041_IHOLD_MASK 0x0000001F +#define TMC5041_IHOLD_SHIFT 0 +#define TMC5041_IHOLD_FIELD(motor) ((RegisterField) {TMC5041_IHOLD_MASK, TMC5041_IHOLD_SHIFT, TMC5041_IHOLD_IRUN(motor), false}) +#define TMC5041_IRUN_MASK 0x00001F00 +#define TMC5041_IRUN_SHIFT 8 +#define TMC5041_IRUN_FIELD(motor) ((RegisterField) {TMC5041_IRUN_MASK, TMC5041_IRUN_SHIFT, TMC5041_IHOLD_IRUN(motor), false}) +#define TMC5041_IHOLDDELAY_MASK 0x000F0000 +#define TMC5041_IHOLDDELAY_SHIFT 16 +#define TMC5041_IHOLDDELAY_FIELD(motor) ((RegisterField) {TMC5041_IHOLDDELAY_MASK, TMC5041_IHOLDDELAY_SHIFT, TMC5041_IHOLD_IRUN(motor), false}) +#define TMC5041_VCOOLTHRS_MASK 0x007FFFFF +#define TMC5041_VCOOLTHRS_SHIFT 0 +#define TMC5041_VCOOLTHRS_FIELD(motor) ((RegisterField) {TMC5041_VCOOLTHRS_MASK, TMC5041_VCOOLTHRS_SHIFT, TMC5041_VCOOLTHRS(motor), false}) +#define TMC5041_VHIGH_MASK 0x007FFFFF +#define TMC5041_VHIGH_SHIFT 0 +#define TMC5041_VHIGH_FIELD(motor) ((RegisterField) {TMC5041_VHIGH_MASK, TMC5041_VHIGH_SHIFT, TMC5041_VHIGH(motor), false}) +#define TMC5041_VDCMIN_MASK 0x007FFFFF +#define TMC5041_VDCMIN_SHIFT 0 +#define TMC5041_VDCMIN_FIELD(motor) ((RegisterField) {TMC5041_VDCMIN_MASK, TMC5041_VDCMIN_SHIFT, TMC5041_VDCMIN(motor), false}) +#define TMC5041_STOP_L_ENABLE_MASK 0x00000001 +#define TMC5041_STOP_L_ENABLE_SHIFT 0 +#define TMC5041_STOP_L_ENABLE_FIELD(motor) ((RegisterField) {TMC5041_STOP_L_ENABLE_MASK, TMC5041_STOP_L_ENABLE_SHIFT, TMC5041_SWMODE(motor), false}) +#define TMC5041_STOP_R_ENABLE_MASK 0x00000002 +#define TMC5041_STOP_R_ENABLE_SHIFT 1 +#define TMC5041_STOP_R_ENABLE_FIELD(motor) ((RegisterField) {TMC5041_STOP_R_ENABLE_MASK, TMC5041_STOP_R_ENABLE_SHIFT, TMC5041_SWMODE(motor), false}) +#define TMC5041_POL_STOP_L_MASK 0x00000004 +#define TMC5041_POL_STOP_L_SHIFT 2 +#define TMC5041_POL_STOP_L_FIELD(motor) ((RegisterField) {TMC5041_POL_STOP_L_MASK, TMC5041_POL_STOP_L_SHIFT, TMC5041_SWMODE(motor), false}) +#define TMC5041_POL_STOP_R_MASK 0x00000008 +#define TMC5041_POL_STOP_R_SHIFT 3 +#define TMC5041_POL_STOP_R_FIELD(motor) ((RegisterField) {TMC5041_POL_STOP_R_MASK, TMC5041_POL_STOP_R_SHIFT, TMC5041_SWMODE(motor), false}) +#define TMC5041_SWAP_LR_MASK 0x00000010 +#define TMC5041_SWAP_LR_SHIFT 4 +#define TMC5041_SWAP_LR_FIELD(motor) ((RegisterField) {TMC5041_SWAP_LR_MASK, TMC5041_SWAP_LR_SHIFT, TMC5041_SWMODE(motor), false}) +#define TMC5041_LATCH_L_ACTIVE_MASK 0x00000020 +#define TMC5041_LATCH_L_ACTIVE_SHIFT 5 +#define TMC5041_LATCH_L_ACTIVE_FIELD(motor) ((RegisterField) {TMC5041_LATCH_L_ACTIVE_MASK, TMC5041_LATCH_L_ACTIVE_SHIFT, TMC5041_SWMODE(motor), false}) +#define TMC5041_LATCH_L_INACTIVE_MASK 0x00000040 +#define TMC5041_LATCH_L_INACTIVE_SHIFT 6 +#define TMC5041_LATCH_L_INACTIVE_FIELD(motor) ((RegisterField) {TMC5041_LATCH_L_INACTIVE_MASK, TMC5041_LATCH_L_INACTIVE_SHIFT, TMC5041_SWMODE(motor), false}) +#define TMC5041_LATCH_R_ACTIVE_MASK 0x00000080 +#define TMC5041_LATCH_R_ACTIVE_SHIFT 7 +#define TMC5041_LATCH_R_ACTIVE_FIELD(motor) ((RegisterField) {TMC5041_LATCH_R_ACTIVE_MASK, TMC5041_LATCH_R_ACTIVE_SHIFT, TMC5041_SWMODE(motor), false}) +#define TMC5041_LATCH_R_INACTIVE_MASK 0x00000100 +#define TMC5041_LATCH_R_INACTIVE_SHIFT 8 +#define TMC5041_LATCH_R_INACTIVE_FIELD(motor) ((RegisterField) {TMC5041_LATCH_R_INACTIVE_MASK, TMC5041_LATCH_R_INACTIVE_SHIFT, TMC5041_SWMODE(motor), false}) +#define TMC5041_SG_STOP_MASK 0x00000400 +#define TMC5041_SG_STOP_SHIFT 10 +#define TMC5041_SG_STOP_FIELD(motor) ((RegisterField) {TMC5041_SG_STOP_MASK, TMC5041_SG_STOP_SHIFT, TMC5041_SWMODE(motor), false}) +#define TMC5041_EN_SOFTSTOP_MASK 0x00000800 +#define TMC5041_EN_SOFTSTOP_SHIFT 11 +#define TMC5041_EN_SOFTSTOP_FIELD(motor) ((RegisterField) {TMC5041_EN_SOFTSTOP_MASK, TMC5041_EN_SOFTSTOP_SHIFT, TMC5041_SWMODE(motor), false}) +#define TMC5041_STATUS_STOP_L_MASK 0x00000001 +#define TMC5041_STATUS_STOP_L_SHIFT 0 +#define TMC5041_STATUS_STOP_L_FIELD(motor) ((RegisterField) {TMC5041_STATUS_STOP_L_MASK, TMC5041_STATUS_STOP_L_SHIFT, TMC5041_RAMPSTAT(motor), false}) +#define TMC5041_STATUS_STOP_R_MASK 0x00000002 +#define TMC5041_STATUS_STOP_R_SHIFT 1 +#define TMC5041_STATUS_STOP_R_FIELD(motor) ((RegisterField) {TMC5041_STATUS_STOP_R_MASK, TMC5041_STATUS_STOP_R_SHIFT, TMC5041_RAMPSTAT(motor), false}) +#define TMC5041_STATUS_LATCH_L_MASK 0x00000004 +#define TMC5041_STATUS_LATCH_L_SHIFT 2 +#define TMC5041_STATUS_LATCH_L_FIELD(motor) ((RegisterField) {TMC5041_STATUS_LATCH_L_MASK, TMC5041_STATUS_LATCH_L_SHIFT, TMC5041_RAMPSTAT(motor), false}) +#define TMC5041_STATUS_LATCH_R_MASK 0x00000008 +#define TMC5041_STATUS_LATCH_R_SHIFT 3 +#define TMC5041_STATUS_LATCH_R_FIELD(motor) ((RegisterField) {TMC5041_STATUS_LATCH_R_MASK, TMC5041_STATUS_LATCH_R_SHIFT, TMC5041_RAMPSTAT(motor), false}) +#define TMC5041_EVENT_STOP_L_MASK 0x00000010 +#define TMC5041_EVENT_STOP_L_SHIFT 4 +#define TMC5041_EVENT_STOP_L_FIELD(motor) ((RegisterField) {TMC5041_EVENT_STOP_L_MASK, TMC5041_EVENT_STOP_L_SHIFT, TMC5041_RAMPSTAT(motor), false}) +#define TMC5041_EVENT_STOP_R_MASK 0x00000020 +#define TMC5041_EVENT_STOP_R_SHIFT 5 +#define TMC5041_EVENT_STOP_R_FIELD(motor) ((RegisterField) {TMC5041_EVENT_STOP_R_MASK, TMC5041_EVENT_STOP_R_SHIFT, TMC5041_RAMPSTAT(motor), false}) +#define TMC5041_EVENT_STOP_SG_MASK 0x00000040 +#define TMC5041_EVENT_STOP_SG_SHIFT 6 +#define TMC5041_EVENT_STOP_SG_FIELD(motor) ((RegisterField) {TMC5041_EVENT_STOP_SG_MASK, TMC5041_EVENT_STOP_SG_SHIFT, TMC5041_RAMPSTAT(motor), false}) +#define TMC5041_EVENT_POS_REACHED_MASK 0x00000080 +#define TMC5041_EVENT_POS_REACHED_SHIFT 7 +#define TMC5041_EVENT_POS_REACHED_FIELD(motor) ((RegisterField) {TMC5041_EVENT_POS_REACHED_MASK, TMC5041_EVENT_POS_REACHED_SHIFT, TMC5041_RAMPSTAT(motor), false}) +#define TMC5041_VELOCITY_REACHED_MASK 0x00000100 +#define TMC5041_VELOCITY_REACHED_SHIFT 8 +#define TMC5041_VELOCITY_REACHED_FIELD(motor) ((RegisterField) {TMC5041_VELOCITY_REACHED_MASK, TMC5041_VELOCITY_REACHED_SHIFT, TMC5041_RAMPSTAT(motor), false}) +#define TMC5041_POSITION_REACHED_MASK 0x00000200 +#define TMC5041_POSITION_REACHED_SHIFT 9 +#define TMC5041_POSITION_REACHED_FIELD(motor) ((RegisterField) {TMC5041_POSITION_REACHED_MASK, TMC5041_POSITION_REACHED_SHIFT, TMC5041_RAMPSTAT(motor), false}) +#define TMC5041_VZERO_MASK 0x00000400 +#define TMC5041_VZERO_SHIFT 10 +#define TMC5041_VZERO_FIELD(motor) ((RegisterField) {TMC5041_VZERO_MASK, TMC5041_VZERO_SHIFT, TMC5041_RAMPSTAT(motor), false}) +#define TMC5041_T_ZEROWAIT_ACTIVE_MASK 0x00000800 +#define TMC5041_T_ZEROWAIT_ACTIVE_SHIFT 11 +#define TMC5041_T_ZEROWAIT_ACTIVE_FIELD(motor) ((RegisterField) {TMC5041_T_ZEROWAIT_ACTIVE_MASK, TMC5041_T_ZEROWAIT_ACTIVE_SHIFT, TMC5041_RAMPSTAT(motor), false}) +#define TMC5041_SECOND_MOVE_MASK 0x00001000 +#define TMC5041_SECOND_MOVE_SHIFT 12 +#define TMC5041_SECOND_MOVE_FIELD(motor) ((RegisterField) {TMC5041_SECOND_MOVE_MASK, TMC5041_SECOND_MOVE_SHIFT, TMC5041_RAMPSTAT(motor), false}) +#define TMC5041_STATUS_SG_MASK 0x00002000 +#define TMC5041_STATUS_SG_SHIFT 13 +#define TMC5041_STATUS_SG_FIELD(motor) ((RegisterField) {TMC5041_STATUS_SG_MASK, TMC5041_STATUS_SG_SHIFT, TMC5041_RAMPSTAT(motor), false}) +#define TMC5041_XLATCH_MASK 0xFFFFFFFF +#define TMC5041_XLATCH_SHIFT 0 +#define TMC5041_XLATCH_FIELD(motor) ((RegisterField) {TMC5041_XLATCH_MASK, TMC5041_XLATCH_SHIFT, TMC5041_XLATCH(motor), false}) +#define TMC5041_OFS0_MASK 0x00000001 +#define TMC5041_OFS0_SHIFT 0 +#define TMC5041_OFS0_FIELD(motor) ((RegisterField) {TMC5041_OFS0_MASK, TMC5041_OFS0_SHIFT, TMC5041_MSLUT[0], false}) +#define TMC5041_OFS1_MASK 0x00000002 +#define TMC5041_OFS1_SHIFT 1 +#define TMC5041_OFS1_FIELD(motor) ((RegisterField) {TMC5041_OFS1_MASK, TMC5041_OFS1_SHIFT, TMC5041_MSLUT[0], false}) +#define TMC5041_OFS2_MASK 0x00000004 +#define TMC5041_OFS2_SHIFT 2 +#define TMC5041_OFS2_FIELD(motor) ((RegisterField) {TMC5041_OFS2_MASK, TMC5041_OFS2_SHIFT, TMC5041_MSLUT[0], false}) +#define TMC5041_OFS3_MASK 0x00000008 +#define TMC5041_OFS3_SHIFT 3 +#define TMC5041_OFS3_FIELD(motor) ((RegisterField) {TMC5041_OFS3_MASK, TMC5041_OFS3_SHIFT, TMC5041_MSLUT[0], false}) +#define TMC5041_OFS4_MASK 0x00000010 +#define TMC5041_OFS4_SHIFT 4 +#define TMC5041_OFS4_FIELD(motor) ((RegisterField) {TMC5041_OFS4_MASK, TMC5041_OFS4_SHIFT, TMC5041_MSLUT[0], false}) +#define TMC5041_OFS5_MASK 0x00000020 +#define TMC5041_OFS5_SHIFT 5 +#define TMC5041_OFS5_FIELD(motor) ((RegisterField) {TMC5041_OFS5_MASK, TMC5041_OFS5_SHIFT, TMC5041_MSLUT[0], false}) +#define TMC5041_OFS6_MASK 0x00000040 +#define TMC5041_OFS6_SHIFT 6 +#define TMC5041_OFS6_FIELD(motor) ((RegisterField) {TMC5041_OFS6_MASK, TMC5041_OFS6_SHIFT, TMC5041_MSLUT[0], false}) +#define TMC5041_OFS7_MASK 0x00000080 +#define TMC5041_OFS7_SHIFT 7 +#define TMC5041_OFS7_FIELD(motor) ((RegisterField) {TMC5041_OFS7_MASK, TMC5041_OFS7_SHIFT, TMC5041_MSLUT[0], false}) +#define TMC5041_OFS8_MASK 0x00000100 +#define TMC5041_OFS8_SHIFT 8 +#define TMC5041_OFS8_FIELD(motor) ((RegisterField) {TMC5041_OFS8_MASK, TMC5041_OFS8_SHIFT, TMC5041_MSLUT[0], false}) +#define TMC5041_OFS9_MASK 0x00000200 +#define TMC5041_OFS9_SHIFT 9 +#define TMC5041_OFS9_FIELD(motor) ((RegisterField) {TMC5041_OFS9_MASK, TMC5041_OFS9_SHIFT, TMC5041_MSLUT[0], false}) +#define TMC5041_OFS10_MASK 0x00000400 +#define TMC5041_OFS10_SHIFT 10 +#define TMC5041_OFS10_FIELD(motor) ((RegisterField) {TMC5041_OFS10_MASK, TMC5041_OFS10_SHIFT, TMC5041_MSLUT[0], false}) +#define TMC5041_OFS11_MASK 0x00000800 +#define TMC5041_OFS11_SHIFT 11 +#define TMC5041_OFS11_FIELD(motor) ((RegisterField) {TMC5041_OFS11_MASK, TMC5041_OFS11_SHIFT, TMC5041_MSLUT[0], false}) +#define TMC5041_OFS12_MASK 0x00001000 +#define TMC5041_OFS12_SHIFT 12 +#define TMC5041_OFS12_FIELD(motor) ((RegisterField) {TMC5041_OFS12_MASK, TMC5041_OFS12_SHIFT, TMC5041_MSLUT[0], false}) +#define TMC5041_OFS13_MASK 0x00002000 +#define TMC5041_OFS13_SHIFT 13 +#define TMC5041_OFS13_FIELD(motor) ((RegisterField) {TMC5041_OFS13_MASK, TMC5041_OFS13_SHIFT, TMC5041_MSLUT[0], false}) +#define TMC5041_OFS14_MASK 0x00004000 +#define TMC5041_OFS14_SHIFT 14 +#define TMC5041_OFS14_FIELD(motor) ((RegisterField) {TMC5041_OFS14_MASK, TMC5041_OFS14_SHIFT, TMC5041_MSLUT[0], false}) +#define TMC5041_OFS15_MASK 0x00008000 +#define TMC5041_OFS15_SHIFT 15 +#define TMC5041_OFS15_FIELD(motor) ((RegisterField) {TMC5041_OFS15_MASK, TMC5041_OFS15_SHIFT, TMC5041_MSLUT[0], false}) +#define TMC5041_OFS16_MASK 0x00010000 +#define TMC5041_OFS16_SHIFT 16 +#define TMC5041_OFS16_FIELD(motor) ((RegisterField) {TMC5041_OFS16_MASK, TMC5041_OFS16_SHIFT, TMC5041_MSLUT[0], false}) +#define TMC5041_OFS17_MASK 0x00020000 +#define TMC5041_OFS17_SHIFT 17 +#define TMC5041_OFS17_FIELD(motor) ((RegisterField) {TMC5041_OFS17_MASK, TMC5041_OFS17_SHIFT, TMC5041_MSLUT[0], false}) +#define TMC5041_OFS18_MASK 0x00040000 +#define TMC5041_OFS18_SHIFT 18 +#define TMC5041_OFS18_FIELD(motor) ((RegisterField) {TMC5041_OFS18_MASK, TMC5041_OFS18_SHIFT, TMC5041_MSLUT[0], false}) +#define TMC5041_OFS19_MASK 0x00080000 +#define TMC5041_OFS19_SHIFT 19 +#define TMC5041_OFS19_FIELD(motor) ((RegisterField) {TMC5041_OFS19_MASK, TMC5041_OFS19_SHIFT, TMC5041_MSLUT[0], false}) +#define TMC5041_OFS20_MASK 0x00100000 +#define TMC5041_OFS20_SHIFT 20 +#define TMC5041_OFS20_FIELD(motor) ((RegisterField) {TMC5041_OFS20_MASK, TMC5041_OFS20_SHIFT, TMC5041_MSLUT[0], false}) +#define TMC5041_OFS21_MASK 0x00200000 +#define TMC5041_OFS21_SHIFT 21 +#define TMC5041_OFS21_FIELD(motor) ((RegisterField) {TMC5041_OFS21_MASK, TMC5041_OFS21_SHIFT, TMC5041_MSLUT[0], false}) +#define TMC5041_OFS22_MASK 0x00400000 +#define TMC5041_OFS22_SHIFT 22 +#define TMC5041_OFS22_FIELD(motor) ((RegisterField) {TMC5041_OFS22_MASK, TMC5041_OFS22_SHIFT, TMC5041_MSLUT[0], false}) +#define TMC5041_OFS23_MASK 0x00800000 +#define TMC5041_OFS23_SHIFT 23 +#define TMC5041_OFS23_FIELD(motor) ((RegisterField) {TMC5041_OFS23_MASK, TMC5041_OFS23_SHIFT, TMC5041_MSLUT[0], false}) +#define TMC5041_OFS24_MASK 0x01000000 +#define TMC5041_OFS24_SHIFT 24 +#define TMC5041_OFS24_FIELD(motor) ((RegisterField) {TMC5041_OFS24_MASK, TMC5041_OFS24_SHIFT, TMC5041_MSLUT[0], false}) +#define TMC5041_OFS25_MASK 0x02000000 +#define TMC5041_OFS25_SHIFT 25 +#define TMC5041_OFS25_FIELD(motor) ((RegisterField) {TMC5041_OFS25_MASK, TMC5041_OFS25_SHIFT, TMC5041_MSLUT[0], false}) +#define TMC5041_OFS26_MASK 0x04000000 +#define TMC5041_OFS26_SHIFT 26 +#define TMC5041_OFS26_FIELD(motor) ((RegisterField) {TMC5041_OFS26_MASK, TMC5041_OFS26_SHIFT, TMC5041_MSLUT[0], false}) +#define TMC5041_OFS27_MASK 0x08000000 +#define TMC5041_OFS27_SHIFT 27 +#define TMC5041_OFS27_FIELD(motor) ((RegisterField) {TMC5041_OFS27_MASK, TMC5041_OFS27_SHIFT, TMC5041_MSLUT[0], false}) +#define TMC5041_OFS28_MASK 0x10000000 +#define TMC5041_OFS28_SHIFT 28 +#define TMC5041_OFS28_FIELD(motor) ((RegisterField) {TMC5041_OFS28_MASK, TMC5041_OFS28_SHIFT, TMC5041_MSLUT[0], false}) +#define TMC5041_OFS29_MASK 0x20000000 +#define TMC5041_OFS29_SHIFT 29 +#define TMC5041_OFS29_FIELD(motor) ((RegisterField) {TMC5041_OFS29_MASK, TMC5041_OFS29_SHIFT, TMC5041_MSLUT[0], false}) +#define TMC5041_OFS30_MASK 0x40000000 +#define TMC5041_OFS30_SHIFT 30 +#define TMC5041_OFS30_FIELD(motor) ((RegisterField) {TMC5041_OFS30_MASK, TMC5041_OFS30_SHIFT, TMC5041_MSLUT[0], false}) +#define TMC5041_OFS31_MASK 0x80000000 +#define TMC5041_OFS31_SHIFT 31 +#define TMC5041_OFS31_FIELD(motor) ((RegisterField) {TMC5041_OFS31_MASK, TMC5041_OFS31_SHIFT, TMC5041_MSLUT[0], false}) +#define TMC5041_OFS32_MASK 0x00000001 +#define TMC5041_OFS32_SHIFT 0 +#define TMC5041_OFS32_FIELD(motor) ((RegisterField) {TMC5041_OFS32_MASK, TMC5041_OFS32_SHIFT, TMC5041_MSLUT[1], false}) +#define TMC5041_OFS33_MASK 0x00000002 +#define TMC5041_OFS33_SHIFT 1 +#define TMC5041_OFS33_FIELD(motor) ((RegisterField) {TMC5041_OFS33_MASK, TMC5041_OFS33_SHIFT, TMC5041_MSLUT[1], false}) +#define TMC5041_OFS34_MASK 0x00000004 +#define TMC5041_OFS34_SHIFT 2 +#define TMC5041_OFS34_FIELD(motor) ((RegisterField) {TMC5041_OFS34_MASK, TMC5041_OFS34_SHIFT, TMC5041_MSLUT[1], false}) +#define TMC5041_OFS35_MASK 0x00000008 +#define TMC5041_OFS35_SHIFT 3 +#define TMC5041_OFS35_FIELD(motor) ((RegisterField) {TMC5041_OFS35_MASK, TMC5041_OFS35_SHIFT, TMC5041_MSLUT[1], false}) +#define TMC5041_OFS36_MASK 0x00000010 +#define TMC5041_OFS36_SHIFT 4 +#define TMC5041_OFS36_FIELD(motor) ((RegisterField) {TMC5041_OFS36_MASK, TMC5041_OFS36_SHIFT, TMC5041_MSLUT[1], false}) +#define TMC5041_OFS37_MASK 0x00000020 +#define TMC5041_OFS37_SHIFT 5 +#define TMC5041_OFS37_FIELD(motor) ((RegisterField) {TMC5041_OFS37_MASK, TMC5041_OFS37_SHIFT, TMC5041_MSLUT[1], false}) +#define TMC5041_OFS38_MASK 0x00000040 +#define TMC5041_OFS38_SHIFT 6 +#define TMC5041_OFS38_FIELD(motor) ((RegisterField) {TMC5041_OFS38_MASK, TMC5041_OFS38_SHIFT, TMC5041_MSLUT[1], false}) +#define TMC5041_OFS39_MASK 0x00000080 +#define TMC5041_OFS39_SHIFT 7 +#define TMC5041_OFS39_FIELD(motor) ((RegisterField) {TMC5041_OFS39_MASK, TMC5041_OFS39_SHIFT, TMC5041_MSLUT[1], false}) +#define TMC5041_OFS40_MASK 0x00000100 +#define TMC5041_OFS40_SHIFT 8 +#define TMC5041_OFS40_FIELD(motor) ((RegisterField) {TMC5041_OFS40_MASK, TMC5041_OFS40_SHIFT, TMC5041_MSLUT[1], false}) +#define TMC5041_OFS41_MASK 0x00000200 +#define TMC5041_OFS41_SHIFT 9 +#define TMC5041_OFS41_FIELD(motor) ((RegisterField) {TMC5041_OFS41_MASK, TMC5041_OFS41_SHIFT, TMC5041_MSLUT[1], false}) +#define TMC5041_OFS42_MASK 0x00000400 +#define TMC5041_OFS42_SHIFT 10 +#define TMC5041_OFS42_FIELD(motor) ((RegisterField) {TMC5041_OFS42_MASK, TMC5041_OFS42_SHIFT, TMC5041_MSLUT[1], false}) +#define TMC5041_OFS43_MASK 0x00000800 +#define TMC5041_OFS43_SHIFT 11 +#define TMC5041_OFS43_FIELD(motor) ((RegisterField) {TMC5041_OFS43_MASK, TMC5041_OFS43_SHIFT, TMC5041_MSLUT[1], false}) +#define TMC5041_OFS44_MASK 0x00001000 +#define TMC5041_OFS44_SHIFT 12 +#define TMC5041_OFS44_FIELD(motor) ((RegisterField) {TMC5041_OFS44_MASK, TMC5041_OFS44_SHIFT, TMC5041_MSLUT[1], false}) +#define TMC5041_OFS45_MASK 0x00002000 +#define TMC5041_OFS45_SHIFT 13 +#define TMC5041_OFS45_FIELD(motor) ((RegisterField) {TMC5041_OFS45_MASK, TMC5041_OFS45_SHIFT, TMC5041_MSLUT[1], false}) +#define TMC5041_OFS46_MASK 0x00004000 +#define TMC5041_OFS46_SHIFT 14 +#define TMC5041_OFS46_FIELD(motor) ((RegisterField) {TMC5041_OFS46_MASK, TMC5041_OFS46_SHIFT, TMC5041_MSLUT[1], false}) +#define TMC5041_OFS47_MASK 0x00008000 +#define TMC5041_OFS47_SHIFT 15 +#define TMC5041_OFS47_FIELD(motor) ((RegisterField) {TMC5041_OFS47_MASK, TMC5041_OFS47_SHIFT, TMC5041_MSLUT[1], false}) +#define TMC5041_OFS48_MASK 0x00010000 +#define TMC5041_OFS48_SHIFT 16 +#define TMC5041_OFS48_FIELD(motor) ((RegisterField) {TMC5041_OFS48_MASK, TMC5041_OFS48_SHIFT, TMC5041_MSLUT[1], false}) +#define TMC5041_OFS49_MASK 0x00020000 +#define TMC5041_OFS49_SHIFT 17 +#define TMC5041_OFS49_FIELD(motor) ((RegisterField) {TMC5041_OFS49_MASK, TMC5041_OFS49_SHIFT, TMC5041_MSLUT[1], false}) +#define TMC5041_OFS50_MASK 0x00040000 +#define TMC5041_OFS50_SHIFT 18 +#define TMC5041_OFS50_FIELD(motor) ((RegisterField) {TMC5041_OFS50_MASK, TMC5041_OFS50_SHIFT, TMC5041_MSLUT[1], false}) +#define TMC5041_OFS51_MASK 0x00080000 +#define TMC5041_OFS51_SHIFT 19 +#define TMC5041_OFS51_FIELD(motor) ((RegisterField) {TMC5041_OFS51_MASK, TMC5041_OFS51_SHIFT, TMC5041_MSLUT[1], false}) +#define TMC5041_OFS52_MASK 0x00100000 +#define TMC5041_OFS52_SHIFT 20 +#define TMC5041_OFS52_FIELD(motor) ((RegisterField) {TMC5041_OFS52_MASK, TMC5041_OFS52_SHIFT, TMC5041_MSLUT[1], false}) +#define TMC5041_OFS53_MASK 0x00200000 +#define TMC5041_OFS53_SHIFT 21 +#define TMC5041_OFS53_FIELD(motor) ((RegisterField) {TMC5041_OFS53_MASK, TMC5041_OFS53_SHIFT, TMC5041_MSLUT[1], false}) +#define TMC5041_OFS54_MASK 0x00400000 +#define TMC5041_OFS54_SHIFT 22 +#define TMC5041_OFS54_FIELD(motor) ((RegisterField) {TMC5041_OFS54_MASK, TMC5041_OFS54_SHIFT, TMC5041_MSLUT[1], false}) +#define TMC5041_OFS55_MASK 0x00800000 +#define TMC5041_OFS55_SHIFT 23 +#define TMC5041_OFS55_FIELD(motor) ((RegisterField) {TMC5041_OFS55_MASK, TMC5041_OFS55_SHIFT, TMC5041_MSLUT[1], false}) +#define TMC5041_OFS56_MASK 0x01000000 +#define TMC5041_OFS56_SHIFT 24 +#define TMC5041_OFS56_FIELD(motor) ((RegisterField) {TMC5041_OFS56_MASK, TMC5041_OFS56_SHIFT, TMC5041_MSLUT[1], false}) +#define TMC5041_OFS57_MASK 0x02000000 +#define TMC5041_OFS57_SHIFT 25 +#define TMC5041_OFS57_FIELD(motor) ((RegisterField) {TMC5041_OFS57_MASK, TMC5041_OFS57_SHIFT, TMC5041_MSLUT[1], false}) +#define TMC5041_OFS58_MASK 0x04000000 +#define TMC5041_OFS58_SHIFT 26 +#define TMC5041_OFS58_FIELD(motor) ((RegisterField) {TMC5041_OFS58_MASK, TMC5041_OFS58_SHIFT, TMC5041_MSLUT[1], false}) +#define TMC5041_OFS59_MASK 0x08000000 +#define TMC5041_OFS59_SHIFT 27 +#define TMC5041_OFS59_FIELD(motor) ((RegisterField) {TMC5041_OFS59_MASK, TMC5041_OFS59_SHIFT, TMC5041_MSLUT[1], false}) +#define TMC5041_OFS60_MASK 0x10000000 +#define TMC5041_OFS60_SHIFT 28 +#define TMC5041_OFS60_FIELD(motor) ((RegisterField) {TMC5041_OFS60_MASK, TMC5041_OFS60_SHIFT, TMC5041_MSLUT[1], false}) +#define TMC5041_OFS61_MASK 0x20000000 +#define TMC5041_OFS61_SHIFT 29 +#define TMC5041_OFS61_FIELD(motor) ((RegisterField) {TMC5041_OFS61_MASK, TMC5041_OFS61_SHIFT, TMC5041_MSLUT[1], false}) +#define TMC5041_OFS62_MASK 0x40000000 +#define TMC5041_OFS62_SHIFT 30 +#define TMC5041_OFS62_FIELD(motor) ((RegisterField) {TMC5041_OFS62_MASK, TMC5041_OFS62_SHIFT, TMC5041_MSLUT[1], false}) +#define TMC5041_OFS63_MASK 0x80000000 +#define TMC5041_OFS63_SHIFT 31 +#define TMC5041_OFS63_FIELD(motor) ((RegisterField) {TMC5041_OFS63_MASK, TMC5041_OFS63_SHIFT, TMC5041_MSLUT[1], false}) +#define TMC5041_OFS64_MASK 0x00000001 +#define TMC5041_OFS64_SHIFT 0 +#define TMC5041_OFS64_FIELD(motor) ((RegisterField) {TMC5041_OFS64_MASK, TMC5041_OFS64_SHIFT, TMC5041_MSLUT[2], false}) +#define TMC5041_OFS65_MASK 0x00000002 +#define TMC5041_OFS65_SHIFT 1 +#define TMC5041_OFS65_FIELD(motor) ((RegisterField) {TMC5041_OFS65_MASK, TMC5041_OFS65_SHIFT, TMC5041_MSLUT[2], false}) +#define TMC5041_OFS66_MASK 0x00000004 +#define TMC5041_OFS66_SHIFT 2 +#define TMC5041_OFS66_FIELD(motor) ((RegisterField) {TMC5041_OFS66_MASK, TMC5041_OFS66_SHIFT, TMC5041_MSLUT[2], false}) +#define TMC5041_OFS67_MASK 0x00000008 +#define TMC5041_OFS67_SHIFT 3 +#define TMC5041_OFS67_FIELD(motor) ((RegisterField) {TMC5041_OFS67_MASK, TMC5041_OFS67_SHIFT, TMC5041_MSLUT[2], false}) +#define TMC5041_OFS68_MASK 0x00000010 +#define TMC5041_OFS68_SHIFT 4 +#define TMC5041_OFS68_FIELD(motor) ((RegisterField) {TMC5041_OFS68_MASK, TMC5041_OFS68_SHIFT, TMC5041_MSLUT[2], false}) +#define TMC5041_OFS69_MASK 0x00000020 +#define TMC5041_OFS69_SHIFT 5 +#define TMC5041_OFS69_FIELD(motor) ((RegisterField) {TMC5041_OFS69_MASK, TMC5041_OFS69_SHIFT, TMC5041_MSLUT[2], false}) +#define TMC5041_OFS70_MASK 0x00000040 +#define TMC5041_OFS70_SHIFT 6 +#define TMC5041_OFS70_FIELD(motor) ((RegisterField) {TMC5041_OFS70_MASK, TMC5041_OFS70_SHIFT, TMC5041_MSLUT[2], false}) +#define TMC5041_OFS71_MASK 0x00000080 +#define TMC5041_OFS71_SHIFT 7 +#define TMC5041_OFS71_FIELD(motor) ((RegisterField) {TMC5041_OFS71_MASK, TMC5041_OFS71_SHIFT, TMC5041_MSLUT[2], false}) +#define TMC5041_OFS72_MASK 0x00000100 +#define TMC5041_OFS72_SHIFT 8 +#define TMC5041_OFS72_FIELD(motor) ((RegisterField) {TMC5041_OFS72_MASK, TMC5041_OFS72_SHIFT, TMC5041_MSLUT[2], false}) +#define TMC5041_OFS73_MASK 0x00000200 +#define TMC5041_OFS73_SHIFT 9 +#define TMC5041_OFS73_FIELD(motor) ((RegisterField) {TMC5041_OFS73_MASK, TMC5041_OFS73_SHIFT, TMC5041_MSLUT[2], false}) +#define TMC5041_OFS74_MASK 0x00000400 +#define TMC5041_OFS74_SHIFT 10 +#define TMC5041_OFS74_FIELD(motor) ((RegisterField) {TMC5041_OFS74_MASK, TMC5041_OFS74_SHIFT, TMC5041_MSLUT[2], false}) +#define TMC5041_OFS75_MASK 0x00000800 +#define TMC5041_OFS75_SHIFT 11 +#define TMC5041_OFS75_FIELD(motor) ((RegisterField) {TMC5041_OFS75_MASK, TMC5041_OFS75_SHIFT, TMC5041_MSLUT[2], false}) +#define TMC5041_OFS76_MASK 0x00001000 +#define TMC5041_OFS76_SHIFT 12 +#define TMC5041_OFS76_FIELD(motor) ((RegisterField) {TMC5041_OFS76_MASK, TMC5041_OFS76_SHIFT, TMC5041_MSLUT[2], false}) +#define TMC5041_OFS77_MASK 0x00002000 +#define TMC5041_OFS77_SHIFT 13 +#define TMC5041_OFS77_FIELD(motor) ((RegisterField) {TMC5041_OFS77_MASK, TMC5041_OFS77_SHIFT, TMC5041_MSLUT[2], false}) +#define TMC5041_OFS78_MASK 0x00004000 +#define TMC5041_OFS78_SHIFT 14 +#define TMC5041_OFS78_FIELD(motor) ((RegisterField) {TMC5041_OFS78_MASK, TMC5041_OFS78_SHIFT, TMC5041_MSLUT[2], false}) +#define TMC5041_OFS79_MASK 0x00008000 +#define TMC5041_OFS79_SHIFT 15 +#define TMC5041_OFS79_FIELD(motor) ((RegisterField) {TMC5041_OFS79_MASK, TMC5041_OFS79_SHIFT, TMC5041_MSLUT[2], false}) +#define TMC5041_OFS80_MASK 0x00010000 +#define TMC5041_OFS80_SHIFT 16 +#define TMC5041_OFS80_FIELD(motor) ((RegisterField) {TMC5041_OFS80_MASK, TMC5041_OFS80_SHIFT, TMC5041_MSLUT[2], false}) +#define TMC5041_OFS81_MASK 0x00020000 +#define TMC5041_OFS81_SHIFT 17 +#define TMC5041_OFS81_FIELD(motor) ((RegisterField) {TMC5041_OFS81_MASK, TMC5041_OFS81_SHIFT, TMC5041_MSLUT[2], false}) +#define TMC5041_OFS82_MASK 0x00040000 +#define TMC5041_OFS82_SHIFT 18 +#define TMC5041_OFS82_FIELD(motor) ((RegisterField) {TMC5041_OFS82_MASK, TMC5041_OFS82_SHIFT, TMC5041_MSLUT[2], false}) +#define TMC5041_OFS83_MASK 0x00080000 +#define TMC5041_OFS83_SHIFT 19 +#define TMC5041_OFS83_FIELD(motor) ((RegisterField) {TMC5041_OFS83_MASK, TMC5041_OFS83_SHIFT, TMC5041_MSLUT[2], false}) +#define TMC5041_OFS84_MASK 0x00100000 +#define TMC5041_OFS84_SHIFT 20 +#define TMC5041_OFS84_FIELD(motor) ((RegisterField) {TMC5041_OFS84_MASK, TMC5041_OFS84_SHIFT, TMC5041_MSLUT[2], false}) +#define TMC5041_OFS85_MASK 0x00200000 +#define TMC5041_OFS85_SHIFT 21 +#define TMC5041_OFS85_FIELD(motor) ((RegisterField) {TMC5041_OFS85_MASK, TMC5041_OFS85_SHIFT, TMC5041_MSLUT[2], false}) +#define TMC5041_OFS86_MASK 0x00400000 +#define TMC5041_OFS86_SHIFT 22 +#define TMC5041_OFS86_FIELD(motor) ((RegisterField) {TMC5041_OFS86_MASK, TMC5041_OFS86_SHIFT, TMC5041_MSLUT[2], false}) +#define TMC5041_OFS87_MASK 0x00800000 +#define TMC5041_OFS87_SHIFT 23 +#define TMC5041_OFS87_FIELD(motor) ((RegisterField) {TMC5041_OFS87_MASK, TMC5041_OFS87_SHIFT, TMC5041_MSLUT[2], false}) +#define TMC5041_OFS88_MASK 0x01000000 +#define TMC5041_OFS88_SHIFT 24 +#define TMC5041_OFS88_FIELD(motor) ((RegisterField) {TMC5041_OFS88_MASK, TMC5041_OFS88_SHIFT, TMC5041_MSLUT[2], false}) +#define TMC5041_OFS89_MASK 0x02000000 +#define TMC5041_OFS89_SHIFT 25 +#define TMC5041_OFS89_FIELD(motor) ((RegisterField) {TMC5041_OFS89_MASK, TMC5041_OFS89_SHIFT, TMC5041_MSLUT[2], false}) +#define TMC5041_OFS90_MASK 0x04000000 +#define TMC5041_OFS90_SHIFT 26 +#define TMC5041_OFS90_FIELD(motor) ((RegisterField) {TMC5041_OFS90_MASK, TMC5041_OFS90_SHIFT, TMC5041_MSLUT[2], false}) +#define TMC5041_OFS91_MASK 0x08000000 +#define TMC5041_OFS91_SHIFT 27 +#define TMC5041_OFS91_FIELD(motor) ((RegisterField) {TMC5041_OFS91_MASK, TMC5041_OFS91_SHIFT, TMC5041_MSLUT[2], false}) +#define TMC5041_OFS92_MASK 0x10000000 +#define TMC5041_OFS92_SHIFT 28 +#define TMC5041_OFS92_FIELD(motor) ((RegisterField) {TMC5041_OFS92_MASK, TMC5041_OFS92_SHIFT, TMC5041_MSLUT[2], false}) +#define TMC5041_OFS93_MASK 0x20000000 +#define TMC5041_OFS93_SHIFT 29 +#define TMC5041_OFS93_FIELD(motor) ((RegisterField) {TMC5041_OFS93_MASK, TMC5041_OFS93_SHIFT, TMC5041_MSLUT[2], false}) +#define TMC5041_OFS94_MASK 0x40000000 +#define TMC5041_OFS94_SHIFT 30 +#define TMC5041_OFS94_FIELD(motor) ((RegisterField) {TMC5041_OFS94_MASK, TMC5041_OFS94_SHIFT, TMC5041_MSLUT[2], false}) +#define TMC5041_OFS95_MASK 0x80000000 +#define TMC5041_OFS95_SHIFT 31 +#define TMC5041_OFS95_FIELD(motor) ((RegisterField) {TMC5041_OFS95_MASK, TMC5041_OFS95_SHIFT, TMC5041_MSLUT[2], false}) +#define TMC5041_OFS96_MASK 0x00000001 +#define TMC5041_OFS96_SHIFT 0 +#define TMC5041_OFS96_FIELD(motor) ((RegisterField) {TMC5041_OFS96_MASK, TMC5041_OFS96_SHIFT, TMC5041_MSLUT[3], false}) +#define TMC5041_OFS97_MASK 0x00000002 +#define TMC5041_OFS97_SHIFT 1 +#define TMC5041_OFS97_FIELD(motor) ((RegisterField) {TMC5041_OFS97_MASK, TMC5041_OFS97_SHIFT, TMC5041_MSLUT[3], false}) +#define TMC5041_OFS98_MASK 0x00000004 +#define TMC5041_OFS98_SHIFT 2 +#define TMC5041_OFS98_FIELD(motor) ((RegisterField) {TMC5041_OFS98_MASK, TMC5041_OFS98_SHIFT, TMC5041_MSLUT[3], false}) +#define TMC5041_OFS99_MASK 0x00000008 +#define TMC5041_OFS99_SHIFT 3 +#define TMC5041_OFS99_FIELD(motor) ((RegisterField) {TMC5041_OFS99_MASK, TMC5041_OFS99_SHIFT, TMC5041_MSLUT[3], false}) +#define TMC5041_OFS100_MASK 0x00000010 +#define TMC5041_OFS100_SHIFT 4 +#define TMC5041_OFS100_FIELD(motor) ((RegisterField) {TMC5041_OFS100_MASK, TMC5041_OFS100_SHIFT, TMC5041_MSLUT[3], false}) +#define TMC5041_OFS101_MASK 0x00000020 +#define TMC5041_OFS101_SHIFT 5 +#define TMC5041_OFS101_FIELD(motor) ((RegisterField) {TMC5041_OFS101_MASK, TMC5041_OFS101_SHIFT, TMC5041_MSLUT[3], false}) +#define TMC5041_OFS102_MASK 0x00000040 +#define TMC5041_OFS102_SHIFT 6 +#define TMC5041_OFS102_FIELD(motor) ((RegisterField) {TMC5041_OFS102_MASK, TMC5041_OFS102_SHIFT, TMC5041_MSLUT[3], false}) +#define TMC5041_OFS103_MASK 0x00000080 +#define TMC5041_OFS103_SHIFT 7 +#define TMC5041_OFS103_FIELD(motor) ((RegisterField) {TMC5041_OFS103_MASK, TMC5041_OFS103_SHIFT, TMC5041_MSLUT[3], false}) +#define TMC5041_OFS104_MASK 0x00000100 +#define TMC5041_OFS104_SHIFT 8 +#define TMC5041_OFS104_FIELD(motor) ((RegisterField) {TMC5041_OFS104_MASK, TMC5041_OFS104_SHIFT, TMC5041_MSLUT[3], false}) +#define TMC5041_OFS105_MASK 0x00000200 +#define TMC5041_OFS105_SHIFT 9 +#define TMC5041_OFS105_FIELD(motor) ((RegisterField) {TMC5041_OFS105_MASK, TMC5041_OFS105_SHIFT, TMC5041_MSLUT[3], false}) +#define TMC5041_OFS106_MASK 0x00000400 +#define TMC5041_OFS106_SHIFT 10 +#define TMC5041_OFS106_FIELD(motor) ((RegisterField) {TMC5041_OFS106_MASK, TMC5041_OFS106_SHIFT, TMC5041_MSLUT[3], false}) +#define TMC5041_OFS107_MASK 0x00000800 +#define TMC5041_OFS107_SHIFT 11 +#define TMC5041_OFS107_FIELD(motor) ((RegisterField) {TMC5041_OFS107_MASK, TMC5041_OFS107_SHIFT, TMC5041_MSLUT[3], false}) +#define TMC5041_OFS108_MASK 0x00001000 +#define TMC5041_OFS108_SHIFT 12 +#define TMC5041_OFS108_FIELD(motor) ((RegisterField) {TMC5041_OFS108_MASK, TMC5041_OFS108_SHIFT, TMC5041_MSLUT[3], false}) +#define TMC5041_OFS109_MASK 0x00002000 +#define TMC5041_OFS109_SHIFT 13 +#define TMC5041_OFS109_FIELD(motor) ((RegisterField) {TMC5041_OFS109_MASK, TMC5041_OFS109_SHIFT, TMC5041_MSLUT[3], false}) +#define TMC5041_OFS110_MASK 0x00004000 +#define TMC5041_OFS110_SHIFT 14 +#define TMC5041_OFS110_FIELD(motor) ((RegisterField) {TMC5041_OFS110_MASK, TMC5041_OFS110_SHIFT, TMC5041_MSLUT[3], false}) +#define TMC5041_OFS111_MASK 0x00008000 +#define TMC5041_OFS111_SHIFT 15 +#define TMC5041_OFS111_FIELD(motor) ((RegisterField) {TMC5041_OFS111_MASK, TMC5041_OFS111_SHIFT, TMC5041_MSLUT[3], false}) +#define TMC5041_OFS112_MASK 0x00010000 +#define TMC5041_OFS112_SHIFT 16 +#define TMC5041_OFS112_FIELD(motor) ((RegisterField) {TMC5041_OFS112_MASK, TMC5041_OFS112_SHIFT, TMC5041_MSLUT[3], false}) +#define TMC5041_OFS113_MASK 0x00020000 +#define TMC5041_OFS113_SHIFT 17 +#define TMC5041_OFS113_FIELD(motor) ((RegisterField) {TMC5041_OFS113_MASK, TMC5041_OFS113_SHIFT, TMC5041_MSLUT[3], false}) +#define TMC5041_OFS114_MASK 0x00040000 +#define TMC5041_OFS114_SHIFT 18 +#define TMC5041_OFS114_FIELD(motor) ((RegisterField) {TMC5041_OFS114_MASK, TMC5041_OFS114_SHIFT, TMC5041_MSLUT[3], false}) +#define TMC5041_OFS115_MASK 0x00080000 +#define TMC5041_OFS115_SHIFT 19 +#define TMC5041_OFS115_FIELD(motor) ((RegisterField) {TMC5041_OFS115_MASK, TMC5041_OFS115_SHIFT, TMC5041_MSLUT[3], false}) +#define TMC5041_OFS116_MASK 0x00100000 +#define TMC5041_OFS116_SHIFT 20 +#define TMC5041_OFS116_FIELD(motor) ((RegisterField) {TMC5041_OFS116_MASK, TMC5041_OFS116_SHIFT, TMC5041_MSLUT[3], false}) +#define TMC5041_OFS117_MASK 0x00200000 +#define TMC5041_OFS117_SHIFT 21 +#define TMC5041_OFS117_FIELD(motor) ((RegisterField) {TMC5041_OFS117_MASK, TMC5041_OFS117_SHIFT, TMC5041_MSLUT[3], false}) +#define TMC5041_OFS118_MASK 0x00400000 +#define TMC5041_OFS118_SHIFT 22 +#define TMC5041_OFS118_FIELD(motor) ((RegisterField) {TMC5041_OFS118_MASK, TMC5041_OFS118_SHIFT, TMC5041_MSLUT[3], false}) +#define TMC5041_OFS119_MASK 0x00800000 +#define TMC5041_OFS119_SHIFT 23 +#define TMC5041_OFS119_FIELD(motor) ((RegisterField) {TMC5041_OFS119_MASK, TMC5041_OFS119_SHIFT, TMC5041_MSLUT[3], false}) +#define TMC5041_OFS120_MASK 0x01000000 +#define TMC5041_OFS120_SHIFT 24 +#define TMC5041_OFS120_FIELD(motor) ((RegisterField) {TMC5041_OFS120_MASK, TMC5041_OFS120_SHIFT, TMC5041_MSLUT[3], false}) +#define TMC5041_OFS121_MASK 0x02000000 +#define TMC5041_OFS121_SHIFT 25 +#define TMC5041_OFS121_FIELD(motor) ((RegisterField) {TMC5041_OFS121_MASK, TMC5041_OFS121_SHIFT, TMC5041_MSLUT[3], false}) +#define TMC5041_OFS122_MASK 0x04000000 +#define TMC5041_OFS122_SHIFT 26 +#define TMC5041_OFS122_FIELD(motor) ((RegisterField) {TMC5041_OFS122_MASK, TMC5041_OFS122_SHIFT, TMC5041_MSLUT[3], false}) +#define TMC5041_OFS123_MASK 0x08000000 +#define TMC5041_OFS123_SHIFT 27 +#define TMC5041_OFS123_FIELD(motor) ((RegisterField) {TMC5041_OFS123_MASK, TMC5041_OFS123_SHIFT, TMC5041_MSLUT[3], false}) +#define TMC5041_OFS124_MASK 0x10000000 +#define TMC5041_OFS124_SHIFT 28 +#define TMC5041_OFS124_FIELD(motor) ((RegisterField) {TMC5041_OFS124_MASK, TMC5041_OFS124_SHIFT, TMC5041_MSLUT[3], false}) +#define TMC5041_OFS125_MASK 0x20000000 +#define TMC5041_OFS125_SHIFT 29 +#define TMC5041_OFS125_FIELD(motor) ((RegisterField) {TMC5041_OFS125_MASK, TMC5041_OFS125_SHIFT, TMC5041_MSLUT[3], false}) +#define TMC5041_OFS126_MASK 0x40000000 +#define TMC5041_OFS126_SHIFT 30 +#define TMC5041_OFS126_FIELD(motor) ((RegisterField) {TMC5041_OFS126_MASK, TMC5041_OFS126_SHIFT, TMC5041_MSLUT[3], false}) +#define TMC5041_OFS127_MASK 0x80000000 +#define TMC5041_OFS127_SHIFT 31 +#define TMC5041_OFS127_FIELD(motor) ((RegisterField) {TMC5041_OFS127_MASK, TMC5041_OFS127_SHIFT, TMC5041_MSLUT[3], false}) +#define TMC5041_OFS128_MASK 0x00000001 +#define TMC5041_OFS128_SHIFT 0 +#define TMC5041_OFS128_FIELD(motor) ((RegisterField) {TMC5041_OFS128_MASK, TMC5041_OFS128_SHIFT, TMC5041_MSLUT[4], false}) +#define TMC5041_OFS129_MASK 0x00000002 +#define TMC5041_OFS129_SHIFT 1 +#define TMC5041_OFS129_FIELD(motor) ((RegisterField) {TMC5041_OFS129_MASK, TMC5041_OFS129_SHIFT, TMC5041_MSLUT[4], false}) +#define TMC5041_OFS130_MASK 0x00000004 +#define TMC5041_OFS130_SHIFT 2 +#define TMC5041_OFS130_FIELD(motor) ((RegisterField) {TMC5041_OFS130_MASK, TMC5041_OFS130_SHIFT, TMC5041_MSLUT[4], false}) +#define TMC5041_OFS131_MASK 0x00000008 +#define TMC5041_OFS131_SHIFT 3 +#define TMC5041_OFS131_FIELD(motor) ((RegisterField) {TMC5041_OFS131_MASK, TMC5041_OFS131_SHIFT, TMC5041_MSLUT[4], false}) +#define TMC5041_OFS132_MASK 0x00000010 +#define TMC5041_OFS132_SHIFT 4 +#define TMC5041_OFS132_FIELD(motor) ((RegisterField) {TMC5041_OFS132_MASK, TMC5041_OFS132_SHIFT, TMC5041_MSLUT[4], false}) +#define TMC5041_OFS133_MASK 0x00000020 +#define TMC5041_OFS133_SHIFT 5 +#define TMC5041_OFS133_FIELD(motor) ((RegisterField) {TMC5041_OFS133_MASK, TMC5041_OFS133_SHIFT, TMC5041_MSLUT[4], false}) +#define TMC5041_OFS134_MASK 0x00000040 +#define TMC5041_OFS134_SHIFT 6 +#define TMC5041_OFS134_FIELD(motor) ((RegisterField) {TMC5041_OFS134_MASK, TMC5041_OFS134_SHIFT, TMC5041_MSLUT[4], false}) +#define TMC5041_OFS135_MASK 0x00000080 +#define TMC5041_OFS135_SHIFT 7 +#define TMC5041_OFS135_FIELD(motor) ((RegisterField) {TMC5041_OFS135_MASK, TMC5041_OFS135_SHIFT, TMC5041_MSLUT[4], false}) +#define TMC5041_OFS136_MASK 0x00000100 +#define TMC5041_OFS136_SHIFT 8 +#define TMC5041_OFS136_FIELD(motor) ((RegisterField) {TMC5041_OFS136_MASK, TMC5041_OFS136_SHIFT, TMC5041_MSLUT[4], false}) +#define TMC5041_OFS137_MASK 0x00000200 +#define TMC5041_OFS137_SHIFT 9 +#define TMC5041_OFS137_FIELD(motor) ((RegisterField) {TMC5041_OFS137_MASK, TMC5041_OFS137_SHIFT, TMC5041_MSLUT[4], false}) +#define TMC5041_OFS138_MASK 0x00000400 +#define TMC5041_OFS138_SHIFT 10 +#define TMC5041_OFS138_FIELD(motor) ((RegisterField) {TMC5041_OFS138_MASK, TMC5041_OFS138_SHIFT, TMC5041_MSLUT[4], false}) +#define TMC5041_OFS139_MASK 0x00000800 +#define TMC5041_OFS139_SHIFT 11 +#define TMC5041_OFS139_FIELD(motor) ((RegisterField) {TMC5041_OFS139_MASK, TMC5041_OFS139_SHIFT, TMC5041_MSLUT[4], false}) +#define TMC5041_OFS140_MASK 0x00001000 +#define TMC5041_OFS140_SHIFT 12 +#define TMC5041_OFS140_FIELD(motor) ((RegisterField) {TMC5041_OFS140_MASK, TMC5041_OFS140_SHIFT, TMC5041_MSLUT[4], false}) +#define TMC5041_OFS141_MASK 0x00002000 +#define TMC5041_OFS141_SHIFT 13 +#define TMC5041_OFS141_FIELD(motor) ((RegisterField) {TMC5041_OFS141_MASK, TMC5041_OFS141_SHIFT, TMC5041_MSLUT[4], false}) +#define TMC5041_OFS142_MASK 0x00004000 +#define TMC5041_OFS142_SHIFT 14 +#define TMC5041_OFS142_FIELD(motor) ((RegisterField) {TMC5041_OFS142_MASK, TMC5041_OFS142_SHIFT, TMC5041_MSLUT[4], false}) +#define TMC5041_OFS143_MASK 0x00008000 +#define TMC5041_OFS143_SHIFT 15 +#define TMC5041_OFS143_FIELD(motor) ((RegisterField) {TMC5041_OFS143_MASK, TMC5041_OFS143_SHIFT, TMC5041_MSLUT[4], false}) +#define TMC5041_OFS144_MASK 0x00010000 +#define TMC5041_OFS144_SHIFT 16 +#define TMC5041_OFS144_FIELD(motor) ((RegisterField) {TMC5041_OFS144_MASK, TMC5041_OFS144_SHIFT, TMC5041_MSLUT[4], false}) +#define TMC5041_OFS145_MASK 0x00020000 +#define TMC5041_OFS145_SHIFT 17 +#define TMC5041_OFS145_FIELD(motor) ((RegisterField) {TMC5041_OFS145_MASK, TMC5041_OFS145_SHIFT, TMC5041_MSLUT[4], false}) +#define TMC5041_OFS146_MASK 0x00040000 +#define TMC5041_OFS146_SHIFT 18 +#define TMC5041_OFS146_FIELD(motor) ((RegisterField) {TMC5041_OFS146_MASK, TMC5041_OFS146_SHIFT, TMC5041_MSLUT[4], false}) +#define TMC5041_OFS147_MASK 0x00080000 +#define TMC5041_OFS147_SHIFT 19 +#define TMC5041_OFS147_FIELD(motor) ((RegisterField) {TMC5041_OFS147_MASK, TMC5041_OFS147_SHIFT, TMC5041_MSLUT[4], false}) +#define TMC5041_OFS148_MASK 0x00100000 +#define TMC5041_OFS148_SHIFT 20 +#define TMC5041_OFS148_FIELD(motor) ((RegisterField) {TMC5041_OFS148_MASK, TMC5041_OFS148_SHIFT, TMC5041_MSLUT[4], false}) +#define TMC5041_OFS149_MASK 0x00200000 +#define TMC5041_OFS149_SHIFT 21 +#define TMC5041_OFS149_FIELD(motor) ((RegisterField) {TMC5041_OFS149_MASK, TMC5041_OFS149_SHIFT, TMC5041_MSLUT[4], false}) +#define TMC5041_OFS150_MASK 0x00400000 +#define TMC5041_OFS150_SHIFT 22 +#define TMC5041_OFS150_FIELD(motor) ((RegisterField) {TMC5041_OFS150_MASK, TMC5041_OFS150_SHIFT, TMC5041_MSLUT[4], false}) +#define TMC5041_OFS151_MASK 0x00800000 +#define TMC5041_OFS151_SHIFT 23 +#define TMC5041_OFS151_FIELD(motor) ((RegisterField) {TMC5041_OFS151_MASK, TMC5041_OFS151_SHIFT, TMC5041_MSLUT[4], false}) +#define TMC5041_OFS152_MASK 0x01000000 +#define TMC5041_OFS152_SHIFT 24 +#define TMC5041_OFS152_FIELD(motor) ((RegisterField) {TMC5041_OFS152_MASK, TMC5041_OFS152_SHIFT, TMC5041_MSLUT[4], false}) +#define TMC5041_OFS153_MASK 0x02000000 +#define TMC5041_OFS153_SHIFT 25 +#define TMC5041_OFS153_FIELD(motor) ((RegisterField) {TMC5041_OFS153_MASK, TMC5041_OFS153_SHIFT, TMC5041_MSLUT[4], false}) +#define TMC5041_OFS154_MASK 0x04000000 +#define TMC5041_OFS154_SHIFT 26 +#define TMC5041_OFS154_FIELD(motor) ((RegisterField) {TMC5041_OFS154_MASK, TMC5041_OFS154_SHIFT, TMC5041_MSLUT[4], false}) +#define TMC5041_OFS155_MASK 0x08000000 +#define TMC5041_OFS155_SHIFT 27 +#define TMC5041_OFS155_FIELD(motor) ((RegisterField) {TMC5041_OFS155_MASK, TMC5041_OFS155_SHIFT, TMC5041_MSLUT[4], false}) +#define TMC5041_OFS156_MASK 0x10000000 +#define TMC5041_OFS156_SHIFT 28 +#define TMC5041_OFS156_FIELD(motor) ((RegisterField) {TMC5041_OFS156_MASK, TMC5041_OFS156_SHIFT, TMC5041_MSLUT[4], false}) +#define TMC5041_OFS157_MASK 0x20000000 +#define TMC5041_OFS157_SHIFT 29 +#define TMC5041_OFS157_FIELD(motor) ((RegisterField) {TMC5041_OFS157_MASK, TMC5041_OFS157_SHIFT, TMC5041_MSLUT[4], false}) +#define TMC5041_OFS158_MASK 0x40000000 +#define TMC5041_OFS158_SHIFT 30 +#define TMC5041_OFS158_FIELD(motor) ((RegisterField) {TMC5041_OFS158_MASK, TMC5041_OFS158_SHIFT, TMC5041_MSLUT[4], false}) +#define TMC5041_OFS159_MASK 0x80000000 +#define TMC5041_OFS159_SHIFT 31 +#define TMC5041_OFS159_FIELD(motor) ((RegisterField) {TMC5041_OFS159_MASK, TMC5041_OFS159_SHIFT, TMC5041_MSLUT[4], false}) +#define TMC5041_OFS160_MASK 0x00000001 +#define TMC5041_OFS160_SHIFT 0 +#define TMC5041_OFS160_FIELD(motor) ((RegisterField) {TMC5041_OFS160_MASK, TMC5041_OFS160_SHIFT, TMC5041_MSLUT[5], false}) +#define TMC5041_OFS161_MASK 0x00000002 +#define TMC5041_OFS161_SHIFT 1 +#define TMC5041_OFS161_FIELD(motor) ((RegisterField) {TMC5041_OFS161_MASK, TMC5041_OFS161_SHIFT, TMC5041_MSLUT[5], false}) +#define TMC5041_OFS162_MASK 0x00000004 +#define TMC5041_OFS162_SHIFT 2 +#define TMC5041_OFS162_FIELD(motor) ((RegisterField) {TMC5041_OFS162_MASK, TMC5041_OFS162_SHIFT, TMC5041_MSLUT[5], false}) +#define TMC5041_OFS163_MASK 0x00000008 +#define TMC5041_OFS163_SHIFT 3 +#define TMC5041_OFS163_FIELD(motor) ((RegisterField) {TMC5041_OFS163_MASK, TMC5041_OFS163_SHIFT, TMC5041_MSLUT[5], false}) +#define TMC5041_OFS164_MASK 0x00000010 +#define TMC5041_OFS164_SHIFT 4 +#define TMC5041_OFS164_FIELD(motor) ((RegisterField) {TMC5041_OFS164_MASK, TMC5041_OFS164_SHIFT, TMC5041_MSLUT[5], false}) +#define TMC5041_OFS165_MASK 0x00000020 +#define TMC5041_OFS165_SHIFT 5 +#define TMC5041_OFS165_FIELD(motor) ((RegisterField) {TMC5041_OFS165_MASK, TMC5041_OFS165_SHIFT, TMC5041_MSLUT[5], false}) +#define TMC5041_OFS166_MASK 0x00000040 +#define TMC5041_OFS166_SHIFT 6 +#define TMC5041_OFS166_FIELD(motor) ((RegisterField) {TMC5041_OFS166_MASK, TMC5041_OFS166_SHIFT, TMC5041_MSLUT[5], false}) +#define TMC5041_OFS167_MASK 0x00000080 +#define TMC5041_OFS167_SHIFT 7 +#define TMC5041_OFS167_FIELD(motor) ((RegisterField) {TMC5041_OFS167_MASK, TMC5041_OFS167_SHIFT, TMC5041_MSLUT[5], false}) +#define TMC5041_OFS168_MASK 0x00000100 +#define TMC5041_OFS168_SHIFT 8 +#define TMC5041_OFS168_FIELD(motor) ((RegisterField) {TMC5041_OFS168_MASK, TMC5041_OFS168_SHIFT, TMC5041_MSLUT[5], false}) +#define TMC5041_OFS169_MASK 0x00000200 +#define TMC5041_OFS169_SHIFT 9 +#define TMC5041_OFS169_FIELD(motor) ((RegisterField) {TMC5041_OFS169_MASK, TMC5041_OFS169_SHIFT, TMC5041_MSLUT[5], false}) +#define TMC5041_OFS170_MASK 0x00000400 +#define TMC5041_OFS170_SHIFT 10 +#define TMC5041_OFS170_FIELD(motor) ((RegisterField) {TMC5041_OFS170_MASK, TMC5041_OFS170_SHIFT, TMC5041_MSLUT[5], false}) +#define TMC5041_OFS171_MASK 0x00000800 +#define TMC5041_OFS171_SHIFT 11 +#define TMC5041_OFS171_FIELD(motor) ((RegisterField) {TMC5041_OFS171_MASK, TMC5041_OFS171_SHIFT, TMC5041_MSLUT[5], false}) +#define TMC5041_OFS172_MASK 0x00001000 +#define TMC5041_OFS172_SHIFT 12 +#define TMC5041_OFS172_FIELD(motor) ((RegisterField) {TMC5041_OFS172_MASK, TMC5041_OFS172_SHIFT, TMC5041_MSLUT[5], false}) +#define TMC5041_OFS173_MASK 0x00002000 +#define TMC5041_OFS173_SHIFT 13 +#define TMC5041_OFS173_FIELD(motor) ((RegisterField) {TMC5041_OFS173_MASK, TMC5041_OFS173_SHIFT, TMC5041_MSLUT[5], false}) +#define TMC5041_OFS174_MASK 0x00004000 +#define TMC5041_OFS174_SHIFT 14 +#define TMC5041_OFS174_FIELD(motor) ((RegisterField) {TMC5041_OFS174_MASK, TMC5041_OFS174_SHIFT, TMC5041_MSLUT[5], false}) +#define TMC5041_OFS175_MASK 0x00008000 +#define TMC5041_OFS175_SHIFT 15 +#define TMC5041_OFS175_FIELD(motor) ((RegisterField) {TMC5041_OFS175_MASK, TMC5041_OFS175_SHIFT, TMC5041_MSLUT[5], false}) +#define TMC5041_OFS176_MASK 0x00010000 +#define TMC5041_OFS176_SHIFT 16 +#define TMC5041_OFS176_FIELD(motor) ((RegisterField) {TMC5041_OFS176_MASK, TMC5041_OFS176_SHIFT, TMC5041_MSLUT[5], false}) +#define TMC5041_OFS177_MASK 0x00020000 +#define TMC5041_OFS177_SHIFT 17 +#define TMC5041_OFS177_FIELD(motor) ((RegisterField) {TMC5041_OFS177_MASK, TMC5041_OFS177_SHIFT, TMC5041_MSLUT[5], false}) +#define TMC5041_OFS178_MASK 0x00040000 +#define TMC5041_OFS178_SHIFT 18 +#define TMC5041_OFS178_FIELD(motor) ((RegisterField) {TMC5041_OFS178_MASK, TMC5041_OFS178_SHIFT, TMC5041_MSLUT[5], false}) +#define TMC5041_OFS179_MASK 0x00080000 +#define TMC5041_OFS179_SHIFT 19 +#define TMC5041_OFS179_FIELD(motor) ((RegisterField) {TMC5041_OFS179_MASK, TMC5041_OFS179_SHIFT, TMC5041_MSLUT[5], false}) +#define TMC5041_OFS180_MASK 0x00100000 +#define TMC5041_OFS180_SHIFT 20 +#define TMC5041_OFS180_FIELD(motor) ((RegisterField) {TMC5041_OFS180_MASK, TMC5041_OFS180_SHIFT, TMC5041_MSLUT[5], false}) +#define TMC5041_OFS181_MASK 0x00200000 +#define TMC5041_OFS181_SHIFT 21 +#define TMC5041_OFS181_FIELD(motor) ((RegisterField) {TMC5041_OFS181_MASK, TMC5041_OFS181_SHIFT, TMC5041_MSLUT[5], false}) +#define TMC5041_OFS182_MASK 0x00400000 +#define TMC5041_OFS182_SHIFT 22 +#define TMC5041_OFS182_FIELD(motor) ((RegisterField) {TMC5041_OFS182_MASK, TMC5041_OFS182_SHIFT, TMC5041_MSLUT[5], false}) +#define TMC5041_OFS183_MASK 0x00800000 +#define TMC5041_OFS183_SHIFT 23 +#define TMC5041_OFS183_FIELD(motor) ((RegisterField) {TMC5041_OFS183_MASK, TMC5041_OFS183_SHIFT, TMC5041_MSLUT[5], false}) +#define TMC5041_OFS184_MASK 0x01000000 +#define TMC5041_OFS184_SHIFT 24 +#define TMC5041_OFS184_FIELD(motor) ((RegisterField) {TMC5041_OFS184_MASK, TMC5041_OFS184_SHIFT, TMC5041_MSLUT[5], false}) +#define TMC5041_OFS185_MASK 0x02000000 +#define TMC5041_OFS185_SHIFT 25 +#define TMC5041_OFS185_FIELD(motor) ((RegisterField) {TMC5041_OFS185_MASK, TMC5041_OFS185_SHIFT, TMC5041_MSLUT[5], false}) +#define TMC5041_OFS186_MASK 0x04000000 +#define TMC5041_OFS186_SHIFT 26 +#define TMC5041_OFS186_FIELD(motor) ((RegisterField) {TMC5041_OFS186_MASK, TMC5041_OFS186_SHIFT, TMC5041_MSLUT[5], false}) +#define TMC5041_OFS187_MASK 0x08000000 +#define TMC5041_OFS187_SHIFT 27 +#define TMC5041_OFS187_FIELD(motor) ((RegisterField) {TMC5041_OFS187_MASK, TMC5041_OFS187_SHIFT, TMC5041_MSLUT[5], false}) +#define TMC5041_OFS188_MASK 0x10000000 +#define TMC5041_OFS188_SHIFT 28 +#define TMC5041_OFS188_FIELD(motor) ((RegisterField) {TMC5041_OFS188_MASK, TMC5041_OFS188_SHIFT, TMC5041_MSLUT[5], false}) +#define TMC5041_OFS189_MASK 0x20000000 +#define TMC5041_OFS189_SHIFT 29 +#define TMC5041_OFS189_FIELD(motor) ((RegisterField) {TMC5041_OFS189_MASK, TMC5041_OFS189_SHIFT, TMC5041_MSLUT[5], false}) +#define TMC5041_OFS190_MASK 0x40000000 +#define TMC5041_OFS190_SHIFT 30 +#define TMC5041_OFS190_FIELD(motor) ((RegisterField) {TMC5041_OFS190_MASK, TMC5041_OFS190_SHIFT, TMC5041_MSLUT[5], false}) +#define TMC5041_OFS191_MASK 0x80000000 +#define TMC5041_OFS191_SHIFT 31 +#define TMC5041_OFS191_FIELD(motor) ((RegisterField) {TMC5041_OFS191_MASK, TMC5041_OFS191_SHIFT, TMC5041_MSLUT[5], false}) +#define TMC5041_OFS192_MASK 0x00000001 +#define TMC5041_OFS192_SHIFT 0 +#define TMC5041_OFS192_FIELD(motor) ((RegisterField) {TMC5041_OFS192_MASK, TMC5041_OFS192_SHIFT, TMC5041_MSLUT[6], false}) +#define TMC5041_OFS193_MASK 0x00000002 +#define TMC5041_OFS193_SHIFT 1 +#define TMC5041_OFS193_FIELD(motor) ((RegisterField) {TMC5041_OFS193_MASK, TMC5041_OFS193_SHIFT, TMC5041_MSLUT[6], false}) +#define TMC5041_OFS194_MASK 0x00000004 +#define TMC5041_OFS194_SHIFT 2 +#define TMC5041_OFS194_FIELD(motor) ((RegisterField) {TMC5041_OFS194_MASK, TMC5041_OFS194_SHIFT, TMC5041_MSLUT[6], false}) +#define TMC5041_OFS195_MASK 0x00000008 +#define TMC5041_OFS195_SHIFT 3 +#define TMC5041_OFS195_FIELD(motor) ((RegisterField) {TMC5041_OFS195_MASK, TMC5041_OFS195_SHIFT, TMC5041_MSLUT[6], false}) +#define TMC5041_OFS196_MASK 0x00000010 +#define TMC5041_OFS196_SHIFT 4 +#define TMC5041_OFS196_FIELD(motor) ((RegisterField) {TMC5041_OFS196_MASK, TMC5041_OFS196_SHIFT, TMC5041_MSLUT[6], false}) +#define TMC5041_OFS197_MASK 0x00000020 +#define TMC5041_OFS197_SHIFT 5 +#define TMC5041_OFS197_FIELD(motor) ((RegisterField) {TMC5041_OFS197_MASK, TMC5041_OFS197_SHIFT, TMC5041_MSLUT[6], false}) +#define TMC5041_OFS198_MASK 0x00000040 +#define TMC5041_OFS198_SHIFT 6 +#define TMC5041_OFS198_FIELD(motor) ((RegisterField) {TMC5041_OFS198_MASK, TMC5041_OFS198_SHIFT, TMC5041_MSLUT[6], false}) +#define TMC5041_OFS199_MASK 0x00000080 +#define TMC5041_OFS199_SHIFT 7 +#define TMC5041_OFS199_FIELD(motor) ((RegisterField) {TMC5041_OFS199_MASK, TMC5041_OFS199_SHIFT, TMC5041_MSLUT[6], false}) +#define TMC5041_OFS200_MASK 0x00000100 +#define TMC5041_OFS200_SHIFT 8 +#define TMC5041_OFS200_FIELD(motor) ((RegisterField) {TMC5041_OFS200_MASK, TMC5041_OFS200_SHIFT, TMC5041_MSLUT[6], false}) +#define TMC5041_OFS201_MASK 0x00000200 +#define TMC5041_OFS201_SHIFT 9 +#define TMC5041_OFS201_FIELD(motor) ((RegisterField) {TMC5041_OFS201_MASK, TMC5041_OFS201_SHIFT, TMC5041_MSLUT[6], false}) +#define TMC5041_OFS202_MASK 0x00000400 +#define TMC5041_OFS202_SHIFT 10 +#define TMC5041_OFS202_FIELD(motor) ((RegisterField) {TMC5041_OFS202_MASK, TMC5041_OFS202_SHIFT, TMC5041_MSLUT[6], false}) +#define TMC5041_OFS203_MASK 0x00000800 +#define TMC5041_OFS203_SHIFT 11 +#define TMC5041_OFS203_FIELD(motor) ((RegisterField) {TMC5041_OFS203_MASK, TMC5041_OFS203_SHIFT, TMC5041_MSLUT[6], false}) +#define TMC5041_OFS204_MASK 0x00001000 +#define TMC5041_OFS204_SHIFT 12 +#define TMC5041_OFS204_FIELD(motor) ((RegisterField) {TMC5041_OFS204_MASK, TMC5041_OFS204_SHIFT, TMC5041_MSLUT[6], false}) +#define TMC5041_OFS205_MASK 0x00002000 +#define TMC5041_OFS205_SHIFT 13 +#define TMC5041_OFS205_FIELD(motor) ((RegisterField) {TMC5041_OFS205_MASK, TMC5041_OFS205_SHIFT, TMC5041_MSLUT[6], false}) +#define TMC5041_OFS206_MASK 0x00004000 +#define TMC5041_OFS206_SHIFT 14 +#define TMC5041_OFS206_FIELD(motor) ((RegisterField) {TMC5041_OFS206_MASK, TMC5041_OFS206_SHIFT, TMC5041_MSLUT[6], false}) +#define TMC5041_OFS207_MASK 0x00008000 +#define TMC5041_OFS207_SHIFT 15 +#define TMC5041_OFS207_FIELD(motor) ((RegisterField) {TMC5041_OFS207_MASK, TMC5041_OFS207_SHIFT, TMC5041_MSLUT[6], false}) +#define TMC5041_OFS208_MASK 0x00010000 +#define TMC5041_OFS208_SHIFT 16 +#define TMC5041_OFS208_FIELD(motor) ((RegisterField) {TMC5041_OFS208_MASK, TMC5041_OFS208_SHIFT, TMC5041_MSLUT[6], false}) +#define TMC5041_OFS209_MASK 0x00020000 +#define TMC5041_OFS209_SHIFT 17 +#define TMC5041_OFS209_FIELD(motor) ((RegisterField) {TMC5041_OFS209_MASK, TMC5041_OFS209_SHIFT, TMC5041_MSLUT[6], false}) +#define TMC5041_OFS210_MASK 0x00040000 +#define TMC5041_OFS210_SHIFT 18 +#define TMC5041_OFS210_FIELD(motor) ((RegisterField) {TMC5041_OFS210_MASK, TMC5041_OFS210_SHIFT, TMC5041_MSLUT[6], false}) +#define TMC5041_OFS211_MASK 0x00080000 +#define TMC5041_OFS211_SHIFT 19 +#define TMC5041_OFS211_FIELD(motor) ((RegisterField) {TMC5041_OFS211_MASK, TMC5041_OFS211_SHIFT, TMC5041_MSLUT[6], false}) +#define TMC5041_OFS212_MASK 0x00100000 +#define TMC5041_OFS212_SHIFT 20 +#define TMC5041_OFS212_FIELD(motor) ((RegisterField) {TMC5041_OFS212_MASK, TMC5041_OFS212_SHIFT, TMC5041_MSLUT[6], false}) +#define TMC5041_OFS213_MASK 0x00200000 +#define TMC5041_OFS213_SHIFT 21 +#define TMC5041_OFS213_FIELD(motor) ((RegisterField) {TMC5041_OFS213_MASK, TMC5041_OFS213_SHIFT, TMC5041_MSLUT[6], false}) +#define TMC5041_OFS214_MASK 0x00400000 +#define TMC5041_OFS214_SHIFT 22 +#define TMC5041_OFS214_FIELD(motor) ((RegisterField) {TMC5041_OFS214_MASK, TMC5041_OFS214_SHIFT, TMC5041_MSLUT[6], false}) +#define TMC5041_OFS215_MASK 0x00800000 +#define TMC5041_OFS215_SHIFT 23 +#define TMC5041_OFS215_FIELD(motor) ((RegisterField) {TMC5041_OFS215_MASK, TMC5041_OFS215_SHIFT, TMC5041_MSLUT[6], false}) +#define TMC5041_OFS216_MASK 0x01000000 +#define TMC5041_OFS216_SHIFT 24 +#define TMC5041_OFS216_FIELD(motor) ((RegisterField) {TMC5041_OFS216_MASK, TMC5041_OFS216_SHIFT, TMC5041_MSLUT[6], false}) +#define TMC5041_OFS217_MASK 0x02000000 +#define TMC5041_OFS217_SHIFT 25 +#define TMC5041_OFS217_FIELD(motor) ((RegisterField) {TMC5041_OFS217_MASK, TMC5041_OFS217_SHIFT, TMC5041_MSLUT[6], false}) +#define TMC5041_OFS218_MASK 0x04000000 +#define TMC5041_OFS218_SHIFT 26 +#define TMC5041_OFS218_FIELD(motor) ((RegisterField) {TMC5041_OFS218_MASK, TMC5041_OFS218_SHIFT, TMC5041_MSLUT[6], false}) +#define TMC5041_OFS219_MASK 0x08000000 +#define TMC5041_OFS219_SHIFT 27 +#define TMC5041_OFS219_FIELD(motor) ((RegisterField) {TMC5041_OFS219_MASK, TMC5041_OFS219_SHIFT, TMC5041_MSLUT[6], false}) +#define TMC5041_OFS220_MASK 0x10000000 +#define TMC5041_OFS220_SHIFT 28 +#define TMC5041_OFS220_FIELD(motor) ((RegisterField) {TMC5041_OFS220_MASK, TMC5041_OFS220_SHIFT, TMC5041_MSLUT[6], false}) +#define TMC5041_OFS221_MASK 0x20000000 +#define TMC5041_OFS221_SHIFT 29 +#define TMC5041_OFS221_FIELD(motor) ((RegisterField) {TMC5041_OFS221_MASK, TMC5041_OFS221_SHIFT, TMC5041_MSLUT[6], false}) +#define TMC5041_OFS222_MASK 0x40000000 +#define TMC5041_OFS222_SHIFT 30 +#define TMC5041_OFS222_FIELD(motor) ((RegisterField) {TMC5041_OFS222_MASK, TMC5041_OFS222_SHIFT, TMC5041_MSLUT[6], false}) +#define TMC5041_OFS223_MASK 0x80000000 +#define TMC5041_OFS223_SHIFT 31 +#define TMC5041_OFS223_FIELD(motor) ((RegisterField) {TMC5041_OFS223_MASK, TMC5041_OFS223_SHIFT, TMC5041_MSLUT[6], false}) +#define TMC5041_OFS224_MASK 0x00000001 +#define TMC5041_OFS224_SHIFT 0 +#define TMC5041_OFS224_FIELD(motor) ((RegisterField) {TMC5041_OFS224_MASK, TMC5041_OFS224_SHIFT, TMC5041_MSLUT[7], false}) +#define TMC5041_OFS225_MASK 0x00000002 +#define TMC5041_OFS225_SHIFT 1 +#define TMC5041_OFS225_FIELD(motor) ((RegisterField) {TMC5041_OFS225_MASK, TMC5041_OFS225_SHIFT, TMC5041_MSLUT[7], false}) +#define TMC5041_OFS226_MASK 0x00000004 +#define TMC5041_OFS226_SHIFT 2 +#define TMC5041_OFS226_FIELD(motor) ((RegisterField) {TMC5041_OFS226_MASK, TMC5041_OFS226_SHIFT, TMC5041_MSLUT[7], false}) +#define TMC5041_OFS227_MASK 0x00000008 +#define TMC5041_OFS227_SHIFT 3 +#define TMC5041_OFS227_FIELD(motor) ((RegisterField) {TMC5041_OFS227_MASK, TMC5041_OFS227_SHIFT, TMC5041_MSLUT[7], false}) +#define TMC5041_OFS228_MASK 0x00000010 +#define TMC5041_OFS228_SHIFT 4 +#define TMC5041_OFS228_FIELD(motor) ((RegisterField) {TMC5041_OFS228_MASK, TMC5041_OFS228_SHIFT, TMC5041_MSLUT[7], false}) +#define TMC5041_OFS229_MASK 0x00000020 +#define TMC5041_OFS229_SHIFT 5 +#define TMC5041_OFS229_FIELD(motor) ((RegisterField) {TMC5041_OFS229_MASK, TMC5041_OFS229_SHIFT, TMC5041_MSLUT[7], false}) +#define TMC5041_OFS230_MASK 0x00000040 +#define TMC5041_OFS230_SHIFT 6 +#define TMC5041_OFS230_FIELD(motor) ((RegisterField) {TMC5041_OFS230_MASK, TMC5041_OFS230_SHIFT, TMC5041_MSLUT[7], false}) +#define TMC5041_OFS231_MASK 0x00000080 +#define TMC5041_OFS231_SHIFT 7 +#define TMC5041_OFS231_FIELD(motor) ((RegisterField) {TMC5041_OFS231_MASK, TMC5041_OFS231_SHIFT, TMC5041_MSLUT[7], false}) +#define TMC5041_OFS232_MASK 0x00000100 +#define TMC5041_OFS232_SHIFT 8 +#define TMC5041_OFS232_FIELD(motor) ((RegisterField) {TMC5041_OFS232_MASK, TMC5041_OFS232_SHIFT, TMC5041_MSLUT[7], false}) +#define TMC5041_OFS233_MASK 0x00000200 +#define TMC5041_OFS233_SHIFT 9 +#define TMC5041_OFS233_FIELD(motor) ((RegisterField) {TMC5041_OFS233_MASK, TMC5041_OFS233_SHIFT, TMC5041_MSLUT[7], false}) +#define TMC5041_OFS234_MASK 0x00000400 +#define TMC5041_OFS234_SHIFT 10 +#define TMC5041_OFS234_FIELD(motor) ((RegisterField) {TMC5041_OFS234_MASK, TMC5041_OFS234_SHIFT, TMC5041_MSLUT[7], false}) +#define TMC5041_OFS235_MASK 0x00000800 +#define TMC5041_OFS235_SHIFT 11 +#define TMC5041_OFS235_FIELD(motor) ((RegisterField) {TMC5041_OFS235_MASK, TMC5041_OFS235_SHIFT, TMC5041_MSLUT[7], false}) +#define TMC5041_OFS236_MASK 0x00001000 +#define TMC5041_OFS236_SHIFT 12 +#define TMC5041_OFS236_FIELD(motor) ((RegisterField) {TMC5041_OFS236_MASK, TMC5041_OFS236_SHIFT, TMC5041_MSLUT[7], false}) +#define TMC5041_OFS237_MASK 0x00002000 +#define TMC5041_OFS237_SHIFT 13 +#define TMC5041_OFS237_FIELD(motor) ((RegisterField) {TMC5041_OFS237_MASK, TMC5041_OFS237_SHIFT, TMC5041_MSLUT[7], false}) +#define TMC5041_OFS238_MASK 0x00004000 +#define TMC5041_OFS238_SHIFT 14 +#define TMC5041_OFS238_FIELD(motor) ((RegisterField) {TMC5041_OFS238_MASK, TMC5041_OFS238_SHIFT, TMC5041_MSLUT[7], false}) +#define TMC5041_OFS239_MASK 0x00008000 +#define TMC5041_OFS239_SHIFT 15 +#define TMC5041_OFS239_FIELD(motor) ((RegisterField) {TMC5041_OFS239_MASK, TMC5041_OFS239_SHIFT, TMC5041_MSLUT[7], false}) +#define TMC5041_OFS240_MASK 0x00010000 +#define TMC5041_OFS240_SHIFT 16 +#define TMC5041_OFS240_FIELD(motor) ((RegisterField) {TMC5041_OFS240_MASK, TMC5041_OFS240_SHIFT, TMC5041_MSLUT[7], false}) +#define TMC5041_OFS241_MASK 0x00020000 +#define TMC5041_OFS241_SHIFT 17 +#define TMC5041_OFS241_FIELD(motor) ((RegisterField) {TMC5041_OFS241_MASK, TMC5041_OFS241_SHIFT, TMC5041_MSLUT[7], false}) +#define TMC5041_OFS242_MASK 0x00040000 +#define TMC5041_OFS242_SHIFT 18 +#define TMC5041_OFS242_FIELD(motor) ((RegisterField) {TMC5041_OFS242_MASK, TMC5041_OFS242_SHIFT, TMC5041_MSLUT[7], false}) +#define TMC5041_OFS243_MASK 0x00080000 +#define TMC5041_OFS243_SHIFT 19 +#define TMC5041_OFS243_FIELD(motor) ((RegisterField) {TMC5041_OFS243_MASK, TMC5041_OFS243_SHIFT, TMC5041_MSLUT[7], false}) +#define TMC5041_OFS244_MASK 0x00100000 +#define TMC5041_OFS244_SHIFT 20 +#define TMC5041_OFS244_FIELD(motor) ((RegisterField) {TMC5041_OFS244_MASK, TMC5041_OFS244_SHIFT, TMC5041_MSLUT[7], false}) +#define TMC5041_OFS245_MASK 0x00200000 +#define TMC5041_OFS245_SHIFT 21 +#define TMC5041_OFS245_FIELD(motor) ((RegisterField) {TMC5041_OFS245_MASK, TMC5041_OFS245_SHIFT, TMC5041_MSLUT[7], false}) +#define TMC5041_OFS246_MASK 0x00400000 +#define TMC5041_OFS246_SHIFT 22 +#define TMC5041_OFS246_FIELD(motor) ((RegisterField) {TMC5041_OFS246_MASK, TMC5041_OFS246_SHIFT, TMC5041_MSLUT[7], false}) +#define TMC5041_OFS247_MASK 0x00800000 +#define TMC5041_OFS247_SHIFT 23 +#define TMC5041_OFS247_FIELD(motor) ((RegisterField) {TMC5041_OFS247_MASK, TMC5041_OFS247_SHIFT, TMC5041_MSLUT[7], false}) +#define TMC5041_OFS248_MASK 0x01000000 +#define TMC5041_OFS248_SHIFT 24 +#define TMC5041_OFS248_FIELD(motor) ((RegisterField) {TMC5041_OFS248_MASK, TMC5041_OFS248_SHIFT, TMC5041_MSLUT[7], false}) +#define TMC5041_OFS249_MASK 0x02000000 +#define TMC5041_OFS249_SHIFT 25 +#define TMC5041_OFS249_FIELD(motor) ((RegisterField) {TMC5041_OFS249_MASK, TMC5041_OFS249_SHIFT, TMC5041_MSLUT[7], false}) +#define TMC5041_OFS250_MASK 0x04000000 +#define TMC5041_OFS250_SHIFT 26 +#define TMC5041_OFS250_FIELD(motor) ((RegisterField) {TMC5041_OFS250_MASK, TMC5041_OFS250_SHIFT, TMC5041_MSLUT[7], false}) +#define TMC5041_OFS251_MASK 0x08000000 +#define TMC5041_OFS251_SHIFT 27 +#define TMC5041_OFS251_FIELD(motor) ((RegisterField) {TMC5041_OFS251_MASK, TMC5041_OFS251_SHIFT, TMC5041_MSLUT[7], false}) +#define TMC5041_OFS252_MASK 0x10000000 +#define TMC5041_OFS252_SHIFT 28 +#define TMC5041_OFS252_FIELD(motor) ((RegisterField) {TMC5041_OFS252_MASK, TMC5041_OFS252_SHIFT, TMC5041_MSLUT[7], false}) +#define TMC5041_OFS253_MASK 0x20000000 +#define TMC5041_OFS253_SHIFT 29 +#define TMC5041_OFS253_FIELD(motor) ((RegisterField) {TMC5041_OFS253_MASK, TMC5041_OFS253_SHIFT, TMC5041_MSLUT[7], false}) +#define TMC5041_OFS254_MASK 0x40000000 +#define TMC5041_OFS254_SHIFT 30 +#define TMC5041_OFS254_FIELD(motor) ((RegisterField) {TMC5041_OFS254_MASK, TMC5041_OFS254_SHIFT, TMC5041_MSLUT[7], false}) +#define TMC5041_OFS255_MASK 0x80000000 +#define TMC5041_OFS255_SHIFT 31 +#define TMC5041_OFS255_FIELD(motor) ((RegisterField) {TMC5041_OFS255_MASK, TMC5041_OFS255_SHIFT, TMC5041_MSLUT[7], false}) +#define TMC5041_W0_MASK 0x00000003 +#define TMC5041_W0_SHIFT 0 +#define TMC5041_W0_FIELD(motor) ((RegisterField) {TMC5041_W0_MASK, TMC5041_W0_SHIFT, TMC5041_MSLUTSEL, false}) +#define TMC5041_W1_MASK 0x0000000C +#define TMC5041_W1_SHIFT 2 +#define TMC5041_W1_FIELD(motor) ((RegisterField) {TMC5041_W1_MASK, TMC5041_W1_SHIFT, TMC5041_MSLUTSEL, false}) +#define TMC5041_W2_MASK 0x00000030 +#define TMC5041_W2_SHIFT 4 +#define TMC5041_W2_FIELD(motor) ((RegisterField) {TMC5041_W2_MASK, TMC5041_W2_SHIFT, TMC5041_MSLUTSEL, false}) +#define TMC5041_W3_MASK 0x000000C0 +#define TMC5041_W3_SHIFT 6 +#define TMC5041_W3_FIELD(motor) ((RegisterField) {TMC5041_W3_MASK, TMC5041_W3_SHIFT, TMC5041_MSLUTSEL, false}) +#define TMC5041_X1_MASK 0x0000FF00 +#define TMC5041_X1_SHIFT 8 +#define TMC5041_X1_FIELD(motor) ((RegisterField) {TMC5041_X1_MASK, TMC5041_X1_SHIFT, TMC5041_MSLUTSEL, false}) +#define TMC5041_X2_MASK 0x00FF0000 +#define TMC5041_X2_SHIFT 16 +#define TMC5041_X2_FIELD(motor) ((RegisterField) {TMC5041_X2_MASK, TMC5041_X2_SHIFT, TMC5041_MSLUTSEL, false}) +#define TMC5041_X3_MASK 0xFF000000 +#define TMC5041_X3_SHIFT 24 +#define TMC5041_X3_FIELD(motor) ((RegisterField) {TMC5041_X3_MASK, TMC5041_X3_SHIFT, TMC5041_MSLUTSEL, false}) +#define TMC5041_START_SIN_MASK 0x000000FF +#define TMC5041_START_SIN_SHIFT 0 +#define TMC5041_START_SIN_FIELD(motor) ((RegisterField) {TMC5041_START_SIN_MASK, TMC5041_START_SIN_SHIFT, TMC5041_MSLUTSTART, false}) +#define TMC5041_START_SIN90_MASK 0x00FF0000 +#define TMC5041_START_SIN90_SHIFT 16 +#define TMC5041_START_SIN90_FIELD(motor) ((RegisterField) {TMC5041_START_SIN90_MASK, TMC5041_START_SIN90_SHIFT, TMC5041_MSLUTSTART, false}) +#define TMC5041_MSCNT_MASK 0x000003FF +#define TMC5041_MSCNT_SHIFT 0 +#define TMC5041_MSCNT_FIELD(motor) ((RegisterField) {TMC5041_MSCNT_MASK, TMC5041_MSCNT_SHIFT, TMC5041_MSCNT(motor), false}) +#define TMC5041_CUR_A_MASK 0x000001FF +#define TMC5041_CUR_A_SHIFT 0 +#define TMC5041_CUR_A_FIELD(motor) ((RegisterField) {TMC5041_CUR_A_MASK, TMC5041_CUR_A_SHIFT, TMC5041_MSCURACT(motor), true}) +#define TMC5041_CUR_B_MASK 0x01FF0000 +#define TMC5041_CUR_B_SHIFT 16 +#define TMC5041_CUR_B_FIELD(motor) ((RegisterField) {TMC5041_CUR_B_MASK, TMC5041_CUR_B_SHIFT, TMC5041_MSCURACT(motor), true}) +#define TMC5041_TOFF_MASK 0x0000000F +#define TMC5041_TOFF_SHIFT 0 +#define TMC5041_TOFF_FIELD(motor) ((RegisterField) {TMC5041_TOFF_MASK, TMC5041_TOFF_SHIFT, TMC5041_CHOPCONF(motor), false}) +#define TMC5041_TFD_2__0__MASK 0x00000070 +#define TMC5041_TFD_2__0__SHIFT 4 +#define TMC5041_TFD_2__0__FIELD(motor) ((RegisterField) {TMC5041_TFD_2__0__MASK, TMC5041_TFD_2__0__SHIFT, TMC5041_CHOPCONF(motor), false}) +#define TMC5041_OFFSET_MASK 0x00000780 +#define TMC5041_OFFSET_SHIFT 7 +#define TMC5041_OFFSET_FIELD(motor) ((RegisterField) {TMC5041_OFFSET_MASK, TMC5041_OFFSET_SHIFT, TMC5041_CHOPCONF(motor), false}) +#define TMC5041_TFD___MASK 0x00000800 +#define TMC5041_TFD___SHIFT 11 +#define TMC5041_TFD___FIELD(motor) ((RegisterField) {TMC5041_TFD___MASK, TMC5041_TFD___SHIFT, TMC5041_CHOPCONF(motor), false}) +#define TMC5041_DISFDCC_MASK 0x00001000 +#define TMC5041_DISFDCC_SHIFT 12 +#define TMC5041_DISFDCC_FIELD(motor) ((RegisterField) {TMC5041_DISFDCC_MASK, TMC5041_DISFDCC_SHIFT, TMC5041_CHOPCONF(motor), false}) +#define TMC5041_RNDTF_MASK 0x00002000 +#define TMC5041_RNDTF_SHIFT 13 +#define TMC5041_RNDTF_FIELD(motor) ((RegisterField) {TMC5041_RNDTF_MASK, TMC5041_RNDTF_SHIFT, TMC5041_CHOPCONF(motor), false}) +#define TMC5041_CHM_MASK 0x00004000 +#define TMC5041_CHM_SHIFT 14 +#define TMC5041_CHM_FIELD(motor) ((RegisterField) {TMC5041_CHM_MASK, TMC5041_CHM_SHIFT, TMC5041_CHOPCONF(motor), false}) +#define TMC5041_TBL_MASK 0x00018000 +#define TMC5041_TBL_SHIFT 15 +#define TMC5041_TBL_FIELD(motor) ((RegisterField) {TMC5041_TBL_MASK, TMC5041_TBL_SHIFT, TMC5041_CHOPCONF(motor), false}) +#define TMC5041_VSENSE_MASK 0x00020000 +#define TMC5041_VSENSE_SHIFT 17 +#define TMC5041_VSENSE_FIELD(motor) ((RegisterField) {TMC5041_VSENSE_MASK, TMC5041_VSENSE_SHIFT, TMC5041_CHOPCONF(motor), false}) +#define TMC5041_VHIGHFS_MASK 0x00040000 +#define TMC5041_VHIGHFS_SHIFT 18 +#define TMC5041_VHIGHFS_FIELD(motor) ((RegisterField) {TMC5041_VHIGHFS_MASK, TMC5041_VHIGHFS_SHIFT, TMC5041_CHOPCONF(motor), false}) +#define TMC5041_VHIGHCHM_MASK 0x00080000 +#define TMC5041_VHIGHCHM_SHIFT 19 +#define TMC5041_VHIGHCHM_FIELD(motor) ((RegisterField) {TMC5041_VHIGHCHM_MASK, TMC5041_VHIGHCHM_SHIFT, TMC5041_CHOPCONF(motor), false}) +#define TMC5041_SYNC_MASK 0x00F00000 +#define TMC5041_SYNC_SHIFT 20 +#define TMC5041_SYNC_FIELD(motor) ((RegisterField) {TMC5041_SYNC_MASK, TMC5041_SYNC_SHIFT, TMC5041_CHOPCONF(motor), false}) +#define TMC5041_MRES_MASK 0x0F000000 +#define TMC5041_MRES_SHIFT 24 +#define TMC5041_MRES_FIELD(motor) ((RegisterField) {TMC5041_MRES_MASK, TMC5041_MRES_SHIFT, TMC5041_CHOPCONF(motor), false}) +#define TMC5041_DISS2G_MASK 0x40000000 +#define TMC5041_DISS2G_SHIFT 30 +#define TMC5041_DISS2G_FIELD(motor) ((RegisterField) {TMC5041_DISS2G_MASK, TMC5041_DISS2G_SHIFT, TMC5041_CHOPCONF(motor), false}) +#define TMC5041_HSTRT_MASK 0x00000070 +#define TMC5041_HSTRT_SHIFT 4 +#define TMC5041_HSTRT_FIELD(motor) ((RegisterField) {TMC5041_HSTRT_MASK, TMC5041_HSTRT_SHIFT, TMC5041_CHOPCONF(motor), false}) +#define TMC5041_HEND_MASK 0x00000780 +#define TMC5041_HEND_SHIFT 7 +#define TMC5041_HEND_FIELD(motor) ((RegisterField) {TMC5041_HEND_MASK, TMC5041_HEND_SHIFT, TMC5041_CHOPCONF(motor), false}) +#define TMC5041_SEMIN_MASK 0x0000000F +#define TMC5041_SEMIN_SHIFT 0 +#define TMC5041_SEMIN_FIELD(motor) ((RegisterField) {TMC5041_SEMIN_MASK, TMC5041_SEMIN_SHIFT, TMC5041_COOLCONF(motor), false}) +#define TMC5041_SEUP_MASK 0x00000060 +#define TMC5041_SEUP_SHIFT 5 +#define TMC5041_SEUP_FIELD(motor) ((RegisterField) {TMC5041_SEUP_MASK, TMC5041_SEUP_SHIFT, TMC5041_COOLCONF(motor), false}) +#define TMC5041_SEMAX_MASK 0x00000F00 +#define TMC5041_SEMAX_SHIFT 8 +#define TMC5041_SEMAX_FIELD(motor) ((RegisterField) {TMC5041_SEMAX_MASK, TMC5041_SEMAX_SHIFT, TMC5041_COOLCONF(motor), false}) +#define TMC5041_SEDN_MASK 0x00006000 +#define TMC5041_SEDN_SHIFT 13 +#define TMC5041_SEDN_FIELD(motor) ((RegisterField) {TMC5041_SEDN_MASK, TMC5041_SEDN_SHIFT, TMC5041_COOLCONF(motor), false}) +#define TMC5041_SEIMIN_MASK 0x00008000 +#define TMC5041_SEIMIN_SHIFT 15 +#define TMC5041_SEIMIN_FIELD(motor) ((RegisterField) {TMC5041_SEIMIN_MASK, TMC5041_SEIMIN_SHIFT, TMC5041_COOLCONF(motor), false}) +#define TMC5041_SGT_MASK 0x007F0000 +#define TMC5041_SGT_SHIFT 16 +#define TMC5041_SGT_FIELD(motor) ((RegisterField) {TMC5041_SGT_MASK, TMC5041_SGT_SHIFT, TMC5041_COOLCONF(motor), true}) +#define TMC5041_SFILT_MASK 0x01000000 +#define TMC5041_SFILT_SHIFT 24 +#define TMC5041_SFILT_FIELD(motor) ((RegisterField) {TMC5041_SFILT_MASK, TMC5041_SFILT_SHIFT, TMC5041_COOLCONF(motor), false}) +#define TMC5041_DC_TIME_MASK 0x000003FF +#define TMC5041_DC_TIME_SHIFT 0 +#define TMC5041_DC_TIME_FIELD(motor) ((RegisterField) {TMC5041_DC_TIME_MASK, TMC5041_DC_TIME_SHIFT, TMC5041_DCCTRL(motor), false}) +#define TMC5041_DC_SG_MASK 0x00FF0000 +#define TMC5041_DC_SG_SHIFT 16 +#define TMC5041_DC_SG_FIELD(motor) ((RegisterField) {TMC5041_DC_SG_MASK, TMC5041_DC_SG_SHIFT, TMC5041_DCCTRL(motor), false}) +#define TMC5041_SG_RESULT_MASK 0x000003FF +#define TMC5041_SG_RESULT_SHIFT 0 +#define TMC5041_SG_RESULT_FIELD(motor) ((RegisterField) {TMC5041_SG_RESULT_MASK, TMC5041_SG_RESULT_SHIFT, TMC5041_DRVSTATUS(motor), false}) +#define TMC5041_FSACTIVE_MASK 0x00008000 +#define TMC5041_FSACTIVE_SHIFT 15 +#define TMC5041_FSACTIVE_FIELD(motor) ((RegisterField) {TMC5041_FSACTIVE_MASK, TMC5041_FSACTIVE_SHIFT, TMC5041_DRVSTATUS(motor), false}) +#define TMC5041_CS_ACTUAL_MASK 0x001F0000 +#define TMC5041_CS_ACTUAL_SHIFT 16 +#define TMC5041_CS_ACTUAL_FIELD(motor) ((RegisterField) {TMC5041_CS_ACTUAL_MASK, TMC5041_CS_ACTUAL_SHIFT, TMC5041_DRVSTATUS(motor), false}) +#define TMC5041_STALLGUARD_MASK 0x01000000 +#define TMC5041_STALLGUARD_SHIFT 24 +#define TMC5041_STALLGUARD_FIELD(motor) ((RegisterField) {TMC5041_STALLGUARD_MASK, TMC5041_STALLGUARD_SHIFT, TMC5041_DRVSTATUS(motor), false}) +#define TMC5041_OT_MASK 0x02000000 +#define TMC5041_OT_SHIFT 25 +#define TMC5041_OT_FIELD(motor) ((RegisterField) {TMC5041_OT_MASK, TMC5041_OT_SHIFT, TMC5041_DRVSTATUS(motor), false}) +#define TMC5041_OTPW_MASK 0x04000000 +#define TMC5041_OTPW_SHIFT 26 +#define TMC5041_OTPW_FIELD(motor) ((RegisterField) {TMC5041_OTPW_MASK, TMC5041_OTPW_SHIFT, TMC5041_DRVSTATUS(motor), false}) +#define TMC5041_S2GA_MASK 0x08000000 +#define TMC5041_S2GA_SHIFT 27 +#define TMC5041_S2GA_FIELD(motor) ((RegisterField) {TMC5041_S2GA_MASK, TMC5041_S2GA_SHIFT, TMC5041_DRVSTATUS(motor), false}) +#define TMC5041_S2GB_MASK 0x10000000 +#define TMC5041_S2GB_SHIFT 28 +#define TMC5041_S2GB_FIELD(motor) ((RegisterField) {TMC5041_S2GB_MASK, TMC5041_S2GB_SHIFT, TMC5041_DRVSTATUS(motor), false}) +#define TMC5041_OLA_MASK 0x20000000 +#define TMC5041_OLA_SHIFT 29 +#define TMC5041_OLA_FIELD(motor) ((RegisterField) {TMC5041_OLA_MASK, TMC5041_OLA_SHIFT, TMC5041_DRVSTATUS(motor), false}) +#define TMC5041_OLB_MASK 0x40000000 +#define TMC5041_OLB_SHIFT 30 +#define TMC5041_OLB_FIELD(motor) ((RegisterField) {TMC5041_OLB_MASK, TMC5041_OLB_SHIFT, TMC5041_DRVSTATUS(motor), false}) +#define TMC5041_STST_MASK 0x80000000 +#define TMC5041_STST_SHIFT 31 +#define TMC5041_STST_FIELD(motor) ((RegisterField) {TMC5041_STST_MASK, TMC5041_STST_SHIFT, TMC5041_DRVSTATUS(motor), false}) + +#endif diff --git a/firmware/lib/tmc/ic/TMC5041/registercall_hierarchy_flowchart_SPI.svg b/firmware/lib/tmc/ic/TMC5041/registercall_hierarchy_flowchart_SPI.svg new file mode 100755 index 0000000..cbad58f --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5041/registercall_hierarchy_flowchart_SPI.svg @@ -0,0 +1,3 @@ + + +

HAL

HAL

APP (Eval)

APP (Eval)

API

API
Read a register
  •  Call tmcXXXX_readRegister function
Read a register...
Returns the register read value
Returns the register read value
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
tmcXXXX.c
tmcXXXX.c
SPI.c
SPI.c
tmcXXXX_eval.c
tmcXXXX_eval.c

 Implementation of SPI_readWrite
  • Sends and receives bytes on the SPI bus
Implementation of SPI_readWrite...
Returns the raw reply data
Returns the raw reply data

Implementation of tmcXXXX_readWriteSPI
  • Sets the CSN pin to LOW
  • Takes the array of data to write
  • Calls hardware function SPI_readWrite
  • Upon completion of data transfer,
    sets CSN to 
    HIGH
Implementation of tmcXXXX_readWriteSPI...
Passes on the raw reply data to the API
Passes on the raw reply data to the API
Implementation of readRegisterSPI
  • Constructs the datagram
  • Calls HAL wrapper function 
Implementation of readRegisterSPI...
tmcXXXX_readWriteSPI
tmcXXXX_readWriteSPI
Parses the reply and returns the register value
Parses the reply and returns the register value
Implementation of tmcXXXX_readRegister 
  • Check which bus is active SPI/UART. (e.g. SPI)
  • Calls bus-specific function (e.g. readRegisterSPI)
 
Implementation of tmcXXXX_readRegister...
Returns the register read value
Returns the register read value
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC5041/uml-tmc-api.svg b/firmware/lib/tmc/ic/TMC5041/uml-tmc-api.svg new file mode 100755 index 0000000..5a5f8dd --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5041/uml-tmc-api.svg @@ -0,0 +1,3 @@ + + +

TMCXXXX_HW_Abstraction.h



TMCXXXX_HW_Abstraction.h...
// Constants
#define TMCXXXX_MOTORS              
                          
// Register definitions
#define TMCXXXX_GCONF        
                          ⋮
// Register fields definitions
#define TMCXXXX_GCONF_OTPW_FIELD
                     
// Constants...

TMCXXXX.h



TMCXXXX.h...
extern void tmcXXXX_readWriteSPI();
extern void tmcXXXX_readWriteUART();
extern TMCXXXXBusType tmcXXXX_getBusType();
extern uint8_t tmcXXXX_getNodeAddress();
                                  ⋮
tmcXXXX_readRegister();
tmcXXXX_writeRegister();
                                  ⋮
extern void tmcXXXX_readWriteSPI();...

TMCXXXX.c



TMCXXXX.c...
const uint8_t tmcCRCTable_Poly7Reflected[256] = {...};
int32_t tmcXXXX_readRegister(){
/* Call tmcXXXX_getBusType();
 * Based on bus type, call readRegisterSPI/UART() that
 * further calls tmcXXXX_readWriteSPI/UART();
 * For UART it also calls tmcXXXX_getNodeAddress();
                                           ⋮
}
                                           ⋮
const uint8_t tmcCRCTable_Poly7Reflected[256] = {.....
TMC-API
TMC-API

TMCXXXX_Simple_Rotation.h


TMCXXXX_Simple_Rotation.h...
void initAllMotors();
             ⋮
  
void initAllMotors()...

TMCXXXX_Simple_Rotation.c


TMCXXXX_Simple_Rotation.c...
void initAllMotors(){

// Configuring registers to enable motor drivers etc..
tmcXXXX_writeRegister();
                    ⋮
}
                    ⋮
void initAllMotors(){...
Examples
Examples
User Project
User Project

User_Project.h


User_Project.h

User_Project.c








User_Project.c...

void tmcXXXX_readWriteSPI(){
                           ⋮
}
void tmcXXXX_readWriteUART(){
                           ⋮
}
TMCXXXXBusType tmcXXXX_getBusType(){
                           ⋮
}
uint8_t tmcXXXX_getNodeAddress(){
                           ⋮
}

// User Code
                           ⋮
void tmcXXXX_readWriteSPI(){...
#include "TMCXXXX_HW_Abstraction.h"
#include "TMCXXXX.h"
#include "TMCXXXX_Simple_Rotation.h"
                                ⋮
TMCXXXXBusType bus = IC_BUS_SPI/UART;
uint8_t nodeAddress = <nodeAddress>;
                                ⋮
#include "TMCXXXX_HW_Abstraction.h"...
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC5062/README.md b/firmware/lib/tmc/ic/TMC5062/README.md new file mode 100755 index 0000000..82282ab --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5062/README.md @@ -0,0 +1,69 @@ +# TMC5062 + + +## How to use + +To access the TMC5062's registers, the TMC-API offers two functions: **tmc5062_readRegister** and **tmc5062_writeRegister**. +Each of these functions takes in an **icID**, which is used to identify the IC when multiple ICs are connected. This identifier is passed down to the callback functions (see How to Integrate). + +## How to integrate: overview + +1. Include all the files of the TMC-API/ic/tmc/TMC5062 folder into the custom project. +2. Include the TMC5062.h file in the custom source code. +3. Implement the necessary callback functions (see below). +4. (optional): Take a look at the Examples subfolder for ready-made examples of the TMC-API usage. + +## Accessing the TMC5062 via UART +The following diagram depicts how to access the TMC5062 via UART using the TMC-API. + +![screenshot](registercall_hierarchy_flowchart_UART.svg) + +The description of the functions, in the above flowchart, are as follows: +- The functions tmc5062_readRegister and tmc5062_writeRegister are used to read and write the registers respectively. These functions check the current active bus and calls the bus-specific function i.e readRegisterUART or writeRegisterUART. +- These bus specific functions constructs the datagram and further calls the bus specific callback 'tmcXXXX_readWriteUART. +- This callback function further calls the hardware specific read/write function for UART and needs to be implemented externally. + +### How to integrate: Callback functions +To communicate with TMC5062 IC, the TMC-API library needs to know which bus (UART, SPI) it shall use. For that, the callback function **'tmc5062_getBusType()'** needs to be implemented. +Additionally, implement the following callback functions to access the chip via UART: +1. **tmc5062_readWriteUART()**, which is a HAL wrapper function that provides the necessary hardware access. + +### Sharing the CRC table with other TMC-API chips +The TMC5062 UART protocol uses an 8 bit CRC. For calculating this, a table-based algorithm is used. This table (tmcCRCTable_Poly7Reflected[256]) is 256 bytes big and identical across multiple different Trinamic chips (i.e. TMC2209). +If multiple Trinamic chips are being used in the same project, avoiding redundant copies of this table could save memory. It is possible to substitute this CRC table with another CRC table. + +### Necessary hardware modification to use UART +To use UART with the Eval-Kit: pin 39 (DIO17) and 40 (DIO18) should be connected with a 1k ohm resistor. Bend pin 39 (DIO17) on the EVAl Board side of the Eselsbrücke out. +Optional: Bend pin 41 (DIO19) out and connect it to 3.3V / 2= 1.65V. You can reach this by making a volage-divider with two 1k ohm resistors. One to 3.3V and one to GND. This can improve the signal quality. + +## Accessing the TMC5062 via SPI +The following diagram depicts how to access the TMC5062 via SPI using the TMC-API. + +![screenshot](registercall_hierarchy_flowchart_SPI.svg) + +The description of the functions, in the above flowchart, are as follows: +- The functions tmc5062_readRegister and tmc5062_writeRegister are used to read and write the registers respectively. These functions check the current active bus and calls the bus-specific function i.e readRegisterSPI or writeRegisterSPI. +- These bus specific functions constructs the datagram and further calls the bus specific callback 'tmcXXXX_readWriteSPI. +- This callback function further calls the hardware specific read/write function for SPI and needs to be implemented externally. + +### How to integrate: Callback functions +To communicate with TMC5062 IC, the TMC-API library needs to know which bus (UART, SPI) it shall use. For that, the callback function **'tmc5062_getBusType()'** needs to be implemented. +Additionally, implement the following callback functions to access the chip via SPI: +1. **tmc5062_readWriteSPI()**, which is a HAL wrapper function that provides the necessary hardware access. This function should also set the chip select pin CSN to low before starting the data transfer and set to high upon completion. Please refer to the datasheet of the IC for further details. + +### Option to use the cache logic for Write-Only registers +The chip features write-only registers that are unable to be read, necessitating the creation of a shadow copy to cache their contents. This copy is automatically updated whenever data is written to these registers. This cache logic could be enabled by setting the macro **TMC5062_CACHE** to **'1'** or disabled by setting to **'0'** respectively. If this feature is enabled then there comes another option to use **tmc5062_cache** function, which is already implemeted in the API, by defining **TMC5062_ENABLE_TMC_CACHE** macro to **'1'** or one can implement their own function. The function **tmc5062_cache** works for both reading from and writing to the shadow array. It first checks whether the register has write-only access and data needs to be read from the hadow copy. On the basis of that, it returns **true** or **false**. The shadowRegisters on the premade cache implementation need to be one per chip. **TMC5062_IC_CACHE_COUNT** is set to '1' by default and is user-overwritable. If multiple chips are being used in the same project, increment its value to the number of chips connected. + +## Further info +### Dependency graph for the ICs with new register R/W mechanism +This graph illustrates the relationships between files within the TMC-API library, highlighting dependencies and identifying the files that are essential for integrating the library into the custom projects. + +![screenshot](uml-tmc-api.svg) + +### Example usage: TMC-Evalsystem +**For a reference usage of the TMC-API**, visit the [TMC-Evalsystem](https://github.com/analogdevicesinc/TMC-EvalSystem) + +## Migration status +The TMC5062 has been reworked to the access system described above. For more infos on the status of this and other ICs, check out the [migration page](https://github.com/analogdevicesinc/TMC-API/issues/53). + + diff --git a/firmware/lib/tmc/ic/TMC5062/TMC5062.c b/firmware/lib/tmc/ic/TMC5062/TMC5062.c new file mode 100755 index 0000000..66da376 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5062/TMC5062.c @@ -0,0 +1,313 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#include "TMC5062.h" + + +#ifdef TMC_API_EXTERNAL_CRC_TABLE +extern const uint8_t tmcCRCTable_Poly7Reflected[256]; +#else +const uint8_t tmcCRCTable_Poly7Reflected[256] = { + 0x00, 0x91, 0xE3, 0x72, 0x07, 0x96, 0xE4, 0x75, 0x0E, 0x9F, 0xED, 0x7C, 0x09, 0x98, 0xEA, 0x7B, + 0x1C, 0x8D, 0xFF, 0x6E, 0x1B, 0x8A, 0xF8, 0x69, 0x12, 0x83, 0xF1, 0x60, 0x15, 0x84, 0xF6, 0x67, + 0x38, 0xA9, 0xDB, 0x4A, 0x3F, 0xAE, 0xDC, 0x4D, 0x36, 0xA7, 0xD5, 0x44, 0x31, 0xA0, 0xD2, 0x43, + 0x24, 0xB5, 0xC7, 0x56, 0x23, 0xB2, 0xC0, 0x51, 0x2A, 0xBB, 0xC9, 0x58, 0x2D, 0xBC, 0xCE, 0x5F, + 0x70, 0xE1, 0x93, 0x02, 0x77, 0xE6, 0x94, 0x05, 0x7E, 0xEF, 0x9D, 0x0C, 0x79, 0xE8, 0x9A, 0x0B, + 0x6C, 0xFD, 0x8F, 0x1E, 0x6B, 0xFA, 0x88, 0x19, 0x62, 0xF3, 0x81, 0x10, 0x65, 0xF4, 0x86, 0x17, + 0x48, 0xD9, 0xAB, 0x3A, 0x4F, 0xDE, 0xAC, 0x3D, 0x46, 0xD7, 0xA5, 0x34, 0x41, 0xD0, 0xA2, 0x33, + 0x54, 0xC5, 0xB7, 0x26, 0x53, 0xC2, 0xB0, 0x21, 0x5A, 0xCB, 0xB9, 0x28, 0x5D, 0xCC, 0xBE, 0x2F, + 0xE0, 0x71, 0x03, 0x92, 0xE7, 0x76, 0x04, 0x95, 0xEE, 0x7F, 0x0D, 0x9C, 0xE9, 0x78, 0x0A, 0x9B, + 0xFC, 0x6D, 0x1F, 0x8E, 0xFB, 0x6A, 0x18, 0x89, 0xF2, 0x63, 0x11, 0x80, 0xF5, 0x64, 0x16, 0x87, + 0xD8, 0x49, 0x3B, 0xAA, 0xDF, 0x4E, 0x3C, 0xAD, 0xD6, 0x47, 0x35, 0xA4, 0xD1, 0x40, 0x32, 0xA3, + 0xC4, 0x55, 0x27, 0xB6, 0xC3, 0x52, 0x20, 0xB1, 0xCA, 0x5B, 0x29, 0xB8, 0xCD, 0x5C, 0x2E, 0xBF, + 0x90, 0x01, 0x73, 0xE2, 0x97, 0x06, 0x74, 0xE5, 0x9E, 0x0F, 0x7D, 0xEC, 0x99, 0x08, 0x7A, 0xEB, + 0x8C, 0x1D, 0x6F, 0xFE, 0x8B, 0x1A, 0x68, 0xF9, 0x82, 0x13, 0x61, 0xF0, 0x85, 0x14, 0x66, 0xF7, + 0xA8, 0x39, 0x4B, 0xDA, 0xAF, 0x3E, 0x4C, 0xDD, 0xA6, 0x37, 0x45, 0xD4, 0xA1, 0x30, 0x42, 0xD3, + 0xB4, 0x25, 0x57, 0xC6, 0xB3, 0x22, 0x50, 0xC1, 0xBA, 0x2B, 0x59, 0xC8, 0xBD, 0x2C, 0x5E, 0xCF, +}; +#endif +/**************************************************************** Cache Implementation *************************************************************************/ +#if TMC5062_CACHE == 0 +static inline bool tmc5062_cache(uint16_t icID, TMC5062CacheOp operation, uint8_t address, uint32_t *value) +{ + UNUSED(icID); + UNUSED(address); + UNUSED(operation); + return false; +} +#else +#if TMC5062_ENABLE_TMC_CACHE == 1 +uint8_t tmc5062_dirtyBits[TMC5062_IC_CACHE_COUNT][TMC5062_REGISTER_COUNT/8]= {0}; +int32_t tmc5062_shadowRegister[TMC5062_IC_CACHE_COUNT][TMC5062_REGISTER_COUNT]; + +void tmc5062_setDirtyBit(uint16_t icID, uint8_t index, bool value) +{ + if(index >= TMC5062_REGISTER_COUNT) + return; + + uint8_t *tmp = &tmc5062_dirtyBits[icID][index / 8]; + uint8_t shift = (index % 8); + uint8_t mask = 1 << shift; + *tmp = (((*tmp) & (~(mask))) | (((value) << (shift)) & (mask))); +} + +bool tmc5062_getDirtyBit(uint16_t icID, uint8_t index) +{ + if(index >= TMC5062_REGISTER_COUNT) + return false; + + uint8_t *tmp = &tmc5062_dirtyBits[icID][index / 8]; + uint8_t shift = (index % 8); + return ((*tmp) >> shift) & 1; + } + +/* + * This function is used to cache the value written to the Write-Only registers in the form of shadow array. + * The shadow copy is then used to read these kinds of registers. + */ +bool tmc5062_cache(uint16_t icID, TMC5062CacheOp operation, uint8_t address, uint32_t *value) +{ + if (operation == TMC5062_CACHE_READ) + { + // Check if the value should come from cache + + // Only supported chips have a cache + if (icID >= TMC5062_IC_CACHE_COUNT) + return false; + + // Only non-readable registers care about caching + // Note: This could also be used to cache i.e. RW config registers to reduce bus accesses + if (TMC5062_IS_READABLE(tmc5062_registerAccess[address])) + return false; + + // Grab the value from the cache + *value = tmc5062_shadowRegister[icID][address]; + return true; + } + else if (operation == TMC5062_CACHE_WRITE || operation == TMC5062_CACHE_FILL_DEFAULT) + { + // Fill the cache + + // only supported chips have a cache + if (icID >= TMC5062_IC_CACHE_COUNT) + return false; + + // Write to the shadow register and mark the register dirty + tmc5062_shadowRegister[icID][address] = *value; + + if (operation == TMC5062_CACHE_WRITE) + { + tmc5062_setDirtyBit(icID, address, true); + } + + return true; + } + return false; +} +void tmc5062_initCache() +{ + // Check if we have constants defined + if(ARRAY_SIZE(tmc5062_RegisterConstants) == 0) + return; + + size_t i, j, id; + + + for(i = 0, j = 0; i < TMC5062_REGISTER_COUNT; i++) + { + // We only need to worry about hardware preset, write-only registers + // that have not yet been written (no dirty bit) here. + if(tmc5062_registerAccess[i] != TMC5062_ACCESS_W_PRESET) + continue; + + // Search the constant list for the current address. With the constant + // list being sorted in ascended order, we can walk through the list + // until the entry with an address equal or greater than i + while(j < ARRAY_SIZE(tmc5062_RegisterConstants) && (tmc5062_RegisterConstants[j].address < i)) + j++; + + // Abort when we reach the end of the constant list + if (j == ARRAY_SIZE(tmc5062_RegisterConstants)) + break; + + // If we have an entry for our current address, write the constant + if(tmc5062_RegisterConstants[j].address == i) + { + for (id = 0; id < TMC5062_IC_CACHE_COUNT; id++) + { + uint32_t temp = tmc5062_RegisterConstants[j].value; + tmc5062_cache(id, TMC5062_CACHE_FILL_DEFAULT, i, &temp); + } + } + } + + +} + +#else +// User must implement their own cache +extern bool tmc5062_cache(uint16_t icID, TMC5062CacheOp operation, uint8_t address, uint32_t *value); +#endif +#endif + +/************************************************************** Register read / write Implementation ******************************************************************/ +static int32_t readRegisterSPI(uint16_t icID, uint8_t address); +static void writeRegisterSPI(uint16_t icID, uint8_t address, int32_t value); +static int32_t readRegisterUART(uint16_t icID, uint8_t registerAddress); +static void writeRegisterUART(uint16_t icID, uint8_t registerAddress, int32_t value); +static uint8_t CRC8(uint8_t *data, uint32_t bytes); + + +int32_t tmc5062_readRegister(uint16_t icID, uint8_t address) +{ + uint32_t value; + + // Read from cache for registers with write-only access + if (tmc5062_cache(icID, TMC5062_CACHE_READ, address, &value)) + return value; + + TMC5062BusType bus = tmc5062_getBusType(icID); + + if(bus == IC_BUS_SPI) + { + return readRegisterSPI(icID, address); + } + else if (bus == IC_BUS_UART) + { + return readRegisterUART(icID, address); + } + + //ToDo: Error handling + return -1; +} + +void tmc5062_writeRegister(uint16_t icID, uint8_t address, int32_t value) +{ + TMC5062BusType bus = tmc5062_getBusType(icID); + + if(bus == IC_BUS_SPI) + { + writeRegisterSPI(icID, address, value); + } + else if(bus == IC_BUS_UART) + { + writeRegisterUART(icID, address, value); + } +} + +int32_t readRegisterSPI(uint16_t icID, uint8_t address) +{ + address = address & TMC5062_ADDRESS_MASK; + + uint8_t data[5] = { 0 }; + + // clear write bit + data[0] = address; + + // Send the read request + tmc5062_readWriteSPI(icID, &data[0], sizeof(data)); + + // Rewrite address and clear write bit + data[0] = address; + + // Send another request to receive the read reply + tmc5062_readWriteSPI(icID, &data[0], sizeof(data)); + + return ((uint32_t)data[1] << 24) | ((uint32_t) data[2] << 16) | ( data[3] << 8) | ( data[4]); +} + +void writeRegisterSPI(uint16_t icID, uint8_t address, int32_t value) +{ + uint8_t data[5] = { 0 }; + + data[0] = address | TMC5062_WRITE_BIT; + data[1] = 0xFF & (value>>24); + data[2] = 0xFF & (value>>16); + data[3] = 0xFF & (value>>8); + data[4] = 0xFF & (value>>0); + + // Send the write request + tmc5062_readWriteSPI(icID, &data[0], sizeof(data)); + + //Cache the registers with write-only access + tmc5062_cache(icID, TMC5062_CACHE_WRITE, address, (uint32_t *)&value); +} + +int32_t readRegisterUART(uint16_t icID, uint8_t address) +{ + uint8_t data[7] = { 0 }; + + address = address & TMC5062_ADDRESS_MASK; + + data[0] = 0x05; + data[1] = address; + data[2] = CRC8(data, 2); + + if (!tmc5062_readWriteUART(icID, &data[0], 3, 7)) + return 0; + + // Byte 0: Sync nibble correct? + if (data[0] != 0xF5) + return 0; + + // Byte 1: Master address correct? + if (data[1] != address) + return 0; + + // Byte 7: CRC correct? + if (data[6] != CRC8(data, 6)) + return 0; + + return ((uint32_t)data[2] << 24) | ((uint32_t)data[3] << 16) | (data[4] << 8) | data[5]; +} + +void writeRegisterUART(uint16_t icID, uint8_t address, int32_t value) +{ + uint8_t data[7]; + + data[0] = 0x05; + data[1] = address | TMC5062_WRITE_BIT; + data[2] = (value >> 24) & 0xFF; + data[3] = (value >> 16) & 0xFF; + data[4] = (value >> 8 ) & 0xFF; + data[5] = (value ) & 0xFF; + data[6] = CRC8(data, 6); + + tmc5062_readWriteUART(icID, &data[0], 7, 0); + + //Cache the registers with write-only access + tmc5062_cache(icID, TMC5062_CACHE_WRITE, address, (uint32_t *)&value); +} + +void tmc5062_rotateMotor(uint16_t icID, uint8_t motor, int32_t velocity) +{ + if(motor >= TMC5062_MOTORS) + return; + + tmc5062_writeRegister(icID, TMC5062_VMAX(motor), (velocity < 0) ? -velocity : velocity); + tmc5062_fieldWrite(icID, TMC5062_RAMPMODE_FIELD(motor), (velocity >= 0) ? TMC5062_MODE_VELPOS : TMC5062_MODE_VELNEG); +} + +static uint8_t CRC8(uint8_t *data, uint32_t bytes) +{ + uint8_t result = 0; + + while(bytes--) + result = tmcCRCTable_Poly7Reflected[result ^ *data++]; + + // Flip the result around + // swap odd and even bits + result = ((result >> 1) & 0x55) | ((result & 0x55) << 1); + // swap consecutive pairs + result = ((result >> 2) & 0x33) | ((result & 0x33) << 2); + // swap nibbles ... + result = ((result >> 4) & 0x0F) | ((result & 0x0F) << 4); + + return result; +} diff --git a/firmware/lib/tmc/ic/TMC5062/TMC5062.h b/firmware/lib/tmc/ic/TMC5062/TMC5062.h new file mode 100755 index 0000000..9296f5a --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5062/TMC5062.h @@ -0,0 +1,252 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#ifndef TMC_IC_TMC5062_H_ +#define TMC_IC_TMC5062_H_ + +#include +#include +#include +#include "TMC5062_HW_Abstraction.h" + +/******************************************************************************* +* API Configuration Defines +* These control optional features of the TMC-API implementation. +* These can be commented in/out here or defined from the build system. +*******************************************************************************/ + +// Uncomment if you want to save space..... +// and put the table into your own .c file +//#define TMC_API_EXTERNAL_CRC_TABLE 1 + +#ifndef TMC5062_CACHE +#define TMC5062_CACHE 1 +//#define TMC5062_CACHE 0 +#endif + +// To use the caching mechanism already implemented by the TMC-API, set TMC5062_ENABLE_TMC_CACHE to '1'. +// Set TMC5062_ENABLE_TMC_CACHE to '0' if one wants to have their own cache implementation. +#ifndef TMC5062_ENABLE_TMC_CACHE +#define TMC5062_ENABLE_TMC_CACHE 1 +//#define TMC5062_ENABLE_TMC_CACHE 0 +#endif + +/******************************************************************************/ + +typedef enum { + IC_BUS_SPI, + IC_BUS_UART, +} TMC5062BusType; + +typedef struct { + uint32_t LUT_0; // Bits 0 - 31 + uint32_t LUT_1; // Bits 32 - 63 + uint32_t LUT_2; // Bits 64 - 95 + uint32_t LUT_3; // Bits 96 - 127 + uint32_t LUT_4; // Bits 128 - 159 + uint32_t LUT_5; // Bits 160 - 191 + uint32_t LUT_6; // Bits 192 - 223 + uint32_t LUT_7; // Bits 224 - 255 + + uint8_t X1; // Segment 1 + uint8_t X2; // Segment 2 + uint8_t X3; // Segment 3 + // Segment width. Determines bit meaning (Actual bit value = (Wn - 1) + bit) + uint8_t W0 : 2; // Segment [ 0 : X1-1] + uint8_t W1 : 2; // Segment [X1 : X2-1] + uint8_t W2 : 2; // Segment [X2 : X3-1] + uint8_t W3 : 2; // Segment [X3 : 255] + + uint8_t START_SIN; // Absolute current at MSLUT[0] + uint8_t START_SIN90; // Absolute current at MSLUT[256] +} TMC5062_MicroStepTable; + +typedef struct +{ + uint32_t mask; + uint8_t shift; + uint8_t address; + bool isSigned; +} RegisterField; + +// => TMC-API wrapper +extern void tmc5062_readWriteSPI(uint16_t icID, uint8_t *data, size_t dataLength); +extern bool tmc5062_readWriteUART(uint16_t icID, uint8_t *data, size_t writeLength, size_t readLength); +extern TMC5062BusType tmc5062_getBusType(uint16_t icID); +// => TMC-API wrapper + +int32_t tmc5062_readRegister(uint16_t icID, uint8_t address); +void tmc5062_writeRegister(uint16_t icID, uint8_t address, int32_t value); +void tmc5062_rotateMotor(uint16_t icID, uint8_t motor, int32_t velocity); + +static inline uint32_t tmc5062_fieldExtract(uint32_t data, RegisterField field) +{ + uint32_t value = (data & field.mask) >> field.shift; + + if (field.isSigned) + { + // Apply signedness conversion + uint32_t baseMask = field.mask >> field.shift; + uint32_t signMask = baseMask & (~baseMask >> 1); + value = (value ^ signMask) - signMask; + } + + return value; +} + +static inline uint32_t tmc5062_fieldRead(uint16_t icID, RegisterField field) +{ + uint32_t value = tmc5062_readRegister(icID, field.address); + + return tmc5062_fieldExtract(value, field); +} + +static inline uint32_t tmc5062_fieldUpdate(uint32_t data, RegisterField field, uint32_t value) +{ + return (data & (~field.mask)) | ((value << field.shift) & field.mask); +} + +static inline void tmc5062_fieldWrite(uint16_t icID, RegisterField field, uint32_t value) +{ + uint32_t regValue = tmc5062_readRegister(icID, field.address); + + regValue = tmc5062_fieldUpdate(regValue, field, value); + + tmc5062_writeRegister(icID, field.address, regValue); +} + +/**************************************************************** Cache Implementation *************************************************************************/ + +#if TMC5062_CACHE == 1 +#if TMC5062_ENABLE_TMC_CACHE == 1 + +// By default, support one IC in the cache +#ifndef TMC5062_IC_CACHE_COUNT +#define TMC5062_IC_CACHE_COUNT 1 +#endif + +typedef enum { + TMC5062_CACHE_READ, + TMC5062_CACHE_WRITE, + + // Special operation: Put content into the cache without marking the entry as dirty. + // Only used to initialize the cache with hardware defaults. This will allow reading + // from write-only registers that have a value inside them on reset. When using this + // operation, a restore will *not* rewrite that filled register! + TMC5062_CACHE_FILL_DEFAULT +} TMC5062CacheOp; + +typedef struct +{ + uint8_t address; + uint32_t value; +} TMC5062RegisterConstants; + +#define TMC5062_ACCESS_DIRTY 0x08 // Register has been written since reset -> shadow register is valid for restore +#define TMC5062_ACCESS_READ 0x01 +#define TMC5062_ACCESS_W_PRESET 0x42 +#define TMC5062_IS_READABLE(x) ((x) & TMC5062_ACCESS_READ) +#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) + +// Default Register Values +#define R30 0x00071703 // IHOLD_IRUN +#define R32 0x00FFFFFF // VHIGH +#define R3A 0x00010000 // ENC_CONST +#define R50 R30 +#define R52 R32 +#define R5A R3A +#define R6C 0x000101D5 // CHOPCONF +#define R7C R6C + +#define ____ 0x00 +#ifndef N_A + #define N_A 0x00 +#endif + +static const int32_t tmc5062_sampleRegisterPreset[TMC5062_REGISTER_COUNT] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x00 - 0x0F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x10 - 0x1F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x20 - 0x2F + R30, 0, R32, 0, 0, 0, 0, 0, 0, 0, R3A, 0, 0, 0, 0, 0, // 0x30 - 0x3F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x40 - 0x4F + R50, 0, R52, 0, 0, 0, 0, 0, 0, 0, R5A, 0, 0, 0, 0, 0, // 0x50 - 0x5F + N_A, N_A, N_A, N_A, N_A, N_A, N_A, N_A, N_A, N_A, 0, 0, R6C, 0, 0, 0, // 0x60 - 0x6F + N_A, N_A, N_A, N_A, N_A, N_A, N_A, N_A, N_A, N_A, 0, 0, R7C, 0, 0, 0 // 0x70 - 0x7F +}; + +// Undefine the default register values. +// This prevents warnings in case multiple TMC-API chip headers are included at once +#undef R30 +#undef R32 +#undef R3A +#undef R50 +#undef R52 +#undef R5A +#undef R6C +#undef R7C + +// Register access permissions: +// 0x00: none (reserved) +// 0x01: read +// 0x02: write +// 0x03: read/write +// 0x13: read/write, separate functions/values for reading or writing +// 0x23: read/write, flag register (write to clear) +// 0x42: write, has hardware presets on reset +static const uint8_t tmc5062_registerAccess[TMC5062_REGISTER_COUNT] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0x03, 0x01, 0x01, 0x02, 0x07, 0x02, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x00 - 0x0F + 0x02, 0x01, ____, ____, ____, ____, ____, ____, 0x02, 0x01, ____, ____, ____, ____, ____, ____, // 0x10 - 0x1F + 0x03, 0x03, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, ____, ____, // 0x20 - 0x2F + 0x02, 0x02, 0x02, 0x02, 0x03, 0x01, 0x01, ____, 0x03, 0x03, 0x02, 0x01, 0x01, ____, ____, ____, // 0x30 - 0x3F + 0x03, 0x03, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, ____, ____, // 0x40 - 0x4F + 0x02, 0x02, 0x02, 0x02, 0x03, 0x01, 0x01, ____, 0x03, 0x03, 0x02, 0x01, 0x01, ____, ____, ____, // 0x50 - 0x5F + 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x01, 0x01, 0x03, 0x02, 0x02, 0x01, // 0x60 - 0x6F + 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x01, 0x01, 0x03, 0x02, 0x02, 0x01 // 0x70 - 0x7F +}; + + +static const TMC5062RegisterConstants tmc5062_RegisterConstants[] = +{ // Use ascending addresses! + { 0x60, 0xAAAAB554 }, // MSLUT[0]_M1 + { 0x61, 0x4A9554AA }, // MSLUT[1]_M1 + { 0x62, 0x24492929 }, // MSLUT[2]_M1 + { 0x63, 0x10104222 }, // MSLUT[3]_M1 + { 0x64, 0xFBFFFFFF }, // MSLUT[4]_M1 + { 0x65, 0xB5BB777D }, // MSLUT[5]_M1 + { 0x66, 0x49295556 }, // MSLUT[6]_M1 + { 0x67, 0x00404222 }, // MSLUT[7]_M1 + { 0x68, 0xFFFF8056 }, // MSLUTSEL_M1 + { 0x69, 0x00F70000 }, // MSLUTSTART_M1 + { 0x70, 0xAAAAB554 }, // MSLUT[0]_M2 + { 0x71, 0x4A9554AA }, // MSLUT[1]_M2 + { 0x72, 0x24492929 }, // MSLUT[2]_M2 + { 0x73, 0x10104222 }, // MSLUT[3]_M2 + { 0x74, 0xFBFFFFFF }, // MSLUT[4]_M2 + { 0x75, 0xB5BB777D }, // MSLUT[5]_M2 + { 0x76, 0x49295556 }, // MSLUT[6]_M2 + { 0x77, 0x00404222 }, // MSLUT[7]_M2 + { 0x78, 0xFFFF8056 }, // MSLUTSEL_M2 + { 0x79, 0x00F70000 } // MSLUTSTART_M2 +}; + +extern uint8_t tmc5062_dirtyBits[TMC5062_IC_CACHE_COUNT][TMC5062_REGISTER_COUNT/8]; +extern int32_t tmc5062_shadowRegister[TMC5062_IC_CACHE_COUNT][TMC5062_REGISTER_COUNT]; +void tmc5062_setDirtyBit(uint16_t icID, uint8_t index, bool value); +bool tmc5062_getDirtyBit(uint16_t icID, uint8_t index); +void tmc5062_initCache(void); +extern bool tmc5062_cache(uint16_t icID, TMC5062CacheOp operation, uint8_t address, uint32_t *value); +#endif +#endif +// => TMC-API wrapper + +/***************************************************************************************************************************************************/ + +#endif /* TMC_IC_TMC5062_H_ */ diff --git a/firmware/lib/tmc/ic/TMC5062/TMC5062_HW_Abstraction.h b/firmware/lib/tmc/ic/TMC5062/TMC5062_HW_Abstraction.h new file mode 100755 index 0000000..bff8d70 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5062/TMC5062_HW_Abstraction.h @@ -0,0 +1,1287 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + +#ifndef TMC5062_HW_ABSTRACTION +#define TMC5062_HW_ABSTRACTION + + +// Constants + +#define TMC5062_REGISTER_COUNT 128 +#define TMC5062_MOTORS 2 +#define TMC5062_WRITE_BIT 0x80 +#define TMC5062_ADDRESS_MASK 0x7F +#define TMC5062_MAX_VELOCITY 8388096 +#define TMC5062_MAX_ACCELERATION 65535 + +// Ramp Mode (Register TMC5062_RAMPMODE) +#define TMC5062_MODE_POSITION 0 +#define TMC5062_MODE_VELPOS 1 +#define TMC5062_MODE_VELNEG 2 +#define TMC5062_MODE_HOLD 3 + +// Registers in TMC5062 + +#define MOTOR_ADDR(m) (0x20 << m) +#define MOTOR_ADDR_DRV(m) (m << 4) +#define MOTOR_ADDR_PWM(m) (m << 3) + +#define TMC5062_GCONF 0x00 +#define TMC5062_GSTAT 0x01 +#define TMC5062_IFCNT 0x02 +#define TMC5062_SLAVECONF 0x03 +#define TMC5062_INP_OUT 0x04 +#define TMC5062_X_COMPARE 0x05 + // motor = 0 motor = 1 +#define TMC5062_PWMCONF(motor) (0x10|MOTOR_ADDR_PWM(motor)) // 0x10 0x18 +#define TMC5062_PWM_STATUS(motor) (0x11|MOTOR_ADDR_PWM(motor)) // 0x11 0x19 + + // motor = 0 motor = 1 +#define TMC5062_RAMPMODE(motor) (0x00|MOTOR_ADDR(motor)) // 0x20 0x40 +#define TMC5062_XACTUAL(motor) (0x01|MOTOR_ADDR(motor)) // 0x21 0x41 +#define TMC5062_VACTUAL(motor) (0x02|MOTOR_ADDR(motor)) // 0x22 0x42 +#define TMC5062_VSTART(motor) (0x03|MOTOR_ADDR(motor)) // 0x23 0x43 +#define TMC5062_A1(motor) (0x04|MOTOR_ADDR(motor)) // 0x24 0x44 +#define TMC5062_V1(motor) (0x05|MOTOR_ADDR(motor)) // 0x25 0x45 +#define TMC5062_AMAX(motor) (0x06|MOTOR_ADDR(motor)) // 0x26 0x46 +#define TMC5062_VMAX(motor) (0x07|MOTOR_ADDR(motor)) // 0x27 0x47 +#define TMC5062_DMAX(motor) (0x08|MOTOR_ADDR(motor)) // 0x28 0x48 +#define TMC5062_D1(motor) (0x0A|MOTOR_ADDR(motor)) // 0x2A 0x4A +#define TMC5062_VSTOP(motor) (0x0B|MOTOR_ADDR(motor)) // 0x2B 0x4B +#define TMC5062_TZEROWAIT(motor) (0x0C|MOTOR_ADDR(motor)) // 0x2C 0x4C +#define TMC5062_XTARGET(motor) (0x0D|MOTOR_ADDR(motor)) // 0x2D 0x4D +#define TMC5062_IHOLD_IRUN(motor) (0x10|MOTOR_ADDR(motor)) // 0x30 0x50 +#define TMC5062_VCOOLTHRS(motor) (0x11|MOTOR_ADDR(motor)) // 0x31 0x51 +#define TMC5062_VHIGH(motor) (0x12|MOTOR_ADDR(motor)) // 0x32 0x52 +#define TMC5062_VDCMIN(motor) (0x13|MOTOR_ADDR(motor)) // 0x33 0x53 +#define TMC5062_SWMODE(motor) (0x14|MOTOR_ADDR(motor)) // 0x34 0x54 +#define TMC5062_RAMPSTAT(motor) (0x15|MOTOR_ADDR(motor)) // 0x35 0x55 +#define TMC5062_XLATCH(motor) (0x16|MOTOR_ADDR(motor)) // 0x36 0x56 +#define TMC5062_ENCMODE(motor) (0x18|MOTOR_ADDR(motor)) // 0x38 0x58 +#define TMC5062_XENC(motor) (0x19|MOTOR_ADDR(motor)) // 0x39 0x59 +#define TMC5062_ENC_CONST(motor) (0x1A|MOTOR_ADDR(motor)) // 0x3A 0x5A +#define TMC5062_ENC_STATUS(motor) (0x1B|MOTOR_ADDR(motor)) // 0x3B 0x5B +#define TMC5062_ENC_LATCH(motor) (0x1C|MOTOR_ADDR(motor)) // 0x3C 0x5C + + // motor = 0 motor = 1 +#define TMC5062_MSLUT0(motor) (0x60|MOTOR_ADDR_DRV(motor)) // 0x60 0x70 +#define TMC5062_MSLUT1(motor) (0x61|MOTOR_ADDR_DRV(motor)) // 0x61 0x71 +#define TMC5062_MSLUT2(motor) (0x62|MOTOR_ADDR_DRV(motor)) // 0x62 0x72 +#define TMC5062_MSLUT3(motor) (0x63|MOTOR_ADDR_DRV(motor)) // 0x63 0x73 +#define TMC5062_MSLUT4(motor) (0x64|MOTOR_ADDR_DRV(motor)) // 0x64 0x74 +#define TMC5062_MSLUT5(motor) (0x65|MOTOR_ADDR_DRV(motor)) // 0x65 0x75 +#define TMC5062_MSLUT6(motor) (0x66|MOTOR_ADDR_DRV(motor)) // 0x66 0x76 +#define TMC5062_MSLUT7(motor) (0x67|MOTOR_ADDR_DRV(motor)) // 0x67 0x77 +#define TMC5062_MSLUTSEL(motor) (0x68|MOTOR_ADDR_DRV(motor)) // 0x68 0x78 +#define TMC5062_MSLUTSTART(motor) (0x69|MOTOR_ADDR_DRV(motor)) // 0x69 0x79 +#define TMC5062_MSCNT(motor) (0x6A|MOTOR_ADDR_DRV(motor)) // 0x6A 0x7A +#define TMC5062_MSCURACT(motor) (0x6B|MOTOR_ADDR_DRV(motor)) // 0x6B 0x7B +#define TMC5062_CHOPCONF(motor) (0x6C|MOTOR_ADDR_DRV(motor)) // 0x6C 0x7C +#define TMC5062_COOLCONF(motor) (0x6D|MOTOR_ADDR_DRV(motor)) // 0x6D 0x7D +#define TMC5062_DCCTRL(motor) (0x6E|MOTOR_ADDR_DRV(motor)) // 0x6E 0x7E +#define TMC5062_DRV_STATUS(motor) (0x6F|MOTOR_ADDR_DRV(motor)) // 0x6F 0x7F + + +// Register fields in TMC5062 + +#define TMC5062_POSCMP_ENABLE_MASK 0x00000008 +#define TMC5062_POSCMP_ENABLE_SHIFT 3 +#define TMC5062_POSCMP_ENABLE_FIELD ((RegisterField) {TMC5062_POSCMP_ENABLE_MASK, TMC5062_POSCMP_ENABLE_SHIFT, TMC5062_GCONF, false}) +#define TMC5062_ENC1_REFSEL_MASK 0x00000010 +#define TMC5062_ENC1_REFSEL_SHIFT 4 +#define TMC5062_ENC1_REFSEL_FIELD ((RegisterField) {TMC5062_ENC1_REFSEL_MASK, TMC5062_ENC1_REFSEL_SHIFT, TMC5062_GCONF, false}) +#define TMC5062_ENC2_ENABLE_MASK 0x00000020 +#define TMC5062_ENC2_ENABLE_SHIFT 5 +#define TMC5062_ENC2_ENABLE_FIELD ((RegisterField) {TMC5062_ENC2_ENABLE_MASK, TMC5062_ENC2_ENABLE_SHIFT, TMC5062_GCONF, false}) +#define TMC5062_ENC2_REFSEL_MASK 0x00000040 +#define TMC5062_ENC2_REFSEL_SHIFT 6 +#define TMC5062_ENC2_REFSEL_FIELD ((RegisterField) {TMC5062_ENC2_REFSEL_MASK, TMC5062_ENC2_REFSEL_SHIFT, TMC5062_GCONF, false}) +#define TMC5062_TEST_MODE_MASK 0x00000080 +#define TMC5062_TEST_MODE_SHIFT 7 +#define TMC5062_TEST_MODE_FIELD ((RegisterField) {TMC5062_TEST_MODE_MASK, TMC5062_TEST_MODE_SHIFT, TMC5062_GCONF, false}) +#define TMC5062_SHAFT1_MASK 0x00000100 +#define TMC5062_SHAFT1_SHIFT 8 +#define TMC5062_SHAFT1_FIELD ((RegisterField) {TMC5062_SHAFT1_MASK, TMC5062_SHAFT1_SHIFT, TMC5062_GCONF, false}) +#define TMC5062_SHAFT2_MASK 0x00000200 +#define TMC5062_SHAFT2_SHIFT 9 +#define TMC5062_SHAFT2_FIELD ((RegisterField) {TMC5062_SHAFT2_MASK, TMC5062_SHAFT2_SHIFT, TMC5062_GCONF, false}) +#define TMC5062_LOCK_GCONF_MASK 0x00000400 +#define TMC5062_LOCK_GCONF_SHIFT 10 +#define TMC5062_LOCK_GCONF_FIELD ((RegisterField) {TMC5062_LOCK_GCONF_MASK, TMC5062_LOCK_GCONF_SHIFT, TMC5062_GCONF, false}) +#define TMC5062_RESET_MASK 0x00000001 +#define TMC5062_RESET_SHIFT 0 +#define TMC5062_RESET_FIELD ((RegisterField) {TMC5062_RESET_MASK, TMC5062_RESET_SHIFT, TMC5062_GSTAT, false}) +#define TMC5062_DRV_ERR1_MASK 0x00000002 +#define TMC5062_DRV_ERR1_SHIFT 1 +#define TMC5062_DRV_ERR1_FIELD ((RegisterField) {TMC5062_DRV_ERR1_MASK, TMC5062_DRV_ERR1_SHIFT, TMC5062_GSTAT, false}) +//#define TMC5062_DRV_ERR1_MASK 0x00000004 +//#define TMC5062_DRV_ERR1_SHIFT 2 +//#define TMC5062_DRV_ERR1_FIELD ((RegisterField) {TMC5062_DRV_ERR1_MASK, TMC5062_DRV_ERR1_SHIFT, TMC5062_GSTAT, false}) +#define TMC5062_UV_CP_MASK 0x00000008 +#define TMC5062_UV_CP_SHIFT 3 +#define TMC5062_UV_CP_FIELD ((RegisterField) {TMC5062_UV_CP_MASK, TMC5062_UV_CP_SHIFT, TMC5062_GSTAT, false}) +#define TMC5062_TEST_SEL_MASK 0x0000000F +#define TMC5062_TEST_SEL_SHIFT 0 +#define TMC5062_TEST_SEL_FIELD ((RegisterField) {TMC5062_TEST_SEL_MASK, TMC5062_TEST_SEL_SHIFT, TMC5062_SLAVECONF, false}) +#define TMC5062_SENDDELAY_MASK 0x000000F0 +#define TMC5062_SENDDELAY_SHIFT 4 +#define TMC5062_SENDDELAY_FIELD ((RegisterField) {TMC5062_SENDDELAY_MASK, TMC5062_SENDDELAY_SHIFT, TMC5062_SLAVECONF, false}) +#define TMC5062_IO0_IN_MASK 0x00000001 +#define TMC5062_IO0_IN_SHIFT 0 +#define TMC5062_IO0_IN_FIELD ((RegisterField) {TMC5062_IO0_IN_MASK, TMC5062_IO0_IN_SHIFT, TMC5062_INP_OUT, false}) +#define TMC5062_IO1_IN_MASK 0x00000002 +#define TMC5062_IO1_IN_SHIFT 1 +#define TMC5062_IO1_IN_FIELD ((RegisterField) {TMC5062_IO1_IN_MASK, TMC5062_IO1_IN_SHIFT, TMC5062_INP_OUT, false}) +#define TMC5062_IO2_IN_MASK 0x00000004 +#define TMC5062_IO2_IN_SHIFT 2 +#define TMC5062_IO2_IN_FIELD ((RegisterField) {TMC5062_IO2_IN_MASK, TMC5062_IO2_IN_SHIFT, TMC5062_INP_OUT, false}) +#define TMC5062_IO3_IN_MASK 0x00000008 +#define TMC5062_IO3_IN_SHIFT 3 +#define TMC5062_IO3_IN_FIELD ((RegisterField) {TMC5062_IO3_IN_MASK, TMC5062_IO3_IN_SHIFT, TMC5062_INP_OUT, false}) +#define TMC5062_IOP_IN_MASK 0x00000010 +#define TMC5062_IOP_IN_SHIFT 4 +#define TMC5062_IOP_IN_FIELD ((RegisterField) {TMC5062_IOP_IN_MASK, TMC5062_IOP_IN_SHIFT, TMC5062_INP_OUT, false}) +#define TMC5062_ION_IN_MASK 0x00000020 +#define TMC5062_ION_IN_SHIFT 5 +#define TMC5062_ION_IN_FIELD ((RegisterField) {TMC5062_ION_IN_MASK, TMC5062_ION_IN_SHIFT, TMC5062_INP_OUT, false}) +#define TMC5062_DRV_ENN_MASK 0x00000080 +#define TMC5062_DRV_ENN_SHIFT 7 +#define TMC5062_DRV_ENN_FIELD ((RegisterField) {TMC5062_DRV_ENN_MASK, TMC5062_DRV_ENN_SHIFT, TMC5062_INP_OUT, false}) +#define TMC5062_VERSION_MASK 0xFF000000 +#define TMC5062_VERSION_SHIFT 24 +#define TMC5062_VERSION_FIELD ((RegisterField) {TMC5062_VERSION_MASK, TMC5062_VERSION_SHIFT, TMC5062_INP_OUT, false}) +#define TMC5062_IO0_OUT_MASK 0x00000001 +#define TMC5062_IO0_OUT_SHIFT 0 +#define TMC5062_IO0_OUT_FIELD ((RegisterField) {TMC5062_IO0_OUT_MASK, TMC5062_IO0_OUT_SHIFT, TMC5062_INP_OUT, false}) +#define TMC5062_IO1_OUT_MASK 0x00000002 +#define TMC5062_IO1_OUT_SHIFT 1 +#define TMC5062_IO1_OUT_FIELD ((RegisterField) {TMC5062_IO1_OUT_MASK, TMC5062_IO1_OUT_SHIFT, TMC5062_INP_OUT, false}) +#define TMC5062_IO2_OUT_MASK 0x00000004 +#define TMC5062_IO2_OUT_SHIFT 2 +#define TMC5062_IO2_OUT_FIELD ((RegisterField) {TMC5062_IO2_OUT_MASK, TMC5062_IO2_OUT_SHIFT, TMC5062_INP_OUT, false}) +#define TMC5062_IO3_OUT_MASK 0x00000008 +#define TMC5062_IO3_OUT_SHIFT 3 +#define TMC5062_IO3_OUT_FIELD ((RegisterField) {TMC5062_IO3_OUT_MASK, TMC5062_IO3_OUT_SHIFT, TMC5062_INP_OUT, false}) +#define TMC5062_IODDR0_MASK 0x00000100 +#define TMC5062_IODDR0_SHIFT 8 +#define TMC5062_IODDR0_FIELD ((RegisterField) {TMC5062_IODDR0_MASK, TMC5062_IODDR0_SHIFT, TMC5062_INP_OUT, false}) +#define TMC5062_IODDR1_MASK 0x00000200 +#define TMC5062_IODDR1_SHIFT 9 +#define TMC5062_IODDR1_FIELD ((RegisterField) {TMC5062_IODDR1_MASK, TMC5062_IODDR1_SHIFT, TMC5062_INP_OUT, false}) +#define TMC5062_IODDR2_MASK 0x00000400 +#define TMC5062_IODDR2_SHIFT 10 +#define TMC5062_IODDR2_FIELD ((RegisterField) {TMC5062_IODDR2_MASK, TMC5062_IODDR2_SHIFT, TMC5062_INP_OUT, false}) +#define TMC5062_IODDR3_MASK 0x00000800 +#define TMC5062_IODDR3_SHIFT 11 +#define TMC5062_IODDR3_FIELD ((RegisterField) {TMC5062_IODDR3_MASK, TMC5062_IODDR3_SHIFT, TMC5062_INP_OUT, false}) +#define TMC5062_X_COMPARE_MASK 0xFFFFFFFF +#define TMC5062_X_COMPARE_SHIFT 0 +#define TMC5062_X_COMPARE_FIELD ((RegisterField) {TMC5062_X_COMPARE_MASK, TMC5062_X_COMPARE_SHIFT, TMC5062_X_COMPARE, false}) +#define TMC5062_RAMPMODE_MASK 0x00000003 +#define TMC5062_RAMPMODE_SHIFT 0 +#define TMC5062_RAMPMODE_FIELD(motor) ((RegisterField) {TMC5062_RAMPMODE_MASK, TMC5062_RAMPMODE_SHIFT, TMC5062_RAMPMODE(motor), false}) +#define TMC5062_XACTUAL_MASK 0xFFFFFFFF +#define TMC5062_XACTUAL_SHIFT 0 +#define TMC5062_XACTUAL_FIELD(motor) ((RegisterField) {TMC5062_XACTUAL_MASK, TMC5062_XACTUAL_SHIFT, TMC5062_XACTUAL(motor), true}) +#define TMC5062_VACTUAL_MASK 0x00FFFFFF +#define TMC5062_VACTUAL_SHIFT 0 +#define TMC5062_VACTUAL_FIELD(motor) ((RegisterField) {TMC5062_VACTUAL_MASK, TMC5062_VACTUAL_SHIFT, TMC5062_VACTUAL(motor), true}) +#define TMC5062_VSTART_MASK 0x0003FFFF +#define TMC5062_VSTART_SHIFT 0 +#define TMC5062_VSTART_FIELD(motor) ((RegisterField) {TMC5062_VSTART_MASK, TMC5062_VSTART_SHIFT, TMC5062_VSTART(motor), false}) +#define TMC5062_A1_MASK 0x0000FFFF +#define TMC5062_A1_SHIFT 0 +#define TMC5062_A1_FIELD(motor) ((RegisterField) {TMC5062_A1_MASK, TMC5062_A1_SHIFT, TMC5062_A1(motor), false}) +#define TMC5062_V1_MASK 0x000FFFFF +#define TMC5062_V1_SHIFT 0 +#define TMC5062_V1_FIELD(motor) ((RegisterField) {TMC5062_V1_MASK, TMC5062_V1_SHIFT, TMC5062_V1(motor), false}) +#define TMC5062_AMAX_MASK 0x0000FFFF +#define TMC5062_AMAX_SHIFT 0 +#define TMC5062_AMAX_FIELD(motor) ((RegisterField) {TMC5062_AMAX_MASK, TMC5062_AMAX_SHIFT, TMC5062_AMAX(motor), false}) +#define TMC5062_VMAX_MASK 0x007FFFFF +#define TMC5062_VMAX_SHIFT 0 +#define TMC5062_VMAX_FIELD(motor) ((RegisterField) {TMC5062_VMAX_MASK, TMC5062_VMAX_SHIFT, TMC5062_VMAX(motor), false}) +#define TMC5062_DMAX_MASK 0x0000FFFF +#define TMC5062_DMAX_SHIFT 0 +#define TMC5062_DMAX_FIELD(motor) ((RegisterField) {TMC5062_DMAX_MASK, TMC5062_DMAX_SHIFT, TMC5062_DMAX(motor), false}) +#define TMC5062_D1_MASK 0x0000FFFF +#define TMC5062_D1_SHIFT 0 +#define TMC5062_D1_FIELD(motor) ((RegisterField) {TMC5062_D1_MASK, TMC5062_D1_SHIFT, TMC5062_D1(motor), false}) +#define TMC5062_VSTOP_MASK 0x0003FFFF +#define TMC5062_VSTOP_SHIFT 0 +#define TMC5062_VSTOP_FIELD(motor) ((RegisterField) {TMC5062_VSTOP_MASK, TMC5062_VSTOP_SHIFT, TMC5062_VSTOP(motor), false}) +#define TMC5062_TZEROWAIT_MASK 0x0000FFFF +#define TMC5062_TZEROWAIT_SHIFT 0 +#define TMC5062_TZEROWAIT_FIELD(motor) ((RegisterField) {TMC5062_TZEROWAIT_MASK, TMC5062_TZEROWAIT_SHIFT, TMC5062_TZEROWAIT(motor), false}) +#define TMC5062_XTARGET_MASK 0xFFFFFFFF +#define TMC5062_XTARGET_SHIFT 0 +#define TMC5062_XTARGET_FIELD(motor) ((RegisterField) {TMC5062_XTARGET_MASK, TMC5062_XTARGET_SHIFT, TMC5062_XTARGET(motor), true}) +#define TMC5062_IHOLD_MASK 0x0000001F +#define TMC5062_IHOLD_SHIFT 0 +#define TMC5062_IHOLD_FIELD(motor) ((RegisterField) {TMC5062_IHOLD_MASK, TMC5062_IHOLD_SHIFT, TMC5062_IHOLD_IRUN(motor), false}) +#define TMC5062_IRUN_MASK 0x00001F00 +#define TMC5062_IRUN_SHIFT 8 +#define TMC5062_IRUN_FIELD(motor) ((RegisterField) {TMC5062_IRUN_MASK, TMC5062_IRUN_SHIFT, TMC5062_IHOLD_IRUN(motor), false}) +#define TMC5062_IHOLDDELAY_MASK 0x000F0000 +#define TMC5062_IHOLDDELAY_SHIFT 16 +#define TMC5062_IHOLDDELAY_FIELD(motor) ((RegisterField) {TMC5062_IHOLDDELAY_MASK, TMC5062_IHOLDDELAY_SHIFT, TMC5062_IHOLD_IRUN(motor), false}) +#define TMC5062_VCOOLTHRS_MASK 0x007FFFFF +#define TMC5062_VCOOLTHRS_SHIFT 0 +#define TMC5062_VCOOLTHRS_FIELD(motor) ((RegisterField) {TMC5062_VCOOLTHRS_MASK, TMC5062_VCOOLTHRS_SHIFT, TMC5062_VCOOLTHRS(motor), false}) +#define TMC5062_VHIGH_MASK 0x007FFFFF +#define TMC5062_VHIGH_SHIFT 0 +#define TMC5062_VHIGH_FIELD(motor) ((RegisterField) {TMC5062_VHIGH_MASK, TMC5062_VHIGH_SHIFT, TMC5062_VHIGH(motor), false}) +#define TMC5062_VDCMIN_MASK 0x007FFFFF +#define TMC5062_VDCMIN_SHIFT 0 +#define TMC5062_VDCMIN_FIELD(motor) ((RegisterField) {TMC5062_VDCMIN_MASK, TMC5062_VDCMIN_SHIFT, TMC5062_VDCMIN(motor), false}) +#define TMC5062_STOP_L_ENABLE_MASK 0x00000001 +#define TMC5062_STOP_L_ENABLE_SHIFT 0 +#define TMC5062_STOP_L_ENABLE_FIELD(motor) ((RegisterField) {TMC5062_STOP_L_ENABLE_MASK, TMC5062_STOP_L_ENABLE_SHIFT, TMC5062_SWMODE(motor), false}) +#define TMC5062_STOP_R_ENABLE_MASK 0x00000002 +#define TMC5062_STOP_R_ENABLE_SHIFT 1 +#define TMC5062_STOP_R_ENABLE_FIELD(motor) ((RegisterField) {TMC5062_STOP_R_ENABLE_MASK, TMC5062_STOP_R_ENABLE_SHIFT, TMC5062_SWMODE(motor), false}) +#define TMC5062_POL_STOP_L_MASK 0x00000004 +#define TMC5062_POL_STOP_L_SHIFT 2 +#define TMC5062_POL_STOP_L_FIELD(motor) ((RegisterField) {TMC5062_POL_STOP_L_MASK, TMC5062_POL_STOP_L_SHIFT, TMC5062_SWMODE(motor), false}) +#define TMC5062_POL_STOP_R_MASK 0x00000008 +#define TMC5062_POL_STOP_R_SHIFT 3 +#define TMC5062_POL_STOP_R_FIELD(motor) ((RegisterField) {TMC5062_POL_STOP_R_MASK, TMC5062_POL_STOP_R_SHIFT, TMC5062_SWMODE(motor), false}) +#define TMC5062_SWAP_LR_MASK 0x00000010 +#define TMC5062_SWAP_LR_SHIFT 4 +#define TMC5062_SWAP_LR_FIELD(motor) ((RegisterField) {TMC5062_SWAP_LR_MASK, TMC5062_SWAP_LR_SHIFT, TMC5062_SWMODE(motor), false}) +#define TMC5062_LATCH_L_ACTIVE_MASK 0x00000020 +#define TMC5062_LATCH_L_ACTIVE_SHIFT 5 +#define TMC5062_LATCH_L_ACTIVE_FIELD(motor) ((RegisterField) {TMC5062_LATCH_L_ACTIVE_MASK, TMC5062_LATCH_L_ACTIVE_SHIFT, TMC5062_SWMODE(motor), false}) +#define TMC5062_LATCH_L_INACTIVE_MASK 0x00000040 +#define TMC5062_LATCH_L_INACTIVE_SHIFT 6 +#define TMC5062_LATCH_L_INACTIVE_FIELD(motor) ((RegisterField) {TMC5062_LATCH_L_INACTIVE_MASK, TMC5062_LATCH_L_INACTIVE_SHIFT, TMC5062_SWMODE(motor), false}) +#define TMC5062_LATCH_R_ACTIVE_MASK 0x00000080 +#define TMC5062_LATCH_R_ACTIVE_SHIFT 7 +#define TMC5062_LATCH_R_ACTIVE_FIELD(motor) ((RegisterField) {TMC5062_LATCH_R_ACTIVE_MASK, TMC5062_LATCH_R_ACTIVE_SHIFT, TMC5062_SWMODE(motor), false}) +#define TMC5062_LATCH_R_INACTIVE_MASK 0x00000100 +#define TMC5062_LATCH_R_INACTIVE_SHIFT 8 +#define TMC5062_LATCH_R_INACTIVE_FIELD(motor) ((RegisterField) {TMC5062_LATCH_R_INACTIVE_MASK, TMC5062_LATCH_R_INACTIVE_SHIFT, TMC5062_SWMODE(motor), false}) +#define TMC5062_EN_LATCH_ENCODER_MASK 0x00000200 +#define TMC5062_EN_LATCH_ENCODER_SHIFT 9 +#define TMC5062_EN_LATCH_ENCODER_FIELD(motor) ((RegisterField) {TMC5062_EN_LATCH_ENCODER_MASK, TMC5062_EN_LATCH_ENCODER_SHIFT, TMC5062_SWMODE(motor), false}) +#define TMC5062_SG_STOP_MASK 0x00000400 +#define TMC5062_SG_STOP_SHIFT 10 +#define TMC5062_SG_STOP_FIELD(motor) ((RegisterField) {TMC5062_SG_STOP_MASK, TMC5062_SG_STOP_SHIFT, TMC5062_SWMODE(motor), false}) +#define TMC5062_EN_SOFTSTOP_MASK 0x00000800 +#define TMC5062_EN_SOFTSTOP_SHIFT 11 +#define TMC5062_EN_SOFTSTOP_FIELD(motor) ((RegisterField) {TMC5062_EN_SOFTSTOP_MASK, TMC5062_EN_SOFTSTOP_SHIFT, TMC5062_SWMODE(motor), false}) +#define TMC5062_STATUS_STOP_L_MASK 0x00000001 +#define TMC5062_STATUS_STOP_L_SHIFT 0 +#define TMC5062_STATUS_STOP_L_FIELD(motor) ((RegisterField) {TMC5062_STATUS_STOP_L_MASK, TMC5062_STATUS_STOP_L_SHIFT, TMC5062_RAMPSTAT(motor), false}) +#define TMC5062_STATUS_STOP_R_MASK 0x00000002 +#define TMC5062_STATUS_STOP_R_SHIFT 1 +#define TMC5062_STATUS_STOP_R_FIELD(motor) ((RegisterField) {TMC5062_STATUS_STOP_R_MASK, TMC5062_STATUS_STOP_R_SHIFT, TMC5062_RAMPSTAT(motor), false}) +#define TMC5062_STATUS_LATCH_L_MASK 0x00000004 +#define TMC5062_STATUS_LATCH_L_SHIFT 2 +#define TMC5062_STATUS_LATCH_L_FIELD(motor) ((RegisterField) {TMC5062_STATUS_LATCH_L_MASK, TMC5062_STATUS_LATCH_L_SHIFT, TMC5062_RAMPSTAT(motor), false}) +#define TMC5062_STATUS_LATCH_R_MASK 0x00000008 +#define TMC5062_STATUS_LATCH_R_SHIFT 3 +#define TMC5062_STATUS_LATCH_R_FIELD(motor) ((RegisterField) {TMC5062_STATUS_LATCH_R_MASK, TMC5062_STATUS_LATCH_R_SHIFT, TMC5062_RAMPSTAT(motor), false}) +#define TMC5062_EVENT_STOP_L_MASK 0x00000010 +#define TMC5062_EVENT_STOP_L_SHIFT 4 +#define TMC5062_EVENT_STOP_L_FIELD(motor) ((RegisterField) {TMC5062_EVENT_STOP_L_MASK, TMC5062_EVENT_STOP_L_SHIFT, TMC5062_RAMPSTAT(motor), false}) +#define TMC5062_EVENT_STOP_R_MASK 0x00000020 +#define TMC5062_EVENT_STOP_R_SHIFT 5 +#define TMC5062_EVENT_STOP_R_FIELD(motor) ((RegisterField) {TMC5062_EVENT_STOP_R_MASK, TMC5062_EVENT_STOP_R_SHIFT, TMC5062_RAMPSTAT(motor), false}) +#define TMC5062_EVENT_STOP_SG_MASK 0x00000040 +#define TMC5062_EVENT_STOP_SG_SHIFT 6 +#define TMC5062_EVENT_STOP_SG_FIELD(motor) ((RegisterField) {TMC5062_EVENT_STOP_SG_MASK, TMC5062_EVENT_STOP_SG_SHIFT, TMC5062_RAMPSTAT(motor), false}) +#define TMC5062_EVENT_POS_REACHED_MASK 0x00000080 +#define TMC5062_EVENT_POS_REACHED_SHIFT 7 +#define TMC5062_EVENT_POS_REACHED_FIELD(motor) ((RegisterField) {TMC5062_EVENT_POS_REACHED_MASK, TMC5062_EVENT_POS_REACHED_SHIFT, TMC5062_RAMPSTAT(motor), false}) +#define TMC5062_VELOCITY_REACHED_MASK 0x00000100 +#define TMC5062_VELOCITY_REACHED_SHIFT 8 +#define TMC5062_VELOCITY_REACHED_FIELD(motor) ((RegisterField) {TMC5062_VELOCITY_REACHED_MASK, TMC5062_VELOCITY_REACHED_SHIFT, TMC5062_RAMPSTAT(motor), false}) +#define TMC5062_POSITION_REACHED_MASK 0x00000200 +#define TMC5062_POSITION_REACHED_SHIFT 9 +#define TMC5062_POSITION_REACHED_FIELD(motor) ((RegisterField) {TMC5062_POSITION_REACHED_MASK, TMC5062_POSITION_REACHED_SHIFT, TMC5062_RAMPSTAT(motor), false}) +#define TMC5062_VZERO_MASK 0x00000400 +#define TMC5062_VZERO_SHIFT 10 +#define TMC5062_VZERO_FIELD(motor) ((RegisterField) {TMC5062_VZERO_MASK, TMC5062_VZERO_SHIFT, TMC5062_RAMPSTAT(motor), false}) +#define TMC5062_T_ZEROWAIT_ACTIVE_MASK 0x00000800 +#define TMC5062_T_ZEROWAIT_ACTIVE_SHIFT 11 +#define TMC5062_T_ZEROWAIT_ACTIVE_FIELD(motor) ((RegisterField) {TMC5062_T_ZEROWAIT_ACTIVE_MASK, TMC5062_T_ZEROWAIT_ACTIVE_SHIFT, TMC5062_RAMPSTAT(motor), false}) +#define TMC5062_SECOND_MOVE_MASK 0x00001000 +#define TMC5062_SECOND_MOVE_SHIFT 12 +#define TMC5062_SECOND_MOVE_FIELD(motor) ((RegisterField) {TMC5062_SECOND_MOVE_MASK, TMC5062_SECOND_MOVE_SHIFT, TMC5062_RAMPSTAT(motor), false}) +#define TMC5062_STATUS_SG_MASK 0x00002000 +#define TMC5062_STATUS_SG_SHIFT 13 +#define TMC5062_STATUS_SG_FIELD(motor) ((RegisterField) {TMC5062_STATUS_SG_MASK, TMC5062_STATUS_SG_SHIFT, TMC5062_RAMPSTAT(motor), false}) +#define TMC5062_XLATCH_MASK 0xFFFFFFFF +#define TMC5062_XLATCH_SHIFT 0 +#define TMC5062_XLATCH_FIELD(motor) ((RegisterField) {TMC5062_XLATCH_MASK, TMC5062_XLATCH_SHIFT, TMC5062_XLATCH(motor), false}) +#define TMC5062_POL_A_MASK 0x00000001 +#define TMC5062_POL_A_SHIFT 0 +#define TMC5062_POL_A_FIELD(motor) ((RegisterField) {TMC5062_POL_A_MASK, TMC5062_POL_A_SHIFT, TMC5062_ENCMODE(motor), false}) +#define TMC5062_POL_B_MASK 0x00000002 +#define TMC5062_POL_B_SHIFT 1 +#define TMC5062_POL_B_FIELD(motor) ((RegisterField) {TMC5062_POL_B_MASK, TMC5062_POL_B_SHIFT, TMC5062_ENCMODE(motor), false}) +#define TMC5062_POL_N_MASK 0x00000004 +#define TMC5062_POL_N_SHIFT 2 +#define TMC5062_POL_N_FIELD(motor) ((RegisterField) {TMC5062_POL_N_MASK, TMC5062_POL_N_SHIFT, TMC5062_ENCMODE(motor), false}) +#define TMC5062_IGNORE_AB_MASK 0x00000008 +#define TMC5062_IGNORE_AB_SHIFT 3 +#define TMC5062_IGNORE_AB_FIELD(motor) ((RegisterField) {TMC5062_IGNORE_AB_MASK, TMC5062_IGNORE_AB_SHIFT, TMC5062_ENCMODE(motor), false}) +#define TMC5062_CLR_CONT_MASK 0x00000010 +#define TMC5062_CLR_CONT_SHIFT 4 +#define TMC5062_CLR_CONT_FIELD(motor) ((RegisterField) {TMC5062_CLR_CONT_MASK, TMC5062_CLR_CONT_SHIFT, TMC5062_ENCMODE(motor), false}) +#define TMC5062_CLR_ONCE_MASK 0x00000020 +#define TMC5062_CLR_ONCE_SHIFT 5 +#define TMC5062_CLR_ONCE_FIELD(motor) ((RegisterField) {TMC5062_CLR_ONCE_MASK, TMC5062_CLR_ONCE_SHIFT, TMC5062_ENCMODE(motor), false}) +#define TMC5062_POS_EDGE_NEG_EDGE_MASK 0x000000C0 +#define TMC5062_POS_EDGE_NEG_EDGE_SHIFT 6 +#define TMC5062_POS_EDGE_NEG_EDGE_FIELD(motor) ((RegisterField) {TMC5062_POS_EDGE_NEG_EDGE_MASK, TMC5062_POS_EDGE_NEG_EDGE_SHIFT, TMC5062_ENCMODE(motor), false}) +#define TMC5062_CLR_ENC_X_MASK 0x00000100 +#define TMC5062_CLR_ENC_X_SHIFT 8 +#define TMC5062_CLR_ENC_X_FIELD(motor) ((RegisterField) {TMC5062_CLR_ENC_X_MASK, TMC5062_CLR_ENC_X_SHIFT, TMC5062_ENCMODE(motor), false}) +#define TMC5062_LATCH_X_ACT_MASK 0x00000200 +#define TMC5062_LATCH_X_ACT_SHIFT 9 +#define TMC5062_LATCH_X_ACT_FIELD(motor) ((RegisterField) {TMC5062_LATCH_X_ACT_MASK, TMC5062_LATCH_X_ACT_SHIFT, TMC5062_ENCMODE(motor), false}) +#define TMC5062_ENC_SEL_DECIMAL_MASK 0x00000400 +#define TMC5062_ENC_SEL_DECIMAL_SHIFT 10 +#define TMC5062_ENC_SEL_DECIMAL_FIELD(motor) ((RegisterField) {TMC5062_ENC_SEL_DECIMAL_MASK, TMC5062_ENC_SEL_DECIMAL_SHIFT, TMC5062_ENCMODE(motor), false}) +#define TMC5062_X_ENC_MASK 0xFFFFFFFF +#define TMC5062_X_ENC_SHIFT 0 +#define TMC5062_X_ENC_FIELD(motor) ((RegisterField) {TMC5062_X_ENC_MASK, TMC5062_X_ENC_SHIFT, TMC5062_X_ENC(motor), true}) +#define TMC5062_INTEGER_MASK 0xFFFF0000 +#define TMC5062_INTEGER_SHIFT 16 +#define TMC5062_INTEGER_FIELD(motor) ((RegisterField) {TMC5062_INTEGER_MASK, TMC5062_INTEGER_SHIFT, TMC5062_ENC_CONST(motor), false}) +#define TMC5062_FRACTIONAL_MASK 0x0000FFFF +#define TMC5062_FRACTIONAL_SHIFT 0 +#define TMC5062_FRACTIONAL_FIELD(motor) ((RegisterField) {TMC5062_FRACTIONAL_MASK, TMC5062_FRACTIONAL_SHIFT, TMC5062_ENC_CONST(motor), false}) +#define TMC5062_ENC_STATUS_MASK 0x00000001 +#define TMC5062_ENC_STATUS_SHIFT 0 +#define TMC5062_ENC_STATUS_FIELD(motor) ((RegisterField) {TMC5062_ENC_STATUS_MASK, TMC5062_ENC_STATUS_SHIFT, TMC5062_ENC_STATUS(motor), false}) +#define TMC5062_ENC_LATCH_MASK 0xFFFFFFFF +#define TMC5062_ENC_LATCH_SHIFT 0 +#define TMC5062_ENC_LATCH_FIELD(motor) ((RegisterField) {TMC5062_ENC_LATCH_MASK, TMC5062_ENC_LATCH_SHIFT, TMC5062_ENC_LATCH(motor), true}) +#define TMC5062_OFS0_MASK 0x00000001 +#define TMC5062_OFS0_SHIFT 0 +#define TMC5062_OFS0_FIELD(motor) ((RegisterField) {TMC5062_OFS0_MASK, TMC5062_OFS0_SHIFT, TMC5062_MSLUT0(motor), false}) +#define TMC5062_OFS1_MASK 0x00000002 +#define TMC5062_OFS1_SHIFT 1 +#define TMC5062_OFS1_FIELD(motor) ((RegisterField) {TMC5062_OFS1_MASK, TMC5062_OFS1_SHIFT, TMC5062_MSLUT0(motor), false}) +#define TMC5062_OFS2_MASK 0x00000004 +#define TMC5062_OFS2_SHIFT 2 +#define TMC5062_OFS2_FIELD(motor) ((RegisterField) {TMC5062_OFS2_MASK, TMC5062_OFS2_SHIFT, TMC5062_MSLUT0(motor), false}) +#define TMC5062_OFS3_MASK 0x00000008 +#define TMC5062_OFS3_SHIFT 3 +#define TMC5062_OFS3_FIELD(motor) ((RegisterField) {TMC5062_OFS3_MASK, TMC5062_OFS3_SHIFT, TMC5062_MSLUT0(motor), false}) +#define TMC5062_OFS4_MASK 0x00000010 +#define TMC5062_OFS4_SHIFT 4 +#define TMC5062_OFS4_FIELD(motor) ((RegisterField) {TMC5062_OFS4_MASK, TMC5062_OFS4_SHIFT, TMC5062_MSLUT0(motor), false}) +#define TMC5062_OFS5_MASK 0x00000020 +#define TMC5062_OFS5_SHIFT 5 +#define TMC5062_OFS5_FIELD(motor) ((RegisterField) {TMC5062_OFS5_MASK, TMC5062_OFS5_SHIFT, TMC5062_MSLUT0(motor), false}) +#define TMC5062_OFS6_MASK 0x00000040 +#define TMC5062_OFS6_SHIFT 6 +#define TMC5062_OFS6_FIELD(motor) ((RegisterField) {TMC5062_OFS6_MASK, TMC5062_OFS6_SHIFT, TMC5062_MSLUT0(motor), false}) +#define TMC5062_OFS7_MASK 0x00000080 +#define TMC5062_OFS7_SHIFT 7 +#define TMC5062_OFS7_FIELD(motor) ((RegisterField) {TMC5062_OFS7_MASK, TMC5062_OFS7_SHIFT, TMC5062_MSLUT0(motor), false}) +#define TMC5062_OFS8_MASK 0x00000100 +#define TMC5062_OFS8_SHIFT 8 +#define TMC5062_OFS8_FIELD(motor) ((RegisterField) {TMC5062_OFS8_MASK, TMC5062_OFS8_SHIFT, TMC5062_MSLUT0(motor), false}) +#define TMC5062_OFS9_MASK 0x00000200 +#define TMC5062_OFS9_SHIFT 9 +#define TMC5062_OFS9_FIELD(motor) ((RegisterField) {TMC5062_OFS9_MASK, TMC5062_OFS9_SHIFT, TMC5062_MSLUT0(motor), false}) +#define TMC5062_OFS10_MASK 0x00000400 +#define TMC5062_OFS10_SHIFT 10 +#define TMC5062_OFS10_FIELD(motor) ((RegisterField) {TMC5062_OFS10_MASK, TMC5062_OFS10_SHIFT, TMC5062_MSLUT0(motor), false}) +#define TMC5062_OFS11_MASK 0x00000800 +#define TMC5062_OFS11_SHIFT 11 +#define TMC5062_OFS11_FIELD(motor) ((RegisterField) {TMC5062_OFS11_MASK, TMC5062_OFS11_SHIFT, TMC5062_MSLUT0(motor), false}) +#define TMC5062_OFS12_MASK 0x00001000 +#define TMC5062_OFS12_SHIFT 12 +#define TMC5062_OFS12_FIELD(motor) ((RegisterField) {TMC5062_OFS12_MASK, TMC5062_OFS12_SHIFT, TMC5062_MSLUT0(motor), false}) +#define TMC5062_OFS13_MASK 0x00002000 +#define TMC5062_OFS13_SHIFT 13 +#define TMC5062_OFS13_FIELD(motor) ((RegisterField) {TMC5062_OFS13_MASK, TMC5062_OFS13_SHIFT, TMC5062_MSLUT0(motor), false}) +#define TMC5062_OFS14_MASK 0x00004000 +#define TMC5062_OFS14_SHIFT 14 +#define TMC5062_OFS14_FIELD(motor) ((RegisterField) {TMC5062_OFS14_MASK, TMC5062_OFS14_SHIFT, TMC5062_MSLUT0(motor), false}) +#define TMC5062_OFS15_MASK 0x00008000 +#define TMC5062_OFS15_SHIFT 15 +#define TMC5062_OFS15_FIELD(motor) ((RegisterField) {TMC5062_OFS15_MASK, TMC5062_OFS15_SHIFT, TMC5062_MSLUT0(motor), false}) +#define TMC5062_OFS16_MASK 0x00010000 +#define TMC5062_OFS16_SHIFT 16 +#define TMC5062_OFS16_FIELD(motor) ((RegisterField) {TMC5062_OFS16_MASK, TMC5062_OFS16_SHIFT, TMC5062_MSLUT0(motor), false}) +#define TMC5062_OFS17_MASK 0x00020000 +#define TMC5062_OFS17_SHIFT 17 +#define TMC5062_OFS17_FIELD(motor) ((RegisterField) {TMC5062_OFS17_MASK, TMC5062_OFS17_SHIFT, TMC5062_MSLUT0(motor), false}) +#define TMC5062_OFS18_MASK 0x00040000 +#define TMC5062_OFS18_SHIFT 18 +#define TMC5062_OFS18_FIELD(motor) ((RegisterField) {TMC5062_OFS18_MASK, TMC5062_OFS18_SHIFT, TMC5062_MSLUT0(motor), false}) +#define TMC5062_OFS19_MASK 0x00080000 +#define TMC5062_OFS19_SHIFT 19 +#define TMC5062_OFS19_FIELD(motor) ((RegisterField) {TMC5062_OFS19_MASK, TMC5062_OFS19_SHIFT, TMC5062_MSLUT0(motor), false}) +#define TMC5062_OFS20_MASK 0x00100000 +#define TMC5062_OFS20_SHIFT 20 +#define TMC5062_OFS20_FIELD(motor) ((RegisterField) {TMC5062_OFS20_MASK, TMC5062_OFS20_SHIFT, TMC5062_MSLUT0(motor), false}) +#define TMC5062_OFS21_MASK 0x00200000 +#define TMC5062_OFS21_SHIFT 21 +#define TMC5062_OFS21_FIELD(motor) ((RegisterField) {TMC5062_OFS21_MASK, TMC5062_OFS21_SHIFT, TMC5062_MSLUT0(motor), false}) +#define TMC5062_OFS22_MASK 0x00400000 +#define TMC5062_OFS22_SHIFT 22 +#define TMC5062_OFS22_FIELD(motor) ((RegisterField) {TMC5062_OFS22_MASK, TMC5062_OFS22_SHIFT, TMC5062_MSLUT0(motor), false}) +#define TMC5062_OFS23_MASK 0x00800000 +#define TMC5062_OFS23_SHIFT 23 +#define TMC5062_OFS23_FIELD(motor) ((RegisterField) {TMC5062_OFS23_MASK, TMC5062_OFS23_SHIFT, TMC5062_MSLUT0(motor), false}) +#define TMC5062_OFS24_MASK 0x01000000 +#define TMC5062_OFS24_SHIFT 24 +#define TMC5062_OFS24_FIELD(motor) ((RegisterField) {TMC5062_OFS24_MASK, TMC5062_OFS24_SHIFT, TMC5062_MSLUT0(motor), false}) +#define TMC5062_OFS25_MASK 0x02000000 +#define TMC5062_OFS25_SHIFT 25 +#define TMC5062_OFS25_FIELD(motor) ((RegisterField) {TMC5062_OFS25_MASK, TMC5062_OFS25_SHIFT, TMC5062_MSLUT0(motor), false}) +#define TMC5062_OFS26_MASK 0x04000000 +#define TMC5062_OFS26_SHIFT 26 +#define TMC5062_OFS26_FIELD(motor) ((RegisterField) {TMC5062_OFS26_MASK, TMC5062_OFS26_SHIFT, TMC5062_MSLUT0(motor), false}) +#define TMC5062_OFS27_MASK 0x08000000 +#define TMC5062_OFS27_SHIFT 27 +#define TMC5062_OFS27_FIELD(motor) ((RegisterField) {TMC5062_OFS27_MASK, TMC5062_OFS27_SHIFT, TMC5062_MSLUT0(motor), false}) +#define TMC5062_OFS28_MASK 0x10000000 +#define TMC5062_OFS28_SHIFT 28 +#define TMC5062_OFS28_FIELD(motor) ((RegisterField) {TMC5062_OFS28_MASK, TMC5062_OFS28_SHIFT, TMC5062_MSLUT0(motor), false}) +#define TMC5062_OFS29_MASK 0x20000000 +#define TMC5062_OFS29_SHIFT 29 +#define TMC5062_OFS29_FIELD(motor) ((RegisterField) {TMC5062_OFS29_MASK, TMC5062_OFS29_SHIFT, TMC5062_MSLUT0(motor), false}) +#define TMC5062_OFS30_MASK 0x40000000 +#define TMC5062_OFS30_SHIFT 30 +#define TMC5062_OFS30_FIELD(motor) ((RegisterField) {TMC5062_OFS30_MASK, TMC5062_OFS30_SHIFT, TMC5062_MSLUT0(motor), false}) +#define TMC5062_OFS31_MASK 0x80000000 +#define TMC5062_OFS31_SHIFT 31 +#define TMC5062_OFS31_FIELD(motor) ((RegisterField) {TMC5062_OFS31_MASK, TMC5062_OFS31_SHIFT, TMC5062_MSLUT0(motor), false}) +#define TMC5062_OFS32_MASK 0x00000001 +#define TMC5062_OFS32_SHIFT 0 +#define TMC5062_OFS32_FIELD(motor) ((RegisterField) {TMC5062_OFS32_MASK, TMC5062_OFS32_SHIFT, TMC5062_MSLUT1(motor), false}) +#define TMC5062_OFS33_MASK 0x00000002 +#define TMC5062_OFS33_SHIFT 1 +#define TMC5062_OFS33_FIELD(motor) ((RegisterField) {TMC5062_OFS33_MASK, TMC5062_OFS33_SHIFT, TMC5062_MSLUT1(motor), false}) +#define TMC5062_OFS34_MASK 0x00000004 +#define TMC5062_OFS34_SHIFT 2 +#define TMC5062_OFS34_FIELD(motor) ((RegisterField) {TMC5062_OFS34_MASK, TMC5062_OFS34_SHIFT, TMC5062_MSLUT1(motor), false}) +#define TMC5062_OFS35_MASK 0x00000008 +#define TMC5062_OFS35_SHIFT 3 +#define TMC5062_OFS35_FIELD(motor) ((RegisterField) {TMC5062_OFS35_MASK, TMC5062_OFS35_SHIFT, TMC5062_MSLUT1(motor), false}) +#define TMC5062_OFS36_MASK 0x00000010 +#define TMC5062_OFS36_SHIFT 4 +#define TMC5062_OFS36_FIELD(motor) ((RegisterField) {TMC5062_OFS36_MASK, TMC5062_OFS36_SHIFT, TMC5062_MSLUT1(motor), false}) +#define TMC5062_OFS37_MASK 0x00000020 +#define TMC5062_OFS37_SHIFT 5 +#define TMC5062_OFS37_FIELD(motor) ((RegisterField) {TMC5062_OFS37_MASK, TMC5062_OFS37_SHIFT, TMC5062_MSLUT1(motor), false}) +#define TMC5062_OFS38_MASK 0x00000040 +#define TMC5062_OFS38_SHIFT 6 +#define TMC5062_OFS38_FIELD(motor) ((RegisterField) {TMC5062_OFS38_MASK, TMC5062_OFS38_SHIFT, TMC5062_MSLUT1(motor), false}) +#define TMC5062_OFS39_MASK 0x00000080 +#define TMC5062_OFS39_SHIFT 7 +#define TMC5062_OFS39_FIELD(motor) ((RegisterField) {TMC5062_OFS39_MASK, TMC5062_OFS39_SHIFT, TMC5062_MSLUT1(motor), false}) +#define TMC5062_OFS40_MASK 0x00000100 +#define TMC5062_OFS40_SHIFT 8 +#define TMC5062_OFS40_FIELD(motor) ((RegisterField) {TMC5062_OFS40_MASK, TMC5062_OFS40_SHIFT, TMC5062_MSLUT1(motor), false}) +#define TMC5062_OFS41_MASK 0x00000200 +#define TMC5062_OFS41_SHIFT 9 +#define TMC5062_OFS41_FIELD(motor) ((RegisterField) {TMC5062_OFS41_MASK, TMC5062_OFS41_SHIFT, TMC5062_MSLUT1(motor), false}) +#define TMC5062_OFS42_MASK 0x00000400 +#define TMC5062_OFS42_SHIFT 10 +#define TMC5062_OFS42_FIELD(motor) ((RegisterField) {TMC5062_OFS42_MASK, TMC5062_OFS42_SHIFT, TMC5062_MSLUT1(motor), false}) +#define TMC5062_OFS43_MASK 0x00000800 +#define TMC5062_OFS43_SHIFT 11 +#define TMC5062_OFS43_FIELD(motor) ((RegisterField) {TMC5062_OFS43_MASK, TMC5062_OFS43_SHIFT, TMC5062_MSLUT1(motor), false}) +#define TMC5062_OFS44_MASK 0x00001000 +#define TMC5062_OFS44_SHIFT 12 +#define TMC5062_OFS44_FIELD(motor) ((RegisterField) {TMC5062_OFS44_MASK, TMC5062_OFS44_SHIFT, TMC5062_MSLUT1(motor), false}) +#define TMC5062_OFS45_MASK 0x00002000 +#define TMC5062_OFS45_SHIFT 13 +#define TMC5062_OFS45_FIELD(motor) ((RegisterField) {TMC5062_OFS45_MASK, TMC5062_OFS45_SHIFT, TMC5062_MSLUT1(motor), false}) +#define TMC5062_OFS46_MASK 0x00004000 +#define TMC5062_OFS46_SHIFT 14 +#define TMC5062_OFS46_FIELD(motor) ((RegisterField) {TMC5062_OFS46_MASK, TMC5062_OFS46_SHIFT, TMC5062_MSLUT1(motor), false}) +#define TMC5062_OFS47_MASK 0x00008000 +#define TMC5062_OFS47_SHIFT 15 +#define TMC5062_OFS47_FIELD(motor) ((RegisterField) {TMC5062_OFS47_MASK, TMC5062_OFS47_SHIFT, TMC5062_MSLUT1(motor), false}) +#define TMC5062_OFS48_MASK 0x00010000 +#define TMC5062_OFS48_SHIFT 16 +#define TMC5062_OFS48_FIELD(motor) ((RegisterField) {TMC5062_OFS48_MASK, TMC5062_OFS48_SHIFT, TMC5062_MSLUT1(motor), false}) +#define TMC5062_OFS49_MASK 0x00020000 +#define TMC5062_OFS49_SHIFT 17 +#define TMC5062_OFS49_FIELD(motor) ((RegisterField) {TMC5062_OFS49_MASK, TMC5062_OFS49_SHIFT, TMC5062_MSLUT1(motor), false}) +#define TMC5062_OFS50_MASK 0x00040000 +#define TMC5062_OFS50_SHIFT 18 +#define TMC5062_OFS50_FIELD(motor) ((RegisterField) {TMC5062_OFS50_MASK, TMC5062_OFS50_SHIFT, TMC5062_MSLUT1(motor), false}) +#define TMC5062_OFS51_MASK 0x00080000 +#define TMC5062_OFS51_SHIFT 19 +#define TMC5062_OFS51_FIELD(motor) ((RegisterField) {TMC5062_OFS51_MASK, TMC5062_OFS51_SHIFT, TMC5062_MSLUT1(motor), false}) +#define TMC5062_OFS52_MASK 0x00100000 +#define TMC5062_OFS52_SHIFT 20 +#define TMC5062_OFS52_FIELD(motor) ((RegisterField) {TMC5062_OFS52_MASK, TMC5062_OFS52_SHIFT, TMC5062_MSLUT1(motor), false}) +#define TMC5062_OFS53_MASK 0x00200000 +#define TMC5062_OFS53_SHIFT 21 +#define TMC5062_OFS53_FIELD(motor) ((RegisterField) {TMC5062_OFS53_MASK, TMC5062_OFS53_SHIFT, TMC5062_MSLUT1(motor), false}) +#define TMC5062_OFS54_MASK 0x00400000 +#define TMC5062_OFS54_SHIFT 22 +#define TMC5062_OFS54_FIELD(motor) ((RegisterField) {TMC5062_OFS54_MASK, TMC5062_OFS54_SHIFT, TMC5062_MSLUT1(motor), false}) +#define TMC5062_OFS55_MASK 0x00800000 +#define TMC5062_OFS55_SHIFT 23 +#define TMC5062_OFS55_FIELD(motor) ((RegisterField) {TMC5062_OFS55_MASK, TMC5062_OFS55_SHIFT, TMC5062_MSLUT1(motor), false}) +#define TMC5062_OFS56_MASK 0x01000000 +#define TMC5062_OFS56_SHIFT 24 +#define TMC5062_OFS56_FIELD(motor) ((RegisterField) {TMC5062_OFS56_MASK, TMC5062_OFS56_SHIFT, TMC5062_MSLUT1(motor), false}) +#define TMC5062_OFS57_MASK 0x02000000 +#define TMC5062_OFS57_SHIFT 25 +#define TMC5062_OFS57_FIELD(motor) ((RegisterField) {TMC5062_OFS57_MASK, TMC5062_OFS57_SHIFT, TMC5062_MSLUT1(motor), false}) +#define TMC5062_OFS58_MASK 0x04000000 +#define TMC5062_OFS58_SHIFT 26 +#define TMC5062_OFS58_FIELD(motor) ((RegisterField) {TMC5062_OFS58_MASK, TMC5062_OFS58_SHIFT, TMC5062_MSLUT1(motor), false}) +#define TMC5062_OFS59_MASK 0x08000000 +#define TMC5062_OFS59_SHIFT 27 +#define TMC5062_OFS59_FIELD(motor) ((RegisterField) {TMC5062_OFS59_MASK, TMC5062_OFS59_SHIFT, TMC5062_MSLUT1(motor), false}) +#define TMC5062_OFS60_MASK 0x10000000 +#define TMC5062_OFS60_SHIFT 28 +#define TMC5062_OFS60_FIELD(motor) ((RegisterField) {TMC5062_OFS60_MASK, TMC5062_OFS60_SHIFT, TMC5062_MSLUT1(motor), false}) +#define TMC5062_OFS61_MASK 0x20000000 +#define TMC5062_OFS61_SHIFT 29 +#define TMC5062_OFS61_FIELD(motor) ((RegisterField) {TMC5062_OFS61_MASK, TMC5062_OFS61_SHIFT, TMC5062_MSLUT1(motor), false}) +#define TMC5062_OFS62_MASK 0x40000000 +#define TMC5062_OFS62_SHIFT 30 +#define TMC5062_OFS62_FIELD(motor) ((RegisterField) {TMC5062_OFS62_MASK, TMC5062_OFS62_SHIFT, TMC5062_MSLUT1(motor), false}) +#define TMC5062_OFS63_MASK 0x80000000 +#define TMC5062_OFS63_SHIFT 31 +#define TMC5062_OFS63_FIELD(motor) ((RegisterField) {TMC5062_OFS63_MASK, TMC5062_OFS63_SHIFT, TMC5062_MSLUT1(motor), false}) +#define TMC5062_OFS64_MASK 0x00000001 +#define TMC5062_OFS64_SHIFT 0 +#define TMC5062_OFS64_FIELD(motor) ((RegisterField) {TMC5062_OFS64_MASK, TMC5062_OFS64_SHIFT, TMC5062_MSLUT2(motor), false}) +#define TMC5062_OFS65_MASK 0x00000002 +#define TMC5062_OFS65_SHIFT 1 +#define TMC5062_OFS65_FIELD(motor) ((RegisterField) {TMC5062_OFS65_MASK, TMC5062_OFS65_SHIFT, TMC5062_MSLUT2(motor), false}) +#define TMC5062_OFS66_MASK 0x00000004 +#define TMC5062_OFS66_SHIFT 2 +#define TMC5062_OFS66_FIELD(motor) ((RegisterField) {TMC5062_OFS66_MASK, TMC5062_OFS66_SHIFT, TMC5062_MSLUT2(motor), false}) +#define TMC5062_OFS67_MASK 0x00000008 +#define TMC5062_OFS67_SHIFT 3 +#define TMC5062_OFS67_FIELD(motor) ((RegisterField) {TMC5062_OFS67_MASK, TMC5062_OFS67_SHIFT, TMC5062_MSLUT2(motor), false}) +#define TMC5062_OFS68_MASK 0x00000010 +#define TMC5062_OFS68_SHIFT 4 +#define TMC5062_OFS68_FIELD(motor) ((RegisterField) {TMC5062_OFS68_MASK, TMC5062_OFS68_SHIFT, TMC5062_MSLUT2(motor), false}) +#define TMC5062_OFS69_MASK 0x00000020 +#define TMC5062_OFS69_SHIFT 5 +#define TMC5062_OFS69_FIELD(motor) ((RegisterField) {TMC5062_OFS69_MASK, TMC5062_OFS69_SHIFT, TMC5062_MSLUT2(motor), false}) +#define TMC5062_OFS70_MASK 0x00000040 +#define TMC5062_OFS70_SHIFT 6 +#define TMC5062_OFS70_FIELD(motor) ((RegisterField) {TMC5062_OFS70_MASK, TMC5062_OFS70_SHIFT, TMC5062_MSLUT2(motor), false}) +#define TMC5062_OFS71_MASK 0x00000080 +#define TMC5062_OFS71_SHIFT 7 +#define TMC5062_OFS71_FIELD(motor) ((RegisterField) {TMC5062_OFS71_MASK, TMC5062_OFS71_SHIFT, TMC5062_MSLUT2(motor), false}) +#define TMC5062_OFS72_MASK 0x00000100 +#define TMC5062_OFS72_SHIFT 8 +#define TMC5062_OFS72_FIELD(motor) ((RegisterField) {TMC5062_OFS72_MASK, TMC5062_OFS72_SHIFT, TMC5062_MSLUT2(motor), false}) +#define TMC5062_OFS73_MASK 0x00000200 +#define TMC5062_OFS73_SHIFT 9 +#define TMC5062_OFS73_FIELD(motor) ((RegisterField) {TMC5062_OFS73_MASK, TMC5062_OFS73_SHIFT, TMC5062_MSLUT2(motor), false}) +#define TMC5062_OFS74_MASK 0x00000400 +#define TMC5062_OFS74_SHIFT 10 +#define TMC5062_OFS74_FIELD(motor) ((RegisterField) {TMC5062_OFS74_MASK, TMC5062_OFS74_SHIFT, TMC5062_MSLUT2(motor), false}) +#define TMC5062_OFS75_MASK 0x00000800 +#define TMC5062_OFS75_SHIFT 11 +#define TMC5062_OFS75_FIELD(motor) ((RegisterField) {TMC5062_OFS75_MASK, TMC5062_OFS75_SHIFT, TMC5062_MSLUT2(motor), false}) +#define TMC5062_OFS76_MASK 0x00001000 +#define TMC5062_OFS76_SHIFT 12 +#define TMC5062_OFS76_FIELD(motor) ((RegisterField) {TMC5062_OFS76_MASK, TMC5062_OFS76_SHIFT, TMC5062_MSLUT2(motor), false}) +#define TMC5062_OFS77_MASK 0x00002000 +#define TMC5062_OFS77_SHIFT 13 +#define TMC5062_OFS77_FIELD(motor) ((RegisterField) {TMC5062_OFS77_MASK, TMC5062_OFS77_SHIFT, TMC5062_MSLUT2(motor), false}) +#define TMC5062_OFS78_MASK 0x00004000 +#define TMC5062_OFS78_SHIFT 14 +#define TMC5062_OFS78_FIELD(motor) ((RegisterField) {TMC5062_OFS78_MASK, TMC5062_OFS78_SHIFT, TMC5062_MSLUT2(motor), false}) +#define TMC5062_OFS79_MASK 0x00008000 +#define TMC5062_OFS79_SHIFT 15 +#define TMC5062_OFS79_FIELD(motor) ((RegisterField) {TMC5062_OFS79_MASK, TMC5062_OFS79_SHIFT, TMC5062_MSLUT2(motor), false}) +#define TMC5062_OFS80_MASK 0x00010000 +#define TMC5062_OFS80_SHIFT 16 +#define TMC5062_OFS80_FIELD(motor) ((RegisterField) {TMC5062_OFS80_MASK, TMC5062_OFS80_SHIFT, TMC5062_MSLUT2(motor), false}) +#define TMC5062_OFS81_MASK 0x00020000 +#define TMC5062_OFS81_SHIFT 17 +#define TMC5062_OFS81_FIELD(motor) ((RegisterField) {TMC5062_OFS81_MASK, TMC5062_OFS81_SHIFT, TMC5062_MSLUT2(motor), false}) +#define TMC5062_OFS82_MASK 0x00040000 +#define TMC5062_OFS82_SHIFT 18 +#define TMC5062_OFS82_FIELD(motor) ((RegisterField) {TMC5062_OFS82_MASK, TMC5062_OFS82_SHIFT, TMC5062_MSLUT2(motor), false}) +#define TMC5062_OFS83_MASK 0x00080000 +#define TMC5062_OFS83_SHIFT 19 +#define TMC5062_OFS83_FIELD(motor) ((RegisterField) {TMC5062_OFS83_MASK, TMC5062_OFS83_SHIFT, TMC5062_MSLUT2(motor), false}) +#define TMC5062_OFS84_MASK 0x00100000 +#define TMC5062_OFS84_SHIFT 20 +#define TMC5062_OFS84_FIELD(motor) ((RegisterField) {TMC5062_OFS84_MASK, TMC5062_OFS84_SHIFT, TMC5062_MSLUT2(motor), false}) +#define TMC5062_OFS85_MASK 0x00200000 +#define TMC5062_OFS85_SHIFT 21 +#define TMC5062_OFS85_FIELD(motor) ((RegisterField) {TMC5062_OFS85_MASK, TMC5062_OFS85_SHIFT, TMC5062_MSLUT2(motor), false}) +#define TMC5062_OFS86_MASK 0x00400000 +#define TMC5062_OFS86_SHIFT 22 +#define TMC5062_OFS86_FIELD(motor) ((RegisterField) {TMC5062_OFS86_MASK, TMC5062_OFS86_SHIFT, TMC5062_MSLUT2(motor), false}) +#define TMC5062_OFS87_MASK 0x00800000 +#define TMC5062_OFS87_SHIFT 23 +#define TMC5062_OFS87_FIELD(motor) ((RegisterField) {TMC5062_OFS87_MASK, TMC5062_OFS87_SHIFT, TMC5062_MSLUT2(motor), false}) +#define TMC5062_OFS88_MASK 0x01000000 +#define TMC5062_OFS88_SHIFT 24 +#define TMC5062_OFS88_FIELD(motor) ((RegisterField) {TMC5062_OFS88_MASK, TMC5062_OFS88_SHIFT, TMC5062_MSLUT2(motor), false}) +#define TMC5062_OFS89_MASK 0x02000000 +#define TMC5062_OFS89_SHIFT 25 +#define TMC5062_OFS89_FIELD(motor) ((RegisterField) {TMC5062_OFS89_MASK, TMC5062_OFS89_SHIFT, TMC5062_MSLUT2(motor), false}) +#define TMC5062_OFS90_MASK 0x04000000 +#define TMC5062_OFS90_SHIFT 26 +#define TMC5062_OFS90_FIELD(motor) ((RegisterField) {TMC5062_OFS90_MASK, TMC5062_OFS90_SHIFT, TMC5062_MSLUT2(motor), false}) +#define TMC5062_OFS91_MASK 0x08000000 +#define TMC5062_OFS91_SHIFT 27 +#define TMC5062_OFS91_FIELD(motor) ((RegisterField) {TMC5062_OFS91_MASK, TMC5062_OFS91_SHIFT, TMC5062_MSLUT2(motor), false}) +#define TMC5062_OFS92_MASK 0x10000000 +#define TMC5062_OFS92_SHIFT 28 +#define TMC5062_OFS92_FIELD(motor) ((RegisterField) {TMC5062_OFS92_MASK, TMC5062_OFS92_SHIFT, TMC5062_MSLUT2(motor), false}) +#define TMC5062_OFS93_MASK 0x20000000 +#define TMC5062_OFS93_SHIFT 29 +#define TMC5062_OFS93_FIELD(motor) ((RegisterField) {TMC5062_OFS93_MASK, TMC5062_OFS93_SHIFT, TMC5062_MSLUT2(motor), false}) +#define TMC5062_OFS94_MASK 0x40000000 +#define TMC5062_OFS94_SHIFT 30 +#define TMC5062_OFS94_FIELD(motor) ((RegisterField) {TMC5062_OFS94_MASK, TMC5062_OFS94_SHIFT, TMC5062_MSLUT2(motor), false}) +#define TMC5062_OFS95_MASK 0x80000000 +#define TMC5062_OFS95_SHIFT 31 +#define TMC5062_OFS95_FIELD(motor) ((RegisterField) {TMC5062_OFS95_MASK, TMC5062_OFS95_SHIFT, TMC5062_MSLUT2(motor), false}) +#define TMC5062_OFS96_MASK 0x00000001 +#define TMC5062_OFS96_SHIFT 0 +#define TMC5062_OFS96_FIELD(motor) ((RegisterField) {TMC5062_OFS96_MASK, TMC5062_OFS96_SHIFT, TMC5062_MSLUT3(motor), false}) +#define TMC5062_OFS97_MASK 0x00000002 +#define TMC5062_OFS97_SHIFT 1 +#define TMC5062_OFS97_FIELD(motor) ((RegisterField) {TMC5062_OFS97_MASK, TMC5062_OFS97_SHIFT, TMC5062_MSLUT3(motor), false}) +#define TMC5062_OFS98_MASK 0x00000004 +#define TMC5062_OFS98_SHIFT 2 +#define TMC5062_OFS98_FIELD(motor) ((RegisterField) {TMC5062_OFS98_MASK, TMC5062_OFS98_SHIFT, TMC5062_MSLUT3(motor), false}) +#define TMC5062_OFS99_MASK 0x00000008 +#define TMC5062_OFS99_SHIFT 3 +#define TMC5062_OFS99_FIELD(motor) ((RegisterField) {TMC5062_OFS99_MASK, TMC5062_OFS99_SHIFT, TMC5062_MSLUT3(motor), false}) +#define TMC5062_OFS100_MASK 0x00000010 +#define TMC5062_OFS100_SHIFT 4 +#define TMC5062_OFS100_FIELD(motor) ((RegisterField) {TMC5062_OFS100_MASK, TMC5062_OFS100_SHIFT, TMC5062_MSLUT3(motor), false}) +#define TMC5062_OFS101_MASK 0x00000020 +#define TMC5062_OFS101_SHIFT 5 +#define TMC5062_OFS101_FIELD(motor) ((RegisterField) {TMC5062_OFS101_MASK, TMC5062_OFS101_SHIFT, TMC5062_MSLUT3(motor), false}) +#define TMC5062_OFS102_MASK 0x00000040 +#define TMC5062_OFS102_SHIFT 6 +#define TMC5062_OFS102_FIELD(motor) ((RegisterField) {TMC5062_OFS102_MASK, TMC5062_OFS102_SHIFT, TMC5062_MSLUT3(motor), false}) +#define TMC5062_OFS103_MASK 0x00000080 +#define TMC5062_OFS103_SHIFT 7 +#define TMC5062_OFS103_FIELD(motor) ((RegisterField) {TMC5062_OFS103_MASK, TMC5062_OFS103_SHIFT, TMC5062_MSLUT3(motor), false}) +#define TMC5062_OFS104_MASK 0x00000100 +#define TMC5062_OFS104_SHIFT 8 +#define TMC5062_OFS104_FIELD(motor) ((RegisterField) {TMC5062_OFS104_MASK, TMC5062_OFS104_SHIFT, TMC5062_MSLUT3(motor), false}) +#define TMC5062_OFS105_MASK 0x00000200 +#define TMC5062_OFS105_SHIFT 9 +#define TMC5062_OFS105_FIELD(motor) ((RegisterField) {TMC5062_OFS105_MASK, TMC5062_OFS105_SHIFT, TMC5062_MSLUT3(motor), false}) +#define TMC5062_OFS106_MASK 0x00000400 +#define TMC5062_OFS106_SHIFT 10 +#define TMC5062_OFS106_FIELD(motor) ((RegisterField) {TMC5062_OFS106_MASK, TMC5062_OFS106_SHIFT, TMC5062_MSLUT3(motor), false}) +#define TMC5062_OFS107_MASK 0x00000800 +#define TMC5062_OFS107_SHIFT 11 +#define TMC5062_OFS107_FIELD(motor) ((RegisterField) {TMC5062_OFS107_MASK, TMC5062_OFS107_SHIFT, TMC5062_MSLUT3(motor), false}) +#define TMC5062_OFS108_MASK 0x00001000 +#define TMC5062_OFS108_SHIFT 12 +#define TMC5062_OFS108_FIELD(motor) ((RegisterField) {TMC5062_OFS108_MASK, TMC5062_OFS108_SHIFT, TMC5062_MSLUT3(motor), false}) +#define TMC5062_OFS109_MASK 0x00002000 +#define TMC5062_OFS109_SHIFT 13 +#define TMC5062_OFS109_FIELD(motor) ((RegisterField) {TMC5062_OFS109_MASK, TMC5062_OFS109_SHIFT, TMC5062_MSLUT3(motor), false}) +#define TMC5062_OFS110_MASK 0x00004000 +#define TMC5062_OFS110_SHIFT 14 +#define TMC5062_OFS110_FIELD(motor) ((RegisterField) {TMC5062_OFS110_MASK, TMC5062_OFS110_SHIFT, TMC5062_MSLUT3(motor), false}) +#define TMC5062_OFS111_MASK 0x00008000 +#define TMC5062_OFS111_SHIFT 15 +#define TMC5062_OFS111_FIELD(motor) ((RegisterField) {TMC5062_OFS111_MASK, TMC5062_OFS111_SHIFT, TMC5062_MSLUT3(motor), false}) +#define TMC5062_OFS112_MASK 0x00010000 +#define TMC5062_OFS112_SHIFT 16 +#define TMC5062_OFS112_FIELD(motor) ((RegisterField) {TMC5062_OFS112_MASK, TMC5062_OFS112_SHIFT, TMC5062_MSLUT3(motor), false}) +#define TMC5062_OFS113_MASK 0x00020000 +#define TMC5062_OFS113_SHIFT 17 +#define TMC5062_OFS113_FIELD(motor) ((RegisterField) {TMC5062_OFS113_MASK, TMC5062_OFS113_SHIFT, TMC5062_MSLUT3(motor), false}) +#define TMC5062_OFS114_MASK 0x00040000 +#define TMC5062_OFS114_SHIFT 18 +#define TMC5062_OFS114_FIELD(motor) ((RegisterField) {TMC5062_OFS114_MASK, TMC5062_OFS114_SHIFT, TMC5062_MSLUT3(motor), false}) +#define TMC5062_OFS115_MASK 0x00080000 +#define TMC5062_OFS115_SHIFT 19 +#define TMC5062_OFS115_FIELD(motor) ((RegisterField) {TMC5062_OFS115_MASK, TMC5062_OFS115_SHIFT, TMC5062_MSLUT3(motor), false}) +#define TMC5062_OFS116_MASK 0x00100000 +#define TMC5062_OFS116_SHIFT 20 +#define TMC5062_OFS116_FIELD(motor) ((RegisterField) {TMC5062_OFS116_MASK, TMC5062_OFS116_SHIFT, TMC5062_MSLUT3(motor), false}) +#define TMC5062_OFS117_MASK 0x00200000 +#define TMC5062_OFS117_SHIFT 21 +#define TMC5062_OFS117_FIELD(motor) ((RegisterField) {TMC5062_OFS117_MASK, TMC5062_OFS117_SHIFT, TMC5062_MSLUT3(motor), false}) +#define TMC5062_OFS118_MASK 0x00400000 +#define TMC5062_OFS118_SHIFT 22 +#define TMC5062_OFS118_FIELD(motor) ((RegisterField) {TMC5062_OFS118_MASK, TMC5062_OFS118_SHIFT, TMC5062_MSLUT3(motor), false}) +#define TMC5062_OFS119_MASK 0x00800000 +#define TMC5062_OFS119_SHIFT 23 +#define TMC5062_OFS119_FIELD(motor) ((RegisterField) {TMC5062_OFS119_MASK, TMC5062_OFS119_SHIFT, TMC5062_MSLUT3(motor), false}) +#define TMC5062_OFS120_MASK 0x01000000 +#define TMC5062_OFS120_SHIFT 24 +#define TMC5062_OFS120_FIELD(motor) ((RegisterField) {TMC5062_OFS120_MASK, TMC5062_OFS120_SHIFT, TMC5062_MSLUT3(motor), false}) +#define TMC5062_OFS121_MASK 0x02000000 +#define TMC5062_OFS121_SHIFT 25 +#define TMC5062_OFS121_FIELD(motor) ((RegisterField) {TMC5062_OFS121_MASK, TMC5062_OFS121_SHIFT, TMC5062_MSLUT3(motor), false}) +#define TMC5062_OFS122_MASK 0x04000000 +#define TMC5062_OFS122_SHIFT 26 +#define TMC5062_OFS122_FIELD(motor) ((RegisterField) {TMC5062_OFS122_MASK, TMC5062_OFS122_SHIFT, TMC5062_MSLUT3(motor), false}) +#define TMC5062_OFS123_MASK 0x08000000 +#define TMC5062_OFS123_SHIFT 27 +#define TMC5062_OFS123_FIELD(motor) ((RegisterField) {TMC5062_OFS123_MASK, TMC5062_OFS123_SHIFT, TMC5062_MSLUT3(motor), false}) +#define TMC5062_OFS124_MASK 0x10000000 +#define TMC5062_OFS124_SHIFT 28 +#define TMC5062_OFS124_FIELD(motor) ((RegisterField) {TMC5062_OFS124_MASK, TMC5062_OFS124_SHIFT, TMC5062_MSLUT3(motor), false}) +#define TMC5062_OFS125_MASK 0x20000000 +#define TMC5062_OFS125_SHIFT 29 +#define TMC5062_OFS125_FIELD(motor) ((RegisterField) {TMC5062_OFS125_MASK, TMC5062_OFS125_SHIFT, TMC5062_MSLUT3(motor), false}) +#define TMC5062_OFS126_MASK 0x40000000 +#define TMC5062_OFS126_SHIFT 30 +#define TMC5062_OFS126_FIELD(motor) ((RegisterField) {TMC5062_OFS126_MASK, TMC5062_OFS126_SHIFT, TMC5062_MSLUT3(motor), false}) +#define TMC5062_OFS127_MASK 0x80000000 +#define TMC5062_OFS127_SHIFT 31 +#define TMC5062_OFS127_FIELD(motor) ((RegisterField) {TMC5062_OFS127_MASK, TMC5062_OFS127_SHIFT, TMC5062_MSLUT3(motor), false}) +#define TMC5062_OFS128_MASK 0x00000001 +#define TMC5062_OFS128_SHIFT 0 +#define TMC5062_OFS128_FIELD(motor) ((RegisterField) {TMC5062_OFS128_MASK, TMC5062_OFS128_SHIFT, TMC5062_MSLUT4(motor), false}) +#define TMC5062_OFS129_MASK 0x00000002 +#define TMC5062_OFS129_SHIFT 1 +#define TMC5062_OFS129_FIELD(motor) ((RegisterField) {TMC5062_OFS129_MASK, TMC5062_OFS129_SHIFT, TMC5062_MSLUT4(motor), false}) +#define TMC5062_OFS130_MASK 0x00000004 +#define TMC5062_OFS130_SHIFT 2 +#define TMC5062_OFS130_FIELD(motor) ((RegisterField) {TMC5062_OFS130_MASK, TMC5062_OFS130_SHIFT, TMC5062_MSLUT4(motor), false}) +#define TMC5062_OFS131_MASK 0x00000008 +#define TMC5062_OFS131_SHIFT 3 +#define TMC5062_OFS131_FIELD(motor) ((RegisterField) {TMC5062_OFS131_MASK, TMC5062_OFS131_SHIFT, TMC5062_MSLUT4(motor), false}) +#define TMC5062_OFS132_MASK 0x00000010 +#define TMC5062_OFS132_SHIFT 4 +#define TMC5062_OFS132_FIELD(motor) ((RegisterField) {TMC5062_OFS132_MASK, TMC5062_OFS132_SHIFT, TMC5062_MSLUT4(motor), false}) +#define TMC5062_OFS133_MASK 0x00000020 +#define TMC5062_OFS133_SHIFT 5 +#define TMC5062_OFS133_FIELD(motor) ((RegisterField) {TMC5062_OFS133_MASK, TMC5062_OFS133_SHIFT, TMC5062_MSLUT4(motor), false}) +#define TMC5062_OFS134_MASK 0x00000040 +#define TMC5062_OFS134_SHIFT 6 +#define TMC5062_OFS134_FIELD(motor) ((RegisterField) {TMC5062_OFS134_MASK, TMC5062_OFS134_SHIFT, TMC5062_MSLUT4(motor), false}) +#define TMC5062_OFS135_MASK 0x00000080 +#define TMC5062_OFS135_SHIFT 7 +#define TMC5062_OFS135_FIELD(motor) ((RegisterField) {TMC5062_OFS135_MASK, TMC5062_OFS135_SHIFT, TMC5062_MSLUT4(motor), false}) +#define TMC5062_OFS136_MASK 0x00000100 +#define TMC5062_OFS136_SHIFT 8 +#define TMC5062_OFS136_FIELD(motor) ((RegisterField) {TMC5062_OFS136_MASK, TMC5062_OFS136_SHIFT, TMC5062_MSLUT4(motor), false}) +#define TMC5062_OFS137_MASK 0x00000200 +#define TMC5062_OFS137_SHIFT 9 +#define TMC5062_OFS137_FIELD(motor) ((RegisterField) {TMC5062_OFS137_MASK, TMC5062_OFS137_SHIFT, TMC5062_MSLUT4(motor), false}) +#define TMC5062_OFS138_MASK 0x00000400 +#define TMC5062_OFS138_SHIFT 10 +#define TMC5062_OFS138_FIELD(motor) ((RegisterField) {TMC5062_OFS138_MASK, TMC5062_OFS138_SHIFT, TMC5062_MSLUT4(motor), false}) +#define TMC5062_OFS139_MASK 0x00000800 +#define TMC5062_OFS139_SHIFT 11 +#define TMC5062_OFS139_FIELD(motor) ((RegisterField) {TMC5062_OFS139_MASK, TMC5062_OFS139_SHIFT, TMC5062_MSLUT4(motor), false}) +#define TMC5062_OFS140_MASK 0x00001000 +#define TMC5062_OFS140_SHIFT 12 +#define TMC5062_OFS140_FIELD(motor) ((RegisterField) {TMC5062_OFS140_MASK, TMC5062_OFS140_SHIFT, TMC5062_MSLUT4(motor), false}) +#define TMC5062_OFS141_MASK 0x00002000 +#define TMC5062_OFS141_SHIFT 13 +#define TMC5062_OFS141_FIELD(motor) ((RegisterField) {TMC5062_OFS141_MASK, TMC5062_OFS141_SHIFT, TMC5062_MSLUT4(motor), false}) +#define TMC5062_OFS142_MASK 0x00004000 +#define TMC5062_OFS142_SHIFT 14 +#define TMC5062_OFS142_FIELD(motor) ((RegisterField) {TMC5062_OFS142_MASK, TMC5062_OFS142_SHIFT, TMC5062_MSLUT4(motor), false}) +#define TMC5062_OFS143_MASK 0x00008000 +#define TMC5062_OFS143_SHIFT 15 +#define TMC5062_OFS143_FIELD(motor) ((RegisterField) {TMC5062_OFS143_MASK, TMC5062_OFS143_SHIFT, TMC5062_MSLUT4(motor), false}) +#define TMC5062_OFS144_MASK 0x00010000 +#define TMC5062_OFS144_SHIFT 16 +#define TMC5062_OFS144_FIELD(motor) ((RegisterField) {TMC5062_OFS144_MASK, TMC5062_OFS144_SHIFT, TMC5062_MSLUT4(motor), false}) +#define TMC5062_OFS145_MASK 0x00020000 +#define TMC5062_OFS145_SHIFT 17 +#define TMC5062_OFS145_FIELD(motor) ((RegisterField) {TMC5062_OFS145_MASK, TMC5062_OFS145_SHIFT, TMC5062_MSLUT4(motor), false}) +#define TMC5062_OFS146_MASK 0x00040000 +#define TMC5062_OFS146_SHIFT 18 +#define TMC5062_OFS146_FIELD(motor) ((RegisterField) {TMC5062_OFS146_MASK, TMC5062_OFS146_SHIFT, TMC5062_MSLUT4(motor), false}) +#define TMC5062_OFS147_MASK 0x00080000 +#define TMC5062_OFS147_SHIFT 19 +#define TMC5062_OFS147_FIELD(motor) ((RegisterField) {TMC5062_OFS147_MASK, TMC5062_OFS147_SHIFT, TMC5062_MSLUT4(motor), false}) +#define TMC5062_OFS148_MASK 0x00100000 +#define TMC5062_OFS148_SHIFT 20 +#define TMC5062_OFS148_FIELD(motor) ((RegisterField) {TMC5062_OFS148_MASK, TMC5062_OFS148_SHIFT, TMC5062_MSLUT4(motor), false}) +#define TMC5062_OFS149_MASK 0x00200000 +#define TMC5062_OFS149_SHIFT 21 +#define TMC5062_OFS149_FIELD(motor) ((RegisterField) {TMC5062_OFS149_MASK, TMC5062_OFS149_SHIFT, TMC5062_MSLUT4(motor), false}) +#define TMC5062_OFS150_MASK 0x00400000 +#define TMC5062_OFS150_SHIFT 22 +#define TMC5062_OFS150_FIELD(motor) ((RegisterField) {TMC5062_OFS150_MASK, TMC5062_OFS150_SHIFT, TMC5062_MSLUT4(motor), false}) +#define TMC5062_OFS151_MASK 0x00800000 +#define TMC5062_OFS151_SHIFT 23 +#define TMC5062_OFS151_FIELD(motor) ((RegisterField) {TMC5062_OFS151_MASK, TMC5062_OFS151_SHIFT, TMC5062_MSLUT4(motor), false}) +#define TMC5062_OFS152_MASK 0x01000000 +#define TMC5062_OFS152_SHIFT 24 +#define TMC5062_OFS152_FIELD(motor) ((RegisterField) {TMC5062_OFS152_MASK, TMC5062_OFS152_SHIFT, TMC5062_MSLUT4(motor), false}) +#define TMC5062_OFS153_MASK 0x02000000 +#define TMC5062_OFS153_SHIFT 25 +#define TMC5062_OFS153_FIELD(motor) ((RegisterField) {TMC5062_OFS153_MASK, TMC5062_OFS153_SHIFT, TMC5062_MSLUT4(motor), false}) +#define TMC5062_OFS154_MASK 0x04000000 +#define TMC5062_OFS154_SHIFT 26 +#define TMC5062_OFS154_FIELD(motor) ((RegisterField) {TMC5062_OFS154_MASK, TMC5062_OFS154_SHIFT, TMC5062_MSLUT4(motor), false}) +#define TMC5062_OFS155_MASK 0x08000000 +#define TMC5062_OFS155_SHIFT 27 +#define TMC5062_OFS155_FIELD(motor) ((RegisterField) {TMC5062_OFS155_MASK, TMC5062_OFS155_SHIFT, TMC5062_MSLUT4(motor), false}) +#define TMC5062_OFS156_MASK 0x10000000 +#define TMC5062_OFS156_SHIFT 28 +#define TMC5062_OFS156_FIELD(motor) ((RegisterField) {TMC5062_OFS156_MASK, TMC5062_OFS156_SHIFT, TMC5062_MSLUT4(motor), false}) +#define TMC5062_OFS157_MASK 0x20000000 +#define TMC5062_OFS157_SHIFT 29 +#define TMC5062_OFS157_FIELD(motor) ((RegisterField) {TMC5062_OFS157_MASK, TMC5062_OFS157_SHIFT, TMC5062_MSLUT4(motor), false}) +#define TMC5062_OFS158_MASK 0x40000000 +#define TMC5062_OFS158_SHIFT 30 +#define TMC5062_OFS158_FIELD(motor) ((RegisterField) {TMC5062_OFS158_MASK, TMC5062_OFS158_SHIFT, TMC5062_MSLUT4(motor), false}) +#define TMC5062_OFS159_MASK 0x80000000 +#define TMC5062_OFS159_SHIFT 31 +#define TMC5062_OFS159_FIELD(motor) ((RegisterField) {TMC5062_OFS159_MASK, TMC5062_OFS159_SHIFT, TMC5062_MSLUT4(motor), false}) +#define TMC5062_OFS160_MASK 0x00000001 +#define TMC5062_OFS160_SHIFT 0 +#define TMC5062_OFS160_FIELD(motor) ((RegisterField) {TMC5062_OFS160_MASK, TMC5062_OFS160_SHIFT, TMC5062_MSLUT5(motor), false}) +#define TMC5062_OFS161_MASK 0x00000002 +#define TMC5062_OFS161_SHIFT 1 +#define TMC5062_OFS161_FIELD(motor) ((RegisterField) {TMC5062_OFS161_MASK, TMC5062_OFS161_SHIFT, TMC5062_MSLUT5(motor), false}) +#define TMC5062_OFS162_MASK 0x00000004 +#define TMC5062_OFS162_SHIFT 2 +#define TMC5062_OFS162_FIELD(motor) ((RegisterField) {TMC5062_OFS162_MASK, TMC5062_OFS162_SHIFT, TMC5062_MSLUT5(motor), false}) +#define TMC5062_OFS163_MASK 0x00000008 +#define TMC5062_OFS163_SHIFT 3 +#define TMC5062_OFS163_FIELD(motor) ((RegisterField) {TMC5062_OFS163_MASK, TMC5062_OFS163_SHIFT, TMC5062_MSLUT5(motor), false}) +#define TMC5062_OFS164_MASK 0x00000010 +#define TMC5062_OFS164_SHIFT 4 +#define TMC5062_OFS164_FIELD(motor) ((RegisterField) {TMC5062_OFS164_MASK, TMC5062_OFS164_SHIFT, TMC5062_MSLUT5(motor), false}) +#define TMC5062_OFS165_MASK 0x00000020 +#define TMC5062_OFS165_SHIFT 5 +#define TMC5062_OFS165_FIELD(motor) ((RegisterField) {TMC5062_OFS165_MASK, TMC5062_OFS165_SHIFT, TMC5062_MSLUT5(motor), false}) +#define TMC5062_OFS166_MASK 0x00000040 +#define TMC5062_OFS166_SHIFT 6 +#define TMC5062_OFS166_FIELD(motor) ((RegisterField) {TMC5062_OFS166_MASK, TMC5062_OFS166_SHIFT, TMC5062_MSLUT5(motor), false}) +#define TMC5062_OFS167_MASK 0x00000080 +#define TMC5062_OFS167_SHIFT 7 +#define TMC5062_OFS167_FIELD(motor) ((RegisterField) {TMC5062_OFS167_MASK, TMC5062_OFS167_SHIFT, TMC5062_MSLUT5(motor), false}) +#define TMC5062_OFS168_MASK 0x00000100 +#define TMC5062_OFS168_SHIFT 8 +#define TMC5062_OFS168_FIELD(motor) ((RegisterField) {TMC5062_OFS168_MASK, TMC5062_OFS168_SHIFT, TMC5062_MSLUT5(motor), false}) +#define TMC5062_OFS169_MASK 0x00000200 +#define TMC5062_OFS169_SHIFT 9 +#define TMC5062_OFS169_FIELD(motor) ((RegisterField) {TMC5062_OFS169_MASK, TMC5062_OFS169_SHIFT, TMC5062_MSLUT5(motor), false}) +#define TMC5062_OFS170_MASK 0x00000400 +#define TMC5062_OFS170_SHIFT 10 +#define TMC5062_OFS170_FIELD(motor) ((RegisterField) {TMC5062_OFS170_MASK, TMC5062_OFS170_SHIFT, TMC5062_MSLUT5(motor), false}) +#define TMC5062_OFS171_MASK 0x00000800 +#define TMC5062_OFS171_SHIFT 11 +#define TMC5062_OFS171_FIELD(motor) ((RegisterField) {TMC5062_OFS171_MASK, TMC5062_OFS171_SHIFT, TMC5062_MSLUT5(motor), false}) +#define TMC5062_OFS172_MASK 0x00001000 +#define TMC5062_OFS172_SHIFT 12 +#define TMC5062_OFS172_FIELD(motor) ((RegisterField) {TMC5062_OFS172_MASK, TMC5062_OFS172_SHIFT, TMC5062_MSLUT5(motor), false}) +#define TMC5062_OFS173_MASK 0x00002000 +#define TMC5062_OFS173_SHIFT 13 +#define TMC5062_OFS173_FIELD(motor) ((RegisterField) {TMC5062_OFS173_MASK, TMC5062_OFS173_SHIFT, TMC5062_MSLUT5(motor), false}) +#define TMC5062_OFS174_MASK 0x00004000 +#define TMC5062_OFS174_SHIFT 14 +#define TMC5062_OFS174_FIELD(motor) ((RegisterField) {TMC5062_OFS174_MASK, TMC5062_OFS174_SHIFT, TMC5062_MSLUT5(motor), false}) +#define TMC5062_OFS175_MASK 0x00008000 +#define TMC5062_OFS175_SHIFT 15 +#define TMC5062_OFS175_FIELD(motor) ((RegisterField) {TMC5062_OFS175_MASK, TMC5062_OFS175_SHIFT, TMC5062_MSLUT5(motor), false}) +#define TMC5062_OFS176_MASK 0x00010000 +#define TMC5062_OFS176_SHIFT 16 +#define TMC5062_OFS176_FIELD(motor) ((RegisterField) {TMC5062_OFS176_MASK, TMC5062_OFS176_SHIFT, TMC5062_MSLUT5(motor), false}) +#define TMC5062_OFS177_MASK 0x00020000 +#define TMC5062_OFS177_SHIFT 17 +#define TMC5062_OFS177_FIELD(motor) ((RegisterField) {TMC5062_OFS177_MASK, TMC5062_OFS177_SHIFT, TMC5062_MSLUT5(motor), false}) +#define TMC5062_OFS178_MASK 0x00040000 +#define TMC5062_OFS178_SHIFT 18 +#define TMC5062_OFS178_FIELD(motor) ((RegisterField) {TMC5062_OFS178_MASK, TMC5062_OFS178_SHIFT, TMC5062_MSLUT5(motor), false}) +#define TMC5062_OFS179_MASK 0x00080000 +#define TMC5062_OFS179_SHIFT 19 +#define TMC5062_OFS179_FIELD(motor) ((RegisterField) {TMC5062_OFS179_MASK, TMC5062_OFS179_SHIFT, TMC5062_MSLUT5(motor), false}) +#define TMC5062_OFS180_MASK 0x00100000 +#define TMC5062_OFS180_SHIFT 20 +#define TMC5062_OFS180_FIELD(motor) ((RegisterField) {TMC5062_OFS180_MASK, TMC5062_OFS180_SHIFT, TMC5062_MSLUT5(motor), false}) +#define TMC5062_OFS181_MASK 0x00200000 +#define TMC5062_OFS181_SHIFT 21 +#define TMC5062_OFS181_FIELD(motor) ((RegisterField) {TMC5062_OFS181_MASK, TMC5062_OFS181_SHIFT, TMC5062_MSLUT5(motor), false}) +#define TMC5062_OFS182_MASK 0x00400000 +#define TMC5062_OFS182_SHIFT 22 +#define TMC5062_OFS182_FIELD(motor) ((RegisterField) {TMC5062_OFS182_MASK, TMC5062_OFS182_SHIFT, TMC5062_MSLUT5(motor), false}) +#define TMC5062_OFS183_MASK 0x00800000 +#define TMC5062_OFS183_SHIFT 23 +#define TMC5062_OFS183_FIELD(motor) ((RegisterField) {TMC5062_OFS183_MASK, TMC5062_OFS183_SHIFT, TMC5062_MSLUT5(motor), false}) +#define TMC5062_OFS184_MASK 0x01000000 +#define TMC5062_OFS184_SHIFT 24 +#define TMC5062_OFS184_FIELD(motor) ((RegisterField) {TMC5062_OFS184_MASK, TMC5062_OFS184_SHIFT, TMC5062_MSLUT5(motor), false}) +#define TMC5062_OFS185_MASK 0x02000000 +#define TMC5062_OFS185_SHIFT 25 +#define TMC5062_OFS185_FIELD(motor) ((RegisterField) {TMC5062_OFS185_MASK, TMC5062_OFS185_SHIFT, TMC5062_MSLUT5(motor), false}) +#define TMC5062_OFS186_MASK 0x04000000 +#define TMC5062_OFS186_SHIFT 26 +#define TMC5062_OFS186_FIELD(motor) ((RegisterField) {TMC5062_OFS186_MASK, TMC5062_OFS186_SHIFT, TMC5062_MSLUT5(motor), false}) +#define TMC5062_OFS187_MASK 0x08000000 +#define TMC5062_OFS187_SHIFT 27 +#define TMC5062_OFS187_FIELD(motor) ((RegisterField) {TMC5062_OFS187_MASK, TMC5062_OFS187_SHIFT, TMC5062_MSLUT5(motor), false}) +#define TMC5062_OFS188_MASK 0x10000000 +#define TMC5062_OFS188_SHIFT 28 +#define TMC5062_OFS188_FIELD(motor) ((RegisterField) {TMC5062_OFS188_MASK, TMC5062_OFS188_SHIFT, TMC5062_MSLUT5(motor), false}) +#define TMC5062_OFS189_MASK 0x20000000 +#define TMC5062_OFS189_SHIFT 29 +#define TMC5062_OFS189_FIELD(motor) ((RegisterField) {TMC5062_OFS189_MASK, TMC5062_OFS189_SHIFT, TMC5062_MSLUT5(motor), false}) +#define TMC5062_OFS190_MASK 0x40000000 +#define TMC5062_OFS190_SHIFT 30 +#define TMC5062_OFS190_FIELD(motor) ((RegisterField) {TMC5062_OFS190_MASK, TMC5062_OFS190_SHIFT, TMC5062_MSLUT5(motor), false}) +#define TMC5062_OFS191_MASK 0x80000000 +#define TMC5062_OFS191_SHIFT 31 +#define TMC5062_OFS191_FIELD(motor) ((RegisterField) {TMC5062_OFS191_MASK, TMC5062_OFS191_SHIFT, TMC5062_MSLUT5(motor), false}) +#define TMC5062_OFS192_MASK 0x00000001 +#define TMC5062_OFS192_SHIFT 0 +#define TMC5062_OFS192_FIELD(motor) ((RegisterField) {TMC5062_OFS192_MASK, TMC5062_OFS192_SHIFT, TMC5062_MSLUT6(motor), false}) +#define TMC5062_OFS193_MASK 0x00000002 +#define TMC5062_OFS193_SHIFT 1 +#define TMC5062_OFS193_FIELD(motor) ((RegisterField) {TMC5062_OFS193_MASK, TMC5062_OFS193_SHIFT, TMC5062_MSLUT6(motor), false}) +#define TMC5062_OFS194_MASK 0x00000004 +#define TMC5062_OFS194_SHIFT 2 +#define TMC5062_OFS194_FIELD(motor) ((RegisterField) {TMC5062_OFS194_MASK, TMC5062_OFS194_SHIFT, TMC5062_MSLUT6(motor), false}) +#define TMC5062_OFS195_MASK 0x00000008 +#define TMC5062_OFS195_SHIFT 3 +#define TMC5062_OFS195_FIELD(motor) ((RegisterField) {TMC5062_OFS195_MASK, TMC5062_OFS195_SHIFT, TMC5062_MSLUT6(motor), false}) +#define TMC5062_OFS196_MASK 0x00000010 +#define TMC5062_OFS196_SHIFT 4 +#define TMC5062_OFS196_FIELD(motor) ((RegisterField) {TMC5062_OFS196_MASK, TMC5062_OFS196_SHIFT, TMC5062_MSLUT6(motor), false}) +#define TMC5062_OFS197_MASK 0x00000020 +#define TMC5062_OFS197_SHIFT 5 +#define TMC5062_OFS197_FIELD(motor) ((RegisterField) {TMC5062_OFS197_MASK, TMC5062_OFS197_SHIFT, TMC5062_MSLUT6(motor), false}) +#define TMC5062_OFS198_MASK 0x00000040 +#define TMC5062_OFS198_SHIFT 6 +#define TMC5062_OFS198_FIELD(motor) ((RegisterField) {TMC5062_OFS198_MASK, TMC5062_OFS198_SHIFT, TMC5062_MSLUT6(motor), false}) +#define TMC5062_OFS199_MASK 0x00000080 +#define TMC5062_OFS199_SHIFT 7 +#define TMC5062_OFS199_FIELD(motor) ((RegisterField) {TMC5062_OFS199_MASK, TMC5062_OFS199_SHIFT, TMC5062_MSLUT6(motor), false}) +#define TMC5062_OFS200_MASK 0x00000100 +#define TMC5062_OFS200_SHIFT 8 +#define TMC5062_OFS200_FIELD(motor) ((RegisterField) {TMC5062_OFS200_MASK, TMC5062_OFS200_SHIFT, TMC5062_MSLUT6(motor), false}) +#define TMC5062_OFS201_MASK 0x00000200 +#define TMC5062_OFS201_SHIFT 9 +#define TMC5062_OFS201_FIELD(motor) ((RegisterField) {TMC5062_OFS201_MASK, TMC5062_OFS201_SHIFT, TMC5062_MSLUT6(motor), false}) +#define TMC5062_OFS202_MASK 0x00000400 +#define TMC5062_OFS202_SHIFT 10 +#define TMC5062_OFS202_FIELD(motor) ((RegisterField) {TMC5062_OFS202_MASK, TMC5062_OFS202_SHIFT, TMC5062_MSLUT6(motor), false}) +#define TMC5062_OFS203_MASK 0x00000800 +#define TMC5062_OFS203_SHIFT 11 +#define TMC5062_OFS203_FIELD(motor) ((RegisterField) {TMC5062_OFS203_MASK, TMC5062_OFS203_SHIFT, TMC5062_MSLUT6(motor), false}) +#define TMC5062_OFS204_MASK 0x00001000 +#define TMC5062_OFS204_SHIFT 12 +#define TMC5062_OFS204_FIELD(motor) ((RegisterField) {TMC5062_OFS204_MASK, TMC5062_OFS204_SHIFT, TMC5062_MSLUT6(motor), false}) +#define TMC5062_OFS205_MASK 0x00002000 +#define TMC5062_OFS205_SHIFT 13 +#define TMC5062_OFS205_FIELD(motor) ((RegisterField) {TMC5062_OFS205_MASK, TMC5062_OFS205_SHIFT, TMC5062_MSLUT6(motor), false}) +#define TMC5062_OFS206_MASK 0x00004000 +#define TMC5062_OFS206_SHIFT 14 +#define TMC5062_OFS206_FIELD(motor) ((RegisterField) {TMC5062_OFS206_MASK, TMC5062_OFS206_SHIFT, TMC5062_MSLUT6(motor), false}) +#define TMC5062_OFS207_MASK 0x00008000 +#define TMC5062_OFS207_SHIFT 15 +#define TMC5062_OFS207_FIELD(motor) ((RegisterField) {TMC5062_OFS207_MASK, TMC5062_OFS207_SHIFT, TMC5062_MSLUT6(motor), false}) +#define TMC5062_OFS208_MASK 0x00010000 +#define TMC5062_OFS208_SHIFT 16 +#define TMC5062_OFS208_FIELD(motor) ((RegisterField) {TMC5062_OFS208_MASK, TMC5062_OFS208_SHIFT, TMC5062_MSLUT6(motor), false}) +#define TMC5062_OFS209_MASK 0x00020000 +#define TMC5062_OFS209_SHIFT 17 +#define TMC5062_OFS209_FIELD(motor) ((RegisterField) {TMC5062_OFS209_MASK, TMC5062_OFS209_SHIFT, TMC5062_MSLUT6(motor), false}) +#define TMC5062_OFS210_MASK 0x00040000 +#define TMC5062_OFS210_SHIFT 18 +#define TMC5062_OFS210_FIELD(motor) ((RegisterField) {TMC5062_OFS210_MASK, TMC5062_OFS210_SHIFT, TMC5062_MSLUT6(motor), false}) +#define TMC5062_OFS211_MASK 0x00080000 +#define TMC5062_OFS211_SHIFT 19 +#define TMC5062_OFS211_FIELD(motor) ((RegisterField) {TMC5062_OFS211_MASK, TMC5062_OFS211_SHIFT, TMC5062_MSLUT6(motor), false}) +#define TMC5062_OFS212_MASK 0x00100000 +#define TMC5062_OFS212_SHIFT 20 +#define TMC5062_OFS212_FIELD(motor) ((RegisterField) {TMC5062_OFS212_MASK, TMC5062_OFS212_SHIFT, TMC5062_MSLUT6(motor), false}) +#define TMC5062_OFS213_MASK 0x00200000 +#define TMC5062_OFS213_SHIFT 21 +#define TMC5062_OFS213_FIELD(motor) ((RegisterField) {TMC5062_OFS213_MASK, TMC5062_OFS213_SHIFT, TMC5062_MSLUT6(motor), false}) +#define TMC5062_OFS214_MASK 0x00400000 +#define TMC5062_OFS214_SHIFT 22 +#define TMC5062_OFS214_FIELD(motor) ((RegisterField) {TMC5062_OFS214_MASK, TMC5062_OFS214_SHIFT, TMC5062_MSLUT6(motor), false}) +#define TMC5062_OFS215_MASK 0x00800000 +#define TMC5062_OFS215_SHIFT 23 +#define TMC5062_OFS215_FIELD(motor) ((RegisterField) {TMC5062_OFS215_MASK, TMC5062_OFS215_SHIFT, TMC5062_MSLUT6(motor), false}) +#define TMC5062_OFS216_MASK 0x01000000 +#define TMC5062_OFS216_SHIFT 24 +#define TMC5062_OFS216_FIELD(motor) ((RegisterField) {TMC5062_OFS216_MASK, TMC5062_OFS216_SHIFT, TMC5062_MSLUT6(motor), false}) +#define TMC5062_OFS217_MASK 0x02000000 +#define TMC5062_OFS217_SHIFT 25 +#define TMC5062_OFS217_FIELD(motor) ((RegisterField) {TMC5062_OFS217_MASK, TMC5062_OFS217_SHIFT, TMC5062_MSLUT6(motor), false}) +#define TMC5062_OFS218_MASK 0x04000000 +#define TMC5062_OFS218_SHIFT 26 +#define TMC5062_OFS218_FIELD(motor) ((RegisterField) {TMC5062_OFS218_MASK, TMC5062_OFS218_SHIFT, TMC5062_MSLUT6(motor), false}) +#define TMC5062_OFS219_MASK 0x08000000 +#define TMC5062_OFS219_SHIFT 27 +#define TMC5062_OFS219_FIELD(motor) ((RegisterField) {TMC5062_OFS219_MASK, TMC5062_OFS219_SHIFT, TMC5062_MSLUT6(motor), false}) +#define TMC5062_OFS220_MASK 0x10000000 +#define TMC5062_OFS220_SHIFT 28 +#define TMC5062_OFS220_FIELD(motor) ((RegisterField) {TMC5062_OFS220_MASK, TMC5062_OFS220_SHIFT, TMC5062_MSLUT6(motor), false}) +#define TMC5062_OFS221_MASK 0x20000000 +#define TMC5062_OFS221_SHIFT 29 +#define TMC5062_OFS221_FIELD(motor) ((RegisterField) {TMC5062_OFS221_MASK, TMC5062_OFS221_SHIFT, TMC5062_MSLUT6(motor), false}) +#define TMC5062_OFS222_MASK 0x40000000 +#define TMC5062_OFS222_SHIFT 30 +#define TMC5062_OFS222_FIELD(motor) ((RegisterField) {TMC5062_OFS222_MASK, TMC5062_OFS222_SHIFT, TMC5062_MSLUT6(motor), false}) +#define TMC5062_OFS223_MASK 0x80000000 +#define TMC5062_OFS223_SHIFT 31 +#define TMC5062_OFS223_FIELD(motor) ((RegisterField) {TMC5062_OFS223_MASK, TMC5062_OFS223_SHIFT, TMC5062_MSLUT6(motor), false}) +#define TMC5062_OFS224_MASK 0x00000001 +#define TMC5062_OFS224_SHIFT 0 +#define TMC5062_OFS224_FIELD(motor) ((RegisterField) {TMC5062_OFS224_MASK, TMC5062_OFS224_SHIFT, TMC5062_MSLUT7(motor), false}) +#define TMC5062_OFS225_MASK 0x00000002 +#define TMC5062_OFS225_SHIFT 1 +#define TMC5062_OFS225_FIELD(motor) ((RegisterField) {TMC5062_OFS225_MASK, TMC5062_OFS225_SHIFT, TMC5062_MSLUT7(motor), false}) +#define TMC5062_OFS226_MASK 0x00000004 +#define TMC5062_OFS226_SHIFT 2 +#define TMC5062_OFS226_FIELD(motor) ((RegisterField) {TMC5062_OFS226_MASK, TMC5062_OFS226_SHIFT, TMC5062_MSLUT7(motor), false}) +#define TMC5062_OFS227_MASK 0x00000008 +#define TMC5062_OFS227_SHIFT 3 +#define TMC5062_OFS227_FIELD(motor) ((RegisterField) {TMC5062_OFS227_MASK, TMC5062_OFS227_SHIFT, TMC5062_MSLUT7(motor), false}) +#define TMC5062_OFS228_MASK 0x00000010 +#define TMC5062_OFS228_SHIFT 4 +#define TMC5062_OFS228_FIELD(motor) ((RegisterField) {TMC5062_OFS228_MASK, TMC5062_OFS228_SHIFT, TMC5062_MSLUT7(motor), false}) +#define TMC5062_OFS229_MASK 0x00000020 +#define TMC5062_OFS229_SHIFT 5 +#define TMC5062_OFS229_FIELD(motor) ((RegisterField) {TMC5062_OFS229_MASK, TMC5062_OFS229_SHIFT, TMC5062_MSLUT7(motor), false}) +#define TMC5062_OFS230_MASK 0x00000040 +#define TMC5062_OFS230_SHIFT 6 +#define TMC5062_OFS230_FIELD(motor) ((RegisterField) {TMC5062_OFS230_MASK, TMC5062_OFS230_SHIFT, TMC5062_MSLUT7(motor), false}) +#define TMC5062_OFS231_MASK 0x00000080 +#define TMC5062_OFS231_SHIFT 7 +#define TMC5062_OFS231_FIELD(motor) ((RegisterField) {TMC5062_OFS231_MASK, TMC5062_OFS231_SHIFT, TMC5062_MSLUT7(motor), false}) +#define TMC5062_OFS232_MASK 0x00000100 +#define TMC5062_OFS232_SHIFT 8 +#define TMC5062_OFS232_FIELD(motor) ((RegisterField) {TMC5062_OFS232_MASK, TMC5062_OFS232_SHIFT, TMC5062_MSLUT7(motor), false}) +#define TMC5062_OFS233_MASK 0x00000200 +#define TMC5062_OFS233_SHIFT 9 +#define TMC5062_OFS233_FIELD(motor) ((RegisterField) {TMC5062_OFS233_MASK, TMC5062_OFS233_SHIFT, TMC5062_MSLUT7(motor), false}) +#define TMC5062_OFS234_MASK 0x00000400 +#define TMC5062_OFS234_SHIFT 10 +#define TMC5062_OFS234_FIELD(motor) ((RegisterField) {TMC5062_OFS234_MASK, TMC5062_OFS234_SHIFT, TMC5062_MSLUT7(motor), false}) +#define TMC5062_OFS235_MASK 0x00000800 +#define TMC5062_OFS235_SHIFT 11 +#define TMC5062_OFS235_FIELD(motor) ((RegisterField) {TMC5062_OFS235_MASK, TMC5062_OFS235_SHIFT, TMC5062_MSLUT7(motor), false}) +#define TMC5062_OFS236_MASK 0x00001000 +#define TMC5062_OFS236_SHIFT 12 +#define TMC5062_OFS236_FIELD(motor) ((RegisterField) {TMC5062_OFS236_MASK, TMC5062_OFS236_SHIFT, TMC5062_MSLUT7(motor), false}) +#define TMC5062_OFS237_MASK 0x00002000 +#define TMC5062_OFS237_SHIFT 13 +#define TMC5062_OFS237_FIELD(motor) ((RegisterField) {TMC5062_OFS237_MASK, TMC5062_OFS237_SHIFT, TMC5062_MSLUT7(motor), false}) +#define TMC5062_OFS238_MASK 0x00004000 +#define TMC5062_OFS238_SHIFT 14 +#define TMC5062_OFS238_FIELD(motor) ((RegisterField) {TMC5062_OFS238_MASK, TMC5062_OFS238_SHIFT, TMC5062_MSLUT7(motor), false}) +#define TMC5062_OFS239_MASK 0x00008000 +#define TMC5062_OFS239_SHIFT 15 +#define TMC5062_OFS239_FIELD(motor) ((RegisterField) {TMC5062_OFS239_MASK, TMC5062_OFS239_SHIFT, TMC5062_MSLUT7(motor), false}) +#define TMC5062_OFS240_MASK 0x00010000 +#define TMC5062_OFS240_SHIFT 16 +#define TMC5062_OFS240_FIELD(motor) ((RegisterField) {TMC5062_OFS240_MASK, TMC5062_OFS240_SHIFT, TMC5062_MSLUT7(motor), false}) +#define TMC5062_OFS241_MASK 0x00020000 +#define TMC5062_OFS241_SHIFT 17 +#define TMC5062_OFS241_FIELD(motor) ((RegisterField) {TMC5062_OFS241_MASK, TMC5062_OFS241_SHIFT, TMC5062_MSLUT7(motor), false}) +#define TMC5062_OFS242_MASK 0x00040000 +#define TMC5062_OFS242_SHIFT 18 +#define TMC5062_OFS242_FIELD(motor) ((RegisterField) {TMC5062_OFS242_MASK, TMC5062_OFS242_SHIFT, TMC5062_MSLUT7(motor), false}) +#define TMC5062_OFS243_MASK 0x00080000 +#define TMC5062_OFS243_SHIFT 19 +#define TMC5062_OFS243_FIELD(motor) ((RegisterField) {TMC5062_OFS243_MASK, TMC5062_OFS243_SHIFT, TMC5062_MSLUT7(motor), false}) +#define TMC5062_OFS244_MASK 0x00100000 +#define TMC5062_OFS244_SHIFT 20 +#define TMC5062_OFS244_FIELD(motor) ((RegisterField) {TMC5062_OFS244_MASK, TMC5062_OFS244_SHIFT, TMC5062_MSLUT7(motor), false}) +#define TMC5062_OFS245_MASK 0x00200000 +#define TMC5062_OFS245_SHIFT 21 +#define TMC5062_OFS245_FIELD(motor) ((RegisterField) {TMC5062_OFS245_MASK, TMC5062_OFS245_SHIFT, TMC5062_MSLUT7(motor), false}) +#define TMC5062_OFS246_MASK 0x00400000 +#define TMC5062_OFS246_SHIFT 22 +#define TMC5062_OFS246_FIELD(motor) ((RegisterField) {TMC5062_OFS246_MASK, TMC5062_OFS246_SHIFT, TMC5062_MSLUT7(motor), false}) +#define TMC5062_OFS247_MASK 0x00800000 +#define TMC5062_OFS247_SHIFT 23 +#define TMC5062_OFS247_FIELD(motor) ((RegisterField) {TMC5062_OFS247_MASK, TMC5062_OFS247_SHIFT, TMC5062_MSLUT7(motor), false}) +#define TMC5062_OFS248_MASK 0x01000000 +#define TMC5062_OFS248_SHIFT 24 +#define TMC5062_OFS248_FIELD(motor) ((RegisterField) {TMC5062_OFS248_MASK, TMC5062_OFS248_SHIFT, TMC5062_MSLUT7(motor), false}) +#define TMC5062_OFS249_MASK 0x02000000 +#define TMC5062_OFS249_SHIFT 25 +#define TMC5062_OFS249_FIELD(motor) ((RegisterField) {TMC5062_OFS249_MASK, TMC5062_OFS249_SHIFT, TMC5062_MSLUT7(motor), false}) +#define TMC5062_OFS250_MASK 0x04000000 +#define TMC5062_OFS250_SHIFT 26 +#define TMC5062_OFS250_FIELD(motor) ((RegisterField) {TMC5062_OFS250_MASK, TMC5062_OFS250_SHIFT, TMC5062_MSLUT7(motor), false}) +#define TMC5062_OFS251_MASK 0x08000000 +#define TMC5062_OFS251_SHIFT 27 +#define TMC5062_OFS251_FIELD(motor) ((RegisterField) {TMC5062_OFS251_MASK, TMC5062_OFS251_SHIFT, TMC5062_MSLUT7(motor), false}) +#define TMC5062_OFS252_MASK 0x10000000 +#define TMC5062_OFS252_SHIFT 28 +#define TMC5062_OFS252_FIELD(motor) ((RegisterField) {TMC5062_OFS252_MASK, TMC5062_OFS252_SHIFT, TMC5062_MSLUT7(motor), false}) +#define TMC5062_OFS253_MASK 0x20000000 +#define TMC5062_OFS253_SHIFT 29 +#define TMC5062_OFS253_FIELD(motor) ((RegisterField) {TMC5062_OFS253_MASK, TMC5062_OFS253_SHIFT, TMC5062_MSLUT7(motor), false}) +#define TMC5062_OFS254_MASK 0x40000000 +#define TMC5062_OFS254_SHIFT 30 +#define TMC5062_OFS254_FIELD(motor) ((RegisterField) {TMC5062_OFS254_MASK, TMC5062_OFS254_SHIFT, TMC5062_MSLUT7(motor), false}) +#define TMC5062_OFS255_MASK 0x80000000 +#define TMC5062_OFS255_SHIFT 31 +#define TMC5062_OFS255_FIELD(motor) ((RegisterField) {TMC5062_OFS255_MASK, TMC5062_OFS255_SHIFT, TMC5062_MSLUT7(motor), false}) +#define TMC5062_W0_MASK 0x00000003 +#define TMC5062_W0_SHIFT 0 +#define TMC5062_W0_FIELD(motor) ((RegisterField) {TMC5062_W0_MASK, TMC5062_W0_SHIFT, TMC5062_MSLUTSEL(motor), false}) +#define TMC5062_W1_MASK 0x0000000C +#define TMC5062_W1_SHIFT 2 +#define TMC5062_W1_FIELD(motor) ((RegisterField) {TMC5062_W1_MASK, TMC5062_W1_SHIFT, TMC5062_MSLUTSEL(motor), false}) +#define TMC5062_W2_MASK 0x00000030 +#define TMC5062_W2_SHIFT 4 +#define TMC5062_W2_FIELD(motor) ((RegisterField) {TMC5062_W2_MASK, TMC5062_W2_SHIFT, TMC5062_MSLUTSEL(motor), false}) +#define TMC5062_W3_MASK 0x000000C0 +#define TMC5062_W3_SHIFT 6 +#define TMC5062_W3_FIELD(motor) ((RegisterField) {TMC5062_W3_MASK, TMC5062_W3_SHIFT, TMC5062_MSLUTSEL(motor), false}) +#define TMC5062_X1_MASK 0x0000FF00 +#define TMC5062_X1_SHIFT 8 +#define TMC5062_X1_FIELD(motor) ((RegisterField) {TMC5062_X1_MASK, TMC5062_X1_SHIFT, TMC5062_MSLUTSEL(motor), false}) +#define TMC5062_X2_MASK 0x00FF0000 +#define TMC5062_X2_SHIFT 16 +#define TMC5062_X2_FIELD(motor) ((RegisterField) {TMC5062_X2_MASK, TMC5062_X2_SHIFT, TMC5062_MSLUTSEL(motor), false}) +#define TMC5062_X3_MASK 0xFF000000 +#define TMC5062_X3_SHIFT 24 +#define TMC5062_X3_FIELD(motor) ((RegisterField) {TMC5062_X3_MASK, TMC5062_X3_SHIFT, TMC5062_MSLUTSEL(motor), false}) +#define TMC5062_START_SIN_MASK 0x000000FF +#define TMC5062_START_SIN_SHIFT 0 +#define TMC5062_START_SIN_FIELD(motor) ((RegisterField) {TMC5062_START_SIN_MASK, TMC5062_START_SIN_SHIFT, TMC5062_MSLUTSTART(motor), false}) +#define TMC5062_START_SIN90_MASK 0x00FF0000 +#define TMC5062_START_SIN90_SHIFT 16 +#define TMC5062_START_SIN90_FIELD(motor) ((RegisterField) {TMC5062_START_SIN90_MASK, TMC5062_START_SIN90_SHIFT, TMC5062_MSLUTSTART(motor), false}) +#define TMC5062_MSCNT_MASK 0x000003FF +#define TMC5062_MSCNT_SHIFT 0 +#define TMC5062_MSCNT_FIELD(motor) ((RegisterField) {TMC5062_MSCNT_MASK, TMC5062_MSCNT_SHIFT, TMC5062_MSCNT(motor), false}) +#define TMC5062_CUR_A_MASK 0x000001FF +#define TMC5062_CUR_A_SHIFT 0 +#define TMC5062_CUR_A_FIELD(motor) ((RegisterField) {TMC5062_CUR_A_MASK, TMC5062_CUR_A_SHIFT, TMC5062_MSCURACT(motor), true}) +#define TMC5062_CUR_B_MASK 0x01FF0000 +#define TMC5062_CUR_B_SHIFT 16 +#define TMC5062_CUR_B_FIELD(motor) ((RegisterField) {TMC5062_CUR_B_MASK, TMC5062_CUR_B_SHIFT, TMC5062_MSCURACT(motor), true}) +#define TMC5062_TOFF_MASK 0x0000000F +#define TMC5062_TOFF_SHIFT 0 +#define TMC5062_TOFF_FIELD(motor) ((RegisterField) {TMC5062_TOFF_MASK, TMC5062_TOFF_SHIFT, TMC5062_CHOPCONF(motor), false}) +#define TMC5062_TFD_ALL_MASK 0x00000070 +#define TMC5062_TFD_ALL_SHIFT 4 +#define TMC5062_TFD_ALL_FIELD(motor) ((RegisterField) {TMC5062_TFD_ALL_MASK, TMC5062_TFD_ALL_SHIFT, TMC5062_CHOPCONF(motor), false}) +#define TMC5062_OFFSET_MASK 0x00000780 +#define TMC5062_OFFSET_SHIFT 7 +#define TMC5062_OFFSET_FIELD(motor) ((RegisterField) {TMC5062_OFFSET_MASK, TMC5062_OFFSET_SHIFT, TMC5062_CHOPCONF(motor), false}) +#define TMC5062_TFD_3_MASK 0x00000800 +#define TMC5062_TFD_3_SHIFT 11 +#define TMC5062_TFD_3_FIELD(motor) ((RegisterField) {TMC5062_TFD_3_MASK, TMC5062_TFD_3_SHIFT, TMC5062_CHOPCONF(motor), false}) +#define TMC5062_DISFDCC_MASK 0x00001000 +#define TMC5062_DISFDCC_SHIFT 12 +#define TMC5062_DISFDCC_FIELD(motor) ((RegisterField) {TMC5062_DISFDCC_MASK, TMC5062_DISFDCC_SHIFT, TMC5062_CHOPCONF(motor), false}) +#define TMC5062_RNDTF_MASK 0x00002000 +#define TMC5062_RNDTF_SHIFT 13 +#define TMC5062_RNDTF_FIELD(motor) ((RegisterField) {TMC5062_RNDTF_MASK, TMC5062_RNDTF_SHIFT, TMC5062_CHOPCONF(motor), false}) +#define TMC5062_CHM_MASK 0x00004000 +#define TMC5062_CHM_SHIFT 14 +#define TMC5062_CHM_FIELD(motor) ((RegisterField) {TMC5062_CHM_MASK, TMC5062_CHM_SHIFT, TMC5062_CHOPCONF(motor), false}) +#define TMC5062_TBL_MASK 0x00018000 +#define TMC5062_TBL_SHIFT 15 +#define TMC5062_TBL_FIELD(motor) ((RegisterField) {TMC5062_TBL_MASK, TMC5062_TBL_SHIFT, TMC5062_CHOPCONF(motor), false}) +#define TMC5062_VSENSE_MASK 0x00020000 +#define TMC5062_VSENSE_SHIFT 17 +#define TMC5062_VSENSE_FIELD(motor) ((RegisterField) {TMC5062_VSENSE_MASK, TMC5062_VSENSE_SHIFT, TMC5062_CHOPCONF(motor), false}) +#define TMC5062_VHIGHFS_MASK 0x00040000 +#define TMC5062_VHIGHFS_SHIFT 18 +#define TMC5062_VHIGHFS_FIELD(motor) ((RegisterField) {TMC5062_VHIGHFS_MASK, TMC5062_VHIGHFS_SHIFT, TMC5062_CHOPCONF(motor), false}) +#define TMC5062_VHIGHCHM_MASK 0x00080000 +#define TMC5062_VHIGHCHM_SHIFT 19 +#define TMC5062_VHIGHCHM_FIELD(motor) ((RegisterField) {TMC5062_VHIGHCHM_MASK, TMC5062_VHIGHCHM_SHIFT, TMC5062_CHOPCONF(motor), false}) +#define TMC5062_MRES_MASK 0x0F000000 // CHOPCONF_M2 // Microstep Resolution (manually added) +#define TMC5062_MRES_SHIFT 24 // min.: 1, max.: 256, default: 256 +#define TMC5062_MRES_FIELD(motor) ((RegisterField) {TMC5062_MRES_MASK, TMC5062_MRES_SHIFT, TMC5062_CHOPCONF(motor), false}) +#define TMC5062_SYNC_MASK 0x00F00000 +#define TMC5062_SYNC_SHIFT 20 +#define TMC5062_SYNC_FIELD(motor) ((RegisterField) {TMC5062_SYNC_MASK, TMC5062_SYNC_SHIFT, TMC5062_CHOPCONF(motor), false}) +#define TMC5062_DISS2G_MASK 0x40000000 +#define TMC5062_DISS2G_SHIFT 30 +#define TMC5062_DISS2G_FIELD(motor) ((RegisterField) {TMC5062_DISS2G_MASK, TMC5062_DISS2G_SHIFT, TMC5062_CHOPCONF(motor), false}) +#define TMC5062_HSTRT_MASK 0x00000070 +#define TMC5062_HSTRT_SHIFT 4 +#define TMC5062_HSTRT_FIELD(motor) ((RegisterField) {TMC5062_HSTRT_MASK, TMC5062_HSTRT_SHIFT, TMC5062_CHOPCONF(motor), false}) +#define TMC5062_HEND_MASK 0x00000780 +#define TMC5062_HEND_SHIFT 7 +#define TMC5062_HEND_FIELD(motor) ((RegisterField) {TMC5062_HEND_MASK, TMC5062_HEND_SHIFT, TMC5062_CHOPCONF(motor), false}) +#define TMC5062_PH3SEL_MASK 0x80000000 +#define TMC5062_PH3SEL_SHIFT 31 +#define TMC5062_PH3SEL_FIELD(motor) ((RegisterField) {TMC5062_PH3SEL_MASK, TMC5062_PH3SEL_SHIFT, TMC5062_CHOPCONF(motor), false}) +#define TMC5062_HYST_MASK 0x000003F0 +#define TMC5062_HYST_SHIFT 4 +#define TMC5062_HYST_FIELD(motor) ((RegisterField) {TMC5062_HYST_MASK, TMC5062_HYST_SHIFT, TMC5062_CHOPCONF(motor), false}) +#define TMC5062_NOSD3PH_MASK 0x00000400 +#define TMC5062_NOSD3PH_SHIFT 10 +#define TMC5062_NOSD3PH_FIELD(motor) ((RegisterField) {TMC5062_NOSD3PH_MASK, TMC5062_NOSD3PH_SHIFT, TMC5062_CHOPCONF(motor), false}) +#define TMC5062_CSYNC_MASK 0x00001000 +#define TMC5062_CSYNC_SHIFT 12 +#define TMC5062_CSYNC_FIELD(motor) ((RegisterField) {TMC5062_CSYNC_MASK, TMC5062_CSYNC_SHIFT, TMC5062_CHOPCONF(motor), false}) +#define TMC5062_SEMIN_MASK 0x0000000F +#define TMC5062_SEMIN_SHIFT 0 +#define TMC5062_SEMIN_FIELD(motor) ((RegisterField) {TMC5062_SEMIN_MASK, TMC5062_SEMIN_SHIFT, TMC5062_COOLCONF(motor), false}) +#define TMC5062_SEUP_MASK 0x00000060 +#define TMC5062_SEUP_SHIFT 5 +#define TMC5062_SEUP_FIELD(motor) ((RegisterField) {TMC5062_SEUP_MASK, TMC5062_SEUP_SHIFT, TMC5062_COOLCONF(motor), false}) +#define TMC5062_SEMAX_MASK 0x00000F00 +#define TMC5062_SEMAX_SHIFT 8 +#define TMC5062_SEMAX_FIELD(motor) ((RegisterField) {TMC5062_SEMAX_MASK, TMC5062_SEMAX_SHIFT, TMC5062_COOLCONF(motor), false}) +#define TMC5062_SEDN_MASK 0x00006000 +#define TMC5062_SEDN_SHIFT 13 +#define TMC5062_SEDN_FIELD(motor) ((RegisterField) {TMC5062_SEDN_MASK, TMC5062_SEDN_SHIFT, TMC5062_COOLCONF(motor), false}) +#define TMC5062_SEIMIN_MASK 0x00008000 +#define TMC5062_SEIMIN_SHIFT 15 +#define TMC5062_SEIMIN_FIELD(motor) ((RegisterField) {TMC5062_SEIMIN_MASK, TMC5062_SEIMIN_SHIFT, TMC5062_COOLCONF(motor), false}) +#define TMC5062_SGT_MASK 0x007F0000 +#define TMC5062_SGT_SHIFT 16 +#define TMC5062_SGT_FIELD(motor) ((RegisterField) {TMC5062_SGT_MASK, TMC5062_SGT_SHIFT, TMC5062_COOLCONF(motor), true}) +#define TMC5062_SFILT_MASK 0x01000000 +#define TMC5062_SFILT_SHIFT 24 +#define TMC5062_SFILT_FIELD(motor) ((RegisterField) {TMC5062_SFILT_MASK, TMC5062_SFILT_SHIFT, TMC5062_COOLCONF(motor), false}) +#define TMC5062_SG_RESULT_MASK 0x000003FF +#define TMC5062_SG_RESULT_SHIFT 0 +#define TMC5062_SG_RESULT_FIELD(motor) ((RegisterField) {TMC5062_SG_RESULT_MASK, TMC5062_SG_RESULT_SHIFT, TMC5062_DRV_STATUS(motor), false}) +#define TMC5062_FSACTIVE_MASK 0x00008000 +#define TMC5062_FSACTIVE_SHIFT 15 +#define TMC5062_FSACTIVE_FIELD(motor) ((RegisterField) {TMC5062_FSACTIVE_MASK, TMC5062_FSACTIVE_SHIFT, TMC5062_DRV_STATUS(motor), false}) +#define TMC5062_CS_ACTUAL_MASK 0x001F0000 +#define TMC5062_CS_ACTUAL_SHIFT 16 +#define TMC5062_CS_ACTUAL_FIELD(motor) ((RegisterField) {TMC5062_CS_ACTUAL_MASK, TMC5062_CS_ACTUAL_SHIFT, TMC5062_DRV_STATUS(motor), false}) +#define TMC5062_STALLGUARD_MASK 0x01000000 +#define TMC5062_STALLGUARD_SHIFT 24 +#define TMC5062_STALLGUARD_FIELD(motor) ((RegisterField) {TMC5062_STALLGUARD_MASK, TMC5062_STALLGUARD_SHIFT, TMC5062_DRV_STATUS(motor), false}) +#define TMC5062_OT_MASK 0x02000000 +#define TMC5062_OT_SHIFT 25 +#define TMC5062_OT_FIELD(motor) ((RegisterField) {TMC5062_OT_MASK, TMC5062_OT_SHIFT, TMC5062_DRV_STATUS(motor), false}) +#define TMC5062_OTPW_MASK 0x04000000 +#define TMC5062_OTPW_SHIFT 26 +#define TMC5062_OTPW_FIELD(motor) ((RegisterField) {TMC5062_OTPW_MASK, TMC5062_OTPW_SHIFT, TMC5062_DRV_STATUS(motor), false}) +#define TMC5062_S2GA_MASK 0x08000000 +#define TMC5062_S2GA_SHIFT 27 +#define TMC5062_S2GA_FIELD(motor) ((RegisterField) {TMC5062_S2GA_MASK, TMC5062_S2GA_SHIFT, TMC5062_DRV_STATUS(motor), false}) +#define TMC5062_S2GB_MASK 0x10000000 +#define TMC5062_S2GB_SHIFT 28 +#define TMC5062_S2GB_FIELD(motor) ((RegisterField) {TMC5062_S2GB_MASK, TMC5062_S2GB_SHIFT, TMC5062_DRV_STATUS(motor), false}) +#define TMC5062_OLA_MASK 0x20000000 +#define TMC5062_OLA_SHIFT 29 +#define TMC5062_OLA_FIELD(motor) ((RegisterField) {TMC5062_OLA_MASK, TMC5062_OLA_SHIFT, TMC5062_DRV_STATUS(motor), false}) +#define TMC5062_OLB_MASK 0x40000000 +#define TMC5062_OLB_SHIFT 30 +#define TMC5062_OLB_FIELD(motor) ((RegisterField) {TMC5062_OLB_MASK, TMC5062_OLB_SHIFT, TMC5062_DRV_STATUS(motor), false}) +#define TMC5062_STST_MASK 0x80000000 +#define TMC5062_STST_SHIFT 31 +#define TMC5062_STST_FIELD(motor) ((RegisterField) {TMC5062_STST_MASK, TMC5062_STST_SHIFT, TMC5062_DRV_STATUS(motor), false}) + +#endif diff --git a/firmware/lib/tmc/ic/TMC5062/registercall_hierarchy_flowchart_SPI.svg b/firmware/lib/tmc/ic/TMC5062/registercall_hierarchy_flowchart_SPI.svg new file mode 100755 index 0000000..cbad58f --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5062/registercall_hierarchy_flowchart_SPI.svg @@ -0,0 +1,3 @@ + + +

HAL

HAL

APP (Eval)

APP (Eval)

API

API
Read a register
  •  Call tmcXXXX_readRegister function
Read a register...
Returns the register read value
Returns the register read value
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
tmcXXXX.c
tmcXXXX.c
SPI.c
SPI.c
tmcXXXX_eval.c
tmcXXXX_eval.c

 Implementation of SPI_readWrite
  • Sends and receives bytes on the SPI bus
Implementation of SPI_readWrite...
Returns the raw reply data
Returns the raw reply data

Implementation of tmcXXXX_readWriteSPI
  • Sets the CSN pin to LOW
  • Takes the array of data to write
  • Calls hardware function SPI_readWrite
  • Upon completion of data transfer,
    sets CSN to 
    HIGH
Implementation of tmcXXXX_readWriteSPI...
Passes on the raw reply data to the API
Passes on the raw reply data to the API
Implementation of readRegisterSPI
  • Constructs the datagram
  • Calls HAL wrapper function 
Implementation of readRegisterSPI...
tmcXXXX_readWriteSPI
tmcXXXX_readWriteSPI
Parses the reply and returns the register value
Parses the reply and returns the register value
Implementation of tmcXXXX_readRegister 
  • Check which bus is active SPI/UART. (e.g. SPI)
  • Calls bus-specific function (e.g. readRegisterSPI)
 
Implementation of tmcXXXX_readRegister...
Returns the register read value
Returns the register read value
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC5062/registercall_hierarchy_flowchart_UART.svg b/firmware/lib/tmc/ic/TMC5062/registercall_hierarchy_flowchart_UART.svg new file mode 100755 index 0000000..425f60a --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5062/registercall_hierarchy_flowchart_UART.svg @@ -0,0 +1,3 @@ + + +

HAL

HAL

APP (Eval)

APP (Eval)

API

API
Read a register
  •  Call tmcXXXX_readRegister function
Read a register...
Returns the register read value
Returns the register read value
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
tmcXXXX.c
tmcXXXX.c
UART.c
UART.c
tmcXXXX_eval.c
tmcXXXX_eval.c

 Implementation of UART_readWrite
  • Sends and receives bytes on the UART bus
Implementation of UART_readWrite...
Returns the raw reply data
Returns the raw reply data

Implementation of tmcXXXX_readWriteUART
  • Takes the array of data to write
  • Calls hardware function UART_readWrite
Implementation of tmcXXXX_readWriteUART...
Passes on the raw reply data to the API
Passes on the raw reply data to the API
Implementation of readRegisterUART
  • Constructs the datagram
  • Calls HAL wrapper function 
Implementation of readRegisterUART...
tmcXXXX_readWriteUART
tmcXXXX_readWriteUART
Parses the reply and returns the register value
Parses the reply and returns the register value
Implementation of tmcXXXX_readRegister 
  • Check which bus is active SPI/UART. (e.g. UART)
  • Calls bus-specific function (e.g. readRegisterUART)
 
Implementation of tmcXXXX_readRegister...
Returns the register read value
Returns the register read value
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC5062/uml-tmc-api.svg b/firmware/lib/tmc/ic/TMC5062/uml-tmc-api.svg new file mode 100755 index 0000000..5a5f8dd --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5062/uml-tmc-api.svg @@ -0,0 +1,3 @@ + + +

TMCXXXX_HW_Abstraction.h



TMCXXXX_HW_Abstraction.h...
// Constants
#define TMCXXXX_MOTORS              
                          
// Register definitions
#define TMCXXXX_GCONF        
                          ⋮
// Register fields definitions
#define TMCXXXX_GCONF_OTPW_FIELD
                     
// Constants...

TMCXXXX.h



TMCXXXX.h...
extern void tmcXXXX_readWriteSPI();
extern void tmcXXXX_readWriteUART();
extern TMCXXXXBusType tmcXXXX_getBusType();
extern uint8_t tmcXXXX_getNodeAddress();
                                  ⋮
tmcXXXX_readRegister();
tmcXXXX_writeRegister();
                                  ⋮
extern void tmcXXXX_readWriteSPI();...

TMCXXXX.c



TMCXXXX.c...
const uint8_t tmcCRCTable_Poly7Reflected[256] = {...};
int32_t tmcXXXX_readRegister(){
/* Call tmcXXXX_getBusType();
 * Based on bus type, call readRegisterSPI/UART() that
 * further calls tmcXXXX_readWriteSPI/UART();
 * For UART it also calls tmcXXXX_getNodeAddress();
                                           ⋮
}
                                           ⋮
const uint8_t tmcCRCTable_Poly7Reflected[256] = {.....
TMC-API
TMC-API

TMCXXXX_Simple_Rotation.h


TMCXXXX_Simple_Rotation.h...
void initAllMotors();
             ⋮
  
void initAllMotors()...

TMCXXXX_Simple_Rotation.c


TMCXXXX_Simple_Rotation.c...
void initAllMotors(){

// Configuring registers to enable motor drivers etc..
tmcXXXX_writeRegister();
                    ⋮
}
                    ⋮
void initAllMotors(){...
Examples
Examples
User Project
User Project

User_Project.h


User_Project.h

User_Project.c








User_Project.c...

void tmcXXXX_readWriteSPI(){
                           ⋮
}
void tmcXXXX_readWriteUART(){
                           ⋮
}
TMCXXXXBusType tmcXXXX_getBusType(){
                           ⋮
}
uint8_t tmcXXXX_getNodeAddress(){
                           ⋮
}

// User Code
                           ⋮
void tmcXXXX_readWriteSPI(){...
#include "TMCXXXX_HW_Abstraction.h"
#include "TMCXXXX.h"
#include "TMCXXXX_Simple_Rotation.h"
                                ⋮
TMCXXXXBusType bus = IC_BUS_SPI/UART;
uint8_t nodeAddress = <nodeAddress>;
                                ⋮
#include "TMCXXXX_HW_Abstraction.h"...
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC5072/README.md b/firmware/lib/tmc/ic/TMC5072/README.md new file mode 100755 index 0000000..5dca29e --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5072/README.md @@ -0,0 +1,71 @@ +# TMC5072 + + +## How to use + +To access the TMC5072's registers, the TMC-API offers two functions: **tmc5072_readRegister** and **tmc5072_writeRegister**. +Each of these functions takes in an **icID**, which is used to identify the IC when multiple ICs are connected. This identifier is passed down to the callback functions (see How to Integrate). + +## How to integrate: overview + +1. Include all the files of the TMC-API/ic/tmc/TMC5072 folder into the custom project. +2. Include the TMC5072.h file in the custom source code. +3. Implement the necessary callback functions (see below). +4. (optional): Take a look at the Examples subfolder for ready-made examples of the TMC-API usage. + +## Accessing the TMC5072 via UART +The following diagram depicts how to access the TMC5072 via UART using the TMC-API. + +![screenshot](registercall_hierarchy_flowchart_UART.svg) + +The description of the functions, in the above flowchart, are as follows: +- The functions tmc5072_readRegister and tmc5072_writeRegister are used to read and write the registers respectively. These functions check the current active bus and calls the bus-specific function i.e readRegisterUART or writeRegisterUART. +- These bus specific functions constructs the datagram and further calls the bus specific callback 'tmcXXXX_readWriteUART. +- This callback function further calls the hardware specific read/write function for UART and needs to be implemented externally. + +### How to integrate: Callback functions +To communicate with TMC5072 IC, the TMC-API library needs to know which bus (UART, SPI) it shall use. For that, the callback function **'tmc5072_getBusType()'** needs to be implemented. +Additionally, implement the following callback functions to access the chip via UART: +1. **tmc5072_readWriteUART()**, which is a HAL wrapper function that provides the necessary hardware access. +2. **tmc5072_getNodeAddress()**, that returns the node/slave address. Node address could be set in NODECONF (0x3) register and the address could be incremented as defined by AD0, AD1 and AD2. (Node address + ADx) must be less than 255. For further details please consult the datasheet of TMC5072. + +### Sharing the CRC table with other TMC-API chips +The TMC5072 UART protocol uses an 8 bit CRC. For calculating this, a table-based algorithm is used. This table (tmcCRCTable_Poly7Reflected[256]) is 256 bytes big and identical across multiple different Trinamic chips (i.e. TMC2209). +If multiple Trinamic chips are being used in the same project, avoiding redundant copies of this table could save memory. It is possible to substitute this CRC table with another CRC table. + +### Necessary hardware modification to use UART +To use UART with the Eval-Kit: pin 39 (DIO17) and 40 (DIO18) should be connected with a 1k ohm resistor. Bend pin 39 (DIO17) on the EVAl Board side of the Eselsbrücke out. + +Optional: Bend pin 41 (DIO19) out and connect it to 3.3V / 2= 1.65V. You can reach this by making a volage-divider with two 1k ohm resistors. One to 3.3V and one to GND. This can improve the signal quality. + +## Accessing the TMC5072 via SPI +The following diagram depicts how to access the TMC5072 via SPI using the TMC-API. + +![screenshot](registercall_hierarchy_flowchart_SPI.svg) + +The description of the functions, in the above flowchart, are as follows: +- The functions tmc5072_readRegister and tmc5072_writeRegister are used to read and write the registers respectively. These functions check the current active bus and calls the bus-specific function i.e readRegisterSPI or writeRegisterSPI. +- These bus specific functions constructs the datagram and further calls the bus specific callback 'tmcXXXX_readWriteSPI. +- This callback function further calls the hardware specific read/write function for SPI and needs to be implemented externally. + +### How to integrate: Callback functions +To communicate with TMC5072 IC, the TMC-API library needs to know which bus (UART, SPI) it shall use. For that, the callback function **'tmc5072_getBusType()'** needs to be implemented. +Additionally, implement the following callback functions to access the chip via SPI: +1. **tmc5072_readWriteSPI()**, which is a HAL wrapper function that provides the necessary hardware access. This function should also set the chip select pin CSN to low before starting the data transfer and set to high upon completion. Please refer to the datasheet of the IC for further details. + +### Option to use the cache logic for Write-Only registers +The chip features write-only registers that are unable to be read, necessitating the creation of a shadow copy to cache their contents. This copy is automatically updated whenever data is written to these registers. This cache logic could be enabled by setting the macro **TMC2209_CACHE** to **'1'** or disabled by setting to **'0'** respectively. If this feature is enabled then there comes another option to use **tmc2209_cache** function, which is already implemeted in the API, by defining **TMC2209_ENABLE_TMC_CACHE** macro to **'1** or one can implement their own function. The function **tmc5072_cache** works for both reading from and writing to the shadow array. It first checks whether the register has write-only access and data needs to be read from the hadow copy. On the basis of that, it returns **true** or **false**. The shadowRegisters on the premade cache implementation need to be one per chip. **TMC5072_IC_CACHE_COUNT** is set to '1' y default and is user-overwritable. If multiple chips are being used in the same project, increment its value to the number of chips connected. + +## Further info +### Dependency graph for the ICs with new register R/W mechanism +This graph illustrates the relationships between files within the TMC-API library, highlighting dependencies and identifying the files that are essential for integrating the library into the ustom projects. + +![screenshot](uml-tmc-api.svg) + +### Example usage: TMC-Evalsystem +**For a reference usage of the TMC-API**, visit the [TMC-Evalsystem](https://github.com/analogdevicesinc/TMC-EvalSystem) + +## Migration status +The TMC5072 has been reworked to the access system described above. For more infos on the status of this and other ICs, check out the [migration page](https://github.com/analogdevicesinc/TMC-API/issues/53). + + diff --git a/firmware/lib/tmc/ic/TMC5072/TMC5072.c b/firmware/lib/tmc/ic/TMC5072/TMC5072.c new file mode 100755 index 0000000..0fec245 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5072/TMC5072.c @@ -0,0 +1,304 @@ +/******************************************************************************* +* Copyright © 2017 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + +#include "TMC5072.h" + +#ifdef TMC_API_EXTERNAL_CRC_TABLE +extern const uint8_t tmcCRCTable_Poly7Reflected[256]; +#else +const uint8_t tmcCRCTable_Poly7Reflected[256] = { + 0x00, 0x91, 0xE3, 0x72, 0x07, 0x96, 0xE4, 0x75, 0x0E, 0x9F, 0xED, 0x7C, 0x09, 0x98, 0xEA, 0x7B, + 0x1C, 0x8D, 0xFF, 0x6E, 0x1B, 0x8A, 0xF8, 0x69, 0x12, 0x83, 0xF1, 0x60, 0x15, 0x84, 0xF6, 0x67, + 0x38, 0xA9, 0xDB, 0x4A, 0x3F, 0xAE, 0xDC, 0x4D, 0x36, 0xA7, 0xD5, 0x44, 0x31, 0xA0, 0xD2, 0x43, + 0x24, 0xB5, 0xC7, 0x56, 0x23, 0xB2, 0xC0, 0x51, 0x2A, 0xBB, 0xC9, 0x58, 0x2D, 0xBC, 0xCE, 0x5F, + 0x70, 0xE1, 0x93, 0x02, 0x77, 0xE6, 0x94, 0x05, 0x7E, 0xEF, 0x9D, 0x0C, 0x79, 0xE8, 0x9A, 0x0B, + 0x6C, 0xFD, 0x8F, 0x1E, 0x6B, 0xFA, 0x88, 0x19, 0x62, 0xF3, 0x81, 0x10, 0x65, 0xF4, 0x86, 0x17, + 0x48, 0xD9, 0xAB, 0x3A, 0x4F, 0xDE, 0xAC, 0x3D, 0x46, 0xD7, 0xA5, 0x34, 0x41, 0xD0, 0xA2, 0x33, + 0x54, 0xC5, 0xB7, 0x26, 0x53, 0xC2, 0xB0, 0x21, 0x5A, 0xCB, 0xB9, 0x28, 0x5D, 0xCC, 0xBE, 0x2F, + 0xE0, 0x71, 0x03, 0x92, 0xE7, 0x76, 0x04, 0x95, 0xEE, 0x7F, 0x0D, 0x9C, 0xE9, 0x78, 0x0A, 0x9B, + 0xFC, 0x6D, 0x1F, 0x8E, 0xFB, 0x6A, 0x18, 0x89, 0xF2, 0x63, 0x11, 0x80, 0xF5, 0x64, 0x16, 0x87, + 0xD8, 0x49, 0x3B, 0xAA, 0xDF, 0x4E, 0x3C, 0xAD, 0xD6, 0x47, 0x35, 0xA4, 0xD1, 0x40, 0x32, 0xA3, + 0xC4, 0x55, 0x27, 0xB6, 0xC3, 0x52, 0x20, 0xB1, 0xCA, 0x5B, 0x29, 0xB8, 0xCD, 0x5C, 0x2E, 0xBF, + 0x90, 0x01, 0x73, 0xE2, 0x97, 0x06, 0x74, 0xE5, 0x9E, 0x0F, 0x7D, 0xEC, 0x99, 0x08, 0x7A, 0xEB, + 0x8C, 0x1D, 0x6F, 0xFE, 0x8B, 0x1A, 0x68, 0xF9, 0x82, 0x13, 0x61, 0xF0, 0x85, 0x14, 0x66, 0xF7, + 0xA8, 0x39, 0x4B, 0xDA, 0xAF, 0x3E, 0x4C, 0xDD, 0xA6, 0x37, 0x45, 0xD4, 0xA1, 0x30, 0x42, 0xD3, + 0xB4, 0x25, 0x57, 0xC6, 0xB3, 0x22, 0x50, 0xC1, 0xBA, 0x2B, 0x59, 0xC8, 0xBD, 0x2C, 0x5E, 0xCF, +}; +#endif +/**************************************************************** Cache Implementation *************************************************************************/ + +#if TMC5072_CACHE == 0 +static inline bool tmc5072_cache(uint16_t icID, TMC5072CacheOp operation, uint8_t address, uint32_t *value) +{ + UNUSED(icID); + UNUSED(address); + UNUSED(operation); + return false; +} +#else +#if TMC5072_ENABLE_TMC_CACHE == 1 + +uint8_t tmc5072_dirtyBits[TMC5072_IC_CACHE_COUNT][TMC5072_REGISTER_COUNT/8]= {0}; +int32_t tmc5072_shadowRegister[TMC5072_IC_CACHE_COUNT][TMC5072_REGISTER_COUNT]; + +void tmc5072_setDirtyBit(uint16_t icID, uint8_t index, bool value) + { + if(index >= TMC5072_REGISTER_COUNT) + return; + + uint8_t *tmp = &tmc5072_dirtyBits[icID][index / 8]; + uint8_t shift = (index % 8); + uint8_t mask = 1 << shift; + *tmp = (((*tmp) & (~(mask))) | (((value) << (shift)) & (mask))); +} + +bool tmc5072_getDirtyBit(uint16_t icID, uint8_t index) +{ + if(index >= TMC5072_REGISTER_COUNT) + return false; + + uint8_t *tmp = &tmc5072_dirtyBits[icID][index / 8]; + uint8_t shift = (index % 8); + return ((*tmp) >> shift) & 1; +} +/* + * This function is used to cache the value written to the Write-Only registers in the form of shadow array. + * The shadow copy is then used to read these kinds of registers. + */ + +bool tmc5072_cache(uint16_t icID, TMC5072CacheOp operation, uint8_t address, uint32_t *value) +{ + if (operation == TMC5072_CACHE_READ) + { + // Check if the value should come from cache + + // Only supported chips have a cache + if (icID >= TMC5072_IC_CACHE_COUNT) + return false; + + // Only non-readable registers care about caching + // Note: This could also be used to cache i.e. RW config registers to reduce bus accesses + if (TMC5072_IS_READABLE(tmc5072_registerAccess[address])) + return false; + + // Grab the value from the cache + *value = tmc5072_shadowRegister[icID][address]; + return true; + } + else if (operation == TMC5072_CACHE_WRITE || operation == TMC5072_CACHE_FILL_DEFAULT) + { + // Fill the cache + + // only supported chips have a cache + if (icID >= TMC5072_IC_CACHE_COUNT) + return false; + + // Write to the shadow register. + tmc5072_shadowRegister[icID][address] = *value; + // For write operations, mark the register dirty + if (operation == TMC5072_CACHE_WRITE) + { + tmc5072_setDirtyBit(icID, address, true); + } + + return true; + } + return false; +} + +void tmc5072_initCache() +{ + // Check if we have constants defined + if(ARRAY_SIZE(tmc5072_RegisterConstants) == 0) + return; + + size_t i, j, id; + + for(i = 0, j = 0; i < TMC5072_REGISTER_COUNT; i++) + { + // We only need to worry about hardware preset, write-only registers + // that have not yet been written (no dirty bit) here. + if(tmc5072_registerAccess[i] != TMC5072_ACCESS_W_PRESET) + continue; + + // Search the constant list for the current address. With the constant + // list being sorted in ascended order, we can walk through the list + // until the entry with an address equal or greater than i + while(j < ARRAY_SIZE(tmc5072_RegisterConstants) && (tmc5072_RegisterConstants[j].address < i)) + j++; + + // Abort when we reach the end of the constant list + if (j == ARRAY_SIZE(tmc5072_RegisterConstants)) + break; + + // If we have an entry for our current address, write the constant + if(tmc5072_RegisterConstants[j].address == i) + { + for (id = 0; id < TMC5072_IC_CACHE_COUNT; id++) + { + uint32_t temp = tmc5072_RegisterConstants[j].value; + tmc5072_cache(id, TMC5072_CACHE_FILL_DEFAULT, i, &temp); + } + } + } +} +#else +// User must implement their own cache +extern bool tmc5072_cache(uint16_t icID, TMC5072CacheOp operation, uint8_t address, uint32_t *value); +#endif +#endif + +/************************************************************* read / write Implementation *********************************************************************/ +static int32_t readRegisterSPI(uint16_t icID, uint8_t address); +static void writeRegisterSPI(uint16_t icID, uint8_t address, int32_t value); +static int32_t readRegisterUART(uint16_t icID, uint8_t registerAddress); +static void writeRegisterUART(uint16_t icID, uint8_t registerAddress, int32_t value); +static uint8_t CRC8(uint8_t *data, uint32_t bytes); + + +int32_t tmc5072_readRegister(uint16_t icID, uint8_t address) +{ + uint32_t value; + + // Read from cache for registers with write-only access + if (tmc5072_cache(icID, TMC5072_CACHE_READ, address, &value)) + return value; + + TMC5072BusType bus = tmc5072_getBusType(icID); + + if(bus == IC_BUS_SPI) + { + return readRegisterSPI(icID, address); + } + else if (bus == IC_BUS_UART) + { + return readRegisterUART(icID, address); + } + + // ToDo: Error handling + return -1; +} +void tmc5072_writeRegister(uint16_t icID, uint8_t address, int32_t value) +{ + TMC5072BusType bus = tmc5072_getBusType(icID); + + if(bus == IC_BUS_SPI) + { + writeRegisterSPI(icID, address, value); + } + else if(bus == IC_BUS_UART) + { + writeRegisterUART(icID, address, value); + } + + //Cache the registers with write-only access + tmc5072_cache(icID, TMC5072_CACHE_WRITE, address, (uint32_t *)&value); +} + +int32_t readRegisterSPI(uint16_t icID, uint8_t address) +{ + uint8_t data[5] = { 0 }; + + // clear write bit + data[0] = address & TMC5072_ADDRESS_MASK; + + // Send the read request + tmc5072_readWriteSPI(icID, &data[0], sizeof(data)); + + // Rewrite address and clear write bit + data[0] = address & TMC5072_ADDRESS_MASK; + + // Send another request to receive the read reply + tmc5072_readWriteSPI(icID, &data[0], sizeof(data)); + + return ((int32_t)data[1] << 24) | ((int32_t) data[2] << 16) | ((int32_t) data[3] << 8) | ((int32_t) data[4]); +} + +void writeRegisterSPI(uint16_t icID, uint8_t address, int32_t value) +{ + uint8_t data[5] = { 0 }; + + data[0] = address | TMC5072_WRITE_BIT; + data[1] = 0xFF & (value>>24); + data[2] = 0xFF & (value>>16); + data[3] = 0xFF & (value>>8); + data[4] = 0xFF & (value>>0); + + // Send the write request + tmc5072_readWriteSPI(icID, &data[0], sizeof(data)); +} + +int32_t readRegisterUART(uint16_t icID, uint8_t registerAddress) +{ + uint8_t data[8] = { 0 }; + + registerAddress = registerAddress & TMC5072_ADDRESS_MASK; + + data[0] = 0x05; + data[1] = tmc5072_getNodeAddress(icID); + data[2] = registerAddress; + data[3] = CRC8(data, 3); + + if (!tmc5072_readWriteUART(icID, &data[0], 4, 8)) + return 0; + + // Byte 0: Sync nibble correct? + if (data[0] != 0x05) + return 0; + + // Byte 1: Master address correct? + if (data[1] != 0xFF) + return 0; + + // Byte 2: Address correct? + if (data[2] != registerAddress) + return 0; + + // Byte 7: CRC correct? + if (data[7] != CRC8(data, 7)) + return 0; + + return ((uint32_t)data[3] << 24) | ((uint32_t)data[4] << 16) | (data[5] << 8) | data[6]; +} + +void writeRegisterUART(uint16_t icID, uint8_t registerAddress, int32_t value) +{ + uint8_t data[8]; + + data[0] = 0x05; + data[1] = tmc5072_getNodeAddress(icID); + data[2] = registerAddress | TMC5072_WRITE_BIT; + data[3] = (value >> 24) & 0xFF; + data[4] = (value >> 16) & 0xFF; + data[5] = (value >> 8 ) & 0xFF; + data[6] = (value ) & 0xFF; + data[7] = CRC8(data, 7); + + tmc5072_readWriteUART(icID, &data[0], 8, 0); + +} + +static uint8_t CRC8(uint8_t *data, uint32_t bytes) +{ + uint8_t result = 0; + + while(bytes--) + result = tmcCRCTable_Poly7Reflected[result ^ *data++]; + + // Flip the result around + // swap odd and even bits + result = ((result >> 1) & 0x55) | ((result & 0x55) << 1); + // swap consecutive pairs + result = ((result >> 2) & 0x33) | ((result & 0x33) << 2); + // swap nibbles ... + result = ((result >> 4) & 0x0F) | ((result & 0x0F) << 4); + + return result; +} + +/***************************************************************************************************************************************************************/ diff --git a/firmware/lib/tmc/ic/TMC5072/TMC5072.h b/firmware/lib/tmc/ic/TMC5072/TMC5072.h new file mode 100755 index 0000000..d573d91 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5072/TMC5072.h @@ -0,0 +1,232 @@ +/******************************************************************************* +* Copyright © 2017 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#ifndef TMC_IC_TMC5072_H_ +#define TMC_IC_TMC5072_H_ + +#include +#include +#include +#include "TMC5072_HW_Abstraction.h" + +/******************************************************************************* +* API Configuration Defines +* These control optional features of the TMC-API implementation. +* These can be commented in/out here or defined from the build system. +*******************************************************************************/ + +// Uncomment if you want to save space..... +// and put the table into your own .c file +//#define TMC_API_EXTERNAL_CRC_TABLE 1 + +// To enable the cache mechanism in order to keep the copy of all registers, set TMC5072_CACHE to '1'. +// With this mechanism the value of write-only registers could be read from their shadow copies. +#ifndef TMC5072_CACHE +#define TMC5072_CACHE 1 +//#define TMC5072_CACHE 0 +#endif + +// To use the caching mechanism already implemented by the TMC-API, set TMC5072_ENABLE_TMC_CACHE to '1'. +// Set TMC5072_ENABLE_TMC_CACHE to '0' if one wants to have their own cache implementation. +#ifndef TMC5072_ENABLE_TMC_CACHE +#define TMC5072_ENABLE_TMC_CACHE 1 +//#define TMC5072_ENABLE_TMC_CACHE 0 +#endif + +/******************************************************************************/ + + +/************************************************************* read / write Implementation *********************************************************************/ +typedef enum { + IC_BUS_SPI, + IC_BUS_UART, +} TMC5072BusType; + +// => TMC-API wrapper +extern void tmc5072_readWriteSPI(uint16_t icID, uint8_t *data, size_t dataLength); +extern bool tmc5072_readWriteUART(uint16_t icID, uint8_t *data, size_t writeLength, size_t readLength); +extern TMC5072BusType tmc5072_getBusType(uint16_t icID); +extern uint8_t tmc5072_getNodeAddress(uint16_t icID); +// => TMC-API wrapper + +int32_t tmc5072_readRegister(uint16_t icID, uint8_t address); +void tmc5072_writeRegister(uint16_t icID, uint8_t address, int32_t value); + +typedef struct +{ + uint32_t mask; + uint8_t shift; + uint8_t address; + bool isSigned; +} RegisterField; + +static inline uint32_t tmc5072_fieldExtract(uint32_t data, RegisterField field) +{ + uint32_t value = (data & field.mask) >> field.shift; + + if (field.isSigned) + { + // Apply signedness conversion + uint32_t baseMask = field.mask >> field.shift; + uint32_t signMask = baseMask & (~baseMask >> 1); + value = (value ^ signMask) - signMask; + } + + return value; +} + +static inline uint32_t tmc5072_fieldRead(uint16_t icID, RegisterField field) +{ + uint32_t value = tmc5072_readRegister(icID, field.address); + + return tmc5072_fieldExtract(value, field); +} + +static inline uint32_t tmc5072_fieldUpdate(uint32_t data, RegisterField field, uint32_t value) +{ + return (data & (~field.mask)) | ((value << field.shift) & field.mask); +} + +static inline void tmc5072_fieldWrite(uint16_t icID, RegisterField field, uint32_t value) +{ + uint32_t regValue = tmc5072_readRegister(icID, field.address); + + regValue = tmc5072_fieldUpdate(regValue, field, value); + + tmc5072_writeRegister(icID, field.address, regValue); +} + +/**************************************************************** Cache Implementation *************************************************************************/ +#if TMC5072_CACHE == 1 +#ifdef TMC5072_ENABLE_TMC_CACHE + +// By default, support one IC in the cache +#ifndef TMC5072_IC_CACHE_COUNT +#define TMC5072_IC_CACHE_COUNT 1 +#endif + +typedef enum { + TMC5072_CACHE_READ, + TMC5072_CACHE_WRITE, + // Special operation: Put content into the cache without marking the entry as dirty. + // Only used to initialize the cache with hardware defaults. This will allow reading + // from write-only registers that have a value inside them on reset. When using this + // operation, a restore will *not* rewrite that filled register! + TMC5072_CACHE_FILL_DEFAULT, +} TMC5072CacheOp; + +typedef struct{ + uint8_t address; + uint32_t value; +} TMC5072RegisterConstants; + +#define TMC5072_ACCESS_DIRTY 0x08 // Register has been written since reset -> shadow register is valid for restore +#define TMC5072_ACCESS_READ 0x01 +#define TMC5072_ACCESS_W_PRESET 0x42 +#define TMC5072_IS_READABLE(x) ((x) & TMC5072_ACCESS_READ) +#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) + +// Default Register Values +#define R30 0x00071703 // IHOLD_IRUN (Motor 1) +#define R32 0x00FFFFFF // VHIGH (Motor 1) +#define R3A 0x00010000 // ENC_CONST (Motor 1) +#define R50 0x00071703 // IHOLD_IRUN (Motor 1) +#define R52 0x00FFFFFF // VHIGH (Motor 1) +#define R5A 0x00010000 // ENC_CONST (Motor 1) +#define R6C 0x000101D5 // CHOPCONF (Motor 1) +#define R7C 0x000101D5 // CHOPCONF (Motor 2) + +// Helper define: +// Most register permission arrays are initialized with 128 values. +// In those fields its quite hard to have an easy overview of available +// registers. For that, ____ is defined to 0, since 4 underscores are +// very easy to distinguish from the 2-digit hexadecimal values. +// This way, the used registers (permission != ACCESS_NONE) are easily spotted +// amongst unused (permission == ACCESS_NONE) registers. +#define ____ 0x00 + +// Helper define: +// Default reset values are not used if the corresponding register has a +// hardware preset. Since this is not directly visible in the default +// register reset values array, N_A is used as an indicator for a preset +// value, where any value will be ignored anyways (N_A: not available). +#define N_A 0 + +// Register access permissions: +// 0x00: none (reserved) +// 0x01: read +// 0x02: write +// 0x03: read/write +// 0x13: read/write, separate functions/values for reading or writing +// 0x21: read, flag register (read to clear) +// 0x42: write, has hardware presets on reset +static const uint8_t tmc5072_registerAccess[TMC5072_REGISTER_COUNT] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0x03, 0x01, 0x01, 0x02, 0x13, 0x02, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x00 - 0x0F + 0x02, 0x01, ____, ____, ____, ____, ____, ____, 0x02, 0x01, ____, ____, ____, ____, ____, ____, // 0x10 - 0x1F + 0x03, 0x03, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, ____, 0x02, 0x02, 0x02, 0x03, ____, ____, // 0x20 - 0x2F + 0x02, 0x02, 0x02, 0x02, 0x03, 0x01, 0x01, ____, 0x03, 0x03, 0x02, 0x01, 0x01, ____, ____, ____, // 0x30 - 0x3F + 0x03, 0x03, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, ____, 0x02, 0x02, 0x02, 0x03, ____, ____, // 0x40 - 0x4F + 0x02, 0x02, 0x02, 0x02, 0x03, 0x01, 0x01, ____, 0x03, 0x03, 0x02, 0x01, 0x01, ____, ____, ____, // 0x50 - 0x5F + 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x01, 0x01, 0x03, 0x02, 0x02, 0x01, // 0x60 - 0x6F + ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, 0x01, 0x01, 0x03, 0x02, 0x02, 0x01 // 0x70 - 0x7F +}; + +static const int32_t tmc5072_sampleRegisterPreset[TMC5072_REGISTER_COUNT] = { +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x00 - 0x0F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x10 - 0x1F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x20 - 0x2F + R30, 0, R32, 0, 0, 0, 0, 0, 0, 0, R3A, 0, 0, 0, 0, 0, // 0x30 - 0x3F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x40 - 0x4F + R50, 0, R52, 0, 0, 0, 0, 0, 0, 0, R5A, 0, 0, 0, 0, 0, // 0x50 - 0x5F + N_A, N_A, N_A, N_A, N_A, N_A, N_A, N_A, N_A, N_A, 0, 0, R6C, 0, 0, 0, // 0x60 - 0x6F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, R7C, 0, 0, 0 // 0x70 - 0x7F +}; + +// Undefine the default register values. +// This prevents warnings in case multiple TMC-API chip headers are included at once +#undef R30 +#undef R32 +#undef R3A +#undef R50 +#undef R52 +#undef R5A +#undef R6C +#undef R7C + +// Register constants (only required for 0x42 registers, since we do not have +// any way to find out the content but want to hold the actual value in the +// shadow register so an application (i.e. the TMCL IDE) can still display +// the values. This only works when the register content is constant. +static const TMC5072RegisterConstants tmc5072_RegisterConstants[] = +{ // Use ascending addresses! + { 0x60, 0xAAAAB554 }, // MSLUT[0] + { 0x61, 0x4A9554AA }, // MSLUT[1] + { 0x62, 0x24492929 }, // MSLUT[2] + { 0x63, 0x10104222 }, // MSLUT[3] + { 0x64, 0xFBFFFFFF }, // MSLUT[4] + { 0x65, 0xB5BB777D }, // MSLUT[5] + { 0x66, 0x49295556 }, // MSLUT[6] + { 0x67, 0x00404222 }, // MSLUT[7] + { 0x68, 0xFFFF8056 }, // MSLUTSEL + { 0x69, 0x00F70000 } // MSLUTSTART +}; + +extern uint8_t tmc5072_dirtyBits[TMC5072_IC_CACHE_COUNT][TMC5072_REGISTER_COUNT/8]; +extern int32_t tmc5072_shadowRegister[TMC5072_IC_CACHE_COUNT][TMC5072_REGISTER_COUNT]; +extern bool tmc5072_cache(uint16_t icID, TMC5072CacheOp operation, uint8_t address, uint32_t *value); +extern void tmc5072_initCache(void); +void tmc5072_setDirtyBit(uint16_t icID, uint8_t index, bool value); +bool tmc5072_getDirtyBit(uint16_t icID, uint8_t index); +#endif +#endif + +/***************************************************************************************************************************************************/ +#endif /* TMC_IC_TMC5072_H_ */ diff --git a/firmware/lib/tmc/ic/TMC5072/TMC5072_HW_Abstraction.h b/firmware/lib/tmc/ic/TMC5072/TMC5072_HW_Abstraction.h new file mode 100755 index 0000000..7fc094b --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5072/TMC5072_HW_Abstraction.h @@ -0,0 +1,1327 @@ +/******************************************************************************* +* Copyright © 2018 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#ifndef TMC5072_HW_ABSTRACTION +#define TMC5072_HW_ABSTRACTION + +// Constants + +#define TMC5072_REGISTER_COUNT 128 // Default register count +#define TMC5072_MOTORS 2 +#define TMC5072_WRITE_BIT 0x80 +#define TMC5072_ADDRESS_MASK 0x7F +#define TMC5072_MAX_VELOCITY 8388096 +#define TMC5072_MAX_ACCELERATION 65535 + + +// Registers + +// Rampenmodi (Register TMC562_RAMPMODE) +#define TMC5072_MODE_POSITION 0 +#define TMC5072_MODE_VELPOS 1 +#define TMC5072_MODE_VELNEG 2 +#define TMC5072_MODE_HOLD 3 + + +#define MOTOR_ADDR(m) (0x20 << m) +#define MOTOR_ADDR_DRV(m) (m << 4) +#define MOTOR_ADDR_PWM(m) (m << 3) + +#define TMC5072_GCONF 0x00 +#define TMC5072_GSTAT 0x01 +#define TMC5072_IFCNT 0x02 +#define TMC5072_SLAVECONF 0x03 +#define TMC5072_INPUT 0x04 +#define TMC5072_OUTPUT 0x04 +#define TMC5072_X_COMPARE 0x05 + // motor = 0 motor = 1 +#define TMC5072_PWMCONF(motor) (0x10|MOTOR_ADDR_PWM(motor)) // 0x10 0x18 +#define TMC5072_PWM_STATUS(motor) (0x11|MOTOR_ADDR_PWM(motor)) // 0x11 0x19 + + // motor = 0 motor = 1 +#define TMC5072_RAMPMODE(motor) (0x00|MOTOR_ADDR(motor)) // 0x20 0x40 +#define TMC5072_XACTUAL(motor) (0x01|MOTOR_ADDR(motor)) // 0x21 0x41 +#define TMC5072_VACTUAL(motor) (0x02|MOTOR_ADDR(motor)) // 0x22 0x42 +#define TMC5072_VSTART(motor) (0x03|MOTOR_ADDR(motor)) // 0x23 0x43 +#define TMC5072_A1(motor) (0x04|MOTOR_ADDR(motor)) // 0x24 0x44 +#define TMC5072_V1(motor) (0x05|MOTOR_ADDR(motor)) // 0x25 0x45 +#define TMC5072_AMAX(motor) (0x06|MOTOR_ADDR(motor)) // 0x26 0x46 +#define TMC5072_VMAX(motor) (0x07|MOTOR_ADDR(motor)) // 0x27 0x47 +#define TMC5072_DMAX(motor) (0x08|MOTOR_ADDR(motor)) // 0x28 0x48 +#define TMC5072_D1(motor) (0x0A|MOTOR_ADDR(motor)) // 0x2A 0x4A +#define TMC5072_VSTOP(motor) (0x0B|MOTOR_ADDR(motor)) // 0x2B 0x4B +#define TMC5072_TZEROWAIT(motor) (0x0C|MOTOR_ADDR(motor)) // 0x2C 0x4C +#define TMC5072_XTARGET(motor) (0x0D|MOTOR_ADDR(motor)) // 0x2D 0x4D +#define TMC5072_IHOLD_IRUN(motor) (0x10|MOTOR_ADDR(motor)) // 0x30 0x50 +#define TMC5072_VCOOLTHRS(motor) (0x11|MOTOR_ADDR(motor)) // 0x31 0x51 +#define TMC5072_VHIGH(motor) (0x12|MOTOR_ADDR(motor)) // 0x32 0x52 +#define TMC5072_VDCMIN(motor) (0x13|MOTOR_ADDR(motor)) // 0x33 0x53 +#define TMC5072_SWMODE(motor) (0x14|MOTOR_ADDR(motor)) // 0x34 0x54 +#define TMC5072_RAMPSTAT(motor) (0x15|MOTOR_ADDR(motor)) // 0x35 0x55 +#define TMC5072_XLATCH(motor) (0x16|MOTOR_ADDR(motor)) // 0x36 0x56 +#define TMC5072_ENCMODE(motor) (0x18|MOTOR_ADDR(motor)) // 0x38 0x58 +#define TMC5072_XENC(motor) (0x19|MOTOR_ADDR(motor)) // 0x39 0x59 +#define TMC5072_ENC_CONST(motor) (0x1A|MOTOR_ADDR(motor)) // 0x3A 0x5A +#define TMC5072_ENC_STATUS(motor) (0x1B|MOTOR_ADDR(motor)) // 0x3B 0x5B +#define TMC5072_ENC_LATCH(motor) (0x1C|MOTOR_ADDR(motor)) // 0x3C 0x5C + +#define TMC5072_MSLUT0 0x60 +#define TMC5072_MSLUT1 0x61 +#define TMC5072_MSLUT2 0x62 +#define TMC5072_MSLUT3 0x63 +#define TMC5072_MSLUT4 0x64 +#define TMC5072_MSLUT5 0x65 +#define TMC5072_MSLUT6 0x66 +#define TMC5072_MSLUT7 0x67 +#define TMC5072_MSLUTSEL 0x68 +#define TMC5072_MSLUTSTART 0x69 + // motor = 0 motor = 1 +#define TMC5072_MSCNT(motor) (0x6A|MOTOR_ADDR_DRV(motor)) // 0x6A 0x7A +#define TMC5072_MSCURACT(motor) (0x6B|MOTOR_ADDR_DRV(motor)) // 0x6B 0x7B +#define TMC5072_CHOPCONF(motor) (0x6C|MOTOR_ADDR_DRV(motor)) // 0x6C 0x7C +#define TMC5072_COOLCONF(motor) (0x6D|MOTOR_ADDR_DRV(motor)) // 0x6D 0x7D +#define TMC5072_DCCTRL(motor) (0x6E|MOTOR_ADDR_DRV(motor)) // 0x6E 0x7E +#define TMC5072_DRVSTATUS(motor) (0x6F|MOTOR_ADDR_DRV(motor)) // 0x6F 0x7F + + +// Register fields + +#define TMC5072_SINGLE_DRIVER_MASK 0x00000001 +#define TMC5072_SINGLE_DRIVER_SHIFT 0 +#define TMC5072_SINGLE_DRIVER_FIELD(motor) ((RegisterField) {TMC5072_SINGLE_DRIVER_MASK, TMC5072_SINGLE_DRIVER_SHIFT, TMC5072_GCONF, false}) +#define TMC5072_STEPDIR1_ENABLE_MASK 0x00000002 +#define TMC5072_STEPDIR1_ENABLE_SHIFT 1 +#define TMC5072_STEPDIR1_ENABLE_FIELD(motor) ((RegisterField) {TMC5072_STEPDIR1_ENABLE_MASK, TMC5072_STEPDIR1_ENABLE_SHIFT, TMC5072_GCONF, false}) +#define TMC5072_STEPDIR2_ENABLE_MASK 0x00000004 +#define TMC5072_STEPDIR2_ENABLE_SHIFT 2 +#define TMC5072_STEPDIR2_ENABLE_FIELD(motor) ((RegisterField) {TMC5072_STEPDIR2_ENABLE_MASK, TMC5072_STEPDIR2_ENABLE_SHIFT, TMC5072_GCONF, false}) +#define TMC5072_POSCMP_ENABLE_MASK 0x00000008 +#define TMC5072_POSCMP_ENABLE_SHIFT 3 +#define TMC5072_POSCMP_ENABLE_FIELD(motor) ((RegisterField) {TMC5072_POSCMP_ENABLE_MASK, TMC5072_POSCMP_ENABLE_SHIFT, TMC5072_GCONF, false}) +#define TMC5072_ENC1_REFSEL_MASK 0x00000010 +#define TMC5072_ENC1_REFSEL_SHIFT 4 +#define TMC5072_ENC1_REFSEL_FIELD(motor) ((RegisterField) {TMC5072_ENC1_REFSEL_MASK, TMC5072_ENC1_REFSEL_SHIFT, TMC5072_GCONF, false}) +#define TMC5072_ENC2_ENABLE_MASK 0x00000020 +#define TMC5072_ENC2_ENABLE_SHIFT 5 +#define TMC5072_ENC2_ENABLE_FIELD(motor) ((RegisterField) {TMC5072_ENC2_ENABLE_MASK, TMC5072_ENC2_ENABLE_SHIFT, TMC5072_GCONF, false}) +#define TMC5072_ENC2_REFSEL_MASK 0x00000040 +#define TMC5072_ENC2_REFSEL_SHIFT 6 +#define TMC5072_ENC2_REFSEL_FIELD(motor) ((RegisterField) {TMC5072_ENC2_REFSEL_MASK, TMC5072_ENC2_REFSEL_SHIFT, TMC5072_GCONF, false}) +#define TMC5072_TEST_MODE_MASK 0x00000080 +#define TMC5072_TEST_MODE_SHIFT 7 +#define TMC5072_TEST_MODE_FIELD(motor) ((RegisterField) {TMC5072_TEST_MODE_MASK, TMC5072_TEST_MODE_SHIFT, TMC5072_GCONF, false}) +#define TMC5072_SHAFT1_MASK 0x00000100 +#define TMC5072_SHAFT1_SHIFT 8 +#define TMC5072_SHAFT1_FIELD(motor) ((RegisterField) {TMC5072_SHAFT1_MASK, TMC5072_SHAFT1_SHIFT, TMC5072_GCONF, false}) +#define TMC5072_SHAFT2_MASK 0x00000200 +#define TMC5072_SHAFT2_SHIFT 9 +#define TMC5072_SHAFT2_FIELD(motor) ((RegisterField) {TMC5072_SHAFT2_MASK, TMC5072_SHAFT2_SHIFT, TMC5072_GCONF, false}) +#define TMC5072_LOCK_GCONF_MASK 0x00000400 +#define TMC5072_LOCK_GCONF_SHIFT 10 +#define TMC5072_LOCK_GCONF_FIELD(motor) ((RegisterField) {TMC5072_LOCK_GCONF_MASK, TMC5072_LOCK_GCONF_SHIFT, TMC5072_GCONF, false}) +#define TMC5072_DC_SYNC_MASK 0x00000800 +#define TMC5072_DC_SYNC_SHIFT 11 +#define TMC5072_DC_SYNC_FIELD(motor) ((RegisterField) {TMC5072_DC_SYNC_MASK, TMC5072_DC_SYNC_SHIFT, TMC5072_GCONF, false}) +#define TMC5072_RESET_MASK 0x00000001 +#define TMC5072_RESET_SHIFT 0 +#define TMC5072_RESET_FIELD(motor) ((RegisterField) {TMC5072_RESET_MASK, TMC5072_RESET_SHIFT, TMC5072_GSTAT, false}) +#define TMC5072_DRV_ERR1_MASK 0x00000002 +#define TMC5072_DRV_ERR1_SHIFT 1 +#define TMC5072_DRV_ERR1_FIELD(motor) ((RegisterField) {TMC5072_DRV_ERR1_MASK, TMC5072_DRV_ERR1_SHIFT, TMC5072_GSTAT, false}) +#define TMC5072_UV_CP_MASK 0x00000008 +#define TMC5072_UV_CP_SHIFT 3 +#define TMC5072_UV_CP_FIELD(motor) ((RegisterField) {TMC5072_UV_CP_MASK, TMC5072_UV_CP_SHIFT, TMC5072_GSTAT, false}) +#define TMC5072_IFCNT_MASK 0x000000FF +#define TMC5072_IFCNT_SHIFT 0 +#define TMC5072_IFCNT_FIELD(motor) ((RegisterField) {TMC5072_IFCNT_MASK, TMC5072_IFCNT_SHIFT, TMC5072_IFCNT, false}) +#define TMC5072_SLAVEADDR_MASK 0x0000000F +#define TMC5072_SLAVEADDR_SHIFT 0 +#define TMC5072_SLAVEADDR_FIELD(motor) ((RegisterField) {TMC5072_SLAVEADDR_MASK, TMC5072_SLAVEADDR_SHIFT, TMC5072_SLAVECONF, false}) +#define TMC5072_SENDDELAY_MASK 0x000000F0 +#define TMC5072_SENDDELAY_SHIFT 4 +#define TMC5072_SENDDELAY_FIELD(motor) ((RegisterField) {TMC5072_SENDDELAY_MASK, TMC5072_SENDDELAY_SHIFT, TMC5072_SLAVECONF, false}) +#define TMC5072_TEST_SEL_MASK 0x0000000F +#define TMC5072_TEST_SEL_SHIFT 0 +#define TMC5072_TEST_SEL_FIELD(motor) ((RegisterField) {TMC5072_TEST_SEL_MASK, TMC5072_TEST_SEL_SHIFT, TMC5072_SLAVECONF, false}) +#define TMC5072_IO0_IN_MASK 0x00000001 +#define TMC5072_IO0_IN_SHIFT 0 +#define TMC5072_IO0_IN_FIELD(motor) ((RegisterField) {TMC5072_IO0_IN_MASK, TMC5072_IO0_IN_SHIFT, TMC5072_INPUT, false}) +#define TMC5072_IO1_IN_MASK 0x00000002 +#define TMC5072_IO1_IN_SHIFT 1 +#define TMC5072_IO1_IN_FIELD(motor) ((RegisterField) {TMC5072_IO1_IN_MASK, TMC5072_IO1_IN_SHIFT, TMC5072_INPUT, false}) +#define TMC5072_IO2_IN_MASK 0x00000004 +#define TMC5072_IO2_IN_SHIFT 2 +#define TMC5072_IO2_IN_FIELD(motor) ((RegisterField) {TMC5072_IO2_IN_MASK, TMC5072_IO2_IN_SHIFT, TMC5072_INPUT, false}) +#define TMC5072_IO3_IN_MASK 0x00000008 +#define TMC5072_IO3_IN_SHIFT 3 +#define TMC5072_IO3_IN_FIELD(motor) ((RegisterField) {TMC5072_IO3_IN_MASK, TMC5072_IO3_IN_SHIFT, TMC5072_INPUT, false}) +#define TMC5072_IOP_IN_MASK 0x00000010 +#define TMC5072_IOP_IN_SHIFT 4 +#define TMC5072_IOP_IN_FIELD(motor) ((RegisterField) {TMC5072_IOP_IN_MASK, TMC5072_IOP_IN_SHIFT, TMC5072_INPUT, false}) +#define TMC5072_ION_IN_MASK 0x00000020 +#define TMC5072_ION_IN_SHIFT 5 +#define TMC5072_ION_IN_FIELD(motor) ((RegisterField) {TMC5072_ION_IN_MASK, TMC5072_ION_IN_SHIFT, TMC5072_INPUT, false}) +#define TMC5072_NEXTADDR_IN_MASK 0x00000040 +#define TMC5072_NEXTADDR_IN_SHIFT 6 +#define TMC5072_NEXTADDR_IN_FIELD(motor) ((RegisterField) {TMC5072_NEXTADDR_IN_MASK, TMC5072_NEXTADDR_IN_SHIFT, TMC5072_INPUT, false}) +#define TMC5072_DRV_ENN_MASK 0x00000080 +#define TMC5072_DRV_ENN_SHIFT 7 +#define TMC5072_DRV_ENN_FIELD(motor) ((RegisterField) {TMC5072_DRV_ENN_MASK, TMC5072_DRV_ENN_SHIFT, TMC5072_INPUT, false}) +#define TMC5072_SW_COMP_IN_MASK 0x00000100 +#define TMC5072_SW_COMP_IN_SHIFT 8 +#define TMC5072_SW_COMP_IN_FIELD(motor) ((RegisterField) {TMC5072_SW_COMP_IN_MASK, TMC5072_SW_COMP_IN_SHIFT, TMC5072_INPUT, false}) +#define TMC5072_VERSION_MASK 0xFF000000 +#define TMC5072_VERSION_SHIFT 24 +#define TMC5072_VERSION_FIELD(motor) ((RegisterField) {TMC5072_VERSION_MASK, TMC5072_VERSION_SHIFT, TMC5072_INPUT, false}) +#define TMC5072_IO0_OUT_MASK 0x00000001 +#define TMC5072_IO0_OUT_SHIFT 0 +#define TMC5072_IO0_OUT_FIELD(motor) ((RegisterField) {TMC5072_IO0_OUT_MASK, TMC5072_IO0_OUT_SHIFT, TMC5072_OUTPUT, false}) +#define TMC5072_IO1_OUT_MASK 0x00000002 +#define TMC5072_IO1_OUT_SHIFT 1 +#define TMC5072_IO1_OUT_FIELD(motor) ((RegisterField) {TMC5072_IO1_OUT_MASK, TMC5072_IO1_OUT_SHIFT, TMC5072_OUTPUT, false}) +#define TMC5072_IO2_OUT_MASK 0x00000004 +#define TMC5072_IO2_OUT_SHIFT 2 +#define TMC5072_IO2_OUT_FIELD(motor) ((RegisterField) {TMC5072_IO2_OUT_MASK, TMC5072_IO2_OUT_SHIFT, TMC5072_OUTPUT, false}) +#define TMC5072_IODDR0_MASK 0x00000100 +#define TMC5072_IODDR0_SHIFT 8 +#define TMC5072_IODDR0_FIELD(motor) ((RegisterField) {TMC5072_IODDR0_MASK, TMC5072_IODDR0_SHIFT, TMC5072_OUTPUT, false}) +#define TMC5072_IODDR1_MASK 0x00000200 +#define TMC5072_IODDR1_SHIFT 9 +#define TMC5072_IODDR1_FIELD(motor) ((RegisterField) {TMC5072_IODDR1_MASK, TMC5072_IODDR1_SHIFT, TMC5072_OUTPUT, false}) +#define TMC5072_IODDR2_MASK 0x00000400 +#define TMC5072_IODDR2_SHIFT 10 +#define TMC5072_IODDR2_FIELD(motor) ((RegisterField) {TMC5072_IODDR2_MASK, TMC5072_IODDR2_SHIFT, TMC5072_OUTPUT, false}) +#define TMC5072_X_COMPARE_MASK 0xFFFFFFFF +#define TMC5072_X_COMPARE_SHIFT 0 +#define TMC5072_X_COMPARE_FIELD(motor) ((RegisterField) {TMC5072_X_COMPARE_MASK, TMC5072_X_COMPARE_SHIFT, TMC5072_X_COMPARE, false}) +#define TMC5072_PWM_AMPL_MASK 0x000000FF +#define TMC5072_PWM_AMPL_SHIFT 0 +#define TMC5072_PWM_AMPL_FIELD(motor) ((RegisterField) {TMC5072_PWM_AMPL_MASK, TMC5072_PWM_AMPL_SHIFT, TMC5072_PWMCONF(motor), false}) +#define TMC5072_PWM_GRAD_MASK 0x0000FF00 +#define TMC5072_PWM_GRAD_SHIFT 8 +#define TMC5072_PWM_GRAD_FIELD(motor) ((RegisterField) {TMC5072_PWM_GRAD_MASK, TMC5072_PWM_GRAD_SHIFT, TMC5072_PWMCONF(motor), false}) +#define TMC5072_PWM_FREQ_MASK 0x00030000 +#define TMC5072_PWM_FREQ_SHIFT 16 +#define TMC5072_PWM_FREQ_FIELD(motor) ((RegisterField) {TMC5072_PWM_FREQ_MASK, TMC5072_PWM_FREQ_SHIFT, TMC5072_PWMCONF(motor), false}) +#define TMC5072_PWM_AUTOSCALE_MASK 0x00040000 +#define TMC5072_PWM_AUTOSCALE_SHIFT 18 +#define TMC5072_PWM_AUTOSCALE_FIELD(motor) ((RegisterField) {TMC5072_PWM_AUTOSCALE_MASK, TMC5072_PWM_AUTOSCALE_SHIFT, TMC5072_PWMCONF(motor), false}) +#define TMC5072_PWM_SYMMETRIC_MASK 0x00080000 +#define TMC5072_PWM_SYMMETRIC_SHIFT 19 +#define TMC5072_PWM_SYMMETRIC_FIELD(motor) ((RegisterField) {TMC5072_PWM_SYMMETRIC_MASK, TMC5072_PWM_SYMMETRIC_SHIFT, TMC5072_PWMCONF(motor), false}) +#define TMC5072_FREEWHEEL_MASK 0x00300000 +#define TMC5072_FREEWHEEL_SHIFT 20 +#define TMC5072_FREEWHEEL_FIELD(motor) ((RegisterField) {TMC5072_FREEWHEEL_MASK, TMC5072_FREEWHEEL_SHIFT, TMC5072_PWMCONF(motor), false}) +#define TMC5072_PWM_STATUS_MASK 0x000000FF +#define TMC5072_PWM_STATUS_SHIFT 0 +#define TMC5072_PWM_STATUS_FIELD(motor) ((RegisterField) {TMC5072_PWM_STATUS_MASK, TMC5072_PWM_STATUS_SHIFT, TMC5072_PWM_STATUS(motor), false}) +#define TMC5072_RAMPMODE_MASK 0x00000003 +#define TMC5072_RAMPMODE_SHIFT 0 +#define TMC5072_RAMPMODE_FIELD(motor) ((RegisterField) {TMC5072_RAMPMODE_MASK, TMC5072_RAMPMODE_SHIFT, TMC5072_RAMPMODE(motor), false}) +#define TMC5072_XACTUAL_MASK 0xFFFFFFFF +#define TMC5072_XACTUAL_SHIFT 0 +#define TMC5072_XACTUAL_FIELD(motor) ((RegisterField) {TMC5072_XACTUAL_MASK, TMC5072_XACTUAL_SHIFT, TMC5072_XACTUAL(motor), true}) +#define TMC5072_VACTUAL_MASK 0x00FFFFFF +#define TMC5072_VACTUAL_SHIFT 0 +#define TMC5072_VACTUAL_FIELD(motor) ((RegisterField) {TMC5072_VACTUAL_MASK, TMC5072_VACTUAL_SHIFT, TMC5072_VACTUAL(motor), true}) +#define TMC5072_VSTART_MASK 0x0003FFFF +#define TMC5072_VSTART_SHIFT 0 +#define TMC5072_VSTART_FIELD(motor) ((RegisterField) {TMC5072_VSTART_MASK, TMC5072_VSTART_SHIFT, TMC5072_VSTART(motor), false}) +#define TMC5072_A1_MASK 0x0000FFFF +#define TMC5072_A1_SHIFT 0 +#define TMC5072_A1_FIELD(motor) ((RegisterField) {TMC5072_A1_MASK, TMC5072_A1_SHIFT, TMC5072_A1(motor), false}) +#define TMC5072_V1__MASK 0x000FFFFF +#define TMC5072_V1__SHIFT 0 +#define TMC5072_V1__FIELD(motor) ((RegisterField) {TMC5072_V1__MASK, TMC5072_V1__SHIFT, TMC5072_V1(motor), false}) +#define TMC5072_AMAX_MASK 0x0000FFFF +#define TMC5072_AMAX_SHIFT 0 +#define TMC5072_AMAX_FIELD(motor) ((RegisterField) {TMC5072_AMAX_MASK, TMC5072_AMAX_SHIFT, TMC5072_AMAX(motor), false}) +#define TMC5072_VMAX_MASK 0x007FFFFF +#define TMC5072_VMAX_SHIFT 0 +#define TMC5072_VMAX_FIELD(motor) ((RegisterField) {TMC5072_VMAX_MASK, TMC5072_VMAX_SHIFT, TMC5072_VMAX(motor), false}) +#define TMC5072_DMAX_MASK 0x0000FFFF +#define TMC5072_DMAX_SHIFT 0 +#define TMC5072_DMAX_FIELD(motor) ((RegisterField) {TMC5072_DMAX_MASK, TMC5072_DMAX_SHIFT, TMC5072_DMAX(motor), false}) +#define TMC5072_D1_MASK 0x0000FFFF +#define TMC5072_D1_SHIFT 0 +#define TMC5072_D1_FIELD(motor) ((RegisterField) {TMC5072_D1_MASK, TMC5072_D1_SHIFT, TMC5072_D1(motor), false}) +#define TMC5072_VSTOP_MASK 0x0003FFFF +#define TMC5072_VSTOP_SHIFT 0 +#define TMC5072_VSTOP_FIELD(motor) ((RegisterField) {TMC5072_VSTOP_MASK, TMC5072_VSTOP_SHIFT, TMC5072_VSTOP(motor), false}) +#define TMC5072_TZEROWAIT_MASK 0x0000FFFF +#define TMC5072_TZEROWAIT_SHIFT 0 +#define TMC5072_TZEROWAIT_FIELD(motor) ((RegisterField) {TMC5072_TZEROWAIT_MASK, TMC5072_TZEROWAIT_SHIFT, TMC5072_TZEROWAIT(motor), false}) +#define TMC5072_XTARGET_MASK 0xFFFFFFFF +#define TMC5072_XTARGET_SHIFT 0 +#define TMC5072_XTARGET_FIELD(motor) ((RegisterField) {TMC5072_XTARGET_MASK, TMC5072_XTARGET_SHIFT, TMC5072_XTARGET(motor), true}) +#define TMC5072_IHOLD_MASK 0x0000001F +#define TMC5072_IHOLD_SHIFT 0 +#define TMC5072_IHOLD_FIELD(motor) ((RegisterField) {TMC5072_IHOLD_MASK, TMC5072_IHOLD_SHIFT, TMC5072_IHOLD_IRUN(motor), false}) +#define TMC5072_IRUN_MASK 0x00001F00 +#define TMC5072_IRUN_SHIFT 8 +#define TMC5072_IRUN_FIELD(motor) ((RegisterField) {TMC5072_IRUN_MASK, TMC5072_IRUN_SHIFT, TMC5072_IHOLD_IRUN(motor), false}) +#define TMC5072_IHOLDDELAY_MASK 0x000F0000 +#define TMC5072_IHOLDDELAY_SHIFT 16 +#define TMC5072_IHOLDDELAY_FIELD(motor) ((RegisterField) {TMC5072_IHOLDDELAY_MASK, TMC5072_IHOLDDELAY_SHIFT, TMC5072_IHOLD_IRUN(motor), false}) +#define TMC5072_VCOOLTHRS_MASK 0x007FFFFF +#define TMC5072_VCOOLTHRS_SHIFT 0 +#define TMC5072_VCOOLTHRS_FIELD(motor) ((RegisterField) {TMC5072_VCOOLTHRS_MASK, TMC5072_VCOOLTHRS_SHIFT, TMC5072_VCOOLTHRS(motor), false}) +#define TMC5072_VHIGH_MASK 0x007FFFFF +#define TMC5072_VHIGH_SHIFT 0 +#define TMC5072_VHIGH_FIELD(motor) ((RegisterField) {TMC5072_VHIGH_MASK, TMC5072_VHIGH_SHIFT, TMC5072_VHIGH(motor), false}) +#define TMC5072_VDCMIN_MASK 0x007FFFFF +#define TMC5072_VDCMIN_SHIFT 0 +#define TMC5072_VDCMIN_FIELD(motor) ((RegisterField) {TMC5072_VDCMIN_MASK, TMC5072_VDCMIN_SHIFT, TMC5072_VDCMIN(motor), false}) +#define TMC5072_STOP_L_ENABLE_MASK 0x00000001 +#define TMC5072_STOP_L_ENABLE_SHIFT 0 +#define TMC5072_STOP_L_ENABLE_FIELD(motor) ((RegisterField) {TMC5072_STOP_L_ENABLE_MASK, TMC5072_STOP_L_ENABLE_SHIFT, TMC5072_SWMODE(motor), false}) +#define TMC5072_STOP_R_ENABLE_MASK 0x00000002 +#define TMC5072_STOP_R_ENABLE_SHIFT 1 +#define TMC5072_STOP_R_ENABLE_FIELD(motor) ((RegisterField) {TMC5072_STOP_R_ENABLE_MASK, TMC5072_STOP_R_ENABLE_SHIFT, TMC5072_SWMODE(motor), false}) +#define TMC5072_POL_STOP_L_MASK 0x00000004 +#define TMC5072_POL_STOP_L_SHIFT 2 +#define TMC5072_POL_STOP_L_FIELD(motor) ((RegisterField) {TMC5072_POL_STOP_L_MASK, TMC5072_POL_STOP_L_SHIFT, TMC5072_SWMODE(motor), false}) +#define TMC5072_POL_STOP_R_MASK 0x00000008 +#define TMC5072_POL_STOP_R_SHIFT 3 +#define TMC5072_POL_STOP_R_FIELD(motor) ((RegisterField) {TMC5072_POL_STOP_R_MASK, TMC5072_POL_STOP_R_SHIFT, TMC5072_SWMODE(motor), false}) +#define TMC5072_SWAP_LR_MASK 0x00000010 +#define TMC5072_SWAP_LR_SHIFT 4 +#define TMC5072_SWAP_LR_FIELD(motor) ((RegisterField) {TMC5072_SWAP_LR_MASK, TMC5072_SWAP_LR_SHIFT, TMC5072_SWMODE(motor), false}) +#define TMC5072_LATCH_L_ACTIVE_MASK 0x00000020 +#define TMC5072_LATCH_L_ACTIVE_SHIFT 5 +#define TMC5072_LATCH_L_ACTIVE_FIELD(motor) ((RegisterField) {TMC5072_LATCH_L_ACTIVE_MASK, TMC5072_LATCH_L_ACTIVE_SHIFT, TMC5072_SWMODE(motor), false}) +#define TMC5072_LATCH_L_INACTIVE_MASK 0x00000040 +#define TMC5072_LATCH_L_INACTIVE_SHIFT 6 +#define TMC5072_LATCH_L_INACTIVE_FIELD(motor) ((RegisterField) {TMC5072_LATCH_L_INACTIVE_MASK, TMC5072_LATCH_L_INACTIVE_SHIFT, TMC5072_SWMODE(motor), false}) +#define TMC5072_LATCH_R_ACTIVE_MASK 0x00000080 +#define TMC5072_LATCH_R_ACTIVE_SHIFT 7 +#define TMC5072_LATCH_R_ACTIVE_FIELD(motor) ((RegisterField) {TMC5072_LATCH_R_ACTIVE_MASK, TMC5072_LATCH_R_ACTIVE_SHIFT, TMC5072_SWMODE(motor), false}) +#define TMC5072_LATCH_R_INACTIVE_MASK 0x00000100 +#define TMC5072_LATCH_R_INACTIVE_SHIFT 8 +#define TMC5072_LATCH_R_INACTIVE_FIELD(motor) ((RegisterField) {TMC5072_LATCH_R_INACTIVE_MASK, TMC5072_LATCH_R_INACTIVE_SHIFT, TMC5072_SWMODE(motor), false}) +#define TMC5072_EN_LATCH_ENCODER_MASK 0x00000200 +#define TMC5072_EN_LATCH_ENCODER_SHIFT 9 +#define TMC5072_EN_LATCH_ENCODER_FIELD(motor) ((RegisterField) {TMC5072_EN_LATCH_ENCODER_MASK, TMC5072_EN_LATCH_ENCODER_SHIFT, TMC5072_SWMODE(motor), false}) +#define TMC5072_SG_STOP_MASK 0x00000400 +#define TMC5072_SG_STOP_SHIFT 10 +#define TMC5072_SG_STOP_FIELD(motor) ((RegisterField) {TMC5072_SG_STOP_MASK, TMC5072_SG_STOP_SHIFT, TMC5072_SWMODE(motor), false}) +#define TMC5072_EN_SOFTSTOP_MASK 0x00000800 +#define TMC5072_EN_SOFTSTOP_SHIFT 11 +#define TMC5072_EN_SOFTSTOP_FIELD(motor) ((RegisterField) {TMC5072_EN_SOFTSTOP_MASK, TMC5072_EN_SOFTSTOP_SHIFT, TMC5072_SWMODE(motor), false}) +#define TMC5072_STATUS_STOP_L_MASK 0x00000001 +#define TMC5072_STATUS_STOP_L_SHIFT 0 +#define TMC5072_STATUS_STOP_L_FIELD(motor) ((RegisterField) {TMC5072_STATUS_STOP_L_MASK, TMC5072_STATUS_STOP_L_SHIFT, TMC5072_RAMPSTAT(motor), false}) +#define TMC5072_STATUS_STOP_R_MASK 0x00000002 +#define TMC5072_STATUS_STOP_R_SHIFT 1 +#define TMC5072_STATUS_STOP_R_FIELD(motor) ((RegisterField) {TMC5072_STATUS_STOP_R_MASK, TMC5072_STATUS_STOP_R_SHIFT, TMC5072_RAMPSTAT(motor), false}) +#define TMC5072_STATUS_LATCH_L_MASK 0x00000004 +#define TMC5072_STATUS_LATCH_L_SHIFT 2 +#define TMC5072_STATUS_LATCH_L_FIELD(motor) ((RegisterField) {TMC5072_STATUS_LATCH_L_MASK, TMC5072_STATUS_LATCH_L_SHIFT, TMC5072_RAMPSTAT(motor), false}) +#define TMC5072_STATUS_LATCH_R_MASK 0x00000008 +#define TMC5072_STATUS_LATCH_R_SHIFT 3 +#define TMC5072_STATUS_LATCH_R_FIELD(motor) ((RegisterField) {TMC5072_STATUS_LATCH_R_MASK, TMC5072_STATUS_LATCH_R_SHIFT, TMC5072_RAMPSTAT(motor), false}) +#define TMC5072_EVENT_STOP_L_MASK 0x00000010 +#define TMC5072_EVENT_STOP_L_SHIFT 4 +#define TMC5072_EVENT_STOP_L_FIELD(motor) ((RegisterField) {TMC5072_EVENT_STOP_L_MASK, TMC5072_EVENT_STOP_L_SHIFT, TMC5072_RAMPSTAT(motor), false}) +#define TMC5072_EVENT_STOP_R_MASK 0x00000020 +#define TMC5072_EVENT_STOP_R_SHIFT 5 +#define TMC5072_EVENT_STOP_R_FIELD(motor) ((RegisterField) {TMC5072_EVENT_STOP_R_MASK, TMC5072_EVENT_STOP_R_SHIFT, TMC5072_RAMPSTAT(motor), false}) +#define TMC5072_EVENT_STOP_SG_MASK 0x00000040 +#define TMC5072_EVENT_STOP_SG_SHIFT 6 +#define TMC5072_EVENT_STOP_SG_FIELD(motor) ((RegisterField) {TMC5072_EVENT_STOP_SG_MASK, TMC5072_EVENT_STOP_SG_SHIFT, TMC5072_RAMPSTAT(motor), false}) +#define TMC5072_EVENT_POS_REACHED_MASK 0x00000080 +#define TMC5072_EVENT_POS_REACHED_SHIFT 7 +#define TMC5072_EVENT_POS_REACHED_FIELD(motor) ((RegisterField) {TMC5072_EVENT_POS_REACHED_MASK, TMC5072_EVENT_POS_REACHED_SHIFT, TMC5072_RAMPSTAT(motor), false}) +#define TMC5072_VELOCITY_REACHED_MASK 0x00000100 +#define TMC5072_VELOCITY_REACHED_SHIFT 8 +#define TMC5072_VELOCITY_REACHED_FIELD(motor) ((RegisterField) {TMC5072_VELOCITY_REACHED_MASK, TMC5072_VELOCITY_REACHED_SHIFT, TMC5072_RAMPSTAT(motor), false}) +#define TMC5072_POSITION_REACHED_MASK 0x00000200 +#define TMC5072_POSITION_REACHED_SHIFT 9 +#define TMC5072_POSITION_REACHED_FIELD(motor) ((RegisterField) {TMC5072_POSITION_REACHED_MASK, TMC5072_POSITION_REACHED_SHIFT, TMC5072_RAMPSTAT(motor), false}) +#define TMC5072_VZERO_MASK 0x00000400 +#define TMC5072_VZERO_SHIFT 10 +#define TMC5072_VZERO_FIELD(motor) ((RegisterField) {TMC5072_VZERO_MASK, TMC5072_VZERO_SHIFT, TMC5072_RAMPSTAT(motor), false}) +#define TMC5072_T_ZEROWAIT_ACTIVE_MASK 0x00000800 +#define TMC5072_T_ZEROWAIT_ACTIVE_SHIFT 11 +#define TMC5072_T_ZEROWAIT_ACTIVE_FIELD(motor) ((RegisterField) {TMC5072_T_ZEROWAIT_ACTIVE_MASK, TMC5072_T_ZEROWAIT_ACTIVE_SHIFT, TMC5072_RAMPSTAT(motor), false}) +#define TMC5072_SECOND_MOVE_MASK 0x00001000 +#define TMC5072_SECOND_MOVE_SHIFT 12 +#define TMC5072_SECOND_MOVE_FIELD(motor) ((RegisterField) {TMC5072_SECOND_MOVE_MASK, TMC5072_SECOND_MOVE_SHIFT, TMC5072_RAMPSTAT(motor), false}) +#define TMC5072_STATUS_SG_MASK 0x00002000 +#define TMC5072_STATUS_SG_SHIFT 13 +#define TMC5072_STATUS_SG_FIELD(motor) ((RegisterField) {TMC5072_STATUS_SG_MASK, TMC5072_STATUS_SG_SHIFT, TMC5072_RAMPSTAT(motor), false}) +#define TMC5072_XLATCH_MASK 0xFFFFFFFF +#define TMC5072_XLATCH_SHIFT 0 +#define TMC5072_XLATCH_FIELD(motor) ((RegisterField) {TMC5072_XLATCH_MASK, TMC5072_XLATCH_SHIFT, TMC5072_XLATCH(motor), false}) +#define TMC5072_POL_A_MASK 0x00000001 +#define TMC5072_POL_A_SHIFT 0 +#define TMC5072_POL_A_FIELD(motor) ((RegisterField) {TMC5072_POL_A_MASK, TMC5072_POL_A_SHIFT, TMC5072_ENCMODE(motor), false}) +#define TMC5072_POL_B_MASK 0x00000002 +#define TMC5072_POL_B_SHIFT 1 +#define TMC5072_POL_B_FIELD(motor) ((RegisterField) {TMC5072_POL_B_MASK, TMC5072_POL_B_SHIFT, TMC5072_ENCMODE(motor), false}) +#define TMC5072_POL_N_MASK 0x00000004 +#define TMC5072_POL_N_SHIFT 2 +#define TMC5072_POL_N_FIELD(motor) ((RegisterField) {TMC5072_POL_N_MASK, TMC5072_POL_N_SHIFT, TMC5072_ENCMODE(motor), false}) +#define TMC5072_IGNORE_AB_MASK 0x00000008 +#define TMC5072_IGNORE_AB_SHIFT 3 +#define TMC5072_IGNORE_AB_FIELD(motor) ((RegisterField) {TMC5072_IGNORE_AB_MASK, TMC5072_IGNORE_AB_SHIFT, TMC5072_ENCMODE(motor), false}) +#define TMC5072_CLR_CONT_MASK 0x00000010 +#define TMC5072_CLR_CONT_SHIFT 4 +#define TMC5072_CLR_CONT_FIELD(motor) ((RegisterField) {TMC5072_CLR_CONT_MASK, TMC5072_CLR_CONT_SHIFT, TMC5072_ENCMODE(motor), false}) +#define TMC5072_CLR_ONCE_MASK 0x00000020 +#define TMC5072_CLR_ONCE_SHIFT 5 +#define TMC5072_CLR_ONCE_FIELD(motor) ((RegisterField) {TMC5072_CLR_ONCE_MASK, TMC5072_CLR_ONCE_SHIFT, TMC5072_ENCMODE(motor), false}) +#define TMC5072_POS_EDGE_NEG_EDGE_MASK 0x000000C0 +#define TMC5072_POS_EDGE_NEG_EDGE_SHIFT 6 +#define TMC5072_POS_EDGE_NEG_EDGE_FIELD(motor) ((RegisterField) {TMC5072_POS_EDGE_NEG_EDGE_MASK, TMC5072_POS_EDGE_NEG_EDGE_SHIFT, TMC5072_ENCMODE(motor), false}) +#define TMC5072_CLR_ENC_X_MASK 0x00000100 +#define TMC5072_CLR_ENC_X_SHIFT 8 +#define TMC5072_CLR_ENC_X_FIELD(motor) ((RegisterField) {TMC5072_CLR_ENC_X_MASK, TMC5072_CLR_ENC_X_SHIFT, TMC5072_ENCMODE(motor), false}) +#define TMC5072_LATCH_X_ACT_MASK 0x00000200 +#define TMC5072_LATCH_X_ACT_SHIFT 9 +#define TMC5072_LATCH_X_ACT_FIELD(motor) ((RegisterField) {TMC5072_LATCH_X_ACT_MASK, TMC5072_LATCH_X_ACT_SHIFT, TMC5072_ENCMODE(motor), false}) +#define TMC5072_ENC_SEL_DECIMAL_MASK 0x00000400 +#define TMC5072_ENC_SEL_DECIMAL_SHIFT 10 +#define TMC5072_ENC_SEL_DECIMAL_FIELD(motor) ((RegisterField) {TMC5072_ENC_SEL_DECIMAL_MASK, TMC5072_ENC_SEL_DECIMAL_SHIFT, TMC5072_ENCMODE(motor), false}) +#define TMC5072_LATCH_NOW__MASK 0x00000800 +#define TMC5072_LATCH_NOW__SHIFT 11 +#define TMC5072_LATCH_NOW__FIELD(motor) ((RegisterField) {TMC5072_LATCH_NOW__MASK, TMC5072_LATCH_NOW__SHIFT, TMC5072_ENCMODE(motor), false}) +#define TMC5072_XENC_MASK 0xFFFFFFFF +#define TMC5072_XENC_SHIFT 0 +#define TMC5072_XENC_FIELD(motor) ((RegisterField) {TMC5072_XENC_MASK, TMC5072_XENC_SHIFT, TMC5072_XENC(motor), true}) +#define TMC5072_INTEGER_MASK 0xFFFF0000 +#define TMC5072_INTEGER_SHIFT 16 +#define TMC5072_INTEGER_FIELD(motor) ((RegisterField) {TMC5072_INTEGER_MASK, TMC5072_INTEGER_SHIFT, TMC5072_ENC_CONST(motor), false}) +#define TMC5072_FRACTIONAL_MASK 0x0000FFFF +#define TMC5072_FRACTIONAL_SHIFT 0 +#define TMC5072_FRACTIONAL_FIELD(motor) ((RegisterField) {TMC5072_FRACTIONAL_MASK, TMC5072_FRACTIONAL_SHIFT, TMC5072_ENC_CONST(motor), false}) +#define TMC5072_ENC_STATUS_MASK 0x00000001 +#define TMC5072_ENC_STATUS_SHIFT 0 +#define TMC5072_ENC_STATUS_FIELD(motor) ((RegisterField) {TMC5072_ENC_STATUS_MASK, TMC5072_ENC_STATUS_SHIFT, TMC5072_ENC_STATUS(motor), false}) +#define TMC5072_ENC_LATCH_MASK 0xFFFFFFFF +#define TMC5072_ENC_LATCH_SHIFT 0 +#define TMC5072_ENC_LATCH_FIELD(motor) ((RegisterField) {TMC5072_ENC_LATCH_MASK, TMC5072_ENC_LATCH_SHIFT, TMC5072_ENC_LATCH(motor), true}) +#define TMC5072_OFS0_MASK 0x00000001 +#define TMC5072_OFS0_SHIFT 0 +#define TMC5072_OFS0_FIELD(motor) ((RegisterField) {TMC5072_OFS0_MASK, TMC5072_OFS0_SHIFT, TMC5072_MSLUT[0], false}) +#define TMC5072_OFS1_MASK 0x00000002 +#define TMC5072_OFS1_SHIFT 1 +#define TMC5072_OFS1_FIELD(motor) ((RegisterField) {TMC5072_OFS1_MASK, TMC5072_OFS1_SHIFT, TMC5072_MSLUT[0], false}) +#define TMC5072_OFS2_MASK 0x00000004 +#define TMC5072_OFS2_SHIFT 2 +#define TMC5072_OFS2_FIELD(motor) ((RegisterField) {TMC5072_OFS2_MASK, TMC5072_OFS2_SHIFT, TMC5072_MSLUT[0], false}) +#define TMC5072_OFS3_MASK 0x00000008 +#define TMC5072_OFS3_SHIFT 3 +#define TMC5072_OFS3_FIELD(motor) ((RegisterField) {TMC5072_OFS3_MASK, TMC5072_OFS3_SHIFT, TMC5072_MSLUT[0], false}) +#define TMC5072_OFS4_MASK 0x00000010 +#define TMC5072_OFS4_SHIFT 4 +#define TMC5072_OFS4_FIELD(motor) ((RegisterField) {TMC5072_OFS4_MASK, TMC5072_OFS4_SHIFT, TMC5072_MSLUT[0], false}) +#define TMC5072_OFS5_MASK 0x00000020 +#define TMC5072_OFS5_SHIFT 5 +#define TMC5072_OFS5_FIELD(motor) ((RegisterField) {TMC5072_OFS5_MASK, TMC5072_OFS5_SHIFT, TMC5072_MSLUT[0], false}) +#define TMC5072_OFS6_MASK 0x00000040 +#define TMC5072_OFS6_SHIFT 6 +#define TMC5072_OFS6_FIELD(motor) ((RegisterField) {TMC5072_OFS6_MASK, TMC5072_OFS6_SHIFT, TMC5072_MSLUT[0], false}) +#define TMC5072_OFS7_MASK 0x00000080 +#define TMC5072_OFS7_SHIFT 7 +#define TMC5072_OFS7_FIELD(motor) ((RegisterField) {TMC5072_OFS7_MASK, TMC5072_OFS7_SHIFT, TMC5072_MSLUT[0], false}) +#define TMC5072_OFS8_MASK 0x00000100 +#define TMC5072_OFS8_SHIFT 8 +#define TMC5072_OFS8_FIELD(motor) ((RegisterField) {TMC5072_OFS8_MASK, TMC5072_OFS8_SHIFT, TMC5072_MSLUT[0], false}) +#define TMC5072_OFS9_MASK 0x00000200 +#define TMC5072_OFS9_SHIFT 9 +#define TMC5072_OFS9_FIELD(motor) ((RegisterField) {TMC5072_OFS9_MASK, TMC5072_OFS9_SHIFT, TMC5072_MSLUT[0], false}) +#define TMC5072_OFS10_MASK 0x00000400 +#define TMC5072_OFS10_SHIFT 10 +#define TMC5072_OFS10_FIELD(motor) ((RegisterField) {TMC5072_OFS10_MASK, TMC5072_OFS10_SHIFT, TMC5072_MSLUT[0], false}) +#define TMC5072_OFS11_MASK 0x00000800 +#define TMC5072_OFS11_SHIFT 11 +#define TMC5072_OFS11_FIELD(motor) ((RegisterField) {TMC5072_OFS11_MASK, TMC5072_OFS11_SHIFT, TMC5072_MSLUT[0], false}) +#define TMC5072_OFS12_MASK 0x00001000 +#define TMC5072_OFS12_SHIFT 12 +#define TMC5072_OFS12_FIELD(motor) ((RegisterField) {TMC5072_OFS12_MASK, TMC5072_OFS12_SHIFT, TMC5072_MSLUT[0], false}) +#define TMC5072_OFS13_MASK 0x00002000 +#define TMC5072_OFS13_SHIFT 13 +#define TMC5072_OFS13_FIELD(motor) ((RegisterField) {TMC5072_OFS13_MASK, TMC5072_OFS13_SHIFT, TMC5072_MSLUT[0], false}) +#define TMC5072_OFS14_MASK 0x00004000 +#define TMC5072_OFS14_SHIFT 14 +#define TMC5072_OFS14_FIELD(motor) ((RegisterField) {TMC5072_OFS14_MASK, TMC5072_OFS14_SHIFT, TMC5072_MSLUT[0], false}) +#define TMC5072_OFS15_MASK 0x00008000 +#define TMC5072_OFS15_SHIFT 15 +#define TMC5072_OFS15_FIELD(motor) ((RegisterField) {TMC5072_OFS15_MASK, TMC5072_OFS15_SHIFT, TMC5072_MSLUT[0], false}) +#define TMC5072_OFS16_MASK 0x00010000 +#define TMC5072_OFS16_SHIFT 16 +#define TMC5072_OFS16_FIELD(motor) ((RegisterField) {TMC5072_OFS16_MASK, TMC5072_OFS16_SHIFT, TMC5072_MSLUT[0], false}) +#define TMC5072_OFS17_MASK 0x00020000 +#define TMC5072_OFS17_SHIFT 17 +#define TMC5072_OFS17_FIELD(motor) ((RegisterField) {TMC5072_OFS17_MASK, TMC5072_OFS17_SHIFT, TMC5072_MSLUT[0], false}) +#define TMC5072_OFS18_MASK 0x00040000 +#define TMC5072_OFS18_SHIFT 18 +#define TMC5072_OFS18_FIELD(motor) ((RegisterField) {TMC5072_OFS18_MASK, TMC5072_OFS18_SHIFT, TMC5072_MSLUT[0], false}) +#define TMC5072_OFS19_MASK 0x00080000 +#define TMC5072_OFS19_SHIFT 19 +#define TMC5072_OFS19_FIELD(motor) ((RegisterField) {TMC5072_OFS19_MASK, TMC5072_OFS19_SHIFT, TMC5072_MSLUT[0], false}) +#define TMC5072_OFS20_MASK 0x00100000 +#define TMC5072_OFS20_SHIFT 20 +#define TMC5072_OFS20_FIELD(motor) ((RegisterField) {TMC5072_OFS20_MASK, TMC5072_OFS20_SHIFT, TMC5072_MSLUT[0], false}) +#define TMC5072_OFS21_MASK 0x00200000 +#define TMC5072_OFS21_SHIFT 21 +#define TMC5072_OFS21_FIELD(motor) ((RegisterField) {TMC5072_OFS21_MASK, TMC5072_OFS21_SHIFT, TMC5072_MSLUT[0], false}) +#define TMC5072_OFS22_MASK 0x00400000 +#define TMC5072_OFS22_SHIFT 22 +#define TMC5072_OFS22_FIELD(motor) ((RegisterField) {TMC5072_OFS22_MASK, TMC5072_OFS22_SHIFT, TMC5072_MSLUT[0], false}) +#define TMC5072_OFS23_MASK 0x00800000 +#define TMC5072_OFS23_SHIFT 23 +#define TMC5072_OFS23_FIELD(motor) ((RegisterField) {TMC5072_OFS23_MASK, TMC5072_OFS23_SHIFT, TMC5072_MSLUT[0], false}) +#define TMC5072_OFS24_MASK 0x01000000 +#define TMC5072_OFS24_SHIFT 24 +#define TMC5072_OFS24_FIELD(motor) ((RegisterField) {TMC5072_OFS24_MASK, TMC5072_OFS24_SHIFT, TMC5072_MSLUT[0], false}) +#define TMC5072_OFS25_MASK 0x02000000 +#define TMC5072_OFS25_SHIFT 25 +#define TMC5072_OFS25_FIELD(motor) ((RegisterField) {TMC5072_OFS25_MASK, TMC5072_OFS25_SHIFT, TMC5072_MSLUT[0], false}) +#define TMC5072_OFS26_MASK 0x04000000 +#define TMC5072_OFS26_SHIFT 26 +#define TMC5072_OFS26_FIELD(motor) ((RegisterField) {TMC5072_OFS26_MASK, TMC5072_OFS26_SHIFT, TMC5072_MSLUT[0], false}) +#define TMC5072_OFS27_MASK 0x08000000 +#define TMC5072_OFS27_SHIFT 27 +#define TMC5072_OFS27_FIELD(motor) ((RegisterField) {TMC5072_OFS27_MASK, TMC5072_OFS27_SHIFT, TMC5072_MSLUT[0], false}) +#define TMC5072_OFS28_MASK 0x10000000 +#define TMC5072_OFS28_SHIFT 28 +#define TMC5072_OFS28_FIELD(motor) ((RegisterField) {TMC5072_OFS28_MASK, TMC5072_OFS28_SHIFT, TMC5072_MSLUT[0], false}) +#define TMC5072_OFS29_MASK 0x20000000 +#define TMC5072_OFS29_SHIFT 29 +#define TMC5072_OFS29_FIELD(motor) ((RegisterField) {TMC5072_OFS29_MASK, TMC5072_OFS29_SHIFT, TMC5072_MSLUT[0], false}) +#define TMC5072_OFS30_MASK 0x40000000 +#define TMC5072_OFS30_SHIFT 30 +#define TMC5072_OFS30_FIELD(motor) ((RegisterField) {TMC5072_OFS30_MASK, TMC5072_OFS30_SHIFT, TMC5072_MSLUT[0], false}) +#define TMC5072_OFS31_MASK 0x80000000 +#define TMC5072_OFS31_SHIFT 31 +#define TMC5072_OFS31_FIELD(motor) ((RegisterField) {TMC5072_OFS31_MASK, TMC5072_OFS31_SHIFT, TMC5072_MSLUT[0], false}) +#define TMC5072_OFS32_MASK 0x00000001 +#define TMC5072_OFS32_SHIFT 0 +#define TMC5072_OFS32_FIELD(motor) ((RegisterField) {TMC5072_OFS32_MASK, TMC5072_OFS32_SHIFT, TMC5072_MSLUT[1], false}) +#define TMC5072_OFS33_MASK 0x00000002 +#define TMC5072_OFS33_SHIFT 1 +#define TMC5072_OFS33_FIELD(motor) ((RegisterField) {TMC5072_OFS33_MASK, TMC5072_OFS33_SHIFT, TMC5072_MSLUT[1], false}) +#define TMC5072_OFS34_MASK 0x00000004 +#define TMC5072_OFS34_SHIFT 2 +#define TMC5072_OFS34_FIELD(motor) ((RegisterField) {TMC5072_OFS34_MASK, TMC5072_OFS34_SHIFT, TMC5072_MSLUT[1], false}) +#define TMC5072_OFS35_MASK 0x00000008 +#define TMC5072_OFS35_SHIFT 3 +#define TMC5072_OFS35_FIELD(motor) ((RegisterField) {TMC5072_OFS35_MASK, TMC5072_OFS35_SHIFT, TMC5072_MSLUT[1], false}) +#define TMC5072_OFS36_MASK 0x00000010 +#define TMC5072_OFS36_SHIFT 4 +#define TMC5072_OFS36_FIELD(motor) ((RegisterField) {TMC5072_OFS36_MASK, TMC5072_OFS36_SHIFT, TMC5072_MSLUT[1], false}) +#define TMC5072_OFS37_MASK 0x00000020 +#define TMC5072_OFS37_SHIFT 5 +#define TMC5072_OFS37_FIELD(motor) ((RegisterField) {TMC5072_OFS37_MASK, TMC5072_OFS37_SHIFT, TMC5072_MSLUT[1], false}) +#define TMC5072_OFS38_MASK 0x00000040 +#define TMC5072_OFS38_SHIFT 6 +#define TMC5072_OFS38_FIELD(motor) ((RegisterField) {TMC5072_OFS38_MASK, TMC5072_OFS38_SHIFT, TMC5072_MSLUT[1], false}) +#define TMC5072_OFS39_MASK 0x00000080 +#define TMC5072_OFS39_SHIFT 7 +#define TMC5072_OFS39_FIELD(motor) ((RegisterField) {TMC5072_OFS39_MASK, TMC5072_OFS39_SHIFT, TMC5072_MSLUT[1], false}) +#define TMC5072_OFS40_MASK 0x00000100 +#define TMC5072_OFS40_SHIFT 8 +#define TMC5072_OFS40_FIELD(motor) ((RegisterField) {TMC5072_OFS40_MASK, TMC5072_OFS40_SHIFT, TMC5072_MSLUT[1], false}) +#define TMC5072_OFS41_MASK 0x00000200 +#define TMC5072_OFS41_SHIFT 9 +#define TMC5072_OFS41_FIELD(motor) ((RegisterField) {TMC5072_OFS41_MASK, TMC5072_OFS41_SHIFT, TMC5072_MSLUT[1], false}) +#define TMC5072_OFS42_MASK 0x00000400 +#define TMC5072_OFS42_SHIFT 10 +#define TMC5072_OFS42_FIELD(motor) ((RegisterField) {TMC5072_OFS42_MASK, TMC5072_OFS42_SHIFT, TMC5072_MSLUT[1], false}) +#define TMC5072_OFS43_MASK 0x00000800 +#define TMC5072_OFS43_SHIFT 11 +#define TMC5072_OFS43_FIELD(motor) ((RegisterField) {TMC5072_OFS43_MASK, TMC5072_OFS43_SHIFT, TMC5072_MSLUT[1], false}) +#define TMC5072_OFS44_MASK 0x00001000 +#define TMC5072_OFS44_SHIFT 12 +#define TMC5072_OFS44_FIELD(motor) ((RegisterField) {TMC5072_OFS44_MASK, TMC5072_OFS44_SHIFT, TMC5072_MSLUT[1], false}) +#define TMC5072_OFS45_MASK 0x00002000 +#define TMC5072_OFS45_SHIFT 13 +#define TMC5072_OFS45_FIELD(motor) ((RegisterField) {TMC5072_OFS45_MASK, TMC5072_OFS45_SHIFT, TMC5072_MSLUT[1], false}) +#define TMC5072_OFS46_MASK 0x00004000 +#define TMC5072_OFS46_SHIFT 14 +#define TMC5072_OFS46_FIELD(motor) ((RegisterField) {TMC5072_OFS46_MASK, TMC5072_OFS46_SHIFT, TMC5072_MSLUT[1], false}) +#define TMC5072_OFS47_MASK 0x00008000 +#define TMC5072_OFS47_SHIFT 15 +#define TMC5072_OFS47_FIELD(motor) ((RegisterField) {TMC5072_OFS47_MASK, TMC5072_OFS47_SHIFT, TMC5072_MSLUT[1], false}) +#define TMC5072_OFS48_MASK 0x00010000 +#define TMC5072_OFS48_SHIFT 16 +#define TMC5072_OFS48_FIELD(motor) ((RegisterField) {TMC5072_OFS48_MASK, TMC5072_OFS48_SHIFT, TMC5072_MSLUT[1], false}) +#define TMC5072_OFS49_MASK 0x00020000 +#define TMC5072_OFS49_SHIFT 17 +#define TMC5072_OFS49_FIELD(motor) ((RegisterField) {TMC5072_OFS49_MASK, TMC5072_OFS49_SHIFT, TMC5072_MSLUT[1], false}) +#define TMC5072_OFS50_MASK 0x00040000 +#define TMC5072_OFS50_SHIFT 18 +#define TMC5072_OFS50_FIELD(motor) ((RegisterField) {TMC5072_OFS50_MASK, TMC5072_OFS50_SHIFT, TMC5072_MSLUT[1], false}) +#define TMC5072_OFS51_MASK 0x00080000 +#define TMC5072_OFS51_SHIFT 19 +#define TMC5072_OFS51_FIELD(motor) ((RegisterField) {TMC5072_OFS51_MASK, TMC5072_OFS51_SHIFT, TMC5072_MSLUT[1], false}) +#define TMC5072_OFS52_MASK 0x00100000 +#define TMC5072_OFS52_SHIFT 20 +#define TMC5072_OFS52_FIELD(motor) ((RegisterField) {TMC5072_OFS52_MASK, TMC5072_OFS52_SHIFT, TMC5072_MSLUT[1], false}) +#define TMC5072_OFS53_MASK 0x00200000 +#define TMC5072_OFS53_SHIFT 21 +#define TMC5072_OFS53_FIELD(motor) ((RegisterField) {TMC5072_OFS53_MASK, TMC5072_OFS53_SHIFT, TMC5072_MSLUT[1], false}) +#define TMC5072_OFS54_MASK 0x00400000 +#define TMC5072_OFS54_SHIFT 22 +#define TMC5072_OFS54_FIELD(motor) ((RegisterField) {TMC5072_OFS54_MASK, TMC5072_OFS54_SHIFT, TMC5072_MSLUT[1], false}) +#define TMC5072_OFS55_MASK 0x00800000 +#define TMC5072_OFS55_SHIFT 23 +#define TMC5072_OFS55_FIELD(motor) ((RegisterField) {TMC5072_OFS55_MASK, TMC5072_OFS55_SHIFT, TMC5072_MSLUT[1], false}) +#define TMC5072_OFS56_MASK 0x01000000 +#define TMC5072_OFS56_SHIFT 24 +#define TMC5072_OFS56_FIELD(motor) ((RegisterField) {TMC5072_OFS56_MASK, TMC5072_OFS56_SHIFT, TMC5072_MSLUT[1], false}) +#define TMC5072_OFS57_MASK 0x02000000 +#define TMC5072_OFS57_SHIFT 25 +#define TMC5072_OFS57_FIELD(motor) ((RegisterField) {TMC5072_OFS57_MASK, TMC5072_OFS57_SHIFT, TMC5072_MSLUT[1], false}) +#define TMC5072_OFS58_MASK 0x04000000 +#define TMC5072_OFS58_SHIFT 26 +#define TMC5072_OFS58_FIELD(motor) ((RegisterField) {TMC5072_OFS58_MASK, TMC5072_OFS58_SHIFT, TMC5072_MSLUT[1], false}) +#define TMC5072_OFS59_MASK 0x08000000 +#define TMC5072_OFS59_SHIFT 27 +#define TMC5072_OFS59_FIELD(motor) ((RegisterField) {TMC5072_OFS59_MASK, TMC5072_OFS59_SHIFT, TMC5072_MSLUT[1], false}) +#define TMC5072_OFS60_MASK 0x10000000 +#define TMC5072_OFS60_SHIFT 28 +#define TMC5072_OFS60_FIELD(motor) ((RegisterField) {TMC5072_OFS60_MASK, TMC5072_OFS60_SHIFT, TMC5072_MSLUT[1], false}) +#define TMC5072_OFS61_MASK 0x20000000 +#define TMC5072_OFS61_SHIFT 29 +#define TMC5072_OFS61_FIELD(motor) ((RegisterField) {TMC5072_OFS61_MASK, TMC5072_OFS61_SHIFT, TMC5072_MSLUT[1], false}) +#define TMC5072_OFS62_MASK 0x40000000 +#define TMC5072_OFS62_SHIFT 30 +#define TMC5072_OFS62_FIELD(motor) ((RegisterField) {TMC5072_OFS62_MASK, TMC5072_OFS62_SHIFT, TMC5072_MSLUT[1], false}) +#define TMC5072_OFS63_MASK 0x80000000 +#define TMC5072_OFS63_SHIFT 31 +#define TMC5072_OFS63_FIELD(motor) ((RegisterField) {TMC5072_OFS63_MASK, TMC5072_OFS63_SHIFT, TMC5072_MSLUT[1], false}) +#define TMC5072_OFS64_MASK 0x00000001 +#define TMC5072_OFS64_SHIFT 0 +#define TMC5072_OFS64_FIELD(motor) ((RegisterField) {TMC5072_OFS64_MASK, TMC5072_OFS64_SHIFT, TMC5072_MSLUT[2], false}) +#define TMC5072_OFS65_MASK 0x00000002 +#define TMC5072_OFS65_SHIFT 1 +#define TMC5072_OFS65_FIELD(motor) ((RegisterField) {TMC5072_OFS65_MASK, TMC5072_OFS65_SHIFT, TMC5072_MSLUT[2], false}) +#define TMC5072_OFS66_MASK 0x00000004 +#define TMC5072_OFS66_SHIFT 2 +#define TMC5072_OFS66_FIELD(motor) ((RegisterField) {TMC5072_OFS66_MASK, TMC5072_OFS66_SHIFT, TMC5072_MSLUT[2], false}) +#define TMC5072_OFS67_MASK 0x00000008 +#define TMC5072_OFS67_SHIFT 3 +#define TMC5072_OFS67_FIELD(motor) ((RegisterField) {TMC5072_OFS67_MASK, TMC5072_OFS67_SHIFT, TMC5072_MSLUT[2], false}) +#define TMC5072_OFS68_MASK 0x00000010 +#define TMC5072_OFS68_SHIFT 4 +#define TMC5072_OFS68_FIELD(motor) ((RegisterField) {TMC5072_OFS68_MASK, TMC5072_OFS68_SHIFT, TMC5072_MSLUT[2], false}) +#define TMC5072_OFS69_MASK 0x00000020 +#define TMC5072_OFS69_SHIFT 5 +#define TMC5072_OFS69_FIELD(motor) ((RegisterField) {TMC5072_OFS69_MASK, TMC5072_OFS69_SHIFT, TMC5072_MSLUT[2], false}) +#define TMC5072_OFS70_MASK 0x00000040 +#define TMC5072_OFS70_SHIFT 6 +#define TMC5072_OFS70_FIELD(motor) ((RegisterField) {TMC5072_OFS70_MASK, TMC5072_OFS70_SHIFT, TMC5072_MSLUT[2], false}) +#define TMC5072_OFS71_MASK 0x00000080 +#define TMC5072_OFS71_SHIFT 7 +#define TMC5072_OFS71_FIELD(motor) ((RegisterField) {TMC5072_OFS71_MASK, TMC5072_OFS71_SHIFT, TMC5072_MSLUT[2], false}) +#define TMC5072_OFS72_MASK 0x00000100 +#define TMC5072_OFS72_SHIFT 8 +#define TMC5072_OFS72_FIELD(motor) ((RegisterField) {TMC5072_OFS72_MASK, TMC5072_OFS72_SHIFT, TMC5072_MSLUT[2], false}) +#define TMC5072_OFS73_MASK 0x00000200 +#define TMC5072_OFS73_SHIFT 9 +#define TMC5072_OFS73_FIELD(motor) ((RegisterField) {TMC5072_OFS73_MASK, TMC5072_OFS73_SHIFT, TMC5072_MSLUT[2], false}) +#define TMC5072_OFS74_MASK 0x00000400 +#define TMC5072_OFS74_SHIFT 10 +#define TMC5072_OFS74_FIELD(motor) ((RegisterField) {TMC5072_OFS74_MASK, TMC5072_OFS74_SHIFT, TMC5072_MSLUT[2], false}) +#define TMC5072_OFS75_MASK 0x00000800 +#define TMC5072_OFS75_SHIFT 11 +#define TMC5072_OFS75_FIELD(motor) ((RegisterField) {TMC5072_OFS75_MASK, TMC5072_OFS75_SHIFT, TMC5072_MSLUT[2], false}) +#define TMC5072_OFS76_MASK 0x00001000 +#define TMC5072_OFS76_SHIFT 12 +#define TMC5072_OFS76_FIELD(motor) ((RegisterField) {TMC5072_OFS76_MASK, TMC5072_OFS76_SHIFT, TMC5072_MSLUT[2], false}) +#define TMC5072_OFS77_MASK 0x00002000 +#define TMC5072_OFS77_SHIFT 13 +#define TMC5072_OFS77_FIELD(motor) ((RegisterField) {TMC5072_OFS77_MASK, TMC5072_OFS77_SHIFT, TMC5072_MSLUT[2], false}) +#define TMC5072_OFS78_MASK 0x00004000 +#define TMC5072_OFS78_SHIFT 14 +#define TMC5072_OFS78_FIELD(motor) ((RegisterField) {TMC5072_OFS78_MASK, TMC5072_OFS78_SHIFT, TMC5072_MSLUT[2], false}) +#define TMC5072_OFS79_MASK 0x00008000 +#define TMC5072_OFS79_SHIFT 15 +#define TMC5072_OFS79_FIELD(motor) ((RegisterField) {TMC5072_OFS79_MASK, TMC5072_OFS79_SHIFT, TMC5072_MSLUT[2], false}) +#define TMC5072_OFS80_MASK 0x00010000 +#define TMC5072_OFS80_SHIFT 16 +#define TMC5072_OFS80_FIELD(motor) ((RegisterField) {TMC5072_OFS80_MASK, TMC5072_OFS80_SHIFT, TMC5072_MSLUT[2], false}) +#define TMC5072_OFS81_MASK 0x00020000 +#define TMC5072_OFS81_SHIFT 17 +#define TMC5072_OFS81_FIELD(motor) ((RegisterField) {TMC5072_OFS81_MASK, TMC5072_OFS81_SHIFT, TMC5072_MSLUT[2], false}) +#define TMC5072_OFS82_MASK 0x00040000 +#define TMC5072_OFS82_SHIFT 18 +#define TMC5072_OFS82_FIELD(motor) ((RegisterField) {TMC5072_OFS82_MASK, TMC5072_OFS82_SHIFT, TMC5072_MSLUT[2], false}) +#define TMC5072_OFS83_MASK 0x00080000 +#define TMC5072_OFS83_SHIFT 19 +#define TMC5072_OFS83_FIELD(motor) ((RegisterField) {TMC5072_OFS83_MASK, TMC5072_OFS83_SHIFT, TMC5072_MSLUT[2], false}) +#define TMC5072_OFS84_MASK 0x00100000 +#define TMC5072_OFS84_SHIFT 20 +#define TMC5072_OFS84_FIELD(motor) ((RegisterField) {TMC5072_OFS84_MASK, TMC5072_OFS84_SHIFT, TMC5072_MSLUT[2], false}) +#define TMC5072_OFS85_MASK 0x00200000 +#define TMC5072_OFS85_SHIFT 21 +#define TMC5072_OFS85_FIELD(motor) ((RegisterField) {TMC5072_OFS85_MASK, TMC5072_OFS85_SHIFT, TMC5072_MSLUT[2], false}) +#define TMC5072_OFS86_MASK 0x00400000 +#define TMC5072_OFS86_SHIFT 22 +#define TMC5072_OFS86_FIELD(motor) ((RegisterField) {TMC5072_OFS86_MASK, TMC5072_OFS86_SHIFT, TMC5072_MSLUT[2], false}) +#define TMC5072_OFS87_MASK 0x00800000 +#define TMC5072_OFS87_SHIFT 23 +#define TMC5072_OFS87_FIELD(motor) ((RegisterField) {TMC5072_OFS87_MASK, TMC5072_OFS87_SHIFT, TMC5072_MSLUT[2], false}) +#define TMC5072_OFS88_MASK 0x01000000 +#define TMC5072_OFS88_SHIFT 24 +#define TMC5072_OFS88_FIELD(motor) ((RegisterField) {TMC5072_OFS88_MASK, TMC5072_OFS88_SHIFT, TMC5072_MSLUT[2], false}) +#define TMC5072_OFS89_MASK 0x02000000 +#define TMC5072_OFS89_SHIFT 25 +#define TMC5072_OFS89_FIELD(motor) ((RegisterField) {TMC5072_OFS89_MASK, TMC5072_OFS89_SHIFT, TMC5072_MSLUT[2], false}) +#define TMC5072_OFS90_MASK 0x04000000 +#define TMC5072_OFS90_SHIFT 26 +#define TMC5072_OFS90_FIELD(motor) ((RegisterField) {TMC5072_OFS90_MASK, TMC5072_OFS90_SHIFT, TMC5072_MSLUT[2], false}) +#define TMC5072_OFS91_MASK 0x08000000 +#define TMC5072_OFS91_SHIFT 27 +#define TMC5072_OFS91_FIELD(motor) ((RegisterField) {TMC5072_OFS91_MASK, TMC5072_OFS91_SHIFT, TMC5072_MSLUT[2], false}) +#define TMC5072_OFS92_MASK 0x10000000 +#define TMC5072_OFS92_SHIFT 28 +#define TMC5072_OFS92_FIELD(motor) ((RegisterField) {TMC5072_OFS92_MASK, TMC5072_OFS92_SHIFT, TMC5072_MSLUT[2], false}) +#define TMC5072_OFS93_MASK 0x20000000 +#define TMC5072_OFS93_SHIFT 29 +#define TMC5072_OFS93_FIELD(motor) ((RegisterField) {TMC5072_OFS93_MASK, TMC5072_OFS93_SHIFT, TMC5072_MSLUT[2], false}) +#define TMC5072_OFS94_MASK 0x40000000 +#define TMC5072_OFS94_SHIFT 30 +#define TMC5072_OFS94_FIELD(motor) ((RegisterField) {TMC5072_OFS94_MASK, TMC5072_OFS94_SHIFT, TMC5072_MSLUT[2], false}) +#define TMC5072_OFS95_MASK 0x80000000 +#define TMC5072_OFS95_SHIFT 31 +#define TMC5072_OFS95_FIELD(motor) ((RegisterField) {TMC5072_OFS95_MASK, TMC5072_OFS95_SHIFT, TMC5072_MSLUT[2], false}) +#define TMC5072_OFS96_MASK 0x00000001 +#define TMC5072_OFS96_SHIFT 0 +#define TMC5072_OFS96_FIELD(motor) ((RegisterField) {TMC5072_OFS96_MASK, TMC5072_OFS96_SHIFT, TMC5072_MSLUT[3], false}) +#define TMC5072_OFS97_MASK 0x00000002 +#define TMC5072_OFS97_SHIFT 1 +#define TMC5072_OFS97_FIELD(motor) ((RegisterField) {TMC5072_OFS97_MASK, TMC5072_OFS97_SHIFT, TMC5072_MSLUT[3], false}) +#define TMC5072_OFS98_MASK 0x00000004 +#define TMC5072_OFS98_SHIFT 2 +#define TMC5072_OFS98_FIELD(motor) ((RegisterField) {TMC5072_OFS98_MASK, TMC5072_OFS98_SHIFT, TMC5072_MSLUT[3], false}) +#define TMC5072_OFS99_MASK 0x00000008 +#define TMC5072_OFS99_SHIFT 3 +#define TMC5072_OFS99_FIELD(motor) ((RegisterField) {TMC5072_OFS99_MASK, TMC5072_OFS99_SHIFT, TMC5072_MSLUT[3], false}) +#define TMC5072_OFS100_MASK 0x00000010 +#define TMC5072_OFS100_SHIFT 4 +#define TMC5072_OFS100_FIELD(motor) ((RegisterField) {TMC5072_OFS100_MASK, TMC5072_OFS100_SHIFT, TMC5072_MSLUT[3], false}) +#define TMC5072_OFS101_MASK 0x00000020 +#define TMC5072_OFS101_SHIFT 5 +#define TMC5072_OFS101_FIELD(motor) ((RegisterField) {TMC5072_OFS101_MASK, TMC5072_OFS101_SHIFT, TMC5072_MSLUT[3], false}) +#define TMC5072_OFS102_MASK 0x00000040 +#define TMC5072_OFS102_SHIFT 6 +#define TMC5072_OFS102_FIELD(motor) ((RegisterField) {TMC5072_OFS102_MASK, TMC5072_OFS102_SHIFT, TMC5072_MSLUT[3], false}) +#define TMC5072_OFS103_MASK 0x00000080 +#define TMC5072_OFS103_SHIFT 7 +#define TMC5072_OFS103_FIELD(motor) ((RegisterField) {TMC5072_OFS103_MASK, TMC5072_OFS103_SHIFT, TMC5072_MSLUT[3], false}) +#define TMC5072_OFS104_MASK 0x00000100 +#define TMC5072_OFS104_SHIFT 8 +#define TMC5072_OFS104_FIELD(motor) ((RegisterField) {TMC5072_OFS104_MASK, TMC5072_OFS104_SHIFT, TMC5072_MSLUT[3], false}) +#define TMC5072_OFS105_MASK 0x00000200 +#define TMC5072_OFS105_SHIFT 9 +#define TMC5072_OFS105_FIELD(motor) ((RegisterField) {TMC5072_OFS105_MASK, TMC5072_OFS105_SHIFT, TMC5072_MSLUT[3], false}) +#define TMC5072_OFS106_MASK 0x00000400 +#define TMC5072_OFS106_SHIFT 10 +#define TMC5072_OFS106_FIELD(motor) ((RegisterField) {TMC5072_OFS106_MASK, TMC5072_OFS106_SHIFT, TMC5072_MSLUT[3], false}) +#define TMC5072_OFS107_MASK 0x00000800 +#define TMC5072_OFS107_SHIFT 11 +#define TMC5072_OFS107_FIELD(motor) ((RegisterField) {TMC5072_OFS107_MASK, TMC5072_OFS107_SHIFT, TMC5072_MSLUT[3], false}) +#define TMC5072_OFS108_MASK 0x00001000 +#define TMC5072_OFS108_SHIFT 12 +#define TMC5072_OFS108_FIELD(motor) ((RegisterField) {TMC5072_OFS108_MASK, TMC5072_OFS108_SHIFT, TMC5072_MSLUT[3], false}) +#define TMC5072_OFS109_MASK 0x00002000 +#define TMC5072_OFS109_SHIFT 13 +#define TMC5072_OFS109_FIELD(motor) ((RegisterField) {TMC5072_OFS109_MASK, TMC5072_OFS109_SHIFT, TMC5072_MSLUT[3], false}) +#define TMC5072_OFS110_MASK 0x00004000 +#define TMC5072_OFS110_SHIFT 14 +#define TMC5072_OFS110_FIELD(motor) ((RegisterField) {TMC5072_OFS110_MASK, TMC5072_OFS110_SHIFT, TMC5072_MSLUT[3], false}) +#define TMC5072_OFS111_MASK 0x00008000 +#define TMC5072_OFS111_SHIFT 15 +#define TMC5072_OFS111_FIELD(motor) ((RegisterField) {TMC5072_OFS111_MASK, TMC5072_OFS111_SHIFT, TMC5072_MSLUT[3], false}) +#define TMC5072_OFS112_MASK 0x00010000 +#define TMC5072_OFS112_SHIFT 16 +#define TMC5072_OFS112_FIELD(motor) ((RegisterField) {TMC5072_OFS112_MASK, TMC5072_OFS112_SHIFT, TMC5072_MSLUT[3], false}) +#define TMC5072_OFS113_MASK 0x00020000 +#define TMC5072_OFS113_SHIFT 17 +#define TMC5072_OFS113_FIELD(motor) ((RegisterField) {TMC5072_OFS113_MASK, TMC5072_OFS113_SHIFT, TMC5072_MSLUT[3], false}) +#define TMC5072_OFS114_MASK 0x00040000 +#define TMC5072_OFS114_SHIFT 18 +#define TMC5072_OFS114_FIELD(motor) ((RegisterField) {TMC5072_OFS114_MASK, TMC5072_OFS114_SHIFT, TMC5072_MSLUT[3], false}) +#define TMC5072_OFS115_MASK 0x00080000 +#define TMC5072_OFS115_SHIFT 19 +#define TMC5072_OFS115_FIELD(motor) ((RegisterField) {TMC5072_OFS115_MASK, TMC5072_OFS115_SHIFT, TMC5072_MSLUT[3], false}) +#define TMC5072_OFS116_MASK 0x00100000 +#define TMC5072_OFS116_SHIFT 20 +#define TMC5072_OFS116_FIELD(motor) ((RegisterField) {TMC5072_OFS116_MASK, TMC5072_OFS116_SHIFT, TMC5072_MSLUT[3], false}) +#define TMC5072_OFS117_MASK 0x00200000 +#define TMC5072_OFS117_SHIFT 21 +#define TMC5072_OFS117_FIELD(motor) ((RegisterField) {TMC5072_OFS117_MASK, TMC5072_OFS117_SHIFT, TMC5072_MSLUT[3], false}) +#define TMC5072_OFS118_MASK 0x00400000 +#define TMC5072_OFS118_SHIFT 22 +#define TMC5072_OFS118_FIELD(motor) ((RegisterField) {TMC5072_OFS118_MASK, TMC5072_OFS118_SHIFT, TMC5072_MSLUT[3], false}) +#define TMC5072_OFS119_MASK 0x00800000 +#define TMC5072_OFS119_SHIFT 23 +#define TMC5072_OFS119_FIELD(motor) ((RegisterField) {TMC5072_OFS119_MASK, TMC5072_OFS119_SHIFT, TMC5072_MSLUT[3], false}) +#define TMC5072_OFS120_MASK 0x01000000 +#define TMC5072_OFS120_SHIFT 24 +#define TMC5072_OFS120_FIELD(motor) ((RegisterField) {TMC5072_OFS120_MASK, TMC5072_OFS120_SHIFT, TMC5072_MSLUT[3], false}) +#define TMC5072_OFS121_MASK 0x02000000 +#define TMC5072_OFS121_SHIFT 25 +#define TMC5072_OFS121_FIELD(motor) ((RegisterField) {TMC5072_OFS121_MASK, TMC5072_OFS121_SHIFT, TMC5072_MSLUT[3], false}) +#define TMC5072_OFS122_MASK 0x04000000 +#define TMC5072_OFS122_SHIFT 26 +#define TMC5072_OFS122_FIELD(motor) ((RegisterField) {TMC5072_OFS122_MASK, TMC5072_OFS122_SHIFT, TMC5072_MSLUT[3], false}) +#define TMC5072_OFS123_MASK 0x08000000 +#define TMC5072_OFS123_SHIFT 27 +#define TMC5072_OFS123_FIELD(motor) ((RegisterField) {TMC5072_OFS123_MASK, TMC5072_OFS123_SHIFT, TMC5072_MSLUT[3], false}) +#define TMC5072_OFS124_MASK 0x10000000 +#define TMC5072_OFS124_SHIFT 28 +#define TMC5072_OFS124_FIELD(motor) ((RegisterField) {TMC5072_OFS124_MASK, TMC5072_OFS124_SHIFT, TMC5072_MSLUT[3], false}) +#define TMC5072_OFS125_MASK 0x20000000 +#define TMC5072_OFS125_SHIFT 29 +#define TMC5072_OFS125_FIELD(motor) ((RegisterField) {TMC5072_OFS125_MASK, TMC5072_OFS125_SHIFT, TMC5072_MSLUT[3], false}) +#define TMC5072_OFS126_MASK 0x40000000 +#define TMC5072_OFS126_SHIFT 30 +#define TMC5072_OFS126_FIELD(motor) ((RegisterField) {TMC5072_OFS126_MASK, TMC5072_OFS126_SHIFT, TMC5072_MSLUT[3], false}) +#define TMC5072_OFS127_MASK 0x80000000 +#define TMC5072_OFS127_SHIFT 31 +#define TMC5072_OFS127_FIELD(motor) ((RegisterField) {TMC5072_OFS127_MASK, TMC5072_OFS127_SHIFT, TMC5072_MSLUT[3], false}) +#define TMC5072_OFS128_MASK 0x00000001 +#define TMC5072_OFS128_SHIFT 0 +#define TMC5072_OFS128_FIELD(motor) ((RegisterField) {TMC5072_OFS128_MASK, TMC5072_OFS128_SHIFT, TMC5072_MSLUT[4], false}) +#define TMC5072_OFS129_MASK 0x00000002 +#define TMC5072_OFS129_SHIFT 1 +#define TMC5072_OFS129_FIELD(motor) ((RegisterField) {TMC5072_OFS129_MASK, TMC5072_OFS129_SHIFT, TMC5072_MSLUT[4], false}) +#define TMC5072_OFS130_MASK 0x00000004 +#define TMC5072_OFS130_SHIFT 2 +#define TMC5072_OFS130_FIELD(motor) ((RegisterField) {TMC5072_OFS130_MASK, TMC5072_OFS130_SHIFT, TMC5072_MSLUT[4], false}) +#define TMC5072_OFS131_MASK 0x00000008 +#define TMC5072_OFS131_SHIFT 3 +#define TMC5072_OFS131_FIELD(motor) ((RegisterField) {TMC5072_OFS131_MASK, TMC5072_OFS131_SHIFT, TMC5072_MSLUT[4], false}) +#define TMC5072_OFS132_MASK 0x00000010 +#define TMC5072_OFS132_SHIFT 4 +#define TMC5072_OFS132_FIELD(motor) ((RegisterField) {TMC5072_OFS132_MASK, TMC5072_OFS132_SHIFT, TMC5072_MSLUT[4], false}) +#define TMC5072_OFS133_MASK 0x00000020 +#define TMC5072_OFS133_SHIFT 5 +#define TMC5072_OFS133_FIELD(motor) ((RegisterField) {TMC5072_OFS133_MASK, TMC5072_OFS133_SHIFT, TMC5072_MSLUT[4], false}) +#define TMC5072_OFS134_MASK 0x00000040 +#define TMC5072_OFS134_SHIFT 6 +#define TMC5072_OFS134_FIELD(motor) ((RegisterField) {TMC5072_OFS134_MASK, TMC5072_OFS134_SHIFT, TMC5072_MSLUT[4], false}) +#define TMC5072_OFS135_MASK 0x00000080 +#define TMC5072_OFS135_SHIFT 7 +#define TMC5072_OFS135_FIELD(motor) ((RegisterField) {TMC5072_OFS135_MASK, TMC5072_OFS135_SHIFT, TMC5072_MSLUT[4], false}) +#define TMC5072_OFS136_MASK 0x00000100 +#define TMC5072_OFS136_SHIFT 8 +#define TMC5072_OFS136_FIELD(motor) ((RegisterField) {TMC5072_OFS136_MASK, TMC5072_OFS136_SHIFT, TMC5072_MSLUT[4], false}) +#define TMC5072_OFS137_MASK 0x00000200 +#define TMC5072_OFS137_SHIFT 9 +#define TMC5072_OFS137_FIELD(motor) ((RegisterField) {TMC5072_OFS137_MASK, TMC5072_OFS137_SHIFT, TMC5072_MSLUT[4], false}) +#define TMC5072_OFS138_MASK 0x00000400 +#define TMC5072_OFS138_SHIFT 10 +#define TMC5072_OFS138_FIELD(motor) ((RegisterField) {TMC5072_OFS138_MASK, TMC5072_OFS138_SHIFT, TMC5072_MSLUT[4], false}) +#define TMC5072_OFS139_MASK 0x00000800 +#define TMC5072_OFS139_SHIFT 11 +#define TMC5072_OFS139_FIELD(motor) ((RegisterField) {TMC5072_OFS139_MASK, TMC5072_OFS139_SHIFT, TMC5072_MSLUT[4], false}) +#define TMC5072_OFS140_MASK 0x00001000 +#define TMC5072_OFS140_SHIFT 12 +#define TMC5072_OFS140_FIELD(motor) ((RegisterField) {TMC5072_OFS140_MASK, TMC5072_OFS140_SHIFT, TMC5072_MSLUT[4], false}) +#define TMC5072_OFS141_MASK 0x00002000 +#define TMC5072_OFS141_SHIFT 13 +#define TMC5072_OFS141_FIELD(motor) ((RegisterField) {TMC5072_OFS141_MASK, TMC5072_OFS141_SHIFT, TMC5072_MSLUT[4], false}) +#define TMC5072_OFS142_MASK 0x00004000 +#define TMC5072_OFS142_SHIFT 14 +#define TMC5072_OFS142_FIELD(motor) ((RegisterField) {TMC5072_OFS142_MASK, TMC5072_OFS142_SHIFT, TMC5072_MSLUT[4], false}) +#define TMC5072_OFS143_MASK 0x00008000 +#define TMC5072_OFS143_SHIFT 15 +#define TMC5072_OFS143_FIELD(motor) ((RegisterField) {TMC5072_OFS143_MASK, TMC5072_OFS143_SHIFT, TMC5072_MSLUT[4], false}) +#define TMC5072_OFS144_MASK 0x00010000 +#define TMC5072_OFS144_SHIFT 16 +#define TMC5072_OFS144_FIELD(motor) ((RegisterField) {TMC5072_OFS144_MASK, TMC5072_OFS144_SHIFT, TMC5072_MSLUT[4], false}) +#define TMC5072_OFS145_MASK 0x00020000 +#define TMC5072_OFS145_SHIFT 17 +#define TMC5072_OFS145_FIELD(motor) ((RegisterField) {TMC5072_OFS145_MASK, TMC5072_OFS145_SHIFT, TMC5072_MSLUT[4], false}) +#define TMC5072_OFS146_MASK 0x00040000 +#define TMC5072_OFS146_SHIFT 18 +#define TMC5072_OFS146_FIELD(motor) ((RegisterField) {TMC5072_OFS146_MASK, TMC5072_OFS146_SHIFT, TMC5072_MSLUT[4], false}) +#define TMC5072_OFS147_MASK 0x00080000 +#define TMC5072_OFS147_SHIFT 19 +#define TMC5072_OFS147_FIELD(motor) ((RegisterField) {TMC5072_OFS147_MASK, TMC5072_OFS147_SHIFT, TMC5072_MSLUT[4], false}) +#define TMC5072_OFS148_MASK 0x00100000 +#define TMC5072_OFS148_SHIFT 20 +#define TMC5072_OFS148_FIELD(motor) ((RegisterField) {TMC5072_OFS148_MASK, TMC5072_OFS148_SHIFT, TMC5072_MSLUT[4], false}) +#define TMC5072_OFS149_MASK 0x00200000 +#define TMC5072_OFS149_SHIFT 21 +#define TMC5072_OFS149_FIELD(motor) ((RegisterField) {TMC5072_OFS149_MASK, TMC5072_OFS149_SHIFT, TMC5072_MSLUT[4], false}) +#define TMC5072_OFS150_MASK 0x00400000 +#define TMC5072_OFS150_SHIFT 22 +#define TMC5072_OFS150_FIELD(motor) ((RegisterField) {TMC5072_OFS150_MASK, TMC5072_OFS150_SHIFT, TMC5072_MSLUT[4], false}) +#define TMC5072_OFS151_MASK 0x00800000 +#define TMC5072_OFS151_SHIFT 23 +#define TMC5072_OFS151_FIELD(motor) ((RegisterField) {TMC5072_OFS151_MASK, TMC5072_OFS151_SHIFT, TMC5072_MSLUT[4], false}) +#define TMC5072_OFS152_MASK 0x01000000 +#define TMC5072_OFS152_SHIFT 24 +#define TMC5072_OFS152_FIELD(motor) ((RegisterField) {TMC5072_OFS152_MASK, TMC5072_OFS152_SHIFT, TMC5072_MSLUT[4], false}) +#define TMC5072_OFS153_MASK 0x02000000 +#define TMC5072_OFS153_SHIFT 25 +#define TMC5072_OFS153_FIELD(motor) ((RegisterField) {TMC5072_OFS153_MASK, TMC5072_OFS153_SHIFT, TMC5072_MSLUT[4], false}) +#define TMC5072_OFS154_MASK 0x04000000 +#define TMC5072_OFS154_SHIFT 26 +#define TMC5072_OFS154_FIELD(motor) ((RegisterField) {TMC5072_OFS154_MASK, TMC5072_OFS154_SHIFT, TMC5072_MSLUT[4], false}) +#define TMC5072_OFS155_MASK 0x08000000 +#define TMC5072_OFS155_SHIFT 27 +#define TMC5072_OFS155_FIELD(motor) ((RegisterField) {TMC5072_OFS155_MASK, TMC5072_OFS155_SHIFT, TMC5072_MSLUT[4], false}) +#define TMC5072_OFS156_MASK 0x10000000 +#define TMC5072_OFS156_SHIFT 28 +#define TMC5072_OFS156_FIELD(motor) ((RegisterField) {TMC5072_OFS156_MASK, TMC5072_OFS156_SHIFT, TMC5072_MSLUT[4], false}) +#define TMC5072_OFS157_MASK 0x20000000 +#define TMC5072_OFS157_SHIFT 29 +#define TMC5072_OFS157_FIELD(motor) ((RegisterField) {TMC5072_OFS157_MASK, TMC5072_OFS157_SHIFT, TMC5072_MSLUT[4], false}) +#define TMC5072_OFS158_MASK 0x40000000 +#define TMC5072_OFS158_SHIFT 30 +#define TMC5072_OFS158_FIELD(motor) ((RegisterField) {TMC5072_OFS158_MASK, TMC5072_OFS158_SHIFT, TMC5072_MSLUT[4], false}) +#define TMC5072_OFS159_MASK 0x80000000 +#define TMC5072_OFS159_SHIFT 31 +#define TMC5072_OFS159_FIELD(motor) ((RegisterField) {TMC5072_OFS159_MASK, TMC5072_OFS159_SHIFT, TMC5072_MSLUT[4], false}) +#define TMC5072_OFS160_MASK 0x00000001 +#define TMC5072_OFS160_SHIFT 0 +#define TMC5072_OFS160_FIELD(motor) ((RegisterField) {TMC5072_OFS160_MASK, TMC5072_OFS160_SHIFT, TMC5072_MSLUT[5], false}) +#define TMC5072_OFS161_MASK 0x00000002 +#define TMC5072_OFS161_SHIFT 1 +#define TMC5072_OFS161_FIELD(motor) ((RegisterField) {TMC5072_OFS161_MASK, TMC5072_OFS161_SHIFT, TMC5072_MSLUT[5], false}) +#define TMC5072_OFS162_MASK 0x00000004 +#define TMC5072_OFS162_SHIFT 2 +#define TMC5072_OFS162_FIELD(motor) ((RegisterField) {TMC5072_OFS162_MASK, TMC5072_OFS162_SHIFT, TMC5072_MSLUT[5], false}) +#define TMC5072_OFS163_MASK 0x00000008 +#define TMC5072_OFS163_SHIFT 3 +#define TMC5072_OFS163_FIELD(motor) ((RegisterField) {TMC5072_OFS163_MASK, TMC5072_OFS163_SHIFT, TMC5072_MSLUT[5], false}) +#define TMC5072_OFS164_MASK 0x00000010 +#define TMC5072_OFS164_SHIFT 4 +#define TMC5072_OFS164_FIELD(motor) ((RegisterField) {TMC5072_OFS164_MASK, TMC5072_OFS164_SHIFT, TMC5072_MSLUT[5], false}) +#define TMC5072_OFS165_MASK 0x00000020 +#define TMC5072_OFS165_SHIFT 5 +#define TMC5072_OFS165_FIELD(motor) ((RegisterField) {TMC5072_OFS165_MASK, TMC5072_OFS165_SHIFT, TMC5072_MSLUT[5], false}) +#define TMC5072_OFS166_MASK 0x00000040 +#define TMC5072_OFS166_SHIFT 6 +#define TMC5072_OFS166_FIELD(motor) ((RegisterField) {TMC5072_OFS166_MASK, TMC5072_OFS166_SHIFT, TMC5072_MSLUT[5], false}) +#define TMC5072_OFS167_MASK 0x00000080 +#define TMC5072_OFS167_SHIFT 7 +#define TMC5072_OFS167_FIELD(motor) ((RegisterField) {TMC5072_OFS167_MASK, TMC5072_OFS167_SHIFT, TMC5072_MSLUT[5], false}) +#define TMC5072_OFS168_MASK 0x00000100 +#define TMC5072_OFS168_SHIFT 8 +#define TMC5072_OFS168_FIELD(motor) ((RegisterField) {TMC5072_OFS168_MASK, TMC5072_OFS168_SHIFT, TMC5072_MSLUT[5], false}) +#define TMC5072_OFS169_MASK 0x00000200 +#define TMC5072_OFS169_SHIFT 9 +#define TMC5072_OFS169_FIELD(motor) ((RegisterField) {TMC5072_OFS169_MASK, TMC5072_OFS169_SHIFT, TMC5072_MSLUT[5], false}) +#define TMC5072_OFS170_MASK 0x00000400 +#define TMC5072_OFS170_SHIFT 10 +#define TMC5072_OFS170_FIELD(motor) ((RegisterField) {TMC5072_OFS170_MASK, TMC5072_OFS170_SHIFT, TMC5072_MSLUT[5], false}) +#define TMC5072_OFS171_MASK 0x00000800 +#define TMC5072_OFS171_SHIFT 11 +#define TMC5072_OFS171_FIELD(motor) ((RegisterField) {TMC5072_OFS171_MASK, TMC5072_OFS171_SHIFT, TMC5072_MSLUT[5], false}) +#define TMC5072_OFS172_MASK 0x00001000 +#define TMC5072_OFS172_SHIFT 12 +#define TMC5072_OFS172_FIELD(motor) ((RegisterField) {TMC5072_OFS172_MASK, TMC5072_OFS172_SHIFT, TMC5072_MSLUT[5], false}) +#define TMC5072_OFS173_MASK 0x00002000 +#define TMC5072_OFS173_SHIFT 13 +#define TMC5072_OFS173_FIELD(motor) ((RegisterField) {TMC5072_OFS173_MASK, TMC5072_OFS173_SHIFT, TMC5072_MSLUT[5], false}) +#define TMC5072_OFS174_MASK 0x00004000 +#define TMC5072_OFS174_SHIFT 14 +#define TMC5072_OFS174_FIELD(motor) ((RegisterField) {TMC5072_OFS174_MASK, TMC5072_OFS174_SHIFT, TMC5072_MSLUT[5], false}) +#define TMC5072_OFS175_MASK 0x00008000 +#define TMC5072_OFS175_SHIFT 15 +#define TMC5072_OFS175_FIELD(motor) ((RegisterField) {TMC5072_OFS175_MASK, TMC5072_OFS175_SHIFT, TMC5072_MSLUT[5], false}) +#define TMC5072_OFS176_MASK 0x00010000 +#define TMC5072_OFS176_SHIFT 16 +#define TMC5072_OFS176_FIELD(motor) ((RegisterField) {TMC5072_OFS176_MASK, TMC5072_OFS176_SHIFT, TMC5072_MSLUT[5], false}) +#define TMC5072_OFS177_MASK 0x00020000 +#define TMC5072_OFS177_SHIFT 17 +#define TMC5072_OFS177_FIELD(motor) ((RegisterField) {TMC5072_OFS177_MASK, TMC5072_OFS177_SHIFT, TMC5072_MSLUT[5], false}) +#define TMC5072_OFS178_MASK 0x00040000 +#define TMC5072_OFS178_SHIFT 18 +#define TMC5072_OFS178_FIELD(motor) ((RegisterField) {TMC5072_OFS178_MASK, TMC5072_OFS178_SHIFT, TMC5072_MSLUT[5], false}) +#define TMC5072_OFS179_MASK 0x00080000 +#define TMC5072_OFS179_SHIFT 19 +#define TMC5072_OFS179_FIELD(motor) ((RegisterField) {TMC5072_OFS179_MASK, TMC5072_OFS179_SHIFT, TMC5072_MSLUT[5], false}) +#define TMC5072_OFS180_MASK 0x00100000 +#define TMC5072_OFS180_SHIFT 20 +#define TMC5072_OFS180_FIELD(motor) ((RegisterField) {TMC5072_OFS180_MASK, TMC5072_OFS180_SHIFT, TMC5072_MSLUT[5], false}) +#define TMC5072_OFS181_MASK 0x00200000 +#define TMC5072_OFS181_SHIFT 21 +#define TMC5072_OFS181_FIELD(motor) ((RegisterField) {TMC5072_OFS181_MASK, TMC5072_OFS181_SHIFT, TMC5072_MSLUT[5], false}) +#define TMC5072_OFS182_MASK 0x00400000 +#define TMC5072_OFS182_SHIFT 22 +#define TMC5072_OFS182_FIELD(motor) ((RegisterField) {TMC5072_OFS182_MASK, TMC5072_OFS182_SHIFT, TMC5072_MSLUT[5], false}) +#define TMC5072_OFS183_MASK 0x00800000 +#define TMC5072_OFS183_SHIFT 23 +#define TMC5072_OFS183_FIELD(motor) ((RegisterField) {TMC5072_OFS183_MASK, TMC5072_OFS183_SHIFT, TMC5072_MSLUT[5], false}) +#define TMC5072_OFS184_MASK 0x01000000 +#define TMC5072_OFS184_SHIFT 24 +#define TMC5072_OFS184_FIELD(motor) ((RegisterField) {TMC5072_OFS184_MASK, TMC5072_OFS184_SHIFT, TMC5072_MSLUT[5], false}) +#define TMC5072_OFS185_MASK 0x02000000 +#define TMC5072_OFS185_SHIFT 25 +#define TMC5072_OFS185_FIELD(motor) ((RegisterField) {TMC5072_OFS185_MASK, TMC5072_OFS185_SHIFT, TMC5072_MSLUT[5], false}) +#define TMC5072_OFS186_MASK 0x04000000 +#define TMC5072_OFS186_SHIFT 26 +#define TMC5072_OFS186_FIELD(motor) ((RegisterField) {TMC5072_OFS186_MASK, TMC5072_OFS186_SHIFT, TMC5072_MSLUT[5], false}) +#define TMC5072_OFS187_MASK 0x08000000 +#define TMC5072_OFS187_SHIFT 27 +#define TMC5072_OFS187_FIELD(motor) ((RegisterField) {TMC5072_OFS187_MASK, TMC5072_OFS187_SHIFT, TMC5072_MSLUT[5], false}) +#define TMC5072_OFS188_MASK 0x10000000 +#define TMC5072_OFS188_SHIFT 28 +#define TMC5072_OFS188_FIELD(motor) ((RegisterField) {TMC5072_OFS188_MASK, TMC5072_OFS188_SHIFT, TMC5072_MSLUT[5], false}) +#define TMC5072_OFS189_MASK 0x20000000 +#define TMC5072_OFS189_SHIFT 29 +#define TMC5072_OFS189_FIELD(motor) ((RegisterField) {TMC5072_OFS189_MASK, TMC5072_OFS189_SHIFT, TMC5072_MSLUT[5], false}) +#define TMC5072_OFS190_MASK 0x40000000 +#define TMC5072_OFS190_SHIFT 30 +#define TMC5072_OFS190_FIELD(motor) ((RegisterField) {TMC5072_OFS190_MASK, TMC5072_OFS190_SHIFT, TMC5072_MSLUT[5], false}) +#define TMC5072_OFS191_MASK 0x80000000 +#define TMC5072_OFS191_SHIFT 31 +#define TMC5072_OFS191_FIELD(motor) ((RegisterField) {TMC5072_OFS191_MASK, TMC5072_OFS191_SHIFT, TMC5072_MSLUT[5], false}) +#define TMC5072_OFS192_MASK 0x00000001 +#define TMC5072_OFS192_SHIFT 0 +#define TMC5072_OFS192_FIELD(motor) ((RegisterField) {TMC5072_OFS192_MASK, TMC5072_OFS192_SHIFT, TMC5072_MSLUT[6], false}) +#define TMC5072_OFS193_MASK 0x00000002 +#define TMC5072_OFS193_SHIFT 1 +#define TMC5072_OFS193_FIELD(motor) ((RegisterField) {TMC5072_OFS193_MASK, TMC5072_OFS193_SHIFT, TMC5072_MSLUT[6], false}) +#define TMC5072_OFS194_MASK 0x00000004 +#define TMC5072_OFS194_SHIFT 2 +#define TMC5072_OFS194_FIELD(motor) ((RegisterField) {TMC5072_OFS194_MASK, TMC5072_OFS194_SHIFT, TMC5072_MSLUT[6], false}) +#define TMC5072_OFS195_MASK 0x00000008 +#define TMC5072_OFS195_SHIFT 3 +#define TMC5072_OFS195_FIELD(motor) ((RegisterField) {TMC5072_OFS195_MASK, TMC5072_OFS195_SHIFT, TMC5072_MSLUT[6], false}) +#define TMC5072_OFS196_MASK 0x00000010 +#define TMC5072_OFS196_SHIFT 4 +#define TMC5072_OFS196_FIELD(motor) ((RegisterField) {TMC5072_OFS196_MASK, TMC5072_OFS196_SHIFT, TMC5072_MSLUT[6], false}) +#define TMC5072_OFS197_MASK 0x00000020 +#define TMC5072_OFS197_SHIFT 5 +#define TMC5072_OFS197_FIELD(motor) ((RegisterField) {TMC5072_OFS197_MASK, TMC5072_OFS197_SHIFT, TMC5072_MSLUT[6], false}) +#define TMC5072_OFS198_MASK 0x00000040 +#define TMC5072_OFS198_SHIFT 6 +#define TMC5072_OFS198_FIELD(motor) ((RegisterField) {TMC5072_OFS198_MASK, TMC5072_OFS198_SHIFT, TMC5072_MSLUT[6], false}) +#define TMC5072_OFS199_MASK 0x00000080 +#define TMC5072_OFS199_SHIFT 7 +#define TMC5072_OFS199_FIELD(motor) ((RegisterField) {TMC5072_OFS199_MASK, TMC5072_OFS199_SHIFT, TMC5072_MSLUT[6], false}) +#define TMC5072_OFS200_MASK 0x00000100 +#define TMC5072_OFS200_SHIFT 8 +#define TMC5072_OFS200_FIELD(motor) ((RegisterField) {TMC5072_OFS200_MASK, TMC5072_OFS200_SHIFT, TMC5072_MSLUT[6], false}) +#define TMC5072_OFS201_MASK 0x00000200 +#define TMC5072_OFS201_SHIFT 9 +#define TMC5072_OFS201_FIELD(motor) ((RegisterField) {TMC5072_OFS201_MASK, TMC5072_OFS201_SHIFT, TMC5072_MSLUT[6], false}) +#define TMC5072_OFS202_MASK 0x00000400 +#define TMC5072_OFS202_SHIFT 10 +#define TMC5072_OFS202_FIELD(motor) ((RegisterField) {TMC5072_OFS202_MASK, TMC5072_OFS202_SHIFT, TMC5072_MSLUT[6], false}) +#define TMC5072_OFS203_MASK 0x00000800 +#define TMC5072_OFS203_SHIFT 11 +#define TMC5072_OFS203_FIELD(motor) ((RegisterField) {TMC5072_OFS203_MASK, TMC5072_OFS203_SHIFT, TMC5072_MSLUT[6], false}) +#define TMC5072_OFS204_MASK 0x00001000 +#define TMC5072_OFS204_SHIFT 12 +#define TMC5072_OFS204_FIELD(motor) ((RegisterField) {TMC5072_OFS204_MASK, TMC5072_OFS204_SHIFT, TMC5072_MSLUT[6], false}) +#define TMC5072_OFS205_MASK 0x00002000 +#define TMC5072_OFS205_SHIFT 13 +#define TMC5072_OFS205_FIELD(motor) ((RegisterField) {TMC5072_OFS205_MASK, TMC5072_OFS205_SHIFT, TMC5072_MSLUT[6], false}) +#define TMC5072_OFS206_MASK 0x00004000 +#define TMC5072_OFS206_SHIFT 14 +#define TMC5072_OFS206_FIELD(motor) ((RegisterField) {TMC5072_OFS206_MASK, TMC5072_OFS206_SHIFT, TMC5072_MSLUT[6], false}) +#define TMC5072_OFS207_MASK 0x00008000 +#define TMC5072_OFS207_SHIFT 15 +#define TMC5072_OFS207_FIELD(motor) ((RegisterField) {TMC5072_OFS207_MASK, TMC5072_OFS207_SHIFT, TMC5072_MSLUT[6], false}) +#define TMC5072_OFS208_MASK 0x00010000 +#define TMC5072_OFS208_SHIFT 16 +#define TMC5072_OFS208_FIELD(motor) ((RegisterField) {TMC5072_OFS208_MASK, TMC5072_OFS208_SHIFT, TMC5072_MSLUT[6], false}) +#define TMC5072_OFS209_MASK 0x00020000 +#define TMC5072_OFS209_SHIFT 17 +#define TMC5072_OFS209_FIELD(motor) ((RegisterField) {TMC5072_OFS209_MASK, TMC5072_OFS209_SHIFT, TMC5072_MSLUT[6], false}) +#define TMC5072_OFS210_MASK 0x00040000 +#define TMC5072_OFS210_SHIFT 18 +#define TMC5072_OFS210_FIELD(motor) ((RegisterField) {TMC5072_OFS210_MASK, TMC5072_OFS210_SHIFT, TMC5072_MSLUT[6], false}) +#define TMC5072_OFS211_MASK 0x00080000 +#define TMC5072_OFS211_SHIFT 19 +#define TMC5072_OFS211_FIELD(motor) ((RegisterField) {TMC5072_OFS211_MASK, TMC5072_OFS211_SHIFT, TMC5072_MSLUT[6], false}) +#define TMC5072_OFS212_MASK 0x00100000 +#define TMC5072_OFS212_SHIFT 20 +#define TMC5072_OFS212_FIELD(motor) ((RegisterField) {TMC5072_OFS212_MASK, TMC5072_OFS212_SHIFT, TMC5072_MSLUT[6], false}) +#define TMC5072_OFS213_MASK 0x00200000 +#define TMC5072_OFS213_SHIFT 21 +#define TMC5072_OFS213_FIELD(motor) ((RegisterField) {TMC5072_OFS213_MASK, TMC5072_OFS213_SHIFT, TMC5072_MSLUT[6], false}) +#define TMC5072_OFS214_MASK 0x00400000 +#define TMC5072_OFS214_SHIFT 22 +#define TMC5072_OFS214_FIELD(motor) ((RegisterField) {TMC5072_OFS214_MASK, TMC5072_OFS214_SHIFT, TMC5072_MSLUT[6], false}) +#define TMC5072_OFS215_MASK 0x00800000 +#define TMC5072_OFS215_SHIFT 23 +#define TMC5072_OFS215_FIELD(motor) ((RegisterField) {TMC5072_OFS215_MASK, TMC5072_OFS215_SHIFT, TMC5072_MSLUT[6], false}) +#define TMC5072_OFS216_MASK 0x01000000 +#define TMC5072_OFS216_SHIFT 24 +#define TMC5072_OFS216_FIELD(motor) ((RegisterField) {TMC5072_OFS216_MASK, TMC5072_OFS216_SHIFT, TMC5072_MSLUT[6], false}) +#define TMC5072_OFS217_MASK 0x02000000 +#define TMC5072_OFS217_SHIFT 25 +#define TMC5072_OFS217_FIELD(motor) ((RegisterField) {TMC5072_OFS217_MASK, TMC5072_OFS217_SHIFT, TMC5072_MSLUT[6], false}) +#define TMC5072_OFS218_MASK 0x04000000 +#define TMC5072_OFS218_SHIFT 26 +#define TMC5072_OFS218_FIELD(motor) ((RegisterField) {TMC5072_OFS218_MASK, TMC5072_OFS218_SHIFT, TMC5072_MSLUT[6], false}) +#define TMC5072_OFS219_MASK 0x08000000 +#define TMC5072_OFS219_SHIFT 27 +#define TMC5072_OFS219_FIELD(motor) ((RegisterField) {TMC5072_OFS219_MASK, TMC5072_OFS219_SHIFT, TMC5072_MSLUT[6], false}) +#define TMC5072_OFS220_MASK 0x10000000 +#define TMC5072_OFS220_SHIFT 28 +#define TMC5072_OFS220_FIELD(motor) ((RegisterField) {TMC5072_OFS220_MASK, TMC5072_OFS220_SHIFT, TMC5072_MSLUT[6], false}) +#define TMC5072_OFS221_MASK 0x20000000 +#define TMC5072_OFS221_SHIFT 29 +#define TMC5072_OFS221_FIELD(motor) ((RegisterField) {TMC5072_OFS221_MASK, TMC5072_OFS221_SHIFT, TMC5072_MSLUT[6], false}) +#define TMC5072_OFS222_MASK 0x40000000 +#define TMC5072_OFS222_SHIFT 30 +#define TMC5072_OFS222_FIELD(motor) ((RegisterField) {TMC5072_OFS222_MASK, TMC5072_OFS222_SHIFT, TMC5072_MSLUT[6], false}) +#define TMC5072_OFS223_MASK 0x80000000 +#define TMC5072_OFS223_SHIFT 31 +#define TMC5072_OFS223_FIELD(motor) ((RegisterField) {TMC5072_OFS223_MASK, TMC5072_OFS223_SHIFT, TMC5072_MSLUT[6], false}) +#define TMC5072_OFS224_MASK 0x00000001 +#define TMC5072_OFS224_SHIFT 0 +#define TMC5072_OFS224_FIELD(motor) ((RegisterField) {TMC5072_OFS224_MASK, TMC5072_OFS224_SHIFT, TMC5072_MSLUT[7], false}) +#define TMC5072_OFS225_MASK 0x00000002 +#define TMC5072_OFS225_SHIFT 1 +#define TMC5072_OFS225_FIELD(motor) ((RegisterField) {TMC5072_OFS225_MASK, TMC5072_OFS225_SHIFT, TMC5072_MSLUT[7], false}) +#define TMC5072_OFS226_MASK 0x00000004 +#define TMC5072_OFS226_SHIFT 2 +#define TMC5072_OFS226_FIELD(motor) ((RegisterField) {TMC5072_OFS226_MASK, TMC5072_OFS226_SHIFT, TMC5072_MSLUT[7], false}) +#define TMC5072_OFS227_MASK 0x00000008 +#define TMC5072_OFS227_SHIFT 3 +#define TMC5072_OFS227_FIELD(motor) ((RegisterField) {TMC5072_OFS227_MASK, TMC5072_OFS227_SHIFT, TMC5072_MSLUT[7], false}) +#define TMC5072_OFS228_MASK 0x00000010 +#define TMC5072_OFS228_SHIFT 4 +#define TMC5072_OFS228_FIELD(motor) ((RegisterField) {TMC5072_OFS228_MASK, TMC5072_OFS228_SHIFT, TMC5072_MSLUT[7], false}) +#define TMC5072_OFS229_MASK 0x00000020 +#define TMC5072_OFS229_SHIFT 5 +#define TMC5072_OFS229_FIELD(motor) ((RegisterField) {TMC5072_OFS229_MASK, TMC5072_OFS229_SHIFT, TMC5072_MSLUT[7], false}) +#define TMC5072_OFS230_MASK 0x00000040 +#define TMC5072_OFS230_SHIFT 6 +#define TMC5072_OFS230_FIELD(motor) ((RegisterField) {TMC5072_OFS230_MASK, TMC5072_OFS230_SHIFT, TMC5072_MSLUT[7], false}) +#define TMC5072_OFS231_MASK 0x00000080 +#define TMC5072_OFS231_SHIFT 7 +#define TMC5072_OFS231_FIELD(motor) ((RegisterField) {TMC5072_OFS231_MASK, TMC5072_OFS231_SHIFT, TMC5072_MSLUT[7], false}) +#define TMC5072_OFS232_MASK 0x00000100 +#define TMC5072_OFS232_SHIFT 8 +#define TMC5072_OFS232_FIELD(motor) ((RegisterField) {TMC5072_OFS232_MASK, TMC5072_OFS232_SHIFT, TMC5072_MSLUT[7], false}) +#define TMC5072_OFS233_MASK 0x00000200 +#define TMC5072_OFS233_SHIFT 9 +#define TMC5072_OFS233_FIELD(motor) ((RegisterField) {TMC5072_OFS233_MASK, TMC5072_OFS233_SHIFT, TMC5072_MSLUT[7], false}) +#define TMC5072_OFS234_MASK 0x00000400 +#define TMC5072_OFS234_SHIFT 10 +#define TMC5072_OFS234_FIELD(motor) ((RegisterField) {TMC5072_OFS234_MASK, TMC5072_OFS234_SHIFT, TMC5072_MSLUT[7], false}) +#define TMC5072_OFS235_MASK 0x00000800 +#define TMC5072_OFS235_SHIFT 11 +#define TMC5072_OFS235_FIELD(motor) ((RegisterField) {TMC5072_OFS235_MASK, TMC5072_OFS235_SHIFT, TMC5072_MSLUT[7], false}) +#define TMC5072_OFS236_MASK 0x00001000 +#define TMC5072_OFS236_SHIFT 12 +#define TMC5072_OFS236_FIELD(motor) ((RegisterField) {TMC5072_OFS236_MASK, TMC5072_OFS236_SHIFT, TMC5072_MSLUT[7], false}) +#define TMC5072_OFS237_MASK 0x00002000 +#define TMC5072_OFS237_SHIFT 13 +#define TMC5072_OFS237_FIELD(motor) ((RegisterField) {TMC5072_OFS237_MASK, TMC5072_OFS237_SHIFT, TMC5072_MSLUT[7], false}) +#define TMC5072_OFS238_MASK 0x00004000 +#define TMC5072_OFS238_SHIFT 14 +#define TMC5072_OFS238_FIELD(motor) ((RegisterField) {TMC5072_OFS238_MASK, TMC5072_OFS238_SHIFT, TMC5072_MSLUT[7], false}) +#define TMC5072_OFS239_MASK 0x00008000 +#define TMC5072_OFS239_SHIFT 15 +#define TMC5072_OFS239_FIELD(motor) ((RegisterField) {TMC5072_OFS239_MASK, TMC5072_OFS239_SHIFT, TMC5072_MSLUT[7], false}) +#define TMC5072_OFS240_MASK 0x00010000 +#define TMC5072_OFS240_SHIFT 16 +#define TMC5072_OFS240_FIELD(motor) ((RegisterField) {TMC5072_OFS240_MASK, TMC5072_OFS240_SHIFT, TMC5072_MSLUT[7], false}) +#define TMC5072_OFS241_MASK 0x00020000 +#define TMC5072_OFS241_SHIFT 17 +#define TMC5072_OFS241_FIELD(motor) ((RegisterField) {TMC5072_OFS241_MASK, TMC5072_OFS241_SHIFT, TMC5072_MSLUT[7], false}) +#define TMC5072_OFS242_MASK 0x00040000 +#define TMC5072_OFS242_SHIFT 18 +#define TMC5072_OFS242_FIELD(motor) ((RegisterField) {TMC5072_OFS242_MASK, TMC5072_OFS242_SHIFT, TMC5072_MSLUT[7], false}) +#define TMC5072_OFS243_MASK 0x00080000 +#define TMC5072_OFS243_SHIFT 19 +#define TMC5072_OFS243_FIELD(motor) ((RegisterField) {TMC5072_OFS243_MASK, TMC5072_OFS243_SHIFT, TMC5072_MSLUT[7], false}) +#define TMC5072_OFS244_MASK 0x00100000 +#define TMC5072_OFS244_SHIFT 20 +#define TMC5072_OFS244_FIELD(motor) ((RegisterField) {TMC5072_OFS244_MASK, TMC5072_OFS244_SHIFT, TMC5072_MSLUT[7], false}) +#define TMC5072_OFS245_MASK 0x00200000 +#define TMC5072_OFS245_SHIFT 21 +#define TMC5072_OFS245_FIELD(motor) ((RegisterField) {TMC5072_OFS245_MASK, TMC5072_OFS245_SHIFT, TMC5072_MSLUT[7], false}) +#define TMC5072_OFS246_MASK 0x00400000 +#define TMC5072_OFS246_SHIFT 22 +#define TMC5072_OFS246_FIELD(motor) ((RegisterField) {TMC5072_OFS246_MASK, TMC5072_OFS246_SHIFT, TMC5072_MSLUT[7], false}) +#define TMC5072_OFS247_MASK 0x00800000 +#define TMC5072_OFS247_SHIFT 23 +#define TMC5072_OFS247_FIELD(motor) ((RegisterField) {TMC5072_OFS247_MASK, TMC5072_OFS247_SHIFT, TMC5072_MSLUT[7], false}) +#define TMC5072_OFS248_MASK 0x01000000 +#define TMC5072_OFS248_SHIFT 24 +#define TMC5072_OFS248_FIELD(motor) ((RegisterField) {TMC5072_OFS248_MASK, TMC5072_OFS248_SHIFT, TMC5072_MSLUT[7], false}) +#define TMC5072_OFS249_MASK 0x02000000 +#define TMC5072_OFS249_SHIFT 25 +#define TMC5072_OFS249_FIELD(motor) ((RegisterField) {TMC5072_OFS249_MASK, TMC5072_OFS249_SHIFT, TMC5072_MSLUT[7], false}) +#define TMC5072_OFS250_MASK 0x04000000 +#define TMC5072_OFS250_SHIFT 26 +#define TMC5072_OFS250_FIELD(motor) ((RegisterField) {TMC5072_OFS250_MASK, TMC5072_OFS250_SHIFT, TMC5072_MSLUT[7], false}) +#define TMC5072_OFS251_MASK 0x08000000 +#define TMC5072_OFS251_SHIFT 27 +#define TMC5072_OFS251_FIELD(motor) ((RegisterField) {TMC5072_OFS251_MASK, TMC5072_OFS251_SHIFT, TMC5072_MSLUT[7], false}) +#define TMC5072_OFS252_MASK 0x10000000 +#define TMC5072_OFS252_SHIFT 28 +#define TMC5072_OFS252_FIELD(motor) ((RegisterField) {TMC5072_OFS252_MASK, TMC5072_OFS252_SHIFT, TMC5072_MSLUT[7], false}) +#define TMC5072_OFS253_MASK 0x20000000 +#define TMC5072_OFS253_SHIFT 29 +#define TMC5072_OFS253_FIELD(motor) ((RegisterField) {TMC5072_OFS253_MASK, TMC5072_OFS253_SHIFT, TMC5072_MSLUT[7], false}) +#define TMC5072_OFS254_MASK 0x40000000 +#define TMC5072_OFS254_SHIFT 30 +#define TMC5072_OFS254_FIELD(motor) ((RegisterField) {TMC5072_OFS254_MASK, TMC5072_OFS254_SHIFT, TMC5072_MSLUT[7], false}) +#define TMC5072_OFS255_MASK 0x80000000 +#define TMC5072_OFS255_SHIFT 31 +#define TMC5072_OFS255_FIELD(motor) ((RegisterField) {TMC5072_OFS255_MASK, TMC5072_OFS255_SHIFT, TMC5072_MSLUT[7], false}) +#define TMC5072_W0_MASK 0x00000003 +#define TMC5072_W0_SHIFT 0 +#define TMC5072_W0_FIELD(motor) ((RegisterField) {TMC5072_W0_MASK, TMC5072_W0_SHIFT, TMC5072_MSLUTSEL, false}) +#define TMC5072_W1_MASK 0x0000000C +#define TMC5072_W1_SHIFT 2 +#define TMC5072_W1_FIELD(motor) ((RegisterField) {TMC5072_W1_MASK, TMC5072_W1_SHIFT, TMC5072_MSLUTSEL, false}) +#define TMC5072_W2_MASK 0x00000030 +#define TMC5072_W2_SHIFT 4 +#define TMC5072_W2_FIELD(motor) ((RegisterField) {TMC5072_W2_MASK, TMC5072_W2_SHIFT, TMC5072_MSLUTSEL, false}) +#define TMC5072_W3_MASK 0x000000C0 +#define TMC5072_W3_SHIFT 6 +#define TMC5072_W3_FIELD(motor) ((RegisterField) {TMC5072_W3_MASK, TMC5072_W3_SHIFT, TMC5072_MSLUTSEL, false}) +#define TMC5072_X1_MASK 0x0000FF00 +#define TMC5072_X1_SHIFT 8 +#define TMC5072_X1_FIELD(motor) ((RegisterField) {TMC5072_X1_MASK, TMC5072_X1_SHIFT, TMC5072_MSLUTSEL, false}) +#define TMC5072_X2_MASK 0x00FF0000 +#define TMC5072_X2_SHIFT 16 +#define TMC5072_X2_FIELD(motor) ((RegisterField) {TMC5072_X2_MASK, TMC5072_X2_SHIFT, TMC5072_MSLUTSEL, false}) +#define TMC5072_X3_MASK 0xFF000000 +#define TMC5072_X3_SHIFT 24 +#define TMC5072_X3_FIELD(motor) ((RegisterField) {TMC5072_X3_MASK, TMC5072_X3_SHIFT, TMC5072_MSLUTSEL, false}) +#define TMC5072_START_SIN_MASK 0x000000FF +#define TMC5072_START_SIN_SHIFT 0 +#define TMC5072_START_SIN_FIELD(motor) ((RegisterField) {TMC5072_START_SIN_MASK, TMC5072_START_SIN_SHIFT, TMC5072_MSLUTSTART, false}) +#define TMC5072_START_SIN90_MASK 0x00FF0000 +#define TMC5072_START_SIN90_SHIFT 16 +#define TMC5072_START_SIN90_FIELD(motor) ((RegisterField) {TMC5072_START_SIN90_MASK, TMC5072_START_SIN90_SHIFT, TMC5072_MSLUTSTART, false}) +#define TMC5072_MSCNT_MASK 0x000003FF +#define TMC5072_MSCNT_SHIFT 0 +#define TMC5072_MSCNT_FIELD(motor) ((RegisterField) {TMC5072_MSCNT_MASK, TMC5072_MSCNT_SHIFT, TMC5072_MSCNT(motor), false}) +#define TMC5072_CUR_A_MASK 0x000001FF +#define TMC5072_CUR_A_SHIFT 0 +#define TMC5072_CUR_A_FIELD(motor) ((RegisterField) {TMC5072_CUR_A_MASK, TMC5072_CUR_A_SHIFT, TMC5072_MSCURACT(motor), true}) +#define TMC5072_CUR_B_MASK 0x01FF0000 +#define TMC5072_CUR_B_SHIFT 16 +#define TMC5072_CUR_B_FIELD(motor) ((RegisterField) {TMC5072_CUR_B_MASK, TMC5072_CUR_B_SHIFT, TMC5072_MSCURACT(motor), true}) +#define TMC5072_TOFF_MASK 0x0000000F +#define TMC5072_TOFF_SHIFT 0 +#define TMC5072_TOFF_FIELD(motor) ((RegisterField) {TMC5072_TOFF_MASK, TMC5072_TOFF_SHIFT, TMC5072_CHOPCONF(motor), false}) +#define TMC5072_TFD_2__0__MASK 0x00000070 +#define TMC5072_TFD_2__0__SHIFT 4 +#define TMC5072_TFD_2__0__FIELD(motor) ((RegisterField) {TMC5072_TFD_2__0__MASK, TMC5072_TFD_2__0__SHIFT, TMC5072_CHOPCONF(motor), false}) +#define TMC5072_OFFSET_MASK 0x00000780 +#define TMC5072_OFFSET_SHIFT 7 +#define TMC5072_OFFSET_FIELD(motor) ((RegisterField) {TMC5072_OFFSET_MASK, TMC5072_OFFSET_SHIFT, TMC5072_CHOPCONF(motor), false}) +#define TMC5072_TFD___MASK 0x00000800 +#define TMC5072_TFD___SHIFT 11 +#define TMC5072_TFD___FIELD(motor) ((RegisterField) {TMC5072_TFD___MASK, TMC5072_TFD___SHIFT, TMC5072_CHOPCONF(motor), false}) +#define TMC5072_DISFDCC_MASK 0x00001000 +#define TMC5072_DISFDCC_SHIFT 12 +#define TMC5072_DISFDCC_FIELD(motor) ((RegisterField) {TMC5072_DISFDCC_MASK, TMC5072_DISFDCC_SHIFT, TMC5072_CHOPCONF(motor), false}) +#define TMC5072_RNDTF_MASK 0x00002000 +#define TMC5072_RNDTF_SHIFT 13 +#define TMC5072_RNDTF_FIELD(motor) ((RegisterField) {TMC5072_RNDTF_MASK, TMC5072_RNDTF_SHIFT, TMC5072_CHOPCONF(motor), false}) +#define TMC5072_CHM_MASK 0x00004000 +#define TMC5072_CHM_SHIFT 14 +#define TMC5072_CHM_FIELD(motor) ((RegisterField) {TMC5072_CHM_MASK, TMC5072_CHM_SHIFT, TMC5072_CHOPCONF(motor), false}) +#define TMC5072_TBL_MASK 0x00018000 +#define TMC5072_TBL_SHIFT 15 +#define TMC5072_TBL_FIELD(motor) ((RegisterField) {TMC5072_TBL_MASK, TMC5072_TBL_SHIFT, TMC5072_CHOPCONF(motor), false}) +#define TMC5072_VSENSE_MASK 0x00020000 +#define TMC5072_VSENSE_SHIFT 17 +#define TMC5072_VSENSE_FIELD(motor) ((RegisterField) {TMC5072_VSENSE_MASK, TMC5072_VSENSE_SHIFT, TMC5072_CHOPCONF(motor), false}) +#define TMC5072_VHIGHFS_MASK 0x00040000 +#define TMC5072_VHIGHFS_SHIFT 18 +#define TMC5072_VHIGHFS_FIELD(motor) ((RegisterField) {TMC5072_VHIGHFS_MASK, TMC5072_VHIGHFS_SHIFT, TMC5072_CHOPCONF(motor), false}) +#define TMC5072_VHIGHCHM_MASK 0x00080000 +#define TMC5072_VHIGHCHM_SHIFT 19 +#define TMC5072_VHIGHCHM_FIELD(motor) ((RegisterField) {TMC5072_VHIGHCHM_MASK, TMC5072_VHIGHCHM_SHIFT, TMC5072_CHOPCONF(motor), false}) +#define TMC5072_MRES_MASK 0x0F000000 +#define TMC5072_MRES_SHIFT 24 +#define TMC5072_MRES_FIELD(motor) ((RegisterField) {TMC5072_MRES_MASK, TMC5072_MRES_SHIFT, TMC5072_CHOPCONF(motor), false}) +#define TMC5072_INTPOL_MASK 0x10000000 +#define TMC5072_INTPOL_SHIFT 28 +#define TMC5072_INTPOL_FIELD(motor) ((RegisterField) {TMC5072_INTPOL_MASK, TMC5072_INTPOL_SHIFT, TMC5072_CHOPCONF(motor), false}) +#define TMC5072_DEDGE_MASK 0x20000000 +#define TMC5072_DEDGE_SHIFT 29 +#define TMC5072_DEDGE_FIELD(motor) ((RegisterField) {TMC5072_DEDGE_MASK, TMC5072_DEDGE_SHIFT, TMC5072_CHOPCONF(motor), false}) +#define TMC5072_DISS2G_MASK 0x40000000 +#define TMC5072_DISS2G_SHIFT 30 +#define TMC5072_DISS2G_FIELD(motor) ((RegisterField) {TMC5072_DISS2G_MASK, TMC5072_DISS2G_SHIFT, TMC5072_CHOPCONF(motor), false}) +#define TMC5072_HSTRT_MASK 0x00000070 +#define TMC5072_HSTRT_SHIFT 4 +#define TMC5072_HSTRT_FIELD(motor) ((RegisterField) {TMC5072_HSTRT_MASK, TMC5072_HSTRT_SHIFT, TMC5072_CHOPCONF(motor), false}) +#define TMC5072_HEND_MASK 0x00000780 +#define TMC5072_HEND_SHIFT 7 +#define TMC5072_HEND_FIELD(motor) ((RegisterField) {TMC5072_HEND_MASK, TMC5072_HEND_SHIFT, TMC5072_CHOPCONF(motor), false}) +#define TMC5072_SEMIN_MASK 0x0000000F +#define TMC5072_SEMIN_SHIFT 0 +#define TMC5072_SEMIN_FIELD(motor) ((RegisterField) {TMC5072_SEMIN_MASK, TMC5072_SEMIN_SHIFT, TMC5072_COOLCONF(motor), false}) +#define TMC5072_SEUP_MASK 0x00000060 +#define TMC5072_SEUP_SHIFT 5 +#define TMC5072_SEUP_FIELD(motor) ((RegisterField) {TMC5072_SEUP_MASK, TMC5072_SEUP_SHIFT, TMC5072_COOLCONF(motor), false}) +#define TMC5072_SEMAX_MASK 0x00000F00 +#define TMC5072_SEMAX_SHIFT 8 +#define TMC5072_SEMAX_FIELD(motor) ((RegisterField) {TMC5072_SEMAX_MASK, TMC5072_SEMAX_SHIFT, TMC5072_COOLCONF(motor), false}) +#define TMC5072_SEDN_MASK 0x00006000 +#define TMC5072_SEDN_SHIFT 13 +#define TMC5072_SEDN_FIELD(motor) ((RegisterField) {TMC5072_SEDN_MASK, TMC5072_SEDN_SHIFT, TMC5072_COOLCONF(motor), false}) +#define TMC5072_SEIMIN_MASK 0x00008000 +#define TMC5072_SEIMIN_SHIFT 15 +#define TMC5072_SEIMIN_FIELD(motor) ((RegisterField) {TMC5072_SEIMIN_MASK, TMC5072_SEIMIN_SHIFT, TMC5072_COOLCONF(motor), false}) +#define TMC5072_SGT_MASK 0x007F0000 +#define TMC5072_SGT_SHIFT 16 +#define TMC5072_SGT_FIELD(motor) ((RegisterField) {TMC5072_SGT_MASK, TMC5072_SGT_SHIFT, TMC5072_COOLCONF(motor), true}) +#define TMC5072_SFILT_MASK 0x01000000 +#define TMC5072_SFILT_SHIFT 24 +#define TMC5072_SFILT_FIELD(motor) ((RegisterField) {TMC5072_SFILT_MASK, TMC5072_SFILT_SHIFT, TMC5072_COOLCONF(motor), false}) +#define TMC5072_DC_TIME_MASK 0x000000FF +#define TMC5072_DC_TIME_SHIFT 0 +#define TMC5072_DC_TIME_FIELD(motor) ((RegisterField) {TMC5072_DC_TIME_MASK, TMC5072_DC_TIME_SHIFT, TMC5072_DCCTRL(motor), false}) +#define TMC5072_DC_SG_MASK 0x00FF0000 +#define TMC5072_DC_SG_SHIFT 16 +#define TMC5072_DC_SG_FIELD(motor) ((RegisterField) {TMC5072_DC_SG_MASK, TMC5072_DC_SG_SHIFT, TMC5072_DCCTRL(motor), false}) +#define TMC5072_SG_RESULT_MASK 0x000003FF +#define TMC5072_SG_RESULT_SHIFT 0 +#define TMC5072_SG_RESULT_FIELD(motor) ((RegisterField) {TMC5072_SG_RESULT_MASK, TMC5072_SG_RESULT_SHIFT, TMC5072_DRVSTATUS(motor), false}) +#define TMC5072_FSACTIVE_MASK 0x00008000 +#define TMC5072_FSACTIVE_SHIFT 15 +#define TMC5072_FSACTIVE_FIELD(motor) ((RegisterField) {TMC5072_FSACTIVE_MASK, TMC5072_FSACTIVE_SHIFT, TMC5072_DRVSTATUS(motor), false}) +#define TMC5072_CS_ACTUAL_MASK 0x001F0000 +#define TMC5072_CS_ACTUAL_SHIFT 16 +#define TMC5072_CS_ACTUAL_FIELD(motor) ((RegisterField) {TMC5072_CS_ACTUAL_MASK, TMC5072_CS_ACTUAL_SHIFT, TMC5072_DRVSTATUS(motor), false}) +#define TMC5072_STALLGUARD_MASK 0x01000000 +#define TMC5072_STALLGUARD_SHIFT 24 +#define TMC5072_STALLGUARD_FIELD(motor) ((RegisterField) {TMC5072_STALLGUARD_MASK, TMC5072_STALLGUARD_SHIFT, TMC5072_DRVSTATUS(motor), false}) +#define TMC5072_OT_MASK 0x02000000 +#define TMC5072_OT_SHIFT 25 +#define TMC5072_OT_FIELD(motor) ((RegisterField) {TMC5072_OT_MASK, TMC5072_OT_SHIFT, TMC5072_DRVSTATUS(motor), false}) +#define TMC5072_OTPW_MASK 0x04000000 +#define TMC5072_OTPW_SHIFT 26 +#define TMC5072_OTPW_FIELD(motor) ((RegisterField) {TMC5072_OTPW_MASK, TMC5072_OTPW_SHIFT, TMC5072_DRVSTATUS(motor), false}) +#define TMC5072_S2GA_MASK 0x08000000 +#define TMC5072_S2GA_SHIFT 27 +#define TMC5072_S2GA_FIELD(motor) ((RegisterField) {TMC5072_S2GA_MASK, TMC5072_S2GA_SHIFT, TMC5072_DRVSTATUS(motor), false}) +#define TMC5072_S2GB_MASK 0x10000000 +#define TMC5072_S2GB_SHIFT 28 +#define TMC5072_S2GB_FIELD(motor) ((RegisterField) {TMC5072_S2GB_MASK, TMC5072_S2GB_SHIFT, TMC5072_DRVSTATUS(motor), false}) +#define TMC5072_OLA_MASK 0x20000000 +#define TMC5072_OLA_SHIFT 29 +#define TMC5072_OLA_FIELD(motor) ((RegisterField) {TMC5072_OLA_MASK, TMC5072_OLA_SHIFT, TMC5072_DRVSTATUS(motor), false}) +#define TMC5072_OLB_MASK 0x40000000 +#define TMC5072_OLB_SHIFT 30 +#define TMC5072_OLB_FIELD(motor) ((RegisterField) {TMC5072_OLB_MASK, TMC5072_OLB_SHIFT, TMC5072_DRVSTATUS(motor), false}) +#define TMC5072_STST_MASK 0x80000000 +#define TMC5072_STST_SHIFT 31 +#define TMC5072_STST_FIELD(motor) ((RegisterField) {TMC5072_STST_MASK, TMC5072_STST_SHIFT, TMC5072_DRVSTATUS(motor), false}) + +#endif + diff --git a/firmware/lib/tmc/ic/TMC5072/registercall_hierarchy_flowchart_SPI.svg b/firmware/lib/tmc/ic/TMC5072/registercall_hierarchy_flowchart_SPI.svg new file mode 100755 index 0000000..cbad58f --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5072/registercall_hierarchy_flowchart_SPI.svg @@ -0,0 +1,3 @@ + + +

HAL

HAL

APP (Eval)

APP (Eval)

API

API
Read a register
  •  Call tmcXXXX_readRegister function
Read a register...
Returns the register read value
Returns the register read value
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
tmcXXXX.c
tmcXXXX.c
SPI.c
SPI.c
tmcXXXX_eval.c
tmcXXXX_eval.c

 Implementation of SPI_readWrite
  • Sends and receives bytes on the SPI bus
Implementation of SPI_readWrite...
Returns the raw reply data
Returns the raw reply data

Implementation of tmcXXXX_readWriteSPI
  • Sets the CSN pin to LOW
  • Takes the array of data to write
  • Calls hardware function SPI_readWrite
  • Upon completion of data transfer,
    sets CSN to 
    HIGH
Implementation of tmcXXXX_readWriteSPI...
Passes on the raw reply data to the API
Passes on the raw reply data to the API
Implementation of readRegisterSPI
  • Constructs the datagram
  • Calls HAL wrapper function 
Implementation of readRegisterSPI...
tmcXXXX_readWriteSPI
tmcXXXX_readWriteSPI
Parses the reply and returns the register value
Parses the reply and returns the register value
Implementation of tmcXXXX_readRegister 
  • Check which bus is active SPI/UART. (e.g. SPI)
  • Calls bus-specific function (e.g. readRegisterSPI)
 
Implementation of tmcXXXX_readRegister...
Returns the register read value
Returns the register read value
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC5072/registercall_hierarchy_flowchart_UART.svg b/firmware/lib/tmc/ic/TMC5072/registercall_hierarchy_flowchart_UART.svg new file mode 100755 index 0000000..425f60a --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5072/registercall_hierarchy_flowchart_UART.svg @@ -0,0 +1,3 @@ + + +

HAL

HAL

APP (Eval)

APP (Eval)

API

API
Read a register
  •  Call tmcXXXX_readRegister function
Read a register...
Returns the register read value
Returns the register read value
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
tmcXXXX.c
tmcXXXX.c
UART.c
UART.c
tmcXXXX_eval.c
tmcXXXX_eval.c

 Implementation of UART_readWrite
  • Sends and receives bytes on the UART bus
Implementation of UART_readWrite...
Returns the raw reply data
Returns the raw reply data

Implementation of tmcXXXX_readWriteUART
  • Takes the array of data to write
  • Calls hardware function UART_readWrite
Implementation of tmcXXXX_readWriteUART...
Passes on the raw reply data to the API
Passes on the raw reply data to the API
Implementation of readRegisterUART
  • Constructs the datagram
  • Calls HAL wrapper function 
Implementation of readRegisterUART...
tmcXXXX_readWriteUART
tmcXXXX_readWriteUART
Parses the reply and returns the register value
Parses the reply and returns the register value
Implementation of tmcXXXX_readRegister 
  • Check which bus is active SPI/UART. (e.g. UART)
  • Calls bus-specific function (e.g. readRegisterUART)
 
Implementation of tmcXXXX_readRegister...
Returns the register read value
Returns the register read value
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC5072/uml-tmc-api.svg b/firmware/lib/tmc/ic/TMC5072/uml-tmc-api.svg new file mode 100755 index 0000000..5a5f8dd --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5072/uml-tmc-api.svg @@ -0,0 +1,3 @@ + + +

TMCXXXX_HW_Abstraction.h



TMCXXXX_HW_Abstraction.h...
// Constants
#define TMCXXXX_MOTORS              
                          
// Register definitions
#define TMCXXXX_GCONF        
                          ⋮
// Register fields definitions
#define TMCXXXX_GCONF_OTPW_FIELD
                     
// Constants...

TMCXXXX.h



TMCXXXX.h...
extern void tmcXXXX_readWriteSPI();
extern void tmcXXXX_readWriteUART();
extern TMCXXXXBusType tmcXXXX_getBusType();
extern uint8_t tmcXXXX_getNodeAddress();
                                  ⋮
tmcXXXX_readRegister();
tmcXXXX_writeRegister();
                                  ⋮
extern void tmcXXXX_readWriteSPI();...

TMCXXXX.c



TMCXXXX.c...
const uint8_t tmcCRCTable_Poly7Reflected[256] = {...};
int32_t tmcXXXX_readRegister(){
/* Call tmcXXXX_getBusType();
 * Based on bus type, call readRegisterSPI/UART() that
 * further calls tmcXXXX_readWriteSPI/UART();
 * For UART it also calls tmcXXXX_getNodeAddress();
                                           ⋮
}
                                           ⋮
const uint8_t tmcCRCTable_Poly7Reflected[256] = {.....
TMC-API
TMC-API

TMCXXXX_Simple_Rotation.h


TMCXXXX_Simple_Rotation.h...
void initAllMotors();
             ⋮
  
void initAllMotors()...

TMCXXXX_Simple_Rotation.c


TMCXXXX_Simple_Rotation.c...
void initAllMotors(){

// Configuring registers to enable motor drivers etc..
tmcXXXX_writeRegister();
                    ⋮
}
                    ⋮
void initAllMotors(){...
Examples
Examples
User Project
User Project

User_Project.h


User_Project.h

User_Project.c








User_Project.c...

void tmcXXXX_readWriteSPI(){
                           ⋮
}
void tmcXXXX_readWriteUART(){
                           ⋮
}
TMCXXXXBusType tmcXXXX_getBusType(){
                           ⋮
}
uint8_t tmcXXXX_getNodeAddress(){
                           ⋮
}

// User Code
                           ⋮
void tmcXXXX_readWriteSPI(){...
#include "TMCXXXX_HW_Abstraction.h"
#include "TMCXXXX.h"
#include "TMCXXXX_Simple_Rotation.h"
                                ⋮
TMCXXXXBusType bus = IC_BUS_SPI/UART;
uint8_t nodeAddress = <nodeAddress>;
                                ⋮
#include "TMCXXXX_HW_Abstraction.h"...
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC5130/Examples/TMC5130_Simple_Rotation.c b/firmware/lib/tmc/ic/TMC5130/Examples/TMC5130_Simple_Rotation.c new file mode 100755 index 0000000..7ca4500 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5130/Examples/TMC5130_Simple_Rotation.c @@ -0,0 +1,28 @@ +/******************************************************************************* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#include "TMC5130_Simple_Rotation.h" + +/* + * Configures the registers with the right settings that are needed for rotating the motor. + * E.g Enabling driver, setting IRUN current etc. + */ +void initAllMotors(uint16_t icID) +{ + tmc5130_writeRegister(icID, TMC5130_GCONF, 0x00000000); // Digital current scaling, SpreadCycle mode + + // IHOLD_IRUN: Set max current (IRUN = 31), and hold current (~30% of IRUN) + tmc5130_writeRegister(icID, TMC5130_IHOLD_IRUN, 0x0000AF08); // Max run current, 30% hold current + + // CHOPCONF: VSENSE = 1, microstepping 1/16, TOFF = 3 + tmc5130_writeRegister(icID, TMC5130_CHOPCONF, 0x000101D5); + + // PWMCONF: Enable StealthChop, autoscale PWM, amplitude ~ moderate + tmc5130_writeRegister(icID, TMC5130_PWMCONF, 0x000500C8); + + // AMAX: Setting the acceleration + tmc5130_writeRegister(icID, TMC5130_AMAX, 10000); +} diff --git a/firmware/lib/tmc/ic/TMC5130/Examples/TMC5130_Simple_Rotation.h b/firmware/lib/tmc/ic/TMC5130/Examples/TMC5130_Simple_Rotation.h new file mode 100755 index 0000000..143ef69 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5130/Examples/TMC5130_Simple_Rotation.h @@ -0,0 +1,14 @@ +/******************************************************************************* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#ifndef TMC5130_SIMPLE_ROTATION_H_ +#define TMC5130_SIMPLE_ROTATION_H_ + +#include "TMC5130.h" + +void initAllMotors(uint16_t icID); + +#endif diff --git a/firmware/lib/tmc/ic/TMC5130/README.md b/firmware/lib/tmc/ic/TMC5130/README.md new file mode 100755 index 0000000..dfd21c7 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5130/README.md @@ -0,0 +1,69 @@ +# TMC5130 + + +## How to use + +To access the TMC5130's registers, the TMC-API offers two functions: **tmc5130_readRegister** and **tmc5130_writeRegister**. +Each of these functions takes in an **icID**, which is used to identify the IC when multiple ICs are connected. This identifier is passed down to the callback functions (see How to Integrate). + +## How to integrate: overview + +1. Include all the files of the TMC-API/ic/tmc/TMC5130 folder into the custom project. +2. Include the TMC5130.h file in the custom source code. +3. Implement the necessary callback functions (see below). +4. (optional): Take a look at the Examples subfolder for ready-made examples of the TMC-API usage. + +## Accessing the TMC5130 via UART +The following diagram depicts how to access the TMC5130 via UART using the TMC-API. + +![screenshot](registercall_hierarchy_flowchart_UART.svg) + +The description of the functions, in the above flowchart, are as follows: +- The functions tmc5130_readRegister and tmc5130_writeRegister are used to read and write the registers respectively. These functions check the current active bus and calls the bus-specific function i.e readRegisterUART or writeRegisterUART. +- These bus specific functions constructs the datagram and further calls the bus specific callback 'tmcXXXX_readWriteUART. +- This callback function further calls the hardware specific read/write function for UART and needs to be implemented externally. + +### Necessary hardware modification to use UART +To use UART with the Eval-Kit: pin 39 (DIO17) and 40 (DIO18) should be connected with a 1k ohm resistor. Pin 37 (DIO15) and 40(DIO18) should be shorted. Additionally bend the 37 and 38 on the Landungsbrücke side of the Eselsbrücke out. +For more information checkout the latest TMC5130-EVAL User Manual at https://www.analog.com/en/resources/evaluation-hardware-and-software/evaluation-boards-kits/tmc5130-eval.html +### How to integrate: Callback functions +To communicate with TMC5130 IC, the TMC-API library needs to know which bus (UART, SPI) it shall use. For that, the callback function **'tmc5130_getBusType()'** needs to be implemented. +Additionally, implement the following callback functions to access the chip via UART: +1. **tmc5130_readWriteUART()**, which is a HAL wrapper function that provides the necessary hardware access. +2. **tmc5130_getNodeAddress()**, that returns the node/slave address. Node address could be set in NODECONF (0x3) register and the address could be incremented as defined by AD0, AD1 and AD2. (Node address + ADx) must be less than 255. For further details please consult the datasheet of TMC5130. + +### Sharing the CRC table with other TMC-API chips +The TMC5130 UART protocol uses an 8 bit CRC. For calculating this, a table-based algorithm is used. This table (tmcCRCTable_Poly7Reflected[256]) is 256 bytes big and identical across multiple different Trinamic chips (i.e. TMC5130). +If multiple Trinamic chips are being used in the same project, avoiding redundant copies of this table could save memory. It is possible to substitute this CRC table with another CRC table. + +## Accessing the TMC5130 via SPI +The following diagram depicts how to access the TMC5130 via SPI using the TMC-API. + +![screenshot](registercall_hierarchy_flowchart_SPI.svg) + +The description of the functions, in the above flowchart, are as follows: +- The functions tmc5130_readRegister and tmc5130_writeRegister are used to read and write the registers respectively. These functions check the current active bus and calls the bus-specific function i.e readRegisterSPI or writeRegisterSPI. +- These bus specific functions constructs the datagram and further calls the bus specific callback 'tmcXXXX_readWriteSPI. +- This callback function further calls the hardware specific read/write function for SPI and needs to be implemented externally. + +### How to integrate: Callback functions +To communicate with TMC5130 IC, the TMC-API library needs to know which bus (UART, SPI) it shall use. For that, the callback function **'tmc5130_getBusType()'** needs to be implemented. +Additionally, implement the following callback functions to access the chip via SPI: +1. **tmc5130_readWriteSPI()**, which is a HAL wrapper function that provides the necessary hardware access. This function should also set the chip select pin CSN to low before starting the data transfer and set to high upon completion. Please refer to the datasheet of the IC for further details. + +### Option to use the cache logic for Write-Only registers +The chip features write-only registers that are unable to be read, necessitating the creation of a shadow copy to cache their contents. This copy is automatically updated whenever data is written to these registers. This cache logic could be enabled by setting the macro **TMC5130_CACHE** to **'1'** or disabled by setting to **'0'** respectively. If this feature is enabled then there comes another option to use **tmc5130_cache** function, which is already implemeted in the API, by defining **TMC5130_ENABLE_TMC_CACHE** macro to **'1** or one can implement their own function. The function **tmc5130_cache** works for both reading from and writing to the shadow array. It first checks whether the register has write-only access and data needs to be read from the hadow copy. On the basis of that, it returns **true** or **false**. The shadowRegisters on the premade cache implementation need to be one per chip. **TMC5130_IC_CACHE_COUNT** is set to '1' y default and is user-overwritable. If multiple chips are being used in the same project, increment its value to the number of chips connected. + +## Further info +### Dependency graph for the ICs with new register R/W mechanism +This graph illustrates the relationships between files within the TMC-API library, highlighting dependencies and identifying the files that are essential for integrating the library into the ustom projects. + +![screenshot](uml-tmc-api.svg) + +### Example usage: TMC-Evalsystem +**For a reference usage of the TMC-API**, visit the [TMC-Evalsystem](https://github.com/analogdevicesinc/TMC-EvalSystem) + +## Migration status +The TMC5130 has been reworked to the access system described above. For more infos on the status of this and other ICs, check out the [migration page](https://github.com/analogdevicesinc/TMC-API/issues/53). + + diff --git a/firmware/lib/tmc/ic/TMC5130/TMC5130.c b/firmware/lib/tmc/ic/TMC5130/TMC5130.c new file mode 100755 index 0000000..05f3170 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5130/TMC5130.c @@ -0,0 +1,322 @@ +/******************************************************************************* +* Copyright © 2017 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#include "TMC5130.h" + +#ifdef TMC_API_EXTERNAL_CRC_TABLE +extern const uint8_t tmcCRCTable_Poly7Reflected[256]; +#else +const uint8_t tmcCRCTable_Poly7Reflected[256] = { + 0x00, 0x91, 0xE3, 0x72, 0x07, 0x96, 0xE4, 0x75, 0x0E, 0x9F, 0xED, 0x7C, 0x09, 0x98, 0xEA, 0x7B, + 0x1C, 0x8D, 0xFF, 0x6E, 0x1B, 0x8A, 0xF8, 0x69, 0x12, 0x83, 0xF1, 0x60, 0x15, 0x84, 0xF6, 0x67, + 0x38, 0xA9, 0xDB, 0x4A, 0x3F, 0xAE, 0xDC, 0x4D, 0x36, 0xA7, 0xD5, 0x44, 0x31, 0xA0, 0xD2, 0x43, + 0x24, 0xB5, 0xC7, 0x56, 0x23, 0xB2, 0xC0, 0x51, 0x2A, 0xBB, 0xC9, 0x58, 0x2D, 0xBC, 0xCE, 0x5F, + 0x70, 0xE1, 0x93, 0x02, 0x77, 0xE6, 0x94, 0x05, 0x7E, 0xEF, 0x9D, 0x0C, 0x79, 0xE8, 0x9A, 0x0B, + 0x6C, 0xFD, 0x8F, 0x1E, 0x6B, 0xFA, 0x88, 0x19, 0x62, 0xF3, 0x81, 0x10, 0x65, 0xF4, 0x86, 0x17, + 0x48, 0xD9, 0xAB, 0x3A, 0x4F, 0xDE, 0xAC, 0x3D, 0x46, 0xD7, 0xA5, 0x34, 0x41, 0xD0, 0xA2, 0x33, + 0x54, 0xC5, 0xB7, 0x26, 0x53, 0xC2, 0xB0, 0x21, 0x5A, 0xCB, 0xB9, 0x28, 0x5D, 0xCC, 0xBE, 0x2F, + 0xE0, 0x71, 0x03, 0x92, 0xE7, 0x76, 0x04, 0x95, 0xEE, 0x7F, 0x0D, 0x9C, 0xE9, 0x78, 0x0A, 0x9B, + 0xFC, 0x6D, 0x1F, 0x8E, 0xFB, 0x6A, 0x18, 0x89, 0xF2, 0x63, 0x11, 0x80, 0xF5, 0x64, 0x16, 0x87, + 0xD8, 0x49, 0x3B, 0xAA, 0xDF, 0x4E, 0x3C, 0xAD, 0xD6, 0x47, 0x35, 0xA4, 0xD1, 0x40, 0x32, 0xA3, + 0xC4, 0x55, 0x27, 0xB6, 0xC3, 0x52, 0x20, 0xB1, 0xCA, 0x5B, 0x29, 0xB8, 0xCD, 0x5C, 0x2E, 0xBF, + 0x90, 0x01, 0x73, 0xE2, 0x97, 0x06, 0x74, 0xE5, 0x9E, 0x0F, 0x7D, 0xEC, 0x99, 0x08, 0x7A, 0xEB, + 0x8C, 0x1D, 0x6F, 0xFE, 0x8B, 0x1A, 0x68, 0xF9, 0x82, 0x13, 0x61, 0xF0, 0x85, 0x14, 0x66, 0xF7, + 0xA8, 0x39, 0x4B, 0xDA, 0xAF, 0x3E, 0x4C, 0xDD, 0xA6, 0x37, 0x45, 0xD4, 0xA1, 0x30, 0x42, 0xD3, + 0xB4, 0x25, 0x57, 0xC6, 0xB3, 0x22, 0x50, 0xC1, 0xBA, 0x2B, 0x59, 0xC8, 0xBD, 0x2C, 0x5E, 0xCF, +}; +#endif + +/**************************************************************** Cache Implementation *************************************************************************/ +#if TMC5130_CACHE == 0 +static inline bool tmc5130_cache(uint16_t icID, TMC5130CacheOp operation, uint8_t address, uint32_t *value) +{ + UNUSED(icID); + UNUSED(address); + UNUSED(operation); + return false; +} +#else +#if TMC5130_ENABLE_TMC_CACHE == 1 + +uint8_t tmc5130_dirtyBits[TMC5130_IC_CACHE_COUNT][TMC5130_REGISTER_COUNT/8]= {0}; +int32_t tmc5130_shadowRegister[TMC5130_IC_CACHE_COUNT][TMC5130_REGISTER_COUNT]; + +void tmc5130_setDirtyBit(uint16_t icID, uint8_t index, bool value) + { + if(index >= TMC5130_REGISTER_COUNT) + return; + + uint8_t *tmp = &tmc5130_dirtyBits[icID][index / 8]; + uint8_t shift = (index % 8); + uint8_t mask = 1 << shift; + *tmp = (((*tmp) & (~(mask))) | (((value) << (shift)) & (mask))); +} + +bool tmc5130_getDirtyBit(uint16_t icID, uint8_t index) +{ + if(index >= TMC5130_REGISTER_COUNT) + return false; + + uint8_t *tmp = &tmc5130_dirtyBits[icID][index / 8]; + uint8_t shift = (index % 8); + return ((*tmp) >> shift) & 1; +} +/* + * This function is used to cache the value written to the Write-Only registers in the form of shadow array. + * The shadow copy is then used to read these kinds of registers. + */ +bool tmc5130_cache(uint16_t icID, TMC5130CacheOp operation, uint8_t address, uint32_t *value) +{ + if (operation == TMC5130_CACHE_READ) + { + // Check if the value should come from cache + + // Only supported chips have a cache + if (icID >= TMC5130_IC_CACHE_COUNT) + return false; + + // Only non-readable registers care about caching + // Note: This could also be used to cache i.e. RW config registers to reduce bus accesses + if (TMC5130_IS_READABLE(tmc5130_registerAccess[address])) + return false; + + // Grab the value from the cache + *value = tmc5130_shadowRegister[icID][address]; + return true; + } + + else if (operation == TMC5130_CACHE_WRITE || operation == TMC5130_CACHE_FILL_DEFAULT) + { + // Fill the cache + + // only supported chips have a cache + if (icID >= TMC5130_IC_CACHE_COUNT) + return false; + + // Write to the shadow register. + tmc5130_shadowRegister[icID][address] = *value; + // For write operations, mark the register dirty + if (operation == TMC5130_CACHE_WRITE) + { + tmc5130_setDirtyBit(icID, address, true); + } + + return true; + } + return false; +} + +void tmc5130_initCache() +{ + // Check if we have constants defined + if(ARRAY_SIZE(tmc5130_RegisterConstants) == 0) + return; + + size_t i, j, id; + + for(i = 0, j = 0; i < TMC5130_REGISTER_COUNT; i++) + { + // We only need to worry about hardware preset, write-only registers + // that have not yet been written (no dirty bit) here. + if(tmc5130_registerAccess[i] != TMC5130_ACCESS_W_PRESET) + continue; + + // Search the constant list for the current address. With the constant + // list being sorted in ascended order, we can walk through the list + // until the entry with an address equal or greater than i + while(j < ARRAY_SIZE(tmc5130_RegisterConstants) && (tmc5130_RegisterConstants[j].address < i)) + j++; + + // Abort when we reach the end of the constant list + if (j == ARRAY_SIZE(tmc5130_RegisterConstants)) + break; + + // If we have an entry for our current address, write the constant + if(tmc5130_RegisterConstants[j].address == i) + { + for (id = 0; id < TMC5130_IC_CACHE_COUNT; id++) + { + uint32_t temp = tmc5130_RegisterConstants[j].value; + tmc5130_cache(id, TMC5130_CACHE_FILL_DEFAULT, i, &temp); + } + } + } +} + +#else +// User must implement their own cache +extern bool tmc5130_cache(uint16_t icID, TMC5130CacheOp operation, uint8_t address, uint32_t *value); +#endif +#endif + +/************************************************************** read / write Implementation ******************************************************************/ + +static int32_t readRegisterSPI(uint16_t icID, uint8_t address); +static void writeRegisterSPI(uint16_t icID, uint8_t address, int32_t value); +static int32_t readRegisterUART(uint16_t icID, uint8_t registerAddress); +static void writeRegisterUART(uint16_t icID, uint8_t registerAddress, int32_t value); +static uint8_t CRC8(uint8_t *data, uint32_t bytes); + + +// Checks which BUS type is use and then forwards it to the corresponding read function. See below. +int32_t tmc5130_readRegister(uint16_t icID, uint8_t address) +{ + TMC5130BusType bus = tmc5130_getBusType(icID); + + uint32_t value; + + // Read from cache for registers with write-only access + if (tmc5130_cache(icID, TMC5130_CACHE_READ, address, &value)) + return value; + + if(bus == IC_BUS_SPI) + { + return readRegisterSPI(icID, address); + } + else if (bus == IC_BUS_UART) + { + return readRegisterUART(icID, address); + } + + // ToDo: Error handling + return -1; +} + +// Checks which BUS type is use and then forwards it to the corresponding write function. +void tmc5130_writeRegister(uint16_t icID, uint8_t address, int32_t value) +{ + TMC5130BusType bus = tmc5130_getBusType(icID); + + if(bus == IC_BUS_SPI) + { + writeRegisterSPI(icID, address, value); + } + else if(bus == IC_BUS_UART) + { + writeRegisterUART(icID, address, value); + } +} + +int32_t readRegisterSPI(uint16_t icID, uint8_t address) +{ + uint8_t data[5] = { 0 }; + + // clear write bit + data[0] = address & TMC5130_ADDRESS_MASK; + + // Send the read request + tmc5130_readWriteSPI(icID, &data[0], sizeof(data)); + + // Rewrite address and clear write bit + data[0] = address & TMC5130_ADDRESS_MASK; + + // Send another request to receive the read reply + tmc5130_readWriteSPI(icID, &data[0], sizeof(data)); + + return ((int32_t)data[1] << 24) | ((int32_t) data[2] << 16) | ((int32_t) data[3] << 8) | ((int32_t) data[4]); +} + +void writeRegisterSPI(uint16_t icID, uint8_t address, int32_t value) +{ + uint8_t data[5] = { 0 }; + + data[0] = address | TMC5130_WRITE_BIT; + data[1] = 0xFF & (value>>24); + data[2] = 0xFF & (value>>16); + data[3] = 0xFF & (value>>8); + data[4] = 0xFF & (value>>0); + + // Send the write request + tmc5130_readWriteSPI(icID, &data[0], sizeof(data)); + + //Cache the registers with write-only access + tmc5130_cache(icID, TMC5130_CACHE_WRITE, address, (uint32_t *)&value); +} + +int32_t readRegisterUART(uint16_t icID, uint8_t registerAddress) +{ + uint8_t data[8] = { 0 }; + + registerAddress = registerAddress & TMC5130_ADDRESS_MASK; + + data[0] = 0x05; + data[1] = tmc5130_getNodeAddress(icID); + data[2] = registerAddress; + data[3] = CRC8(data, 3); + + if (!tmc5130_readWriteUART(icID, &data[0], 4, 8)) + return 0; + + // Byte 0: Sync nibble correct? + if (data[0] != 0x05) + return 0; + + // Byte 1: Master address correct? + if (data[1] != 0xFF) + return 0; + + // Byte 2: Address correct? + if (data[2] != registerAddress) + return 0; + + // Byte 7: CRC correct? + if (data[7] != CRC8(data, 7)) + return 0; + + return ((uint32_t)data[3] << 24) | ((uint32_t)data[4] << 16) | (data[5] << 8) | data[6]; +} + +void writeRegisterUART(uint16_t icID, uint8_t registerAddress, int32_t value) +{ + uint8_t data[8]; + + data[0] = 0x05; + data[1] = tmc5130_getNodeAddress(icID); + data[2] = registerAddress | TMC5130_WRITE_BIT; + data[3] = (value >> 24) & 0xFF; + data[4] = (value >> 16) & 0xFF; + data[5] = (value >> 8 ) & 0xFF; + data[6] = (value ) & 0xFF; + data[7] = CRC8(data, 7); + + tmc5130_readWriteUART(icID, &data[0], 8, 0); + + //Cache the registers with write-only access + tmc5130_cache(icID, TMC5130_CACHE_WRITE, registerAddress, (uint32_t *)&value); +} + +static uint8_t CRC8(uint8_t *data, uint32_t bytes) +{ + uint8_t result = 0; + + while(bytes--) + result = tmcCRCTable_Poly7Reflected[result ^ *data++]; + + // Flip the result around + // swap odd and even bits + result = ((result >> 1) & 0x55) | ((result & 0x55) << 1); + // swap consecutive pairs + result = ((result >> 2) & 0x33) | ((result & 0x33) << 2); + // swap nibbles ... + result = ((result >> 4) & 0x0F) | ((result & 0x0F) << 4); + + return result; +} + +void tmc5130_rotateMotor(uint16_t icID, uint8_t motor, int32_t velocity) +{ + if(motor >= TMC5130_MOTORS) + return; + + tmc5130_writeRegister(icID, TMC5130_VMAX, (velocity >= 0)? velocity : -velocity); + // Set direction + tmc5130_writeRegister(icID, TMC5130_RAMPMODE, (velocity >= 0) ? TMC5130_MODE_VELPOS : TMC5130_MODE_VELNEG); +} + +/*******************************************************************************************************************************************************************/ diff --git a/firmware/lib/tmc/ic/TMC5130/TMC5130.h b/firmware/lib/tmc/ic/TMC5130/TMC5130.h new file mode 100755 index 0000000..0a303b7 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5130/TMC5130.h @@ -0,0 +1,225 @@ +/******************************************************************************* +* Copyright © 2017 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#ifndef TMC_IC_TMC5130_H_ +#define TMC_IC_TMC5130_H_ + +#include +#include +#include +#include "TMC5130_HW_Abstraction.h" + +/******************************************************************************* +* API Configuration Defines +* These control optional features of the TMC-API implementation. +* These can be commented in/out here or defined from the build system. +*******************************************************************************/ + +// Uncomment if you want to save space..... +// and put the table into your own .c file +//#define TMC_API_EXTERNAL_CRC_TABLE 1 + + +// To enable the cache mechanism in order to keep the copy of all registers, set TMC5130_CACHE to '1'. +// With this mechanism the value of write-only registers could be read from their shadow copies. +#ifndef TMC5130_CACHE +#define TMC5130_CACHE 1 +//#define TMC5130_CACHE 0 +#endif + +// To use the caching mechanism already implemented by the TMC-API, set TMC5130_ENABLE_TMC_CACHE to '1'. +// Set TMC5130_ENABLE_TMC_CACHE to '0' if one wants to have their own cache implementation. +#ifndef TMC5130_ENABLE_TMC_CACHE +#define TMC5130_ENABLE_TMC_CACHE 1 +//#define TMC5130_ENABLE_TMC_CACHE 0 +#endif + +/******************************************************************************/ + +typedef enum { + IC_BUS_SPI, + IC_BUS_UART, +} TMC5130BusType; + +typedef struct{ + uint32_t mask; + uint8_t shift; + uint8_t address; + bool isSigned; +} RegisterField; + +// => TMC-API wrapper +extern void tmc5130_readWriteSPI(uint16_t icID, uint8_t *data, size_t dataLength); +extern bool tmc5130_readWriteUART(uint16_t icID, uint8_t *data, size_t writeLength, size_t readLength); +extern TMC5130BusType tmc5130_getBusType(uint16_t icID); +extern uint8_t tmc5130_getNodeAddress(uint16_t icID); +// => TMC-API wrapper + +int32_t tmc5130_readRegister(uint16_t icID, uint8_t address); +void tmc5130_writeRegister(uint16_t icID, uint8_t address, int32_t value); +void tmc5130_rotateMotor(uint16_t icID, uint8_t motor, int32_t velocity); + +static inline uint32_t tmc5130_fieldExtract(uint32_t data, RegisterField field) +{ + uint32_t value = (data & field.mask) >> field.shift; + + if (field.isSigned) + { + // Apply signedness conversion + uint32_t baseMask = field.mask >> field.shift; + uint32_t signMask = baseMask & (~baseMask >> 1); + value = (value ^ signMask) - signMask; + } + + return value; +} + +static inline uint32_t tmc5130_fieldRead(uint16_t icID, RegisterField field) +{ + uint32_t value = tmc5130_readRegister(icID, field.address); + + return tmc5130_fieldExtract(value, field); +} + +static inline uint32_t tmc5130_fieldUpdate(uint32_t data, RegisterField field, uint32_t value) +{ + return (data & (~field.mask)) | ((value << field.shift) & field.mask); +} + +static inline void tmc5130_fieldWrite(uint16_t icID, RegisterField field, uint32_t value) +{ + uint32_t regValue = tmc5130_readRegister(icID, field.address); + + regValue = tmc5130_fieldUpdate(regValue, field, value); + + tmc5130_writeRegister(icID, field.address, regValue); +} + + +/**************************************************************** Cache Implementation *************************************************************************/ +#if TMC5130_CACHE == 1 +#ifdef TMC5130_ENABLE_TMC_CACHE + +// By default, support one IC in the cache +#ifndef TMC5130_IC_CACHE_COUNT +#define TMC5130_IC_CACHE_COUNT 1 +#endif + +typedef enum { + TMC5130_CACHE_READ, + TMC5130_CACHE_WRITE, + + // Special operation: Put content into the cache without marking the entry as dirty. + // Only used to initialize the cache with hardware defaults. This will allow reading + // from write-only registers that have a value inside them on reset. When using this + // operation, a restore will *not* rewrite that filled register! + TMC5130_CACHE_FILL_DEFAULT, +} TMC5130CacheOp; + +typedef struct{ + uint8_t address; + uint32_t value; +} TMC5130RegisterConstants; + +#define TMC5130_ACCESS_READ 0x01 +#define TMC5130_ACCESS_W_PRESET 0x42 +#define TMC5130_IS_READABLE(x) ((x) & TMC5130_ACCESS_READ) +#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) + +// Default Register values +#define R10 0x00071703 // IHOLD_IRUN +#define R3A 0x00010000 // ENC_CONST +#define R6C 0x000101D5 // CHOPCONF + +// Helper define: +// Default reset values are not used if the corresponding register has a +// hardware preset. Since this is not directly visible in the default +// register reset values array, N_A is used as an indicator for a preset +// value, where any value will be ignored anyways (N_A: not available). +#define N_A 0 + +// Helper define: +// Most register permission arrays are initialized with 128 values. +// In those fields its quite hard to have an easy overview of available +// registers. For that, ____ is defined to 0, since 4 underscores are +// very easy to distinguish from the 2-digit hexadecimal values. +// This way, the used registers (permission != ACCESS_NONE) are easily spotted +// amongst unused (permission == ACCESS_NONE) registers. +#define ____ 0x00 + +// Register access permissions: +// 0x00: none (reserved) +// 0x01: read +// 0x02: write +// 0x03: read/write +// 0x13: read/write, separate functions/values for reading or writing +// 0x21: read, flag register (read to clear) +// 0x42: write, has hardware presets on reset +static const uint8_t tmc5130_registerAccess[TMC5130_REGISTER_COUNT] = +{ +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0x03, 0x21, 0x01, 0x02, 0x13, 0x02, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x00 - 0x0F + 0x02, 0x02, 0x01, 0x02, 0x02, 0x02, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x10 - 0x1F + 0x03, 0x03, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, ____, 0x02, 0x02, 0x02, 0x03, ____, ____, // 0x20 - 0x2F + ____, ____, ____, 0x02, 0x03, 0x21, 0x01, ____, 0x03, 0x03, 0x02, 0x21, 0x01, ____, ____, ____, // 0x30 - 0x3F + ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x40 - 0x4F + ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x50 - 0x5F + 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x01, 0x01, 0x03, 0x02, 0x02, 0x01, // 0x60 - 0x6F + 0x42, 0x01, 0x02, 0x01, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____ // 0x70 - 0x7F +}; + +static const int32_t tmc5130_sampleRegisterPreset[TMC5130_REGISTER_COUNT] = +{ +// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x00 - 0x0F + R10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x10 - 0x1F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x20 - 0x2F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, R3A, 0, 0, 0, 0, 0, // 0x30 - 0x3F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x40 - 0x4F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x50 - 0x5F + N_A, N_A, N_A, N_A, N_A, N_A, N_A, N_A, N_A, N_A, 0, 0, R6C, 0, 0, 0, // 0x60 - 0x6F + N_A, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x70 - 0x7F +}; + +// Undefine the default register values. +// This prevents warnings in case multiple TMC-API chip headers are included at once +#undef R10 +#undef R3A +#undef R6C + +// Register constants (only required for 0x42 registers, since we do not have +// any way to find out the content but want to hold the actual value in the +// shadow register so an application (i.e. the TMCL IDE) can still display +// the values. This only works when the register content is constant. +static const TMC5130RegisterConstants tmc5130_RegisterConstants[] = +{ // Use ascending addresses! + { 0x60, 0xAAAAB554 }, // MSLUT[0] + { 0x61, 0x4A9554AA }, // MSLUT[1] + { 0x62, 0x24492929 }, // MSLUT[2] + { 0x63, 0x10104222 }, // MSLUT[3] + { 0x64, 0xFBFFFFFF }, // MSLUT[4] + { 0x65, 0xB5BB777D }, // MSLUT[5] + { 0x66, 0x49295556 }, // MSLUT[6] + { 0x67, 0x00404222 }, // MSLUT[7] + { 0x68, 0xFFFF8056 }, // MSLUTSEL + { 0x69, 0x00F70000 }, // MSLUTSTART + { 0x70, 0x00050480 } // PWMCONF +}; + +extern uint8_t tmc5130_dirtyBits[TMC5130_IC_CACHE_COUNT][TMC5130_REGISTER_COUNT/8]; +extern int32_t tmc5130_shadowRegister[TMC5130_IC_CACHE_COUNT][TMC5130_REGISTER_COUNT]; +extern bool tmc5130_cache(uint16_t icID, TMC5130CacheOp operation, uint8_t address, uint32_t *value); +void tmc5130_setDirtyBit(uint16_t icID, uint8_t index, bool value); +bool tmc5130_getDirtyBit(uint16_t icID, uint8_t index); +void tmc5130_initCache(void); +#endif +#endif + +/***************************************************************************************************************************************************/ +#endif /* TMC_IC_TMC5130_H_ */ diff --git a/firmware/lib/tmc/ic/TMC5130/TMC5130_HW_Abstraction.h b/firmware/lib/tmc/ic/TMC5130/TMC5130_HW_Abstraction.h new file mode 100755 index 0000000..9ae77d6 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5130/TMC5130_HW_Abstraction.h @@ -0,0 +1,1384 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#ifndef TMC5130_HW_ABSTRACTION +#define TMC5130_HW_ABSTRACTION + +#define TMC5130_REGISTER_COUNT 128 +#define TMC5130_MOTORS 1 +#define TMC5130_WRITE_BIT 0x80 +#define TMC5130_ADDRESS_MASK 0x7F +#define TMC5130_MAX_VELOCITY 8388096 +#define TMC5130_MAX_ACCELERATION 65535 + +// ramp modes (Register TMC5161_RAMPMODE) +#define TMC5130_MODE_POSITION 0 +#define TMC5130_MODE_VELPOS 1 +#define TMC5130_MODE_VELNEG 2 +#define TMC5130_MODE_HOLD 3 + +// limit switch mode bits (Register TMC5130_SWMODE) +#define TMC5130_SW_STOPL_ENABLE 0x0001 +#define TMC5130_SW_STOPR_ENABLE 0x0002 +#define TMC5130_SW_STOPL_POLARITY 0x0004 +#define TMC5130_SW_STOPR_POLARITY 0x0008 +#define TMC5130_SW_SWAP_LR 0x0010 +#define TMC5130_SW_LATCH_L_ACT 0x0020 +#define TMC5130_SW_LATCH_L_INACT 0x0040 +#define TMC5130_SW_LATCH_R_ACT 0x0080 +#define TMC5130_SW_LATCH_R_INACT 0x0100 +#define TMC5130_SW_LATCH_ENC 0x0200 +#define TMC5130_SW_SG_STOP 0x0400 +#define TMC5130_SW_SOFTSTOP 0x0800 + +// Status bits (Register TMC5130_RAMPSTAT) +#define TMC5130_RS_STOPL 0x0001 +#define TMC5130_RS_STOPR 0x0002 +#define TMC5130_RS_LATCHL 0x0004 +#define TMC5130_RS_LATCHR 0x0008 +#define TMC5130_RS_EV_STOPL 0x0010 +#define TMC5130_RS_EV_STOPR 0x0020 +#define TMC5130_RS_EV_STOP_SG 0x0040 +#define TMC5130_RS_EV_POSREACHED 0x0080 +#define TMC5130_RS_VELREACHED 0x0100 +#define TMC5130_RS_POSREACHED 0x0200 +#define TMC5130_RS_VZERO 0x0400 +#define TMC5130_RS_ZEROWAIT 0x0800 +#define TMC5130_RS_SECONDMOVE 0x1000 +#define TMC5130_RS_SG 0x2000 + +// Encoderbits (Register TMC5130_ENCMODE) +#define TMC5130_EM_DECIMAL 0x0400 +#define TMC5130_EM_LATCH_XACT 0x0200 +#define TMC5130_EM_CLR_XENC 0x0100 +#define TMC5130_EM_NEG_EDGE 0x0080 +#define TMC5130_EM_POS_EDGE 0x0040 +#define TMC5130_EM_CLR_ONCE 0x0020 +#define TMC5130_EM_CLR_CONT 0x0010 +#define TMC5130_EM_IGNORE_AB 0x0008 +#define TMC5130_EM_POL_N 0x0004 +#define TMC5130_EM_POL_B 0x0002 +#define TMC5130_EM_POL_A 0x0001 + +#define TMC5130_GCONF 0x00 +#define TMC5130_GSTAT 0x01 +#define TMC5130_IFCNT 0x02 +#define TMC5130_SLAVECONF 0x03 +#define TMC5130_IOIN 0x04 +#define TMC5130_X_COMPARE 0x05 + +#define TMC5130_IHOLD_IRUN 0x10 +#define TMC5130_TPOWERDOWN 0x11 +#define TMC5130_TSTEP 0x12 +#define TMC5130_TPWMTHRS 0x13 +#define TMC5130_TCOOLTHRS 0x14 +#define TMC5130_THIGH 0x15 + +#define TMC5130_RAMPMODE 0x20 +#define TMC5130_XACTUAL 0x21 +#define TMC5130_VACTUAL 0x22 +#define TMC5130_VSTART 0x23 +#define TMC5130_A1 0x24 +#define TMC5130_V1 0x25 +#define TMC5130_AMAX 0x26 +#define TMC5130_VMAX 0x27 +#define TMC5130_DMAX 0x28 +#define TMC5130_D1 0x2A +#define TMC5130_VSTOP 0x2B +#define TMC5130_TZEROWAIT 0x2C +#define TMC5130_XTARGET 0x2D + +#define TMC5130_VDCMIN 0x33 +#define TMC5130_SWMODE 0x34 +#define TMC5130_RAMPSTAT 0x35 +#define TMC5130_XLATCH 0x36 + +#define TMC5130_ENCMODE 0x38 +#define TMC5130_XENC 0x39 +#define TMC5130_ENC_CONST 0x3A +#define TMC5130_ENC_STATUS 0x3B +#define TMC5130_ENC_LATCH 0x3C + +#define TMC5130_MSLUT0 0x60 +#define TMC5130_MSLUT1 0x61 +#define TMC5130_MSLUT2 0x62 +#define TMC5130_MSLUT3 0x63 +#define TMC5130_MSLUT4 0x64 +#define TMC5130_MSLUT5 0x65 +#define TMC5130_MSLUT6 0x66 +#define TMC5130_MSLUT7 0x67 +#define TMC5130_MSLUTSEL 0x68 +#define TMC5130_MSLUTSTART 0x69 +#define TMC5130_MSCNT 0x6A +#define TMC5130_MSCURACT 0x6B + +#define TMC5130_CHOPCONF 0x6C +#define TMC5130_COOLCONF 0x6D +#define TMC5130_DCCTRL 0x6E +#define TMC5130_DRVSTATUS 0x6F +#define TMC5130_PWMCONF 0x70 +#define TMC5130_PWM_SCALE 0x71 +#define TMC5130_ENCM_CTRL 0x72 +#define TMC5130_LOST_STEPS 0x73 + +// Register fields in + +#define TMC5130_I_SCALE_ANALOG_MASK 0x00000001 +#define TMC5130_I_SCALE_ANALOG_SHIFT 0 +#define TMC5130_I_SCALE_ANALOG_FIELD ((RegisterField) {TMC5130_I_SCALE_ANALOG_MASK, TMC5130_I_SCALE_ANALOG_SHIFT, TMC5130_GCONF, false}) +#define TMC5130_INTERNAL_RSENSE_MASK 0x00000002 +#define TMC5130_INTERNAL_RSENSE_SHIFT 1 +#define TMC5130_INTERNAL_RSENSE_FIELD ((RegisterField) {TMC5130_INTERNAL_RSENSE_MASK, TMC5130_INTERNAL_RSENSE_SHIFT, TMC5130_GCONF, false}) +#define TMC5130_EN_PWM_MODE_MASK 0x00000004 +#define TMC5130_EN_PWM_MODE_SHIFT 2 +#define TMC5130_EN_PWM_MODE_FIELD ((RegisterField) {TMC5130_EN_PWM_MODE_MASK, TMC5130_EN_PWM_MODE_SHIFT, TMC5130_GCONF, false}) +#define TMC5130_ENC_COMMUTATION_MASK 0x00000008 +#define TMC5130_ENC_COMMUTATION_SHIFT 3 +#define TMC5130_ENC_COMMUTATION_FIELD ((RegisterField) {TMC5130_ENC_COMMUTATION_MASK, TMC5130_ENC_COMMUTATION_SHIFT, TMC5130_GCONF, false}) +#define TMC5130_SHAFT_MASK 0x00000010 +#define TMC5130_SHAFT_SHIFT 4 +#define TMC5130_SHAFT_FIELD ((RegisterField) {TMC5130_SHAFT_MASK, TMC5130_SHAFT_SHIFT, TMC5130_GCONF, false}) +#define TMC5130_DIAG0_ERROR__ONLY_WITH_SD_MODE_1__MASK 0x00000020 +#define TMC5130_DIAG0_ERROR__ONLY_WITH_SD_MODE_1__SHIFT 5 +#define TMC5130_DIAG0_ERROR__ONLY_WITH_SD_MODE_1__FIELD ((RegisterField) {TMC5130_DIAG0_ERROR__ONLY_WITH_SD_MODE_1__MASK, TMC5130_DIAG0_ERROR__ONLY_WITH_SD_MODE_1__SHIFT, TMC5130_GCONF, false}) +#define TMC5130_DIAG0_OTPW__ONLY_WITH_SD_MODE_1__MASK 0x00000040 +#define TMC5130_DIAG0_OTPW__ONLY_WITH_SD_MODE_1__SHIFT 6 +#define TMC5130_DIAG0_OTPW__ONLY_WITH_SD_MODE_1__FIELD ((RegisterField) {TMC5130_DIAG0_OTPW__ONLY_WITH_SD_MODE_1__MASK, TMC5130_DIAG0_OTPW__ONLY_WITH_SD_MODE_1__SHIFT, TMC5130_GCONF, false}) +#define TMC5130_DIAG0_STALL_MASK 0x00000080 +#define TMC5130_DIAG0_STALL_SHIFT 7 +#define TMC5130_DIAG0_STALL_FIELD ((RegisterField) {TMC5130_DIAG0_STALL_MASK, TMC5130_DIAG0_STALL_SHIFT, TMC5130_GCONF, false}) +#define TMC5130_DIAG1_STALL_MASK 0x00000100 +#define TMC5130_DIAG1_STALL_SHIFT 8 +#define TMC5130_DIAG1_STALL_FIELD ((RegisterField) {TMC5130_DIAG1_STALL_MASK, TMC5130_DIAG1_STALL_SHIFT, TMC5130_GCONF, false}) +#define TMC5130_DIAG1_INDEX_MASK 0x00000200 +#define TMC5130_DIAG1_INDEX_SHIFT 9 +#define TMC5130_DIAG1_INDEX_FIELD ((RegisterField) {TMC5130_DIAG1_INDEX_MASK, TMC5130_DIAG1_INDEX_SHIFT, TMC5130_GCONF, false}) +#define TMC5130_DIAG1_ONSTATE_MASK 0x00000400 +#define TMC5130_DIAG1_ONSTATE_SHIFT 10 +#define TMC5130_DIAG1_ONSTATE_FIELD ((RegisterField) {TMC5130_DIAG1_ONSTATE_MASK, TMC5130_DIAG1_ONSTATE_SHIFT, TMC5130_GCONF, false}) +#define TMC5130_DIAG1_STEPS_SKIPPED_MASK 0x00000800 +#define TMC5130_DIAG1_STEPS_SKIPPED_SHIFT 11 +#define TMC5130_DIAG1_STEPS_SKIPPED_FIELD ((RegisterField) {TMC5130_DIAG1_STEPS_SKIPPED_MASK, TMC5130_DIAG1_STEPS_SKIPPED_SHIFT, TMC5130_GCONF, false}) +#define TMC5130_DIAG0_INT_PUSHPULL_MASK 0x00001000 +#define TMC5130_DIAG0_INT_PUSHPULL_SHIFT 12 +#define TMC5130_DIAG0_INT_PUSHPULL_FIELD ((RegisterField) {TMC5130_DIAG0_INT_PUSHPULL_MASK, TMC5130_DIAG0_INT_PUSHPULL_SHIFT, TMC5130_GCONF, false}) +#define TMC5130_DIAG1_POSCOMP_PUSHPULL_MASK 0x00002000 +#define TMC5130_DIAG1_POSCOMP_PUSHPULL_SHIFT 13 +#define TMC5130_DIAG1_POSCOMP_PUSHPULL_FIELD ((RegisterField) {TMC5130_DIAG1_POSCOMP_PUSHPULL_MASK, TMC5130_DIAG1_POSCOMP_PUSHPULL_SHIFT, TMC5130_GCONF, false}) +#define TMC5130_SMALL_HYSTERESIS_MASK 0x00004000 +#define TMC5130_SMALL_HYSTERESIS_SHIFT 14 +#define TMC5130_SMALL_HYSTERESIS_FIELD ((RegisterField) {TMC5130_SMALL_HYSTERESIS_MASK, TMC5130_SMALL_HYSTERESIS_SHIFT, TMC5130_GCONF, false}) +#define TMC5130_STOP_ENABLE_MASK 0x00008000 +#define TMC5130_STOP_ENABLE_SHIFT 15 +#define TMC5130_STOP_ENABLE_FIELD ((RegisterField) {TMC5130_STOP_ENABLE_MASK, TMC5130_STOP_ENABLE_SHIFT, TMC5130_GCONF, false}) +#define TMC5130_DIRECT_MODE_MASK 0x00010000 +#define TMC5130_DIRECT_MODE_SHIFT 16 +#define TMC5130_DIRECT_MODE_FIELD ((RegisterField) {TMC5130_DIRECT_MODE_MASK, TMC5130_DIRECT_MODE_SHIFT, TMC5130_GCONF, false}) +#define TMC5130_TEST_MODE_MASK 0x00020000 +#define TMC5130_TEST_MODE_SHIFT 17 +#define TMC5130_TEST_MODE_FIELD ((RegisterField) {TMC5130_TEST_MODE_MASK, TMC5130_TEST_MODE_SHIFT, TMC5130_GCONF, false}) +#define TMC5130_DIAG0_STEP_MASK 0x00000080 +#define TMC5130_DIAG0_STEP_SHIFT 7 +#define TMC5130_DIAG0_STEP_FIELD ((RegisterField) {TMC5130_DIAG0_STEP_MASK, TMC5130_DIAG0_STEP_SHIFT, TMC5130_GCONF, false}) +#define TMC5130_DIAG1_DIR_MASK 0x00000100 +#define TMC5130_DIAG1_DIR_SHIFT 8 +#define TMC5130_DIAG1_DIR_FIELD ((RegisterField) {TMC5130_DIAG1_DIR_MASK, TMC5130_DIAG1_DIR_SHIFT, TMC5130_GCONF, false}) +#define TMC5130_RESET_MASK 0x00000001 +#define TMC5130_RESET_SHIFT 0 +#define TMC5130_RESET_FIELD ((RegisterField) {TMC5130_RESET_MASK, TMC5130_RESET_SHIFT, TMC5130_GSTAT, false}) +#define TMC5130_DRV_ERR_MASK 0x00000002 +#define TMC5130_DRV_ERR_SHIFT 1 +#define TMC5130_DRV_ERR_FIELD ((RegisterField) {TMC5130_DRV_ERR_MASK, TMC5130_DRV_ERR_SHIFT, TMC5130_GSTAT, false}) +#define TMC5130_UV_CP_MASK 0x00000004 +#define TMC5130_UV_CP_SHIFT 2 +#define TMC5130_UV_CP_FIELD ((RegisterField) {TMC5130_UV_CP_MASK, TMC5130_UV_CP_SHIFT, TMC5130_GSTAT, false}) +#define TMC5130_IFCNT_MASK 0x000000FF +#define TMC5130_IFCNT_SHIFT 0 +#define TMC5130_IFCNT_FIELD ((RegisterField) {TMC5130_IFCNT_MASK, TMC5130_IFCNT_SHIFT, TMC5130_IFCNT, false}) +#define TMC5130_SLAVEADDR_MASK 0x000000FF +#define TMC5130_SLAVEADDR_SHIFT 0 +#define TMC5130_SLAVEADDR_FIELD ((RegisterField) {TMC5130_SLAVEADDR_MASK, TMC5130_SLAVEADDR_SHIFT, TMC5130_SLAVECONF, false}) +#define TMC5130_SENDDELAY_MASK 0x00000F00 +#define TMC5130_SENDDELAY_SHIFT 8 +#define TMC5130_SENDDELAY_FIELD ((RegisterField) {TMC5130_SENDDELAY_MASK, TMC5130_SENDDELAY_SHIFT, TMC5130_SLAVECONF, false}) +#define TMC5130_REFL_STEP_MASK 0x00000001 +#define TMC5130_REFL_STEP_SHIFT 0 +#define TMC5130_REFL_STEP_FIELD ((RegisterField) {TMC5130_REFL_STEP_MASK, TMC5130_REFL_STEP_SHIFT, TMC5130_IOIN / OUTPUT, false}) +#define TMC5130_REFR_DIR_MASK 0x00000002 +#define TMC5130_REFR_DIR_SHIFT 1 +#define TMC5130_REFR_DIR_FIELD ((RegisterField) {TMC5130_REFR_DIR_MASK, TMC5130_REFR_DIR_SHIFT, TMC5130_IOIN / OUTPUT, false}) +#define TMC5130_ENCB_DCEN_CFG4_MASK 0x00000004 +#define TMC5130_ENCB_DCEN_CFG4_SHIFT 2 +#define TMC5130_ENCB_DCEN_CFG4_FIELD ((RegisterField) {TMC5130_ENCB_DCEN_CFG4_MASK, TMC5130_ENCB_DCEN_CFG4_SHIFT, TMC5130_IOIN / OUTPUT, false}) +#define TMC5130_ENCA_DCIN_CFG5_MASK 0x00000008 +#define TMC5130_ENCA_DCIN_CFG5_SHIFT 3 +#define TMC5130_ENCA_DCIN_CFG5_FIELD ((RegisterField) {TMC5130_ENCA_DCIN_CFG5_MASK, TMC5130_ENCA_DCIN_CFG5_SHIFT, TMC5130_IOIN / OUTPUT, false}) +#define TMC5130_DRV_ENN_CFG6_MASK 0x00000010 +#define TMC5130_DRV_ENN_CFG6_SHIFT 4 +#define TMC5130_DRV_ENN_CFG6_FIELD ((RegisterField) {TMC5130_DRV_ENN_CFG6_MASK, TMC5130_DRV_ENN_CFG6_SHIFT, TMC5130_IOIN / OUTPUT, false}) +#define TMC5130_ENC_N_DCO_MASK 0x00000020 +#define TMC5130_ENC_N_DCO_SHIFT 5 +#define TMC5130_ENC_N_DCO_FIELD ((RegisterField) {TMC5130_ENC_N_DCO_MASK, TMC5130_ENC_N_DCO_SHIFT, TMC5130_IOIN / OUTPUT, false}) +#define TMC5130_SD_MODE_MASK 0x00000040 +#define TMC5130_SD_MODE_SHIFT 6 +#define TMC5130_SD_MODE_FIELD ((RegisterField) {TMC5130_SD_MODE_MASK, TMC5130_SD_MODE_SHIFT, TMC5130_IOIN / OUTPUT, false}) +#define TMC5130_SWCOMP_IN_MASK 0x00000080 +#define TMC5130_SWCOMP_IN_SHIFT 7 +#define TMC5130_SWCOMP_IN_FIELD ((RegisterField) {TMC5130_SWCOMP_IN_MASK, TMC5130_SWCOMP_IN_SHIFT, TMC5130_IOIN / OUTPUT, false}) +#define TMC5130_VERSION_MASK 0xFF000000 +#define TMC5130_VERSION_SHIFT 24 +#define TMC5130_VERSION_FIELD ((RegisterField) {TMC5130_VERSION_MASK, TMC5130_VERSION_SHIFT, TMC5130_IOIN / OUTPUT, false}) +#define TMC5130_OUTPUT_PIN_POLARITY_MASK 0x00000001 +#define TMC5130_OUTPUT_PIN_POLARITY_SHIFT 0 +#define TMC5130_OUTPUT_PIN_POLARITY_FIELD ((RegisterField) {TMC5130_OUTPUT_PIN_POLARITY_MASK, TMC5130_OUTPUT_PIN_POLARITY_SHIFT, TMC5130_IOIN / OUTPUT, false}) +#define TMC5130_X_COMPARE_MASK 0xFFFFFFFF +#define TMC5130_X_COMPARE_SHIFT 0 +#define TMC5130_X_COMPARE_FIELD ((RegisterField) {TMC5130_X_COMPARE_MASK, TMC5130_X_COMPARE_SHIFT, TMC5130_X_COMPARE, false}) +#define TMC5130_IHOLD_MASK 0x0000001F +#define TMC5130_IHOLD_SHIFT 0 +#define TMC5130_IHOLD_FIELD ((RegisterField) {TMC5130_IHOLD_MASK, TMC5130_IHOLD_SHIFT, TMC5130_IHOLD_IRUN, false}) +#define TMC5130_IRUN_MASK 0x00001F00 +#define TMC5130_IRUN_SHIFT 8 +#define TMC5130_IRUN_FIELD ((RegisterField) {TMC5130_IRUN_MASK, TMC5130_IRUN_SHIFT, TMC5130_IHOLD_IRUN, false}) +#define TMC5130_IHOLDDELAY_MASK 0x000F0000 +#define TMC5130_IHOLDDELAY_SHIFT 16 +#define TMC5130_IHOLDDELAY_FIELD ((RegisterField) {TMC5130_IHOLDDELAY_MASK, TMC5130_IHOLDDELAY_SHIFT, TMC5130_IHOLD_IRUN, false}) +#define TMC5130_TPOWERDOWN_MASK 0x000000FF +#define TMC5130_TPOWERDOWN_SHIFT 0 +#define TMC5130_TPOWERDOWN_FIELD ((RegisterField) {TMC5130_TPOWERDOWN_MASK, TMC5130_TPOWERDOWN_SHIFT, TMC5130_TPOWERDOWN, false}) +#define TMC5130_TSTEP_MASK 0x000FFFFF +#define TMC5130_TSTEP_SHIFT 0 +#define TMC5130_TSTEP_FIELD ((RegisterField) {TMC5130_TSTEP_MASK, TMC5130_TSTEP_SHIFT, TMC5130_TSTEP, false}) +#define TMC5130_TPWMTHRS_MASK 0x000FFFFF +#define TMC5130_TPWMTHRS_SHIFT 0 +#define TMC5130_TPWMTHRS_FIELD ((RegisterField) {TMC5130_TPWMTHRS_MASK, TMC5130_TPWMTHRS_SHIFT, TMC5130_TPWMTHRS, false}) +#define TMC5130_TCOOLTHRS_MASK 0x000FFFFF +#define TMC5130_TCOOLTHRS_SHIFT 0 +#define TMC5130_TCOOLTHRS_FIELD ((RegisterField) {TMC5130_TCOOLTHRS_MASK, TMC5130_TCOOLTHRS_SHIFT, TMC5130_TCOOLTHRS, false}) +#define TMC5130_THIGH_MASK 0x000FFFFF +#define TMC5130_THIGH_SHIFT 0 +#define TMC5130_THIGH_FIELD ((RegisterField) {TMC5130_THIGH_MASK, TMC5130_THIGH_SHIFT, TMC5130_THIGH, false}) +#define TMC5130_RAMPMODE_MASK 0x00000003 +#define TMC5130_RAMPMODE_SHIFT 0 +#define TMC5130_RAMPMODE_FIELD ((RegisterField) {TMC5130_RAMPMODE_MASK, TMC5130_RAMPMODE_SHIFT, TMC5130_RAMPMODE, false}) +#define TMC5130_XACTUAL_MASK 0xFFFFFFFF +#define TMC5130_XACTUAL_SHIFT 0 +#define TMC5130_XACTUAL_FIELD ((RegisterField) {TMC5130_XACTUAL_MASK, TMC5130_XACTUAL_SHIFT, TMC5130_XACTUAL, true}) +#define TMC5130_VACTUAL_MASK 0x00FFFFFF +#define TMC5130_VACTUAL_SHIFT 0 +#define TMC5130_VACTUAL_FIELD ((RegisterField) {TMC5130_VACTUAL_MASK, TMC5130_VACTUAL_SHIFT, TMC5130_VACTUAL, true}) +#define TMC5130_VSTART_MASK 0x0003FFFF +#define TMC5130_VSTART_SHIFT 0 +#define TMC5130_VSTART_FIELD ((RegisterField) {TMC5130_VSTART_MASK, TMC5130_VSTART_SHIFT, TMC5130_VSTART, false}) +#define TMC5130_A1_MASK 0x0000FFFF +#define TMC5130_A1_SHIFT 0 +#define TMC5130_A1_FIELD ((RegisterField) {TMC5130_A1_MASK, TMC5130_A1_SHIFT, TMC5130_A1, false}) +#define TMC5130_V1_MASK 0x000FFFFF +#define TMC5130_V1_SHIFT 0 +#define TMC5130_V1_FIELD ((RegisterField) {TMC5130_V1_MASK, TMC5130_V1_SHIFT, TMC5130_V1, false}) +#define TMC5130_AMAX_MASK 0x0000FFFF +#define TMC5130_AMAX_SHIFT 0 +#define TMC5130_AMAX_FIELD ((RegisterField) {TMC5130_AMAX_MASK, TMC5130_AMAX_SHIFT, TMC5130_AMAX, false}) +#define TMC5130_VMAX_MASK 0x007FFFFF +#define TMC5130_VMAX_SHIFT 0 +#define TMC5130_VMAX_FIELD ((RegisterField) {TMC5130_VMAX_MASK, TMC5130_VMAX_SHIFT, TMC5130_VMAX, false}) +#define TMC5130_DMAX_MASK 0x0000FFFF +#define TMC5130_DMAX_SHIFT 0 +#define TMC5130_DMAX_FIELD ((RegisterField) {TMC5130_DMAX_MASK, TMC5130_DMAX_SHIFT, TMC5130_DMAX, false}) +#define TMC5130_D1_MASK 0x0000FFFF +#define TMC5130_D1_SHIFT 0 +#define TMC5130_D1_FIELD ((RegisterField) {TMC5130_D1_MASK, TMC5130_D1_SHIFT, TMC5130_D1, false}) +#define TMC5130_VSTOP_MASK 0x0003FFFF +#define TMC5130_VSTOP_SHIFT 0 +#define TMC5130_VSTOP_FIELD ((RegisterField) {TMC5130_VSTOP_MASK, TMC5130_VSTOP_SHIFT, TMC5130_VSTOP, false}) +#define TMC5130_TZEROWAIT_MASK 0x0000FFFF +#define TMC5130_TZEROWAIT_SHIFT 0 +#define TMC5130_TZEROWAIT_FIELD ((RegisterField) {TMC5130_TZEROWAIT_MASK, TMC5130_TZEROWAIT_SHIFT, TMC5130_TZEROWAIT, false}) +#define TMC5130_XTARGET_MASK 0xFFFFFFFF +#define TMC5130_XTARGET_SHIFT 0 +#define TMC5130_XTARGET_FIELD ((RegisterField) {TMC5130_XTARGET_MASK, TMC5130_XTARGET_SHIFT, TMC5130_XTARGET, true}) +#define TMC5130_VDCMIN_MASK 0x007FFFFF +#define TMC5130_VDCMIN_SHIFT 0 +#define TMC5130_VDCMIN_FIELD ((RegisterField) {TMC5130_VDCMIN_MASK, TMC5130_VDCMIN_SHIFT, TMC5130_VDCMIN, false}) +#define TMC5130_STOP_L_ENABLE_MASK 0x00000001 +#define TMC5130_STOP_L_ENABLE_SHIFT 0 +#define TMC5130_STOP_L_ENABLE_FIELD ((RegisterField) {TMC5130_STOP_L_ENABLE_MASK, TMC5130_STOP_L_ENABLE_SHIFT, TMC5130_SWMODE, false}) +#define TMC5130_STOP_R_ENABLE_MASK 0x00000002 +#define TMC5130_STOP_R_ENABLE_SHIFT 1 +#define TMC5130_STOP_R_ENABLE_FIELD ((RegisterField) {TMC5130_STOP_R_ENABLE_MASK, TMC5130_STOP_R_ENABLE_SHIFT, TMC5130_SWMODE, false}) +#define TMC5130_POL_STOP_L_MASK 0x00000004 +#define TMC5130_POL_STOP_L_SHIFT 2 +#define TMC5130_POL_STOP_L_FIELD ((RegisterField) {TMC5130_POL_STOP_L_MASK, TMC5130_POL_STOP_L_SHIFT, TMC5130_SWMODE, false}) +#define TMC5130_POL_STOP_R_MASK 0x00000008 +#define TMC5130_POL_STOP_R_SHIFT 3 +#define TMC5130_POL_STOP_R_FIELD ((RegisterField) {TMC5130_POL_STOP_R_MASK, TMC5130_POL_STOP_R_SHIFT, TMC5130_SWMODE, false}) +#define TMC5130_SWAP_LR_MASK 0x00000010 +#define TMC5130_SWAP_LR_SHIFT 4 +#define TMC5130_SWAP_LR_FIELD ((RegisterField) {TMC5130_SWAP_LR_MASK, TMC5130_SWAP_LR_SHIFT, TMC5130_SWMODE, false}) +#define TMC5130_LATCH_L_ACTIVE_MASK 0x00000020 +#define TMC5130_LATCH_L_ACTIVE_SHIFT 5 +#define TMC5130_LATCH_L_ACTIVE_FIELD ((RegisterField) {TMC5130_LATCH_L_ACTIVE_MASK, TMC5130_LATCH_L_ACTIVE_SHIFT, TMC5130_SWMODE, false}) +#define TMC5130_LATCH_L_INACTIVE_MASK 0x00000040 +#define TMC5130_LATCH_L_INACTIVE_SHIFT 6 +#define TMC5130_LATCH_L_INACTIVE_FIELD ((RegisterField) {TMC5130_LATCH_L_INACTIVE_MASK, TMC5130_LATCH_L_INACTIVE_SHIFT, TMC5130_SWMODE, false}) +#define TMC5130_LATCH_R_ACTIVE_MASK 0x00000080 +#define TMC5130_LATCH_R_ACTIVE_SHIFT 7 +#define TMC5130_LATCH_R_ACTIVE_FIELD ((RegisterField) {TMC5130_LATCH_R_ACTIVE_MASK, TMC5130_LATCH_R_ACTIVE_SHIFT, TMC5130_SWMODE, false}) +#define TMC5130_LATCH_R_INACTIVE_MASK 0x00000100 +#define TMC5130_LATCH_R_INACTIVE_SHIFT 8 +#define TMC5130_LATCH_R_INACTIVE_FIELD ((RegisterField) {TMC5130_LATCH_R_INACTIVE_MASK, TMC5130_LATCH_R_INACTIVE_SHIFT, TMC5130_SWMODE, false}) +#define TMC5130_EN_LATCH_ENCODER_MASK 0x00000200 +#define TMC5130_EN_LATCH_ENCODER_SHIFT 9 +#define TMC5130_EN_LATCH_ENCODER_FIELD ((RegisterField) {TMC5130_EN_LATCH_ENCODER_MASK, TMC5130_EN_LATCH_ENCODER_SHIFT, TMC5130_SWMODE, false}) +#define TMC5130_SG_STOP_MASK 0x00000400 +#define TMC5130_SG_STOP_SHIFT 10 +#define TMC5130_SG_STOP_FIELD ((RegisterField) {TMC5130_SG_STOP_MASK, TMC5130_SG_STOP_SHIFT, TMC5130_SWMODE, false}) +#define TMC5130_EN_SOFTSTOP_MASK 0x00000800 +#define TMC5130_EN_SOFTSTOP_SHIFT 11 +#define TMC5130_EN_SOFTSTOP_FIELD ((RegisterField) {TMC5130_EN_SOFTSTOP_MASK, TMC5130_EN_SOFTSTOP_SHIFT, TMC5130_SWMODE, false}) +#define TMC5130_STATUS_STOP_L_MASK 0x00000001 +#define TMC5130_STATUS_STOP_L_SHIFT 0 +#define TMC5130_STATUS_STOP_L_FIELD ((RegisterField) {TMC5130_STATUS_STOP_L_MASK, TMC5130_STATUS_STOP_L_SHIFT, TMC5130_RAMPSTAT, false}) +#define TMC5130_STATUS_STOP_R_MASK 0x00000002 +#define TMC5130_STATUS_STOP_R_SHIFT 1 +#define TMC5130_STATUS_STOP_R_FIELD ((RegisterField) {TMC5130_STATUS_STOP_R_MASK, TMC5130_STATUS_STOP_R_SHIFT, TMC5130_RAMPSTAT, false}) +#define TMC5130_STATUS_LATCH_L_MASK 0x00000004 +#define TMC5130_STATUS_LATCH_L_SHIFT 2 +#define TMC5130_STATUS_LATCH_L_FIELD ((RegisterField) {TMC5130_STATUS_LATCH_L_MASK, TMC5130_STATUS_LATCH_L_SHIFT, TMC5130_RAMPSTAT, false}) +#define TMC5130_STATUS_LATCH_R_MASK 0x00000008 +#define TMC5130_STATUS_LATCH_R_SHIFT 3 +#define TMC5130_STATUS_LATCH_R_FIELD ((RegisterField) {TMC5130_STATUS_LATCH_R_MASK, TMC5130_STATUS_LATCH_R_SHIFT, TMC5130_RAMPSTAT, false}) +#define TMC5130_EVENT_STOP_L_MASK 0x00000010 +#define TMC5130_EVENT_STOP_L_SHIFT 4 +#define TMC5130_EVENT_STOP_L_FIELD ((RegisterField) {TMC5130_EVENT_STOP_L_MASK, TMC5130_EVENT_STOP_L_SHIFT, TMC5130_RAMPSTAT, false}) +#define TMC5130_EVENT_STOP_R_MASK 0x00000020 +#define TMC5130_EVENT_STOP_R_SHIFT 5 +#define TMC5130_EVENT_STOP_R_FIELD ((RegisterField) {TMC5130_EVENT_STOP_R_MASK, TMC5130_EVENT_STOP_R_SHIFT, TMC5130_RAMPSTAT, false}) +#define TMC5130_EVENT_STOP_SG_MASK 0x00000040 +#define TMC5130_EVENT_STOP_SG_SHIFT 6 +#define TMC5130_EVENT_STOP_SG_FIELD ((RegisterField) {TMC5130_EVENT_STOP_SG_MASK, TMC5130_EVENT_STOP_SG_SHIFT, TMC5130_RAMPSTAT, false}) +#define TMC5130_EVENT_POS_REACHED_MASK 0x00000080 +#define TMC5130_EVENT_POS_REACHED_SHIFT 7 +#define TMC5130_EVENT_POS_REACHED_FIELD ((RegisterField) {TMC5130_EVENT_POS_REACHED_MASK, TMC5130_EVENT_POS_REACHED_SHIFT, TMC5130_RAMPSTAT, false}) +#define TMC5130_VELOCITY_REACHED_MASK 0x00000100 +#define TMC5130_VELOCITY_REACHED_SHIFT 8 +#define TMC5130_VELOCITY_REACHED_FIELD ((RegisterField) {TMC5130_VELOCITY_REACHED_MASK, TMC5130_VELOCITY_REACHED_SHIFT, TMC5130_RAMPSTAT, false}) +#define TMC5130_POSITION_REACHED_MASK 0x00000200 +#define TMC5130_POSITION_REACHED_SHIFT 9 +#define TMC5130_POSITION_REACHED_FIELD ((RegisterField) {TMC5130_POSITION_REACHED_MASK, TMC5130_POSITION_REACHED_SHIFT, TMC5130_RAMPSTAT, false}) +#define TMC5130_VZERO_MASK 0x00000400 +#define TMC5130_VZERO_SHIFT 10 +#define TMC5130_VZERO_FIELD ((RegisterField) {TMC5130_VZERO_MASK, TMC5130_VZERO_SHIFT, TMC5130_RAMPSTAT, false}) +#define TMC5130_T_ZEROWAIT_ACTIVE_MASK 0x00000800 +#define TMC5130_T_ZEROWAIT_ACTIVE_SHIFT 11 +#define TMC5130_T_ZEROWAIT_ACTIVE_FIELD ((RegisterField) {TMC5130_T_ZEROWAIT_ACTIVE_MASK, TMC5130_T_ZEROWAIT_ACTIVE_SHIFT, TMC5130_RAMPSTAT, false}) +#define TMC5130_SECOND_MOVE_MASK 0x00001000 +#define TMC5130_SECOND_MOVE_SHIFT 12 +#define TMC5130_SECOND_MOVE_FIELD ((RegisterField) {TMC5130_SECOND_MOVE_MASK, TMC5130_SECOND_MOVE_SHIFT, TMC5130_RAMPSTAT, false}) +#define TMC5130_STATUS_SG_MASK 0x00002000 +#define TMC5130_STATUS_SG_SHIFT 13 +#define TMC5130_STATUS_SG_FIELD ((RegisterField) {TMC5130_STATUS_SG_MASK, TMC5130_STATUS_SG_SHIFT, TMC5130_RAMPSTAT, false}) +#define TMC5130_XLATCH_MASK 0xFFFFFFFF +#define TMC5130_XLATCH_SHIFT 0 +#define TMC5130_XLATCH_FIELD ((RegisterField) {TMC5130_XLATCH_MASK, TMC5130_XLATCH_SHIFT, TMC5130_XLATCH, false}) +#define TMC5130_POL_A_MASK 0x00000001 +#define TMC5130_POL_A_SHIFT 0 +#define TMC5130_POL_A_FIELD ((RegisterField) {TMC5130_POL_A_MASK, TMC5130_POL_A_SHIFT, TMC5130_ENCMODE, false}) +#define TMC5130_POL_B_MASK 0x00000002 +#define TMC5130_POL_B_SHIFT 1 +#define TMC5130_POL_B_FIELD ((RegisterField) {TMC5130_POL_B_MASK, TMC5130_POL_B_SHIFT, TMC5130_ENCMODE, false}) +#define TMC5130_POL_N_MASK 0x00000004 +#define TMC5130_POL_N_SHIFT 2 +#define TMC5130_POL_N_FIELD ((RegisterField) {TMC5130_POL_N_MASK, TMC5130_POL_N_SHIFT, TMC5130_ENCMODE, false}) +#define TMC5130_IGNORE_AB_MASK 0x00000008 +#define TMC5130_IGNORE_AB_SHIFT 3 +#define TMC5130_IGNORE_AB_FIELD ((RegisterField) {TMC5130_IGNORE_AB_MASK, TMC5130_IGNORE_AB_SHIFT, TMC5130_ENCMODE, false}) +#define TMC5130_CLR_CONT_MASK 0x00000010 +#define TMC5130_CLR_CONT_SHIFT 4 +#define TMC5130_CLR_CONT_FIELD ((RegisterField) {TMC5130_CLR_CONT_MASK, TMC5130_CLR_CONT_SHIFT, TMC5130_ENCMODE, false}) +#define TMC5130_CLR_ONCE_MASK 0x00000020 +#define TMC5130_CLR_ONCE_SHIFT 5 +#define TMC5130_CLR_ONCE_FIELD ((RegisterField) {TMC5130_CLR_ONCE_MASK, TMC5130_CLR_ONCE_SHIFT, TMC5130_ENCMODE, false}) +#define TMC5130_POS_EDGE_NEG_EDGE_MASK 0x000000C0 +#define TMC5130_POS_EDGE_NEG_EDGE_SHIFT 6 +#define TMC5130_POS_EDGE_NEG_EDGE_FIELD ((RegisterField) {TMC5130_POS_EDGE_NEG_EDGE_MASK, TMC5130_POS_EDGE_NEG_EDGE_SHIFT, TMC5130_ENCMODE, false}) +#define TMC5130_CLR_ENC_X_MASK 0x00000100 +#define TMC5130_CLR_ENC_X_SHIFT 8 +#define TMC5130_CLR_ENC_X_FIELD ((RegisterField) {TMC5130_CLR_ENC_X_MASK, TMC5130_CLR_ENC_X_SHIFT, TMC5130_ENCMODE, false}) +#define TMC5130_LATCH_X_ACT_MASK 0x00000200 +#define TMC5130_LATCH_X_ACT_SHIFT 9 +#define TMC5130_LATCH_X_ACT_FIELD ((RegisterField) {TMC5130_LATCH_X_ACT_MASK, TMC5130_LATCH_X_ACT_SHIFT, TMC5130_ENCMODE, false}) +#define TMC5130_ENC_SEL_DECIMAL_MASK 0x00000400 +#define TMC5130_ENC_SEL_DECIMAL_SHIFT 10 +#define TMC5130_ENC_SEL_DECIMAL_FIELD ((RegisterField) {TMC5130_ENC_SEL_DECIMAL_MASK, TMC5130_ENC_SEL_DECIMAL_SHIFT, TMC5130_ENCMODE, false}) +#define TMC5130_X_ENC_MASK 0xFFFFFFFF +#define TMC5130_X_ENC_SHIFT 0 +#define TMC5130_X_ENC_FIELD ((RegisterField) {TMC5130_X_ENC_MASK, TMC5130_X_ENC_SHIFT, TMC5130_X_ENC, true}) +#define TMC5130_INTEGER_MASK 0xFFFF0000 +#define TMC5130_INTEGER_SHIFT 16 +#define TMC5130_INTEGER_FIELD ((RegisterField) {TMC5130_INTEGER_MASK, TMC5130_INTEGER_SHIFT, TMC5130_ENC_CONST, false}) +#define TMC5130_FRACTIONAL_MASK 0x0000FFFF +#define TMC5130_FRACTIONAL_SHIFT 0 +#define TMC5130_FRACTIONAL_FIELD ((RegisterField) {TMC5130_FRACTIONAL_MASK, TMC5130_FRACTIONAL_SHIFT, TMC5130_ENC_CONST, false}) +#define TMC5130_ENC_STATUS_MASK 0x00000001 +#define TMC5130_ENC_STATUS_SHIFT 0 +#define TMC5130_ENC_STATUS_FIELD ((RegisterField) {TMC5130_ENC_STATUS_MASK, TMC5130_ENC_STATUS_SHIFT, TMC5130_ENC_STATUS, false}) +#define TMC5130_ENC_LATCH_MASK 0xFFFFFFFF +#define TMC5130_ENC_LATCH_SHIFT 0 +#define TMC5130_ENC_LATCH_FIELD ((RegisterField) {TMC5130_ENC_LATCH_MASK, TMC5130_ENC_LATCH_SHIFT, TMC5130_ENC_LATCH, true}) +#define TMC5130_OFS0_MASK 0x00000001 +#define TMC5130_OFS0_SHIFT 0 +#define TMC5130_OFS0_FIELD ((RegisterField) {TMC5130_OFS0_MASK, TMC5130_OFS0_SHIFT, TMC5130_MSLUT[0], false}) +#define TMC5130_OFS1_MASK 0x00000002 +#define TMC5130_OFS1_SHIFT 1 +#define TMC5130_OFS1_FIELD ((RegisterField) {TMC5130_OFS1_MASK, TMC5130_OFS1_SHIFT, TMC5130_MSLUT[0], false}) +#define TMC5130_OFS2_MASK 0x00000004 +#define TMC5130_OFS2_SHIFT 2 +#define TMC5130_OFS2_FIELD ((RegisterField) {TMC5130_OFS2_MASK, TMC5130_OFS2_SHIFT, TMC5130_MSLUT[0], false}) +#define TMC5130_OFS3_MASK 0x00000008 +#define TMC5130_OFS3_SHIFT 3 +#define TMC5130_OFS3_FIELD ((RegisterField) {TMC5130_OFS3_MASK, TMC5130_OFS3_SHIFT, TMC5130_MSLUT[0], false}) +#define TMC5130_OFS4_MASK 0x00000010 +#define TMC5130_OFS4_SHIFT 4 +#define TMC5130_OFS4_FIELD ((RegisterField) {TMC5130_OFS4_MASK, TMC5130_OFS4_SHIFT, TMC5130_MSLUT[0], false}) +#define TMC5130_OFS5_MASK 0x00000020 +#define TMC5130_OFS5_SHIFT 5 +#define TMC5130_OFS5_FIELD ((RegisterField) {TMC5130_OFS5_MASK, TMC5130_OFS5_SHIFT, TMC5130_MSLUT[0], false}) +#define TMC5130_OFS6_MASK 0x00000040 +#define TMC5130_OFS6_SHIFT 6 +#define TMC5130_OFS6_FIELD ((RegisterField) {TMC5130_OFS6_MASK, TMC5130_OFS6_SHIFT, TMC5130_MSLUT[0], false}) +#define TMC5130_OFS7_MASK 0x00000080 +#define TMC5130_OFS7_SHIFT 7 +#define TMC5130_OFS7_FIELD ((RegisterField) {TMC5130_OFS7_MASK, TMC5130_OFS7_SHIFT, TMC5130_MSLUT[0], false}) +#define TMC5130_OFS8_MASK 0x00000100 +#define TMC5130_OFS8_SHIFT 8 +#define TMC5130_OFS8_FIELD ((RegisterField) {TMC5130_OFS8_MASK, TMC5130_OFS8_SHIFT, TMC5130_MSLUT[0], false}) +#define TMC5130_OFS9_MASK 0x00000200 +#define TMC5130_OFS9_SHIFT 9 +#define TMC5130_OFS9_FIELD ((RegisterField) {TMC5130_OFS9_MASK, TMC5130_OFS9_SHIFT, TMC5130_MSLUT[0], false}) +#define TMC5130_OFS10_MASK 0x00000400 +#define TMC5130_OFS10_SHIFT 10 +#define TMC5130_OFS10_FIELD ((RegisterField) {TMC5130_OFS10_MASK, TMC5130_OFS10_SHIFT, TMC5130_MSLUT[0], false}) +#define TMC5130_OFS11_MASK 0x00000800 +#define TMC5130_OFS11_SHIFT 11 +#define TMC5130_OFS11_FIELD ((RegisterField) {TMC5130_OFS11_MASK, TMC5130_OFS11_SHIFT, TMC5130_MSLUT[0], false}) +#define TMC5130_OFS12_MASK 0x00001000 +#define TMC5130_OFS12_SHIFT 12 +#define TMC5130_OFS12_FIELD ((RegisterField) {TMC5130_OFS12_MASK, TMC5130_OFS12_SHIFT, TMC5130_MSLUT[0], false}) +#define TMC5130_OFS13_MASK 0x00002000 +#define TMC5130_OFS13_SHIFT 13 +#define TMC5130_OFS13_FIELD ((RegisterField) {TMC5130_OFS13_MASK, TMC5130_OFS13_SHIFT, TMC5130_MSLUT[0], false}) +#define TMC5130_OFS14_MASK 0x00004000 +#define TMC5130_OFS14_SHIFT 14 +#define TMC5130_OFS14_FIELD ((RegisterField) {TMC5130_OFS14_MASK, TMC5130_OFS14_SHIFT, TMC5130_MSLUT[0], false}) +#define TMC5130_OFS15_MASK 0x00008000 +#define TMC5130_OFS15_SHIFT 15 +#define TMC5130_OFS15_FIELD ((RegisterField) {TMC5130_OFS15_MASK, TMC5130_OFS15_SHIFT, TMC5130_MSLUT[0], false}) +#define TMC5130_OFS16_MASK 0x00010000 +#define TMC5130_OFS16_SHIFT 16 +#define TMC5130_OFS16_FIELD ((RegisterField) {TMC5130_OFS16_MASK, TMC5130_OFS16_SHIFT, TMC5130_MSLUT[0], false}) +#define TMC5130_OFS17_MASK 0x00020000 +#define TMC5130_OFS17_SHIFT 17 +#define TMC5130_OFS17_FIELD ((RegisterField) {TMC5130_OFS17_MASK, TMC5130_OFS17_SHIFT, TMC5130_MSLUT[0], false}) +#define TMC5130_OFS18_MASK 0x00040000 +#define TMC5130_OFS18_SHIFT 18 +#define TMC5130_OFS18_FIELD ((RegisterField) {TMC5130_OFS18_MASK, TMC5130_OFS18_SHIFT, TMC5130_MSLUT[0], false}) +#define TMC5130_OFS19_MASK 0x00080000 +#define TMC5130_OFS19_SHIFT 19 +#define TMC5130_OFS19_FIELD ((RegisterField) {TMC5130_OFS19_MASK, TMC5130_OFS19_SHIFT, TMC5130_MSLUT[0], false}) +#define TMC5130_OFS20_MASK 0x00100000 +#define TMC5130_OFS20_SHIFT 20 +#define TMC5130_OFS20_FIELD ((RegisterField) {TMC5130_OFS20_MASK, TMC5130_OFS20_SHIFT, TMC5130_MSLUT[0], false}) +#define TMC5130_OFS21_MASK 0x00200000 +#define TMC5130_OFS21_SHIFT 21 +#define TMC5130_OFS21_FIELD ((RegisterField) {TMC5130_OFS21_MASK, TMC5130_OFS21_SHIFT, TMC5130_MSLUT[0], false}) +#define TMC5130_OFS22_MASK 0x00400000 +#define TMC5130_OFS22_SHIFT 22 +#define TMC5130_OFS22_FIELD ((RegisterField) {TMC5130_OFS22_MASK, TMC5130_OFS22_SHIFT, TMC5130_MSLUT[0], false}) +#define TMC5130_OFS23_MASK 0x00800000 +#define TMC5130_OFS23_SHIFT 23 +#define TMC5130_OFS23_FIELD ((RegisterField) {TMC5130_OFS23_MASK, TMC5130_OFS23_SHIFT, TMC5130_MSLUT[0], false}) +#define TMC5130_OFS24_MASK 0x01000000 +#define TMC5130_OFS24_SHIFT 24 +#define TMC5130_OFS24_FIELD ((RegisterField) {TMC5130_OFS24_MASK, TMC5130_OFS24_SHIFT, TMC5130_MSLUT[0], false}) +#define TMC5130_OFS25_MASK 0x02000000 +#define TMC5130_OFS25_SHIFT 25 +#define TMC5130_OFS25_FIELD ((RegisterField) {TMC5130_OFS25_MASK, TMC5130_OFS25_SHIFT, TMC5130_MSLUT[0], false}) +#define TMC5130_OFS26_MASK 0x04000000 +#define TMC5130_OFS26_SHIFT 26 +#define TMC5130_OFS26_FIELD ((RegisterField) {TMC5130_OFS26_MASK, TMC5130_OFS26_SHIFT, TMC5130_MSLUT[0], false}) +#define TMC5130_OFS27_MASK 0x08000000 +#define TMC5130_OFS27_SHIFT 27 +#define TMC5130_OFS27_FIELD ((RegisterField) {TMC5130_OFS27_MASK, TMC5130_OFS27_SHIFT, TMC5130_MSLUT[0], false}) +#define TMC5130_OFS28_MASK 0x10000000 +#define TMC5130_OFS28_SHIFT 28 +#define TMC5130_OFS28_FIELD ((RegisterField) {TMC5130_OFS28_MASK, TMC5130_OFS28_SHIFT, TMC5130_MSLUT[0], false}) +#define TMC5130_OFS29_MASK 0x20000000 +#define TMC5130_OFS29_SHIFT 29 +#define TMC5130_OFS29_FIELD ((RegisterField) {TMC5130_OFS29_MASK, TMC5130_OFS29_SHIFT, TMC5130_MSLUT[0], false}) +#define TMC5130_OFS30_MASK 0x40000000 +#define TMC5130_OFS30_SHIFT 30 +#define TMC5130_OFS30_FIELD ((RegisterField) {TMC5130_OFS30_MASK, TMC5130_OFS30_SHIFT, TMC5130_MSLUT[0], false}) +#define TMC5130_OFS31_MASK 0x80000000 +#define TMC5130_OFS31_SHIFT 31 +#define TMC5130_OFS31_FIELD ((RegisterField) {TMC5130_OFS31_MASK, TMC5130_OFS31_SHIFT, TMC5130_MSLUT[0], false}) +#define TMC5130_OFS32_MASK 0x00000001 +#define TMC5130_OFS32_SHIFT 0 +#define TMC5130_OFS32_FIELD ((RegisterField) {TMC5130_OFS32_MASK, TMC5130_OFS32_SHIFT, TMC5130_MSLUT[1], false}) +#define TMC5130_OFS33_MASK 0x00000002 +#define TMC5130_OFS33_SHIFT 1 +#define TMC5130_OFS33_FIELD ((RegisterField) {TMC5130_OFS33_MASK, TMC5130_OFS33_SHIFT, TMC5130_MSLUT[1], false}) +#define TMC5130_OFS34_MASK 0x00000004 +#define TMC5130_OFS34_SHIFT 2 +#define TMC5130_OFS34_FIELD ((RegisterField) {TMC5130_OFS34_MASK, TMC5130_OFS34_SHIFT, TMC5130_MSLUT[1], false}) +#define TMC5130_OFS35_MASK 0x00000008 +#define TMC5130_OFS35_SHIFT 3 +#define TMC5130_OFS35_FIELD ((RegisterField) {TMC5130_OFS35_MASK, TMC5130_OFS35_SHIFT, TMC5130_MSLUT[1], false}) +#define TMC5130_OFS36_MASK 0x00000010 +#define TMC5130_OFS36_SHIFT 4 +#define TMC5130_OFS36_FIELD ((RegisterField) {TMC5130_OFS36_MASK, TMC5130_OFS36_SHIFT, TMC5130_MSLUT[1], false}) +#define TMC5130_OFS37_MASK 0x00000020 +#define TMC5130_OFS37_SHIFT 5 +#define TMC5130_OFS37_FIELD ((RegisterField) {TMC5130_OFS37_MASK, TMC5130_OFS37_SHIFT, TMC5130_MSLUT[1], false}) +#define TMC5130_OFS38_MASK 0x00000040 +#define TMC5130_OFS38_SHIFT 6 +#define TMC5130_OFS38_FIELD ((RegisterField) {TMC5130_OFS38_MASK, TMC5130_OFS38_SHIFT, TMC5130_MSLUT[1], false}) +#define TMC5130_OFS39_MASK 0x00000080 +#define TMC5130_OFS39_SHIFT 7 +#define TMC5130_OFS39_FIELD ((RegisterField) {TMC5130_OFS39_MASK, TMC5130_OFS39_SHIFT, TMC5130_MSLUT[1], false}) +#define TMC5130_OFS40_MASK 0x00000100 +#define TMC5130_OFS40_SHIFT 8 +#define TMC5130_OFS40_FIELD ((RegisterField) {TMC5130_OFS40_MASK, TMC5130_OFS40_SHIFT, TMC5130_MSLUT[1], false}) +#define TMC5130_OFS41_MASK 0x00000200 +#define TMC5130_OFS41_SHIFT 9 +#define TMC5130_OFS41_FIELD ((RegisterField) {TMC5130_OFS41_MASK, TMC5130_OFS41_SHIFT, TMC5130_MSLUT[1], false}) +#define TMC5130_OFS42_MASK 0x00000400 +#define TMC5130_OFS42_SHIFT 10 +#define TMC5130_OFS42_FIELD ((RegisterField) {TMC5130_OFS42_MASK, TMC5130_OFS42_SHIFT, TMC5130_MSLUT[1], false}) +#define TMC5130_OFS43_MASK 0x00000800 +#define TMC5130_OFS43_SHIFT 11 +#define TMC5130_OFS43_FIELD ((RegisterField) {TMC5130_OFS43_MASK, TMC5130_OFS43_SHIFT, TMC5130_MSLUT[1], false}) +#define TMC5130_OFS44_MASK 0x00001000 +#define TMC5130_OFS44_SHIFT 12 +#define TMC5130_OFS44_FIELD ((RegisterField) {TMC5130_OFS44_MASK, TMC5130_OFS44_SHIFT, TMC5130_MSLUT[1], false}) +#define TMC5130_OFS45_MASK 0x00002000 +#define TMC5130_OFS45_SHIFT 13 +#define TMC5130_OFS45_FIELD ((RegisterField) {TMC5130_OFS45_MASK, TMC5130_OFS45_SHIFT, TMC5130_MSLUT[1], false}) +#define TMC5130_OFS46_MASK 0x00004000 +#define TMC5130_OFS46_SHIFT 14 +#define TMC5130_OFS46_FIELD ((RegisterField) {TMC5130_OFS46_MASK, TMC5130_OFS46_SHIFT, TMC5130_MSLUT[1], false}) +#define TMC5130_OFS47_MASK 0x00008000 +#define TMC5130_OFS47_SHIFT 15 +#define TMC5130_OFS47_FIELD ((RegisterField) {TMC5130_OFS47_MASK, TMC5130_OFS47_SHIFT, TMC5130_MSLUT[1], false}) +#define TMC5130_OFS48_MASK 0x00010000 +#define TMC5130_OFS48_SHIFT 16 +#define TMC5130_OFS48_FIELD ((RegisterField) {TMC5130_OFS48_MASK, TMC5130_OFS48_SHIFT, TMC5130_MSLUT[1], false}) +#define TMC5130_OFS49_MASK 0x00020000 +#define TMC5130_OFS49_SHIFT 17 +#define TMC5130_OFS49_FIELD ((RegisterField) {TMC5130_OFS49_MASK, TMC5130_OFS49_SHIFT, TMC5130_MSLUT[1], false}) +#define TMC5130_OFS50_MASK 0x00040000 +#define TMC5130_OFS50_SHIFT 18 +#define TMC5130_OFS50_FIELD ((RegisterField) {TMC5130_OFS50_MASK, TMC5130_OFS50_SHIFT, TMC5130_MSLUT[1], false}) +#define TMC5130_OFS51_MASK 0x00080000 +#define TMC5130_OFS51_SHIFT 19 +#define TMC5130_OFS51_FIELD ((RegisterField) {TMC5130_OFS51_MASK, TMC5130_OFS51_SHIFT, TMC5130_MSLUT[1], false}) +#define TMC5130_OFS52_MASK 0x00100000 +#define TMC5130_OFS52_SHIFT 20 +#define TMC5130_OFS52_FIELD ((RegisterField) {TMC5130_OFS52_MASK, TMC5130_OFS52_SHIFT, TMC5130_MSLUT[1], false}) +#define TMC5130_OFS53_MASK 0x00200000 +#define TMC5130_OFS53_SHIFT 21 +#define TMC5130_OFS53_FIELD ((RegisterField) {TMC5130_OFS53_MASK, TMC5130_OFS53_SHIFT, TMC5130_MSLUT[1], false}) +#define TMC5130_OFS54_MASK 0x00400000 +#define TMC5130_OFS54_SHIFT 22 +#define TMC5130_OFS54_FIELD ((RegisterField) {TMC5130_OFS54_MASK, TMC5130_OFS54_SHIFT, TMC5130_MSLUT[1], false}) +#define TMC5130_OFS55_MASK 0x00800000 +#define TMC5130_OFS55_SHIFT 23 +#define TMC5130_OFS55_FIELD ((RegisterField) {TMC5130_OFS55_MASK, TMC5130_OFS55_SHIFT, TMC5130_MSLUT[1], false}) +#define TMC5130_OFS56_MASK 0x01000000 +#define TMC5130_OFS56_SHIFT 24 +#define TMC5130_OFS56_FIELD ((RegisterField) {TMC5130_OFS56_MASK, TMC5130_OFS56_SHIFT, TMC5130_MSLUT[1], false}) +#define TMC5130_OFS57_MASK 0x02000000 +#define TMC5130_OFS57_SHIFT 25 +#define TMC5130_OFS57_FIELD ((RegisterField) {TMC5130_OFS57_MASK, TMC5130_OFS57_SHIFT, TMC5130_MSLUT[1], false}) +#define TMC5130_OFS58_MASK 0x04000000 +#define TMC5130_OFS58_SHIFT 26 +#define TMC5130_OFS58_FIELD ((RegisterField) {TMC5130_OFS58_MASK, TMC5130_OFS58_SHIFT, TMC5130_MSLUT[1], false}) +#define TMC5130_OFS59_MASK 0x08000000 +#define TMC5130_OFS59_SHIFT 27 +#define TMC5130_OFS59_FIELD ((RegisterField) {TMC5130_OFS59_MASK, TMC5130_OFS59_SHIFT, TMC5130_MSLUT[1], false}) +#define TMC5130_OFS60_MASK 0x10000000 +#define TMC5130_OFS60_SHIFT 28 +#define TMC5130_OFS60_FIELD ((RegisterField) {TMC5130_OFS60_MASK, TMC5130_OFS60_SHIFT, TMC5130_MSLUT[1], false}) +#define TMC5130_OFS61_MASK 0x20000000 +#define TMC5130_OFS61_SHIFT 29 +#define TMC5130_OFS61_FIELD ((RegisterField) {TMC5130_OFS61_MASK, TMC5130_OFS61_SHIFT, TMC5130_MSLUT[1], false}) +#define TMC5130_OFS62_MASK 0x40000000 +#define TMC5130_OFS62_SHIFT 30 +#define TMC5130_OFS62_FIELD ((RegisterField) {TMC5130_OFS62_MASK, TMC5130_OFS62_SHIFT, TMC5130_MSLUT[1], false}) +#define TMC5130_OFS63_MASK 0x80000000 +#define TMC5130_OFS63_SHIFT 31 +#define TMC5130_OFS63_FIELD ((RegisterField) {TMC5130_OFS63_MASK, TMC5130_OFS63_SHIFT, TMC5130_MSLUT[1], false}) +#define TMC5130_OFS64_MASK 0x00000001 +#define TMC5130_OFS64_SHIFT 0 +#define TMC5130_OFS64_FIELD ((RegisterField) {TMC5130_OFS64_MASK, TMC5130_OFS64_SHIFT, TMC5130_MSLUT[2], false}) +#define TMC5130_OFS65_MASK 0x00000002 +#define TMC5130_OFS65_SHIFT 1 +#define TMC5130_OFS65_FIELD ((RegisterField) {TMC5130_OFS65_MASK, TMC5130_OFS65_SHIFT, TMC5130_MSLUT[2], false}) +#define TMC5130_OFS66_MASK 0x00000004 +#define TMC5130_OFS66_SHIFT 2 +#define TMC5130_OFS66_FIELD ((RegisterField) {TMC5130_OFS66_MASK, TMC5130_OFS66_SHIFT, TMC5130_MSLUT[2], false}) +#define TMC5130_OFS67_MASK 0x00000008 +#define TMC5130_OFS67_SHIFT 3 +#define TMC5130_OFS67_FIELD ((RegisterField) {TMC5130_OFS67_MASK, TMC5130_OFS67_SHIFT, TMC5130_MSLUT[2], false}) +#define TMC5130_OFS68_MASK 0x00000010 +#define TMC5130_OFS68_SHIFT 4 +#define TMC5130_OFS68_FIELD ((RegisterField) {TMC5130_OFS68_MASK, TMC5130_OFS68_SHIFT, TMC5130_MSLUT[2], false}) +#define TMC5130_OFS69_MASK 0x00000020 +#define TMC5130_OFS69_SHIFT 5 +#define TMC5130_OFS69_FIELD ((RegisterField) {TMC5130_OFS69_MASK, TMC5130_OFS69_SHIFT, TMC5130_MSLUT[2], false}) +#define TMC5130_OFS70_MASK 0x00000040 +#define TMC5130_OFS70_SHIFT 6 +#define TMC5130_OFS70_FIELD ((RegisterField) {TMC5130_OFS70_MASK, TMC5130_OFS70_SHIFT, TMC5130_MSLUT[2], false}) +#define TMC5130_OFS71_MASK 0x00000080 +#define TMC5130_OFS71_SHIFT 7 +#define TMC5130_OFS71_FIELD ((RegisterField) {TMC5130_OFS71_MASK, TMC5130_OFS71_SHIFT, TMC5130_MSLUT[2], false}) +#define TMC5130_OFS72_MASK 0x00000100 +#define TMC5130_OFS72_SHIFT 8 +#define TMC5130_OFS72_FIELD ((RegisterField) {TMC5130_OFS72_MASK, TMC5130_OFS72_SHIFT, TMC5130_MSLUT[2], false}) +#define TMC5130_OFS73_MASK 0x00000200 +#define TMC5130_OFS73_SHIFT 9 +#define TMC5130_OFS73_FIELD ((RegisterField) {TMC5130_OFS73_MASK, TMC5130_OFS73_SHIFT, TMC5130_MSLUT[2], false}) +#define TMC5130_OFS74_MASK 0x00000400 +#define TMC5130_OFS74_SHIFT 10 +#define TMC5130_OFS74_FIELD ((RegisterField) {TMC5130_OFS74_MASK, TMC5130_OFS74_SHIFT, TMC5130_MSLUT[2], false}) +#define TMC5130_OFS75_MASK 0x00000800 +#define TMC5130_OFS75_SHIFT 11 +#define TMC5130_OFS75_FIELD ((RegisterField) {TMC5130_OFS75_MASK, TMC5130_OFS75_SHIFT, TMC5130_MSLUT[2], false}) +#define TMC5130_OFS76_MASK 0x00001000 +#define TMC5130_OFS76_SHIFT 12 +#define TMC5130_OFS76_FIELD ((RegisterField) {TMC5130_OFS76_MASK, TMC5130_OFS76_SHIFT, TMC5130_MSLUT[2], false}) +#define TMC5130_OFS77_MASK 0x00002000 +#define TMC5130_OFS77_SHIFT 13 +#define TMC5130_OFS77_FIELD ((RegisterField) {TMC5130_OFS77_MASK, TMC5130_OFS77_SHIFT, TMC5130_MSLUT[2], false}) +#define TMC5130_OFS78_MASK 0x00004000 +#define TMC5130_OFS78_SHIFT 14 +#define TMC5130_OFS78_FIELD ((RegisterField) {TMC5130_OFS78_MASK, TMC5130_OFS78_SHIFT, TMC5130_MSLUT[2], false}) +#define TMC5130_OFS79_MASK 0x00008000 +#define TMC5130_OFS79_SHIFT 15 +#define TMC5130_OFS79_FIELD ((RegisterField) {TMC5130_OFS79_MASK, TMC5130_OFS79_SHIFT, TMC5130_MSLUT[2], false}) +#define TMC5130_OFS80_MASK 0x00010000 +#define TMC5130_OFS80_SHIFT 16 +#define TMC5130_OFS80_FIELD ((RegisterField) {TMC5130_OFS80_MASK, TMC5130_OFS80_SHIFT, TMC5130_MSLUT[2], false}) +#define TMC5130_OFS81_MASK 0x00020000 +#define TMC5130_OFS81_SHIFT 17 +#define TMC5130_OFS81_FIELD ((RegisterField) {TMC5130_OFS81_MASK, TMC5130_OFS81_SHIFT, TMC5130_MSLUT[2], false}) +#define TMC5130_OFS82_MASK 0x00040000 +#define TMC5130_OFS82_SHIFT 18 +#define TMC5130_OFS82_FIELD ((RegisterField) {TMC5130_OFS82_MASK, TMC5130_OFS82_SHIFT, TMC5130_MSLUT[2], false}) +#define TMC5130_OFS83_MASK 0x00080000 +#define TMC5130_OFS83_SHIFT 19 +#define TMC5130_OFS83_FIELD ((RegisterField) {TMC5130_OFS83_MASK, TMC5130_OFS83_SHIFT, TMC5130_MSLUT[2], false}) +#define TMC5130_OFS84_MASK 0x00100000 +#define TMC5130_OFS84_SHIFT 20 +#define TMC5130_OFS84_FIELD ((RegisterField) {TMC5130_OFS84_MASK, TMC5130_OFS84_SHIFT, TMC5130_MSLUT[2], false}) +#define TMC5130_OFS85_MASK 0x00200000 +#define TMC5130_OFS85_SHIFT 21 +#define TMC5130_OFS85_FIELD ((RegisterField) {TMC5130_OFS85_MASK, TMC5130_OFS85_SHIFT, TMC5130_MSLUT[2], false}) +#define TMC5130_OFS86_MASK 0x00400000 +#define TMC5130_OFS86_SHIFT 22 +#define TMC5130_OFS86_FIELD ((RegisterField) {TMC5130_OFS86_MASK, TMC5130_OFS86_SHIFT, TMC5130_MSLUT[2], false}) +#define TMC5130_OFS87_MASK 0x00800000 +#define TMC5130_OFS87_SHIFT 23 +#define TMC5130_OFS87_FIELD ((RegisterField) {TMC5130_OFS87_MASK, TMC5130_OFS87_SHIFT, TMC5130_MSLUT[2], false}) +#define TMC5130_OFS88_MASK 0x01000000 +#define TMC5130_OFS88_SHIFT 24 +#define TMC5130_OFS88_FIELD ((RegisterField) {TMC5130_OFS88_MASK, TMC5130_OFS88_SHIFT, TMC5130_MSLUT[2], false}) +#define TMC5130_OFS89_MASK 0x02000000 +#define TMC5130_OFS89_SHIFT 25 +#define TMC5130_OFS89_FIELD ((RegisterField) {TMC5130_OFS89_MASK, TMC5130_OFS89_SHIFT, TMC5130_MSLUT[2], false}) +#define TMC5130_OFS90_MASK 0x04000000 +#define TMC5130_OFS90_SHIFT 26 +#define TMC5130_OFS90_FIELD ((RegisterField) {TMC5130_OFS90_MASK, TMC5130_OFS90_SHIFT, TMC5130_MSLUT[2], false}) +#define TMC5130_OFS91_MASK 0x08000000 +#define TMC5130_OFS91_SHIFT 27 +#define TMC5130_OFS91_FIELD ((RegisterField) {TMC5130_OFS91_MASK, TMC5130_OFS91_SHIFT, TMC5130_MSLUT[2], false}) +#define TMC5130_OFS92_MASK 0x10000000 +#define TMC5130_OFS92_SHIFT 28 +#define TMC5130_OFS92_FIELD ((RegisterField) {TMC5130_OFS92_MASK, TMC5130_OFS92_SHIFT, TMC5130_MSLUT[2], false}) +#define TMC5130_OFS93_MASK 0x20000000 +#define TMC5130_OFS93_SHIFT 29 +#define TMC5130_OFS93_FIELD ((RegisterField) {TMC5130_OFS93_MASK, TMC5130_OFS93_SHIFT, TMC5130_MSLUT[2], false}) +#define TMC5130_OFS94_MASK 0x40000000 +#define TMC5130_OFS94_SHIFT 30 +#define TMC5130_OFS94_FIELD ((RegisterField) {TMC5130_OFS94_MASK, TMC5130_OFS94_SHIFT, TMC5130_MSLUT[2], false}) +#define TMC5130_OFS95_MASK 0x80000000 +#define TMC5130_OFS95_SHIFT 31 +#define TMC5130_OFS95_FIELD ((RegisterField) {TMC5130_OFS95_MASK, TMC5130_OFS95_SHIFT, TMC5130_MSLUT[2], false}) +#define TMC5130_OFS96_MASK 0x00000001 +#define TMC5130_OFS96_SHIFT 0 +#define TMC5130_OFS96_FIELD ((RegisterField) {TMC5130_OFS96_MASK, TMC5130_OFS96_SHIFT, TMC5130_MSLUT[3], false}) +#define TMC5130_OFS97_MASK 0x00000002 +#define TMC5130_OFS97_SHIFT 1 +#define TMC5130_OFS97_FIELD ((RegisterField) {TMC5130_OFS97_MASK, TMC5130_OFS97_SHIFT, TMC5130_MSLUT[3], false}) +#define TMC5130_OFS98_MASK 0x00000004 +#define TMC5130_OFS98_SHIFT 2 +#define TMC5130_OFS98_FIELD ((RegisterField) {TMC5130_OFS98_MASK, TMC5130_OFS98_SHIFT, TMC5130_MSLUT[3], false}) +#define TMC5130_OFS99_MASK 0x00000008 +#define TMC5130_OFS99_SHIFT 3 +#define TMC5130_OFS99_FIELD ((RegisterField) {TMC5130_OFS99_MASK, TMC5130_OFS99_SHIFT, TMC5130_MSLUT[3], false}) +#define TMC5130_OFS100_MASK 0x00000010 +#define TMC5130_OFS100_SHIFT 4 +#define TMC5130_OFS100_FIELD ((RegisterField) {TMC5130_OFS100_MASK, TMC5130_OFS100_SHIFT, TMC5130_MSLUT[3], false}) +#define TMC5130_OFS101_MASK 0x00000020 +#define TMC5130_OFS101_SHIFT 5 +#define TMC5130_OFS101_FIELD ((RegisterField) {TMC5130_OFS101_MASK, TMC5130_OFS101_SHIFT, TMC5130_MSLUT[3], false}) +#define TMC5130_OFS102_MASK 0x00000040 +#define TMC5130_OFS102_SHIFT 6 +#define TMC5130_OFS102_FIELD ((RegisterField) {TMC5130_OFS102_MASK, TMC5130_OFS102_SHIFT, TMC5130_MSLUT[3], false}) +#define TMC5130_OFS103_MASK 0x00000080 +#define TMC5130_OFS103_SHIFT 7 +#define TMC5130_OFS103_FIELD ((RegisterField) {TMC5130_OFS103_MASK, TMC5130_OFS103_SHIFT, TMC5130_MSLUT[3], false}) +#define TMC5130_OFS104_MASK 0x00000100 +#define TMC5130_OFS104_SHIFT 8 +#define TMC5130_OFS104_FIELD ((RegisterField) {TMC5130_OFS104_MASK, TMC5130_OFS104_SHIFT, TMC5130_MSLUT[3], false}) +#define TMC5130_OFS105_MASK 0x00000200 +#define TMC5130_OFS105_SHIFT 9 +#define TMC5130_OFS105_FIELD ((RegisterField) {TMC5130_OFS105_MASK, TMC5130_OFS105_SHIFT, TMC5130_MSLUT[3], false}) +#define TMC5130_OFS106_MASK 0x00000400 +#define TMC5130_OFS106_SHIFT 10 +#define TMC5130_OFS106_FIELD ((RegisterField) {TMC5130_OFS106_MASK, TMC5130_OFS106_SHIFT, TMC5130_MSLUT[3], false}) +#define TMC5130_OFS107_MASK 0x00000800 +#define TMC5130_OFS107_SHIFT 11 +#define TMC5130_OFS107_FIELD ((RegisterField) {TMC5130_OFS107_MASK, TMC5130_OFS107_SHIFT, TMC5130_MSLUT[3], false}) +#define TMC5130_OFS108_MASK 0x00001000 +#define TMC5130_OFS108_SHIFT 12 +#define TMC5130_OFS108_FIELD ((RegisterField) {TMC5130_OFS108_MASK, TMC5130_OFS108_SHIFT, TMC5130_MSLUT[3], false}) +#define TMC5130_OFS109_MASK 0x00002000 +#define TMC5130_OFS109_SHIFT 13 +#define TMC5130_OFS109_FIELD ((RegisterField) {TMC5130_OFS109_MASK, TMC5130_OFS109_SHIFT, TMC5130_MSLUT[3], false}) +#define TMC5130_OFS110_MASK 0x00004000 +#define TMC5130_OFS110_SHIFT 14 +#define TMC5130_OFS110_FIELD ((RegisterField) {TMC5130_OFS110_MASK, TMC5130_OFS110_SHIFT, TMC5130_MSLUT[3], false}) +#define TMC5130_OFS111_MASK 0x00008000 +#define TMC5130_OFS111_SHIFT 15 +#define TMC5130_OFS111_FIELD ((RegisterField) {TMC5130_OFS111_MASK, TMC5130_OFS111_SHIFT, TMC5130_MSLUT[3], false}) +#define TMC5130_OFS112_MASK 0x00010000 +#define TMC5130_OFS112_SHIFT 16 +#define TMC5130_OFS112_FIELD ((RegisterField) {TMC5130_OFS112_MASK, TMC5130_OFS112_SHIFT, TMC5130_MSLUT[3], false}) +#define TMC5130_OFS113_MASK 0x00020000 +#define TMC5130_OFS113_SHIFT 17 +#define TMC5130_OFS113_FIELD ((RegisterField) {TMC5130_OFS113_MASK, TMC5130_OFS113_SHIFT, TMC5130_MSLUT[3], false}) +#define TMC5130_OFS114_MASK 0x00040000 +#define TMC5130_OFS114_SHIFT 18 +#define TMC5130_OFS114_FIELD ((RegisterField) {TMC5130_OFS114_MASK, TMC5130_OFS114_SHIFT, TMC5130_MSLUT[3], false}) +#define TMC5130_OFS115_MASK 0x00080000 +#define TMC5130_OFS115_SHIFT 19 +#define TMC5130_OFS115_FIELD ((RegisterField) {TMC5130_OFS115_MASK, TMC5130_OFS115_SHIFT, TMC5130_MSLUT[3], false}) +#define TMC5130_OFS116_MASK 0x00100000 +#define TMC5130_OFS116_SHIFT 20 +#define TMC5130_OFS116_FIELD ((RegisterField) {TMC5130_OFS116_MASK, TMC5130_OFS116_SHIFT, TMC5130_MSLUT[3], false}) +#define TMC5130_OFS117_MASK 0x00200000 +#define TMC5130_OFS117_SHIFT 21 +#define TMC5130_OFS117_FIELD ((RegisterField) {TMC5130_OFS117_MASK, TMC5130_OFS117_SHIFT, TMC5130_MSLUT[3], false}) +#define TMC5130_OFS118_MASK 0x00400000 +#define TMC5130_OFS118_SHIFT 22 +#define TMC5130_OFS118_FIELD ((RegisterField) {TMC5130_OFS118_MASK, TMC5130_OFS118_SHIFT, TMC5130_MSLUT[3], false}) +#define TMC5130_OFS119_MASK 0x00800000 +#define TMC5130_OFS119_SHIFT 23 +#define TMC5130_OFS119_FIELD ((RegisterField) {TMC5130_OFS119_MASK, TMC5130_OFS119_SHIFT, TMC5130_MSLUT[3], false}) +#define TMC5130_OFS120_MASK 0x01000000 +#define TMC5130_OFS120_SHIFT 24 +#define TMC5130_OFS120_FIELD ((RegisterField) {TMC5130_OFS120_MASK, TMC5130_OFS120_SHIFT, TMC5130_MSLUT[3], false}) +#define TMC5130_OFS121_MASK 0x02000000 +#define TMC5130_OFS121_SHIFT 25 +#define TMC5130_OFS121_FIELD ((RegisterField) {TMC5130_OFS121_MASK, TMC5130_OFS121_SHIFT, TMC5130_MSLUT[3], false}) +#define TMC5130_OFS122_MASK 0x04000000 +#define TMC5130_OFS122_SHIFT 26 +#define TMC5130_OFS122_FIELD ((RegisterField) {TMC5130_OFS122_MASK, TMC5130_OFS122_SHIFT, TMC5130_MSLUT[3], false}) +#define TMC5130_OFS123_MASK 0x08000000 +#define TMC5130_OFS123_SHIFT 27 +#define TMC5130_OFS123_FIELD ((RegisterField) {TMC5130_OFS123_MASK, TMC5130_OFS123_SHIFT, TMC5130_MSLUT[3], false}) +#define TMC5130_OFS124_MASK 0x10000000 +#define TMC5130_OFS124_SHIFT 28 +#define TMC5130_OFS124_FIELD ((RegisterField) {TMC5130_OFS124_MASK, TMC5130_OFS124_SHIFT, TMC5130_MSLUT[3], false}) +#define TMC5130_OFS125_MASK 0x20000000 +#define TMC5130_OFS125_SHIFT 29 +#define TMC5130_OFS125_FIELD ((RegisterField) {TMC5130_OFS125_MASK, TMC5130_OFS125_SHIFT, TMC5130_MSLUT[3], false}) +#define TMC5130_OFS126_MASK 0x40000000 +#define TMC5130_OFS126_SHIFT 30 +#define TMC5130_OFS126_FIELD ((RegisterField) {TMC5130_OFS126_MASK, TMC5130_OFS126_SHIFT, TMC5130_MSLUT[3], false}) +#define TMC5130_OFS127_MASK 0x80000000 +#define TMC5130_OFS127_SHIFT 31 +#define TMC5130_OFS127_FIELD ((RegisterField) {TMC5130_OFS127_MASK, TMC5130_OFS127_SHIFT, TMC5130_MSLUT[3], false}) +#define TMC5130_OFS128_MASK 0x00000001 +#define TMC5130_OFS128_SHIFT 0 +#define TMC5130_OFS128_FIELD ((RegisterField) {TMC5130_OFS128_MASK, TMC5130_OFS128_SHIFT, TMC5130_MSLUT[4], false}) +#define TMC5130_OFS129_MASK 0x00000002 +#define TMC5130_OFS129_SHIFT 1 +#define TMC5130_OFS129_FIELD ((RegisterField) {TMC5130_OFS129_MASK, TMC5130_OFS129_SHIFT, TMC5130_MSLUT[4], false}) +#define TMC5130_OFS130_MASK 0x00000004 +#define TMC5130_OFS130_SHIFT 2 +#define TMC5130_OFS130_FIELD ((RegisterField) {TMC5130_OFS130_MASK, TMC5130_OFS130_SHIFT, TMC5130_MSLUT[4], false}) +#define TMC5130_OFS131_MASK 0x00000008 +#define TMC5130_OFS131_SHIFT 3 +#define TMC5130_OFS131_FIELD ((RegisterField) {TMC5130_OFS131_MASK, TMC5130_OFS131_SHIFT, TMC5130_MSLUT[4], false}) +#define TMC5130_OFS132_MASK 0x00000010 +#define TMC5130_OFS132_SHIFT 4 +#define TMC5130_OFS132_FIELD ((RegisterField) {TMC5130_OFS132_MASK, TMC5130_OFS132_SHIFT, TMC5130_MSLUT[4], false}) +#define TMC5130_OFS133_MASK 0x00000020 +#define TMC5130_OFS133_SHIFT 5 +#define TMC5130_OFS133_FIELD ((RegisterField) {TMC5130_OFS133_MASK, TMC5130_OFS133_SHIFT, TMC5130_MSLUT[4], false}) +#define TMC5130_OFS134_MASK 0x00000040 +#define TMC5130_OFS134_SHIFT 6 +#define TMC5130_OFS134_FIELD ((RegisterField) {TMC5130_OFS134_MASK, TMC5130_OFS134_SHIFT, TMC5130_MSLUT[4], false}) +#define TMC5130_OFS135_MASK 0x00000080 +#define TMC5130_OFS135_SHIFT 7 +#define TMC5130_OFS135_FIELD ((RegisterField) {TMC5130_OFS135_MASK, TMC5130_OFS135_SHIFT, TMC5130_MSLUT[4], false}) +#define TMC5130_OFS136_MASK 0x00000100 +#define TMC5130_OFS136_SHIFT 8 +#define TMC5130_OFS136_FIELD ((RegisterField) {TMC5130_OFS136_MASK, TMC5130_OFS136_SHIFT, TMC5130_MSLUT[4], false}) +#define TMC5130_OFS137_MASK 0x00000200 +#define TMC5130_OFS137_SHIFT 9 +#define TMC5130_OFS137_FIELD ((RegisterField) {TMC5130_OFS137_MASK, TMC5130_OFS137_SHIFT, TMC5130_MSLUT[4], false}) +#define TMC5130_OFS138_MASK 0x00000400 +#define TMC5130_OFS138_SHIFT 10 +#define TMC5130_OFS138_FIELD ((RegisterField) {TMC5130_OFS138_MASK, TMC5130_OFS138_SHIFT, TMC5130_MSLUT[4], false}) +#define TMC5130_OFS139_MASK 0x00000800 +#define TMC5130_OFS139_SHIFT 11 +#define TMC5130_OFS139_FIELD ((RegisterField) {TMC5130_OFS139_MASK, TMC5130_OFS139_SHIFT, TMC5130_MSLUT[4], false}) +#define TMC5130_OFS140_MASK 0x00001000 +#define TMC5130_OFS140_SHIFT 12 +#define TMC5130_OFS140_FIELD ((RegisterField) {TMC5130_OFS140_MASK, TMC5130_OFS140_SHIFT, TMC5130_MSLUT[4], false}) +#define TMC5130_OFS141_MASK 0x00002000 +#define TMC5130_OFS141_SHIFT 13 +#define TMC5130_OFS141_FIELD ((RegisterField) {TMC5130_OFS141_MASK, TMC5130_OFS141_SHIFT, TMC5130_MSLUT[4], false}) +#define TMC5130_OFS142_MASK 0x00004000 +#define TMC5130_OFS142_SHIFT 14 +#define TMC5130_OFS142_FIELD ((RegisterField) {TMC5130_OFS142_MASK, TMC5130_OFS142_SHIFT, TMC5130_MSLUT[4], false}) +#define TMC5130_OFS143_MASK 0x00008000 +#define TMC5130_OFS143_SHIFT 15 +#define TMC5130_OFS143_FIELD ((RegisterField) {TMC5130_OFS143_MASK, TMC5130_OFS143_SHIFT, TMC5130_MSLUT[4], false}) +#define TMC5130_OFS144_MASK 0x00010000 +#define TMC5130_OFS144_SHIFT 16 +#define TMC5130_OFS144_FIELD ((RegisterField) {TMC5130_OFS144_MASK, TMC5130_OFS144_SHIFT, TMC5130_MSLUT[4], false}) +#define TMC5130_OFS145_MASK 0x00020000 +#define TMC5130_OFS145_SHIFT 17 +#define TMC5130_OFS145_FIELD ((RegisterField) {TMC5130_OFS145_MASK, TMC5130_OFS145_SHIFT, TMC5130_MSLUT[4], false}) +#define TMC5130_OFS146_MASK 0x00040000 +#define TMC5130_OFS146_SHIFT 18 +#define TMC5130_OFS146_FIELD ((RegisterField) {TMC5130_OFS146_MASK, TMC5130_OFS146_SHIFT, TMC5130_MSLUT[4], false}) +#define TMC5130_OFS147_MASK 0x00080000 +#define TMC5130_OFS147_SHIFT 19 +#define TMC5130_OFS147_FIELD ((RegisterField) {TMC5130_OFS147_MASK, TMC5130_OFS147_SHIFT, TMC5130_MSLUT[4], false}) +#define TMC5130_OFS148_MASK 0x00100000 +#define TMC5130_OFS148_SHIFT 20 +#define TMC5130_OFS148_FIELD ((RegisterField) {TMC5130_OFS148_MASK, TMC5130_OFS148_SHIFT, TMC5130_MSLUT[4], false}) +#define TMC5130_OFS149_MASK 0x00200000 +#define TMC5130_OFS149_SHIFT 21 +#define TMC5130_OFS149_FIELD ((RegisterField) {TMC5130_OFS149_MASK, TMC5130_OFS149_SHIFT, TMC5130_MSLUT[4], false}) +#define TMC5130_OFS150_MASK 0x00400000 +#define TMC5130_OFS150_SHIFT 22 +#define TMC5130_OFS150_FIELD ((RegisterField) {TMC5130_OFS150_MASK, TMC5130_OFS150_SHIFT, TMC5130_MSLUT[4], false}) +#define TMC5130_OFS151_MASK 0x00800000 +#define TMC5130_OFS151_SHIFT 23 +#define TMC5130_OFS151_FIELD ((RegisterField) {TMC5130_OFS151_MASK, TMC5130_OFS151_SHIFT, TMC5130_MSLUT[4], false}) +#define TMC5130_OFS152_MASK 0x01000000 +#define TMC5130_OFS152_SHIFT 24 +#define TMC5130_OFS152_FIELD ((RegisterField) {TMC5130_OFS152_MASK, TMC5130_OFS152_SHIFT, TMC5130_MSLUT[4], false}) +#define TMC5130_OFS153_MASK 0x02000000 +#define TMC5130_OFS153_SHIFT 25 +#define TMC5130_OFS153_FIELD ((RegisterField) {TMC5130_OFS153_MASK, TMC5130_OFS153_SHIFT, TMC5130_MSLUT[4], false}) +#define TMC5130_OFS154_MASK 0x04000000 +#define TMC5130_OFS154_SHIFT 26 +#define TMC5130_OFS154_FIELD ((RegisterField) {TMC5130_OFS154_MASK, TMC5130_OFS154_SHIFT, TMC5130_MSLUT[4], false}) +#define TMC5130_OFS155_MASK 0x08000000 +#define TMC5130_OFS155_SHIFT 27 +#define TMC5130_OFS155_FIELD ((RegisterField) {TMC5130_OFS155_MASK, TMC5130_OFS155_SHIFT, TMC5130_MSLUT[4], false}) +#define TMC5130_OFS156_MASK 0x10000000 +#define TMC5130_OFS156_SHIFT 28 +#define TMC5130_OFS156_FIELD ((RegisterField) {TMC5130_OFS156_MASK, TMC5130_OFS156_SHIFT, TMC5130_MSLUT[4], false}) +#define TMC5130_OFS157_MASK 0x20000000 +#define TMC5130_OFS157_SHIFT 29 +#define TMC5130_OFS157_FIELD ((RegisterField) {TMC5130_OFS157_MASK, TMC5130_OFS157_SHIFT, TMC5130_MSLUT[4], false}) +#define TMC5130_OFS158_MASK 0x40000000 +#define TMC5130_OFS158_SHIFT 30 +#define TMC5130_OFS158_FIELD ((RegisterField) {TMC5130_OFS158_MASK, TMC5130_OFS158_SHIFT, TMC5130_MSLUT[4], false}) +#define TMC5130_OFS159_MASK 0x80000000 +#define TMC5130_OFS159_SHIFT 31 +#define TMC5130_OFS159_FIELD ((RegisterField) {TMC5130_OFS159_MASK, TMC5130_OFS159_SHIFT, TMC5130_MSLUT[4], false}) +#define TMC5130_OFS160_MASK 0x00000001 +#define TMC5130_OFS160_SHIFT 0 +#define TMC5130_OFS160_FIELD ((RegisterField) {TMC5130_OFS160_MASK, TMC5130_OFS160_SHIFT, TMC5130_MSLUT[5], false}) +#define TMC5130_OFS161_MASK 0x00000002 +#define TMC5130_OFS161_SHIFT 1 +#define TMC5130_OFS161_FIELD ((RegisterField) {TMC5130_OFS161_MASK, TMC5130_OFS161_SHIFT, TMC5130_MSLUT[5], false}) +#define TMC5130_OFS162_MASK 0x00000004 +#define TMC5130_OFS162_SHIFT 2 +#define TMC5130_OFS162_FIELD ((RegisterField) {TMC5130_OFS162_MASK, TMC5130_OFS162_SHIFT, TMC5130_MSLUT[5], false}) +#define TMC5130_OFS163_MASK 0x00000008 +#define TMC5130_OFS163_SHIFT 3 +#define TMC5130_OFS163_FIELD ((RegisterField) {TMC5130_OFS163_MASK, TMC5130_OFS163_SHIFT, TMC5130_MSLUT[5], false}) +#define TMC5130_OFS164_MASK 0x00000010 +#define TMC5130_OFS164_SHIFT 4 +#define TMC5130_OFS164_FIELD ((RegisterField) {TMC5130_OFS164_MASK, TMC5130_OFS164_SHIFT, TMC5130_MSLUT[5], false}) +#define TMC5130_OFS165_MASK 0x00000020 +#define TMC5130_OFS165_SHIFT 5 +#define TMC5130_OFS165_FIELD ((RegisterField) {TMC5130_OFS165_MASK, TMC5130_OFS165_SHIFT, TMC5130_MSLUT[5], false}) +#define TMC5130_OFS166_MASK 0x00000040 +#define TMC5130_OFS166_SHIFT 6 +#define TMC5130_OFS166_FIELD ((RegisterField) {TMC5130_OFS166_MASK, TMC5130_OFS166_SHIFT, TMC5130_MSLUT[5], false}) +#define TMC5130_OFS167_MASK 0x00000080 +#define TMC5130_OFS167_SHIFT 7 +#define TMC5130_OFS167_FIELD ((RegisterField) {TMC5130_OFS167_MASK, TMC5130_OFS167_SHIFT, TMC5130_MSLUT[5], false}) +#define TMC5130_OFS168_MASK 0x00000100 +#define TMC5130_OFS168_SHIFT 8 +#define TMC5130_OFS168_FIELD ((RegisterField) {TMC5130_OFS168_MASK, TMC5130_OFS168_SHIFT, TMC5130_MSLUT[5], false}) +#define TMC5130_OFS169_MASK 0x00000200 +#define TMC5130_OFS169_SHIFT 9 +#define TMC5130_OFS169_FIELD ((RegisterField) {TMC5130_OFS169_MASK, TMC5130_OFS169_SHIFT, TMC5130_MSLUT[5], false}) +#define TMC5130_OFS170_MASK 0x00000400 +#define TMC5130_OFS170_SHIFT 10 +#define TMC5130_OFS170_FIELD ((RegisterField) {TMC5130_OFS170_MASK, TMC5130_OFS170_SHIFT, TMC5130_MSLUT[5], false}) +#define TMC5130_OFS171_MASK 0x00000800 +#define TMC5130_OFS171_SHIFT 11 +#define TMC5130_OFS171_FIELD ((RegisterField) {TMC5130_OFS171_MASK, TMC5130_OFS171_SHIFT, TMC5130_MSLUT[5], false}) +#define TMC5130_OFS172_MASK 0x00001000 +#define TMC5130_OFS172_SHIFT 12 +#define TMC5130_OFS172_FIELD ((RegisterField) {TMC5130_OFS172_MASK, TMC5130_OFS172_SHIFT, TMC5130_MSLUT[5], false}) +#define TMC5130_OFS173_MASK 0x00002000 +#define TMC5130_OFS173_SHIFT 13 +#define TMC5130_OFS173_FIELD ((RegisterField) {TMC5130_OFS173_MASK, TMC5130_OFS173_SHIFT, TMC5130_MSLUT[5], false}) +#define TMC5130_OFS174_MASK 0x00004000 +#define TMC5130_OFS174_SHIFT 14 +#define TMC5130_OFS174_FIELD ((RegisterField) {TMC5130_OFS174_MASK, TMC5130_OFS174_SHIFT, TMC5130_MSLUT[5], false}) +#define TMC5130_OFS175_MASK 0x00008000 +#define TMC5130_OFS175_SHIFT 15 +#define TMC5130_OFS175_FIELD ((RegisterField) {TMC5130_OFS175_MASK, TMC5130_OFS175_SHIFT, TMC5130_MSLUT[5], false}) +#define TMC5130_OFS176_MASK 0x00010000 +#define TMC5130_OFS176_SHIFT 16 +#define TMC5130_OFS176_FIELD ((RegisterField) {TMC5130_OFS176_MASK, TMC5130_OFS176_SHIFT, TMC5130_MSLUT[5], false}) +#define TMC5130_OFS177_MASK 0x00020000 +#define TMC5130_OFS177_SHIFT 17 +#define TMC5130_OFS177_FIELD ((RegisterField) {TMC5130_OFS177_MASK, TMC5130_OFS177_SHIFT, TMC5130_MSLUT[5], false}) +#define TMC5130_OFS178_MASK 0x00040000 +#define TMC5130_OFS178_SHIFT 18 +#define TMC5130_OFS178_FIELD ((RegisterField) {TMC5130_OFS178_MASK, TMC5130_OFS178_SHIFT, TMC5130_MSLUT[5], false}) +#define TMC5130_OFS179_MASK 0x00080000 +#define TMC5130_OFS179_SHIFT 19 +#define TMC5130_OFS179_FIELD ((RegisterField) {TMC5130_OFS179_MASK, TMC5130_OFS179_SHIFT, TMC5130_MSLUT[5], false}) +#define TMC5130_OFS180_MASK 0x00100000 +#define TMC5130_OFS180_SHIFT 20 +#define TMC5130_OFS180_FIELD ((RegisterField) {TMC5130_OFS180_MASK, TMC5130_OFS180_SHIFT, TMC5130_MSLUT[5], false}) +#define TMC5130_OFS181_MASK 0x00200000 +#define TMC5130_OFS181_SHIFT 21 +#define TMC5130_OFS181_FIELD ((RegisterField) {TMC5130_OFS181_MASK, TMC5130_OFS181_SHIFT, TMC5130_MSLUT[5], false}) +#define TMC5130_OFS182_MASK 0x00400000 +#define TMC5130_OFS182_SHIFT 22 +#define TMC5130_OFS182_FIELD ((RegisterField) {TMC5130_OFS182_MASK, TMC5130_OFS182_SHIFT, TMC5130_MSLUT[5], false}) +#define TMC5130_OFS183_MASK 0x00800000 +#define TMC5130_OFS183_SHIFT 23 +#define TMC5130_OFS183_FIELD ((RegisterField) {TMC5130_OFS183_MASK, TMC5130_OFS183_SHIFT, TMC5130_MSLUT[5], false}) +#define TMC5130_OFS184_MASK 0x01000000 +#define TMC5130_OFS184_SHIFT 24 +#define TMC5130_OFS184_FIELD ((RegisterField) {TMC5130_OFS184_MASK, TMC5130_OFS184_SHIFT, TMC5130_MSLUT[5], false}) +#define TMC5130_OFS185_MASK 0x02000000 +#define TMC5130_OFS185_SHIFT 25 +#define TMC5130_OFS185_FIELD ((RegisterField) {TMC5130_OFS185_MASK, TMC5130_OFS185_SHIFT, TMC5130_MSLUT[5], false}) +#define TMC5130_OFS186_MASK 0x04000000 +#define TMC5130_OFS186_SHIFT 26 +#define TMC5130_OFS186_FIELD ((RegisterField) {TMC5130_OFS186_MASK, TMC5130_OFS186_SHIFT, TMC5130_MSLUT[5], false}) +#define TMC5130_OFS187_MASK 0x08000000 +#define TMC5130_OFS187_SHIFT 27 +#define TMC5130_OFS187_FIELD ((RegisterField) {TMC5130_OFS187_MASK, TMC5130_OFS187_SHIFT, TMC5130_MSLUT[5], false}) +#define TMC5130_OFS188_MASK 0x10000000 +#define TMC5130_OFS188_SHIFT 28 +#define TMC5130_OFS188_FIELD ((RegisterField) {TMC5130_OFS188_MASK, TMC5130_OFS188_SHIFT, TMC5130_MSLUT[5], false}) +#define TMC5130_OFS189_MASK 0x20000000 +#define TMC5130_OFS189_SHIFT 29 +#define TMC5130_OFS189_FIELD ((RegisterField) {TMC5130_OFS189_MASK, TMC5130_OFS189_SHIFT, TMC5130_MSLUT[5], false}) +#define TMC5130_OFS190_MASK 0x40000000 +#define TMC5130_OFS190_SHIFT 30 +#define TMC5130_OFS190_FIELD ((RegisterField) {TMC5130_OFS190_MASK, TMC5130_OFS190_SHIFT, TMC5130_MSLUT[5], false}) +#define TMC5130_OFS191_MASK 0x80000000 +#define TMC5130_OFS191_SHIFT 31 +#define TMC5130_OFS191_FIELD ((RegisterField) {TMC5130_OFS191_MASK, TMC5130_OFS191_SHIFT, TMC5130_MSLUT[5], false}) +#define TMC5130_OFS192_MASK 0x00000001 +#define TMC5130_OFS192_SHIFT 0 +#define TMC5130_OFS192_FIELD ((RegisterField) {TMC5130_OFS192_MASK, TMC5130_OFS192_SHIFT, TMC5130_MSLUT[6], false}) +#define TMC5130_OFS193_MASK 0x00000002 +#define TMC5130_OFS193_SHIFT 1 +#define TMC5130_OFS193_FIELD ((RegisterField) {TMC5130_OFS193_MASK, TMC5130_OFS193_SHIFT, TMC5130_MSLUT[6], false}) +#define TMC5130_OFS194_MASK 0x00000004 +#define TMC5130_OFS194_SHIFT 2 +#define TMC5130_OFS194_FIELD ((RegisterField) {TMC5130_OFS194_MASK, TMC5130_OFS194_SHIFT, TMC5130_MSLUT[6], false}) +#define TMC5130_OFS195_MASK 0x00000008 +#define TMC5130_OFS195_SHIFT 3 +#define TMC5130_OFS195_FIELD ((RegisterField) {TMC5130_OFS195_MASK, TMC5130_OFS195_SHIFT, TMC5130_MSLUT[6], false}) +#define TMC5130_OFS196_MASK 0x00000010 +#define TMC5130_OFS196_SHIFT 4 +#define TMC5130_OFS196_FIELD ((RegisterField) {TMC5130_OFS196_MASK, TMC5130_OFS196_SHIFT, TMC5130_MSLUT[6], false}) +#define TMC5130_OFS197_MASK 0x00000020 +#define TMC5130_OFS197_SHIFT 5 +#define TMC5130_OFS197_FIELD ((RegisterField) {TMC5130_OFS197_MASK, TMC5130_OFS197_SHIFT, TMC5130_MSLUT[6], false}) +#define TMC5130_OFS198_MASK 0x00000040 +#define TMC5130_OFS198_SHIFT 6 +#define TMC5130_OFS198_FIELD ((RegisterField) {TMC5130_OFS198_MASK, TMC5130_OFS198_SHIFT, TMC5130_MSLUT[6], false}) +#define TMC5130_OFS199_MASK 0x00000080 +#define TMC5130_OFS199_SHIFT 7 +#define TMC5130_OFS199_FIELD ((RegisterField) {TMC5130_OFS199_MASK, TMC5130_OFS199_SHIFT, TMC5130_MSLUT[6], false}) +#define TMC5130_OFS200_MASK 0x00000100 +#define TMC5130_OFS200_SHIFT 8 +#define TMC5130_OFS200_FIELD ((RegisterField) {TMC5130_OFS200_MASK, TMC5130_OFS200_SHIFT, TMC5130_MSLUT[6], false}) +#define TMC5130_OFS201_MASK 0x00000200 +#define TMC5130_OFS201_SHIFT 9 +#define TMC5130_OFS201_FIELD ((RegisterField) {TMC5130_OFS201_MASK, TMC5130_OFS201_SHIFT, TMC5130_MSLUT[6], false}) +#define TMC5130_OFS202_MASK 0x00000400 +#define TMC5130_OFS202_SHIFT 10 +#define TMC5130_OFS202_FIELD ((RegisterField) {TMC5130_OFS202_MASK, TMC5130_OFS202_SHIFT, TMC5130_MSLUT[6], false}) +#define TMC5130_OFS203_MASK 0x00000800 +#define TMC5130_OFS203_SHIFT 11 +#define TMC5130_OFS203_FIELD ((RegisterField) {TMC5130_OFS203_MASK, TMC5130_OFS203_SHIFT, TMC5130_MSLUT[6], false}) +#define TMC5130_OFS204_MASK 0x00001000 +#define TMC5130_OFS204_SHIFT 12 +#define TMC5130_OFS204_FIELD ((RegisterField) {TMC5130_OFS204_MASK, TMC5130_OFS204_SHIFT, TMC5130_MSLUT[6], false}) +#define TMC5130_OFS205_MASK 0x00002000 +#define TMC5130_OFS205_SHIFT 13 +#define TMC5130_OFS205_FIELD ((RegisterField) {TMC5130_OFS205_MASK, TMC5130_OFS205_SHIFT, TMC5130_MSLUT[6], false}) +#define TMC5130_OFS206_MASK 0x00004000 +#define TMC5130_OFS206_SHIFT 14 +#define TMC5130_OFS206_FIELD ((RegisterField) {TMC5130_OFS206_MASK, TMC5130_OFS206_SHIFT, TMC5130_MSLUT[6], false}) +#define TMC5130_OFS207_MASK 0x00008000 +#define TMC5130_OFS207_SHIFT 15 +#define TMC5130_OFS207_FIELD ((RegisterField) {TMC5130_OFS207_MASK, TMC5130_OFS207_SHIFT, TMC5130_MSLUT[6], false}) +#define TMC5130_OFS208_MASK 0x00010000 +#define TMC5130_OFS208_SHIFT 16 +#define TMC5130_OFS208_FIELD ((RegisterField) {TMC5130_OFS208_MASK, TMC5130_OFS208_SHIFT, TMC5130_MSLUT[6], false}) +#define TMC5130_OFS209_MASK 0x00020000 +#define TMC5130_OFS209_SHIFT 17 +#define TMC5130_OFS209_FIELD ((RegisterField) {TMC5130_OFS209_MASK, TMC5130_OFS209_SHIFT, TMC5130_MSLUT[6], false}) +#define TMC5130_OFS210_MASK 0x00040000 +#define TMC5130_OFS210_SHIFT 18 +#define TMC5130_OFS210_FIELD ((RegisterField) {TMC5130_OFS210_MASK, TMC5130_OFS210_SHIFT, TMC5130_MSLUT[6], false}) +#define TMC5130_OFS211_MASK 0x00080000 +#define TMC5130_OFS211_SHIFT 19 +#define TMC5130_OFS211_FIELD ((RegisterField) {TMC5130_OFS211_MASK, TMC5130_OFS211_SHIFT, TMC5130_MSLUT[6], false}) +#define TMC5130_OFS212_MASK 0x00100000 +#define TMC5130_OFS212_SHIFT 20 +#define TMC5130_OFS212_FIELD ((RegisterField) {TMC5130_OFS212_MASK, TMC5130_OFS212_SHIFT, TMC5130_MSLUT[6], false}) +#define TMC5130_OFS213_MASK 0x00200000 +#define TMC5130_OFS213_SHIFT 21 +#define TMC5130_OFS213_FIELD ((RegisterField) {TMC5130_OFS213_MASK, TMC5130_OFS213_SHIFT, TMC5130_MSLUT[6], false}) +#define TMC5130_OFS214_MASK 0x00400000 +#define TMC5130_OFS214_SHIFT 22 +#define TMC5130_OFS214_FIELD ((RegisterField) {TMC5130_OFS214_MASK, TMC5130_OFS214_SHIFT, TMC5130_MSLUT[6], false}) +#define TMC5130_OFS215_MASK 0x00800000 +#define TMC5130_OFS215_SHIFT 23 +#define TMC5130_OFS215_FIELD ((RegisterField) {TMC5130_OFS215_MASK, TMC5130_OFS215_SHIFT, TMC5130_MSLUT[6], false}) +#define TMC5130_OFS216_MASK 0x01000000 +#define TMC5130_OFS216_SHIFT 24 +#define TMC5130_OFS216_FIELD ((RegisterField) {TMC5130_OFS216_MASK, TMC5130_OFS216_SHIFT, TMC5130_MSLUT[6], false}) +#define TMC5130_OFS217_MASK 0x02000000 +#define TMC5130_OFS217_SHIFT 25 +#define TMC5130_OFS217_FIELD ((RegisterField) {TMC5130_OFS217_MASK, TMC5130_OFS217_SHIFT, TMC5130_MSLUT[6], false}) +#define TMC5130_OFS218_MASK 0x04000000 +#define TMC5130_OFS218_SHIFT 26 +#define TMC5130_OFS218_FIELD ((RegisterField) {TMC5130_OFS218_MASK, TMC5130_OFS218_SHIFT, TMC5130_MSLUT[6], false}) +#define TMC5130_OFS219_MASK 0x08000000 +#define TMC5130_OFS219_SHIFT 27 +#define TMC5130_OFS219_FIELD ((RegisterField) {TMC5130_OFS219_MASK, TMC5130_OFS219_SHIFT, TMC5130_MSLUT[6], false}) +#define TMC5130_OFS220_MASK 0x10000000 +#define TMC5130_OFS220_SHIFT 28 +#define TMC5130_OFS220_FIELD ((RegisterField) {TMC5130_OFS220_MASK, TMC5130_OFS220_SHIFT, TMC5130_MSLUT[6], false}) +#define TMC5130_OFS221_MASK 0x20000000 +#define TMC5130_OFS221_SHIFT 29 +#define TMC5130_OFS221_FIELD ((RegisterField) {TMC5130_OFS221_MASK, TMC5130_OFS221_SHIFT, TMC5130_MSLUT[6], false}) +#define TMC5130_OFS222_MASK 0x40000000 +#define TMC5130_OFS222_SHIFT 30 +#define TMC5130_OFS222_FIELD ((RegisterField) {TMC5130_OFS222_MASK, TMC5130_OFS222_SHIFT, TMC5130_MSLUT[6], false}) +#define TMC5130_OFS223_MASK 0x80000000 +#define TMC5130_OFS223_SHIFT 31 +#define TMC5130_OFS223_FIELD ((RegisterField) {TMC5130_OFS223_MASK, TMC5130_OFS223_SHIFT, TMC5130_MSLUT[6], false}) +#define TMC5130_OFS224_MASK 0x00000001 +#define TMC5130_OFS224_SHIFT 0 +#define TMC5130_OFS224_FIELD ((RegisterField) {TMC5130_OFS224_MASK, TMC5130_OFS224_SHIFT, TMC5130_MSLUT[7], false}) +#define TMC5130_OFS225_MASK 0x00000002 +#define TMC5130_OFS225_SHIFT 1 +#define TMC5130_OFS225_FIELD ((RegisterField) {TMC5130_OFS225_MASK, TMC5130_OFS225_SHIFT, TMC5130_MSLUT[7], false}) +#define TMC5130_OFS226_MASK 0x00000004 +#define TMC5130_OFS226_SHIFT 2 +#define TMC5130_OFS226_FIELD ((RegisterField) {TMC5130_OFS226_MASK, TMC5130_OFS226_SHIFT, TMC5130_MSLUT[7], false}) +#define TMC5130_OFS227_MASK 0x00000008 +#define TMC5130_OFS227_SHIFT 3 +#define TMC5130_OFS227_FIELD ((RegisterField) {TMC5130_OFS227_MASK, TMC5130_OFS227_SHIFT, TMC5130_MSLUT[7], false}) +#define TMC5130_OFS228_MASK 0x00000010 +#define TMC5130_OFS228_SHIFT 4 +#define TMC5130_OFS228_FIELD ((RegisterField) {TMC5130_OFS228_MASK, TMC5130_OFS228_SHIFT, TMC5130_MSLUT[7], false}) +#define TMC5130_OFS229_MASK 0x00000020 +#define TMC5130_OFS229_SHIFT 5 +#define TMC5130_OFS229_FIELD ((RegisterField) {TMC5130_OFS229_MASK, TMC5130_OFS229_SHIFT, TMC5130_MSLUT[7], false}) +#define TMC5130_OFS230_MASK 0x00000040 +#define TMC5130_OFS230_SHIFT 6 +#define TMC5130_OFS230_FIELD ((RegisterField) {TMC5130_OFS230_MASK, TMC5130_OFS230_SHIFT, TMC5130_MSLUT[7], false}) +#define TMC5130_OFS231_MASK 0x00000080 +#define TMC5130_OFS231_SHIFT 7 +#define TMC5130_OFS231_FIELD ((RegisterField) {TMC5130_OFS231_MASK, TMC5130_OFS231_SHIFT, TMC5130_MSLUT[7], false}) +#define TMC5130_OFS232_MASK 0x00000100 +#define TMC5130_OFS232_SHIFT 8 +#define TMC5130_OFS232_FIELD ((RegisterField) {TMC5130_OFS232_MASK, TMC5130_OFS232_SHIFT, TMC5130_MSLUT[7], false}) +#define TMC5130_OFS233_MASK 0x00000200 +#define TMC5130_OFS233_SHIFT 9 +#define TMC5130_OFS233_FIELD ((RegisterField) {TMC5130_OFS233_MASK, TMC5130_OFS233_SHIFT, TMC5130_MSLUT[7], false}) +#define TMC5130_OFS234_MASK 0x00000400 +#define TMC5130_OFS234_SHIFT 10 +#define TMC5130_OFS234_FIELD ((RegisterField) {TMC5130_OFS234_MASK, TMC5130_OFS234_SHIFT, TMC5130_MSLUT[7], false}) +#define TMC5130_OFS235_MASK 0x00000800 +#define TMC5130_OFS235_SHIFT 11 +#define TMC5130_OFS235_FIELD ((RegisterField) {TMC5130_OFS235_MASK, TMC5130_OFS235_SHIFT, TMC5130_MSLUT[7], false}) +#define TMC5130_OFS236_MASK 0x00001000 +#define TMC5130_OFS236_SHIFT 12 +#define TMC5130_OFS236_FIELD ((RegisterField) {TMC5130_OFS236_MASK, TMC5130_OFS236_SHIFT, TMC5130_MSLUT[7], false}) +#define TMC5130_OFS237_MASK 0x00002000 +#define TMC5130_OFS237_SHIFT 13 +#define TMC5130_OFS237_FIELD ((RegisterField) {TMC5130_OFS237_MASK, TMC5130_OFS237_SHIFT, TMC5130_MSLUT[7], false}) +#define TMC5130_OFS238_MASK 0x00004000 +#define TMC5130_OFS238_SHIFT 14 +#define TMC5130_OFS238_FIELD ((RegisterField) {TMC5130_OFS238_MASK, TMC5130_OFS238_SHIFT, TMC5130_MSLUT[7], false}) +#define TMC5130_OFS239_MASK 0x00008000 +#define TMC5130_OFS239_SHIFT 15 +#define TMC5130_OFS239_FIELD ((RegisterField) {TMC5130_OFS239_MASK, TMC5130_OFS239_SHIFT, TMC5130_MSLUT[7], false}) +#define TMC5130_OFS240_MASK 0x00010000 +#define TMC5130_OFS240_SHIFT 16 +#define TMC5130_OFS240_FIELD ((RegisterField) {TMC5130_OFS240_MASK, TMC5130_OFS240_SHIFT, TMC5130_MSLUT[7], false}) +#define TMC5130_OFS241_MASK 0x00020000 +#define TMC5130_OFS241_SHIFT 17 +#define TMC5130_OFS241_FIELD ((RegisterField) {TMC5130_OFS241_MASK, TMC5130_OFS241_SHIFT, TMC5130_MSLUT[7], false}) +#define TMC5130_OFS242_MASK 0x00040000 +#define TMC5130_OFS242_SHIFT 18 +#define TMC5130_OFS242_FIELD ((RegisterField) {TMC5130_OFS242_MASK, TMC5130_OFS242_SHIFT, TMC5130_MSLUT[7], false}) +#define TMC5130_OFS243_MASK 0x00080000 +#define TMC5130_OFS243_SHIFT 19 +#define TMC5130_OFS243_FIELD ((RegisterField) {TMC5130_OFS243_MASK, TMC5130_OFS243_SHIFT, TMC5130_MSLUT[7], false}) +#define TMC5130_OFS244_MASK 0x00100000 +#define TMC5130_OFS244_SHIFT 20 +#define TMC5130_OFS244_FIELD ((RegisterField) {TMC5130_OFS244_MASK, TMC5130_OFS244_SHIFT, TMC5130_MSLUT[7], false}) +#define TMC5130_OFS245_MASK 0x00200000 +#define TMC5130_OFS245_SHIFT 21 +#define TMC5130_OFS245_FIELD ((RegisterField) {TMC5130_OFS245_MASK, TMC5130_OFS245_SHIFT, TMC5130_MSLUT[7], false}) +#define TMC5130_OFS246_MASK 0x00400000 +#define TMC5130_OFS246_SHIFT 22 +#define TMC5130_OFS246_FIELD ((RegisterField) {TMC5130_OFS246_MASK, TMC5130_OFS246_SHIFT, TMC5130_MSLUT[7], false}) +#define TMC5130_OFS247_MASK 0x00800000 +#define TMC5130_OFS247_SHIFT 23 +#define TMC5130_OFS247_FIELD ((RegisterField) {TMC5130_OFS247_MASK, TMC5130_OFS247_SHIFT, TMC5130_MSLUT[7], false}) +#define TMC5130_OFS248_MASK 0x01000000 +#define TMC5130_OFS248_SHIFT 24 +#define TMC5130_OFS248_FIELD ((RegisterField) {TMC5130_OFS248_MASK, TMC5130_OFS248_SHIFT, TMC5130_MSLUT[7], false}) +#define TMC5130_OFS249_MASK 0x02000000 +#define TMC5130_OFS249_SHIFT 25 +#define TMC5130_OFS249_FIELD ((RegisterField) {TMC5130_OFS249_MASK, TMC5130_OFS249_SHIFT, TMC5130_MSLUT[7], false}) +#define TMC5130_OFS250_MASK 0x04000000 +#define TMC5130_OFS250_SHIFT 26 +#define TMC5130_OFS250_FIELD ((RegisterField) {TMC5130_OFS250_MASK, TMC5130_OFS250_SHIFT, TMC5130_MSLUT[7], false}) +#define TMC5130_OFS251_MASK 0x08000000 +#define TMC5130_OFS251_SHIFT 27 +#define TMC5130_OFS251_FIELD ((RegisterField) {TMC5130_OFS251_MASK, TMC5130_OFS251_SHIFT, TMC5130_MSLUT[7], false}) +#define TMC5130_OFS252_MASK 0x10000000 +#define TMC5130_OFS252_SHIFT 28 +#define TMC5130_OFS252_FIELD ((RegisterField) {TMC5130_OFS252_MASK, TMC5130_OFS252_SHIFT, TMC5130_MSLUT[7], false}) +#define TMC5130_OFS253_MASK 0x20000000 +#define TMC5130_OFS253_SHIFT 29 +#define TMC5130_OFS253_FIELD ((RegisterField) {TMC5130_OFS253_MASK, TMC5130_OFS253_SHIFT, TMC5130_MSLUT[7], false}) +#define TMC5130_OFS254_MASK 0x40000000 +#define TMC5130_OFS254_SHIFT 30 +#define TMC5130_OFS254_FIELD ((RegisterField) {TMC5130_OFS254_MASK, TMC5130_OFS254_SHIFT, TMC5130_MSLUT[7], false}) +#define TMC5130_OFS255_MASK 0x80000000 +#define TMC5130_OFS255_SHIFT 31 +#define TMC5130_OFS255_FIELD ((RegisterField) {TMC5130_OFS255_MASK, TMC5130_OFS255_SHIFT, TMC5130_MSLUT[7], false}) +#define TMC5130_W0_MASK 0x00000003 +#define TMC5130_W0_SHIFT 0 +#define TMC5130_W0_FIELD ((RegisterField) {TMC5130_W0_MASK, TMC5130_W0_SHIFT, TMC5130_MSLUTSEL, false}) +#define TMC5130_W1_MASK 0x0000000C +#define TMC5130_W1_SHIFT 2 +#define TMC5130_W1_FIELD ((RegisterField) {TMC5130_W1_MASK, TMC5130_W1_SHIFT, TMC5130_MSLUTSEL, false}) +#define TMC5130_W2_MASK 0x00000030 +#define TMC5130_W2_SHIFT 4 +#define TMC5130_W2_FIELD ((RegisterField) {TMC5130_W2_MASK, TMC5130_W2_SHIFT, TMC5130_MSLUTSEL, false}) +#define TMC5130_W3_MASK 0x000000C0 +#define TMC5130_W3_SHIFT 6 +#define TMC5130_W3_FIELD ((RegisterField) {TMC5130_W3_MASK, TMC5130_W3_SHIFT, TMC5130_MSLUTSEL, false}) +#define TMC5130_X1_MASK 0x0000FF00 +#define TMC5130_X1_SHIFT 8 +#define TMC5130_X1_FIELD ((RegisterField) {TMC5130_X1_MASK, TMC5130_X1_SHIFT, TMC5130_MSLUTSEL, false}) +#define TMC5130_X2_MASK 0x00FF0000 +#define TMC5130_X2_SHIFT 16 +#define TMC5130_X2_FIELD ((RegisterField) {TMC5130_X2_MASK, TMC5130_X2_SHIFT, TMC5130_MSLUTSEL, false}) +#define TMC5130_X3_MASK 0xFF000000 +#define TMC5130_X3_SHIFT 24 +#define TMC5130_X3_FIELD ((RegisterField) {TMC5130_X3_MASK, TMC5130_X3_SHIFT, TMC5130_MSLUTSEL, false}) +#define TMC5130_START_SIN_MASK 0x000000FF +#define TMC5130_START_SIN_SHIFT 0 +#define TMC5130_START_SIN_FIELD ((RegisterField) {TMC5130_START_SIN_MASK, TMC5130_START_SIN_SHIFT, TMC5130_MSLUTSTART, false}) +#define TMC5130_START_SIN90_MASK 0x00FF0000 +#define TMC5130_START_SIN90_SHIFT 16 +#define TMC5130_START_SIN90_FIELD ((RegisterField) {TMC5130_START_SIN90_MASK, TMC5130_START_SIN90_SHIFT, TMC5130_MSLUTSTART, false}) +#define TMC5130_MSCNT_MASK 0x000003FF +#define TMC5130_MSCNT_SHIFT 0 +#define TMC5130_MSCNT_FIELD ((RegisterField) {TMC5130_MSCNT_MASK, TMC5130_MSCNT_SHIFT, TMC5130_MSCNT, false}) +#define TMC5130_CUR_A_MASK 0x000001FF +#define TMC5130_CUR_A_SHIFT 0 +#define TMC5130_CUR_A_FIELD ((RegisterField) {TMC5130_CUR_A_MASK, TMC5130_CUR_A_SHIFT, TMC5130_MSCURACT, true}) +#define TMC5130_CUR_B_MASK 0x01FF0000 +#define TMC5130_CUR_B_SHIFT 16 +#define TMC5130_CUR_B_FIELD ((RegisterField) {TMC5130_CUR_B_MASK, TMC5130_CUR_B_SHIFT, TMC5130_MSCURACT, true}) +#define TMC5130_TOFF_MASK 0x0000000F +#define TMC5130_TOFF_SHIFT 0 +#define TMC5130_TOFF_FIELD ((RegisterField) {TMC5130_TOFF_MASK, TMC5130_TOFF_SHIFT, TMC5130_CHOPCONF, false}) +#define TMC5130_TFD_2__0__MASK 0x00000070 +#define TMC5130_TFD_2__0__SHIFT 4 +#define TMC5130_TFD_2__0__FIELD ((RegisterField) {TMC5130_TFD_2__0__MASK, TMC5130_TFD_2__0__SHIFT, TMC5130_CHOPCONF, false}) +#define TMC5130_OFFSET_MASK 0x00000780 +#define TMC5130_OFFSET_SHIFT 7 +#define TMC5130_OFFSET_FIELD ((RegisterField) {TMC5130_OFFSET_MASK, TMC5130_OFFSET_SHIFT, TMC5130_CHOPCONF, false}) +#define TMC5130_TFD___MASK 0x00000800 +#define TMC5130_TFD___SHIFT 11 +#define TMC5130_TFD___FIELD ((RegisterField) {TMC5130_TFD___MASK, TMC5130_TFD___SHIFT, TMC5130_CHOPCONF, false}) +#define TMC5130_DISFDCC_MASK 0x00001000 +#define TMC5130_DISFDCC_SHIFT 12 +#define TMC5130_DISFDCC_FIELD ((RegisterField) {TMC5130_DISFDCC_MASK, TMC5130_DISFDCC_SHIFT, TMC5130_CHOPCONF, false}) +#define TMC5130_RNDTF_MASK 0x00002000 +#define TMC5130_RNDTF_SHIFT 13 +#define TMC5130_RNDTF_FIELD ((RegisterField) {TMC5130_RNDTF_MASK, TMC5130_RNDTF_SHIFT, TMC5130_CHOPCONF, false}) +#define TMC5130_CHM_MASK 0x00004000 +#define TMC5130_CHM_SHIFT 14 +#define TMC5130_CHM_FIELD ((RegisterField) {TMC5130_CHM_MASK, TMC5130_CHM_SHIFT, TMC5130_CHOPCONF, false}) +#define TMC5130_TBL_MASK 0x00018000 +#define TMC5130_TBL_SHIFT 15 +#define TMC5130_TBL_FIELD ((RegisterField) {TMC5130_TBL_MASK, TMC5130_TBL_SHIFT, TMC5130_CHOPCONF, false}) +#define TMC5130_VSENSE_MASK 0x00020000 +#define TMC5130_VSENSE_SHIFT 17 +#define TMC5130_VSENSE_FIELD ((RegisterField) {TMC5130_VSENSE_MASK, TMC5130_VSENSE_SHIFT, TMC5130_CHOPCONF, false}) +#define TMC5130_VHIGHFS_MASK 0x00040000 +#define TMC5130_VHIGHFS_SHIFT 18 +#define TMC5130_VHIGHFS_FIELD ((RegisterField) {TMC5130_VHIGHFS_MASK, TMC5130_VHIGHFS_SHIFT, TMC5130_CHOPCONF, false}) +#define TMC5130_VHIGHCHM_MASK 0x00080000 +#define TMC5130_VHIGHCHM_SHIFT 19 +#define TMC5130_VHIGHCHM_FIELD ((RegisterField) {TMC5130_VHIGHCHM_MASK, TMC5130_VHIGHCHM_SHIFT, TMC5130_CHOPCONF, false}) +#define TMC5130_SYNC_MASK 0x00F00000 +#define TMC5130_SYNC_SHIFT 20 +#define TMC5130_SYNC_FIELD ((RegisterField) {TMC5130_SYNC_MASK, TMC5130_SYNC_SHIFT, TMC5130_CHOPCONF, false}) +#define TMC5130_MRES_MASK 0x0F000000 +#define TMC5130_MRES_SHIFT 24 +#define TMC5130_MRES_FIELD ((RegisterField) {TMC5130_MRES_MASK, TMC5130_MRES_SHIFT, TMC5130_CHOPCONF, false}) +#define TMC5130_INTPOL_MASK 0x10000000 +#define TMC5130_INTPOL_SHIFT 28 +#define TMC5130_INTPOL_FIELD ((RegisterField) {TMC5130_INTPOL_MASK, TMC5130_INTPOL_SHIFT, TMC5130_CHOPCONF, false}) +#define TMC5130_DEDGE_MASK 0x20000000 +#define TMC5130_DEDGE_SHIFT 29 +#define TMC5130_DEDGE_FIELD ((RegisterField) {TMC5130_DEDGE_MASK, TMC5130_DEDGE_SHIFT, TMC5130_CHOPCONF, false}) +#define TMC5130_DISS2G_MASK 0x40000000 +#define TMC5130_DISS2G_SHIFT 30 +#define TMC5130_DISS2G_FIELD ((RegisterField) {TMC5130_DISS2G_MASK, TMC5130_DISS2G_SHIFT, TMC5130_CHOPCONF, false}) +#define TMC5130_HSTRT_MASK 0x00000070 +#define TMC5130_HSTRT_SHIFT 4 +#define TMC5130_HSTRT_FIELD ((RegisterField) {TMC5130_HSTRT_MASK, TMC5130_HSTRT_SHIFT, TMC5130_CHOPCONF, false}) +#define TMC5130_HEND_MASK 0x00000780 +#define TMC5130_HEND_SHIFT 7 +#define TMC5130_HEND_FIELD ((RegisterField) {TMC5130_HEND_MASK, TMC5130_HEND_SHIFT, TMC5130_CHOPCONF, false}) +#define TMC5130_SEMIN_MASK 0x0000000F +#define TMC5130_SEMIN_SHIFT 0 +#define TMC5130_SEMIN_FIELD ((RegisterField) {TMC5130_SEMIN_MASK, TMC5130_SEMIN_SHIFT, TMC5130_COOLCONF, false}) +#define TMC5130_SEUP_MASK 0x00000060 +#define TMC5130_SEUP_SHIFT 5 +#define TMC5130_SEUP_FIELD ((RegisterField) {TMC5130_SEUP_MASK, TMC5130_SEUP_SHIFT, TMC5130_COOLCONF, false}) +#define TMC5130_SEMAX_MASK 0x00000F00 +#define TMC5130_SEMAX_SHIFT 8 +#define TMC5130_SEMAX_FIELD ((RegisterField) {TMC5130_SEMAX_MASK, TMC5130_SEMAX_SHIFT, TMC5130_COOLCONF, false}) +#define TMC5130_SEDN_MASK 0x00006000 +#define TMC5130_SEDN_SHIFT 13 +#define TMC5130_SEDN_FIELD ((RegisterField) {TMC5130_SEDN_MASK, TMC5130_SEDN_SHIFT, TMC5130_COOLCONF, false}) +#define TMC5130_SEIMIN_MASK 0x00008000 +#define TMC5130_SEIMIN_SHIFT 15 +#define TMC5130_SEIMIN_FIELD ((RegisterField) {TMC5130_SEIMIN_MASK, TMC5130_SEIMIN_SHIFT, TMC5130_COOLCONF, false}) +#define TMC5130_SGT_MASK 0x007F0000 +#define TMC5130_SGT_SHIFT 16 +#define TMC5130_SGT_FIELD ((RegisterField) {TMC5130_SGT_MASK, TMC5130_SGT_SHIFT, TMC5130_COOLCONF, true}) +#define TMC5130_SFILT_MASK 0x01000000 +#define TMC5130_SFILT_SHIFT 24 +#define TMC5130_SFILT_FIELD ((RegisterField) {TMC5130_SFILT_MASK, TMC5130_SFILT_SHIFT, TMC5130_COOLCONF, false}) +#define TMC5130_DC_TIME_MASK 0x000003FF +#define TMC5130_DC_TIME_SHIFT 0 +#define TMC5130_DC_TIME_FIELD ((RegisterField) {TMC5130_DC_TIME_MASK, TMC5130_DC_TIME_SHIFT, TMC5130_DCCTRL, false}) +#define TMC5130_DC_SG_MASK 0x00FF0000 +#define TMC5130_DC_SG_SHIFT 16 +#define TMC5130_DC_SG_FIELD ((RegisterField) {TMC5130_DC_SG_MASK, TMC5130_DC_SG_SHIFT, TMC5130_DCCTRL, false}) +#define TMC5130_SG_RESULT_MASK 0x000003FF +#define TMC5130_SG_RESULT_SHIFT 0 +#define TMC5130_SG_RESULT_FIELD ((RegisterField) {TMC5130_SG_RESULT_MASK, TMC5130_SG_RESULT_SHIFT, TMC5130_DRVSTATUS, false}) +#define TMC5130_FSACTIVE_MASK 0x00008000 +#define TMC5130_FSACTIVE_SHIFT 15 +#define TMC5130_FSACTIVE_FIELD ((RegisterField) {TMC5130_FSACTIVE_MASK, TMC5130_FSACTIVE_SHIFT, TMC5130_DRVSTATUS, false}) +#define TMC5130_CS_ACTUAL_MASK 0x001F0000 +#define TMC5130_CS_ACTUAL_SHIFT 16 +#define TMC5130_CS_ACTUAL_FIELD ((RegisterField) {TMC5130_CS_ACTUAL_MASK, TMC5130_CS_ACTUAL_SHIFT, TMC5130_DRVSTATUS, false}) +#define TMC5130_STALLGUARD_MASK 0x01000000 +#define TMC5130_STALLGUARD_SHIFT 24 +#define TMC5130_STALLGUARD_FIELD ((RegisterField) {TMC5130_STALLGUARD_MASK, TMC5130_STALLGUARD_SHIFT, TMC5130_DRVSTATUS, false}) +#define TMC5130_OT_MASK 0x02000000 +#define TMC5130_OT_SHIFT 25 +#define TMC5130_OT_FIELD ((RegisterField) {TMC5130_OT_MASK, TMC5130_OT_SHIFT, TMC5130_DRVSTATUS, false}) +#define TMC5130_OTPW_MASK 0x04000000 +#define TMC5130_OTPW_SHIFT 26 +#define TMC5130_OTPW_FIELD ((RegisterField) {TMC5130_OTPW_MASK, TMC5130_OTPW_SHIFT, TMC5130_DRVSTATUS, false}) +#define TMC5130_S2GA_MASK 0x08000000 +#define TMC5130_S2GA_SHIFT 27 +#define TMC5130_S2GA_FIELD ((RegisterField) {TMC5130_S2GA_MASK, TMC5130_S2GA_SHIFT, TMC5130_DRVSTATUS, false}) +#define TMC5130_S2GB_MASK 0x10000000 +#define TMC5130_S2GB_SHIFT 28 +#define TMC5130_S2GB_FIELD ((RegisterField) {TMC5130_S2GB_MASK, TMC5130_S2GB_SHIFT, TMC5130_DRVSTATUS, false}) +#define TMC5130_OLA_MASK 0x20000000 +#define TMC5130_OLA_SHIFT 29 +#define TMC5130_OLA_FIELD ((RegisterField) {TMC5130_OLA_MASK, TMC5130_OLA_SHIFT, TMC5130_DRVSTATUS, false}) +#define TMC5130_OLB_MASK 0x40000000 +#define TMC5130_OLB_SHIFT 30 +#define TMC5130_OLB_FIELD ((RegisterField) {TMC5130_OLB_MASK, TMC5130_OLB_SHIFT, TMC5130_DRVSTATUS, false}) +#define TMC5130_STST_MASK 0x80000000 +#define TMC5130_STST_SHIFT 31 +#define TMC5130_STST_FIELD ((RegisterField) {TMC5130_STST_MASK, TMC5130_STST_SHIFT, TMC5130_DRVSTATUS, false}) +#define TMC5130_PWM_AMPL_MASK 0x000000FF +#define TMC5130_PWM_AMPL_SHIFT 0 +#define TMC5130_PWM_AMPL_FIELD ((RegisterField) {TMC5130_PWM_AMPL_MASK, TMC5130_PWM_AMPL_SHIFT, TMC5130_PWMCONF, false}) +#define TMC5130_PWM_GRAD_MASK 0x0000FF00 +#define TMC5130_PWM_GRAD_SHIFT 8 +#define TMC5130_PWM_GRAD_FIELD ((RegisterField) {TMC5130_PWM_GRAD_MASK, TMC5130_PWM_GRAD_SHIFT, TMC5130_PWMCONF, false}) +#define TMC5130_PWM_FREQ_MASK 0x00030000 +#define TMC5130_PWM_FREQ_SHIFT 16 +#define TMC5130_PWM_FREQ_FIELD ((RegisterField) {TMC5130_PWM_FREQ_MASK, TMC5130_PWM_FREQ_SHIFT, TMC5130_PWMCONF, false}) +#define TMC5130_PWM_AUTOSCALE_MASK 0x00040000 +#define TMC5130_PWM_AUTOSCALE_SHIFT 18 +#define TMC5130_PWM_AUTOSCALE_FIELD ((RegisterField) {TMC5130_PWM_AUTOSCALE_MASK, TMC5130_PWM_AUTOSCALE_SHIFT, TMC5130_PWMCONF, false}) +#define TMC5130_PWM_SYMMETRIC_MASK 0x00080000 +#define TMC5130_PWM_SYMMETRIC_SHIFT 19 +#define TMC5130_PWM_SYMMETRIC_FIELD ((RegisterField) {TMC5130_PWM_SYMMETRIC_MASK, TMC5130_PWM_SYMMETRIC_SHIFT, TMC5130_PWMCONF, false}) +#define TMC5130_FREEWHEEL_MASK 0x00300000 +#define TMC5130_FREEWHEEL_SHIFT 20 +#define TMC5130_FREEWHEEL_FIELD ((RegisterField) {TMC5130_FREEWHEEL_MASK, TMC5130_FREEWHEEL_SHIFT, TMC5130_PWMCONF, false}) +#define TMC5130_PWM_SCALE_MASK 0x000000FF +#define TMC5130_PWM_SCALE_SHIFT 0 +#define TMC5130_PWM_SCALE_FIELD ((RegisterField) {TMC5130_PWM_SCALE_MASK, TMC5130_PWM_SCALE_SHIFT, TMC5130_PWM_SCALE, false}) +#define TMC5130_INV_MASK 0x00000001 +#define TMC5130_INV_SHIFT 0 +#define TMC5130_INV_FIELD ((RegisterField) {TMC5130_INV_MASK, TMC5130_INV_SHIFT, TMC5130_ENCM_CTRL, false}) +#define TMC5130_MAXSPEED_MASK 0x00000002 +#define TMC5130_MAXSPEED_SHIFT 1 +#define TMC5130_MAXSPEED_FIELD ((RegisterField) {TMC5130_MAXSPEED_MASK, TMC5130_MAXSPEED_SHIFT, TMC5130_ENCM_CTRL, false}) +#define TMC5130_LOST_STEPS_MASK 0x000FFFFF +#define TMC5130_LOST_STEPS_SHIFT 0 +#define TMC5130_LOST_STEPS_FIELD ((RegisterField) {TMC5130_LOST_STEPS_MASK, TMC5130_LOST_STEPS_SHIFT, TMC5130_LOST_STEPS, false}) + +#endif diff --git a/firmware/lib/tmc/ic/TMC5130/registercall_hierarchy_flowchart_SPI.svg b/firmware/lib/tmc/ic/TMC5130/registercall_hierarchy_flowchart_SPI.svg new file mode 100755 index 0000000..cbad58f --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5130/registercall_hierarchy_flowchart_SPI.svg @@ -0,0 +1,3 @@ + + +

HAL

HAL

APP (Eval)

APP (Eval)

API

API
Read a register
  •  Call tmcXXXX_readRegister function
Read a register...
Returns the register read value
Returns the register read value
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
tmcXXXX.c
tmcXXXX.c
SPI.c
SPI.c
tmcXXXX_eval.c
tmcXXXX_eval.c

 Implementation of SPI_readWrite
  • Sends and receives bytes on the SPI bus
Implementation of SPI_readWrite...
Returns the raw reply data
Returns the raw reply data

Implementation of tmcXXXX_readWriteSPI
  • Sets the CSN pin to LOW
  • Takes the array of data to write
  • Calls hardware function SPI_readWrite
  • Upon completion of data transfer,
    sets CSN to 
    HIGH
Implementation of tmcXXXX_readWriteSPI...
Passes on the raw reply data to the API
Passes on the raw reply data to the API
Implementation of readRegisterSPI
  • Constructs the datagram
  • Calls HAL wrapper function 
Implementation of readRegisterSPI...
tmcXXXX_readWriteSPI
tmcXXXX_readWriteSPI
Parses the reply and returns the register value
Parses the reply and returns the register value
Implementation of tmcXXXX_readRegister 
  • Check which bus is active SPI/UART. (e.g. SPI)
  • Calls bus-specific function (e.g. readRegisterSPI)
 
Implementation of tmcXXXX_readRegister...
Returns the register read value
Returns the register read value
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC5130/registercall_hierarchy_flowchart_UART.svg b/firmware/lib/tmc/ic/TMC5130/registercall_hierarchy_flowchart_UART.svg new file mode 100755 index 0000000..425f60a --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5130/registercall_hierarchy_flowchart_UART.svg @@ -0,0 +1,3 @@ + + +

HAL

HAL

APP (Eval)

APP (Eval)

API

API
Read a register
  •  Call tmcXXXX_readRegister function
Read a register...
Returns the register read value
Returns the register read value
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
tmcXXXX.c
tmcXXXX.c
UART.c
UART.c
tmcXXXX_eval.c
tmcXXXX_eval.c

 Implementation of UART_readWrite
  • Sends and receives bytes on the UART bus
Implementation of UART_readWrite...
Returns the raw reply data
Returns the raw reply data

Implementation of tmcXXXX_readWriteUART
  • Takes the array of data to write
  • Calls hardware function UART_readWrite
Implementation of tmcXXXX_readWriteUART...
Passes on the raw reply data to the API
Passes on the raw reply data to the API
Implementation of readRegisterUART
  • Constructs the datagram
  • Calls HAL wrapper function 
Implementation of readRegisterUART...
tmcXXXX_readWriteUART
tmcXXXX_readWriteUART
Parses the reply and returns the register value
Parses the reply and returns the register value
Implementation of tmcXXXX_readRegister 
  • Check which bus is active SPI/UART. (e.g. UART)
  • Calls bus-specific function (e.g. readRegisterUART)
 
Implementation of tmcXXXX_readRegister...
Returns the register read value
Returns the register read value
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC5130/uml-tmc-api.svg b/firmware/lib/tmc/ic/TMC5130/uml-tmc-api.svg new file mode 100755 index 0000000..5a5f8dd --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5130/uml-tmc-api.svg @@ -0,0 +1,3 @@ + + +

TMCXXXX_HW_Abstraction.h



TMCXXXX_HW_Abstraction.h...
// Constants
#define TMCXXXX_MOTORS              
                          
// Register definitions
#define TMCXXXX_GCONF        
                          ⋮
// Register fields definitions
#define TMCXXXX_GCONF_OTPW_FIELD
                     
// Constants...

TMCXXXX.h



TMCXXXX.h...
extern void tmcXXXX_readWriteSPI();
extern void tmcXXXX_readWriteUART();
extern TMCXXXXBusType tmcXXXX_getBusType();
extern uint8_t tmcXXXX_getNodeAddress();
                                  ⋮
tmcXXXX_readRegister();
tmcXXXX_writeRegister();
                                  ⋮
extern void tmcXXXX_readWriteSPI();...

TMCXXXX.c



TMCXXXX.c...
const uint8_t tmcCRCTable_Poly7Reflected[256] = {...};
int32_t tmcXXXX_readRegister(){
/* Call tmcXXXX_getBusType();
 * Based on bus type, call readRegisterSPI/UART() that
 * further calls tmcXXXX_readWriteSPI/UART();
 * For UART it also calls tmcXXXX_getNodeAddress();
                                           ⋮
}
                                           ⋮
const uint8_t tmcCRCTable_Poly7Reflected[256] = {.....
TMC-API
TMC-API

TMCXXXX_Simple_Rotation.h


TMCXXXX_Simple_Rotation.h...
void initAllMotors();
             ⋮
  
void initAllMotors()...

TMCXXXX_Simple_Rotation.c


TMCXXXX_Simple_Rotation.c...
void initAllMotors(){

// Configuring registers to enable motor drivers etc..
tmcXXXX_writeRegister();
                    ⋮
}
                    ⋮
void initAllMotors(){...
Examples
Examples
User Project
User Project

User_Project.h


User_Project.h

User_Project.c








User_Project.c...

void tmcXXXX_readWriteSPI(){
                           ⋮
}
void tmcXXXX_readWriteUART(){
                           ⋮
}
TMCXXXXBusType tmcXXXX_getBusType(){
                           ⋮
}
uint8_t tmcXXXX_getNodeAddress(){
                           ⋮
}

// User Code
                           ⋮
void tmcXXXX_readWriteSPI(){...
#include "TMCXXXX_HW_Abstraction.h"
#include "TMCXXXX.h"
#include "TMCXXXX_Simple_Rotation.h"
                                ⋮
TMCXXXXBusType bus = IC_BUS_SPI/UART;
uint8_t nodeAddress = <nodeAddress>;
                                ⋮
#include "TMCXXXX_HW_Abstraction.h"...
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC5160/README.md b/firmware/lib/tmc/ic/TMC5160/README.md new file mode 100755 index 0000000..4fc0bd4 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5160/README.md @@ -0,0 +1,68 @@ +# TMC5160 + + +## How to use + +To access the TMC5160's registers, the TMC-API offers two functions: **tmc5160_readRegister** and **tmc5160_writeRegister**. +Each of these functions takes in an **icID**, which is used to identify the IC when multiple ICs are connected. This identifier is passed down to the callback functions (see How to Integrate). + +## How to integrate: overview + +1. Include all the files of the TMC-API/ic/tmc/TMC5160 folder into the custom project. +2. Include the TMC5160.h file in the custom source code. +3. Implement the necessary callback functions (see below). +4. (optional): Take a look at the Examples subfolder for ready-made examples of the TMC-API usage. + +## Accessing the TMC5160 via UART +The following diagram depicts how to access the TMC5160 via UART using the TMC-API. + +![screenshot](registercall_hierarchy_flowchart_UART.svg) + +The description of the functions, in the above flowchart, are as follows: +- The functions tmc5160_readRegister and tmc5160_writeRegister are used to read and write the registers respectively. These functions check the current active bus and calls the bus-specific function i.e readRegisterUART or writeRegisterUART. +- These bus specific functions constructs the datagram and further calls the bus specific callback 'tmcXXXX_readWriteUART. +- This callback function further calls the hardware specific read/write function for UART and needs to be implemented externally. + +### Necessary hardware modification to use UART +To use UART with the Eval-Kit: pin 39 (DIO17) and 40 (DIO18) should be connected with a 1k ohm resistor. Pin 37 (DIO15) and 40(DIO18) should be shorted. Additionally bend the 37 and 38 on the Landungsbrücke side of the Eselsbrücke out. For more information checkout the latest TMC5160-EVAL UART Info Application Note at https://www.analog.com/en/resources/evaluation-hardware-and-software/evaluation-boards-kits/tmc5160-eval.html + +### How to integrate: Callback functions +To communicate with TMC5160 IC, the TMC-API library needs to know which bus (UART, SPI) it shall use. For that, the callback function **'tmc5160_getBusType()'** needs to be implemented. +Additionally, implement the following callback functions to access the chip via UART: +1. **tmc5160_readWriteUART()**, which is a HAL wrapper function that provides the necessary hardware access. +2. **tmc5160_getNodeAddress()**, that returns the node/slave address. Node address could be set in NODECONF (0x3) register and the address could be incremented as defined by AD0, AD1 and AD2. (Node address + ADx) must be less than 255. For further details please consult the datasheet of TMC5160. + +### Sharing the CRC table with other TMC-API chips +The TMC5160 UART protocol uses an 8 bit CRC. For calculating this, a table-based algorithm is used. This table (tmcCRCTable_Poly7Reflected[256]) is 256 bytes big and identical across multiple different Trinamic chips (i.e. TMC2209). +If multiple Trinamic chips are being used in the same project, avoiding redundant copies of this table could save memory. It is possible to substitute this CRC table with another CRC table. + +## Accessing the TMC5160 via SPI +The following diagram depicts how to access the TMC5160 via SPI using the TMC-API. + +![screenshot](registercall_hierarchy_flowchart_SPI.svg) + +The description of the functions, in the above flowchart, are as follows: +- The functions tmc5160_readRegister and tmc5160_writeRegister are used to read and write the registers respectively. These functions check the current active bus and calls the bus-specific function i.e readRegisterSPI or writeRegisterSPI. +- These bus specific functions constructs the datagram and further calls the bus specific callback 'tmcXXXX_readWriteSPI. +- This callback function further calls the hardware specific read/write function for SPI and needs to be implemented externally. + +### How to integrate: Callback functions +To communicate with TMC5160 IC, the TMC-API library needs to know which bus (UART, SPI) it shall use. For that, the callback function **'tmc5160_getBusType()'** needs to be implemented. +Additionally, implement the following callback functions to access the chip via SPI: +1. **tmc5160_readWriteSPI()**, which is a HAL wrapper function that provides the necessary hardware access. This function should also set the chip select pin CSN to low before starting the data transfer and set to high upon completion. Please refer to the datasheet of the IC for further details. + +### Option to use the cache logic for Write-Only registers +The chip features write-only registers that are unable to be read, necessitating the creation of a shadow copy to cache their contents. This copy is automatically updated whenever data is written to these registers. This cache logic could be enabled by setting the macro **TMC5160_CACHE** to **'1'** or disabled by setting to **'0'** respectively. If this feature is enabled then there comes another option to use **tmc5160_cache** function, which is already implemeted in the API, by defining **TMC5160_ENABLE_TMC_CACHE** macro to **'1'** or one can implement their own function. The function **tmc5160_cache** works for both reading from and writing to the shadow array. It first checks whether the register has write-only access and data needs to be read from the hadow copy. On the basis of that, it returns **true** or **false**. The shadowRegisters on the premade cache implementation need to be one per chip. **TMC5160_IC_CACHE_COUNT** is set to '1' by default and is user-overwritable. If multiple chips are being used in the same project, increment its value to the number of chips connected. + +## Further info +### Dependency graph for the ICs with new register R/W mechanism +This graph illustrates the relationships between files within the TMC-API library, highlighting dependencies and identifying the files that are essential for integrating the library into the custom projects. + +![screenshot](uml-tmc-api.svg) + +### Example usage: TMC-Evalsystem +**For a reference usage of the TMC-API**, visit the [TMC-Evalsystem](https://github.com/analogdevicesinc/TMC-EvalSystem) + +## Migration status +The TMC5160 has been reworked to the access system described above. For more infos on the status of this and other ICs, check out the [migration page](https://github.com/analogdevicesinc/TMC-API/issues/53). + diff --git a/firmware/lib/tmc/ic/TMC5160/TMC5160.c b/firmware/lib/tmc/ic/TMC5160/TMC5160.c new file mode 100755 index 0000000..c74c53c --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5160/TMC5160.c @@ -0,0 +1,311 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#include "TMC5160.h" + +#ifdef TMC_API_EXTERNAL_CRC_TABLE +extern const uint8_t tmcCRCTable_Poly7Reflected[256]; +#else +const uint8_t tmcCRCTable_Poly7Reflected[256] = { + 0x00, 0x91, 0xE3, 0x72, 0x07, 0x96, 0xE4, 0x75, 0x0E, 0x9F, 0xED, 0x7C, 0x09, 0x98, 0xEA, 0x7B, + 0x1C, 0x8D, 0xFF, 0x6E, 0x1B, 0x8A, 0xF8, 0x69, 0x12, 0x83, 0xF1, 0x60, 0x15, 0x84, 0xF6, 0x67, + 0x38, 0xA9, 0xDB, 0x4A, 0x3F, 0xAE, 0xDC, 0x4D, 0x36, 0xA7, 0xD5, 0x44, 0x31, 0xA0, 0xD2, 0x43, + 0x24, 0xB5, 0xC7, 0x56, 0x23, 0xB2, 0xC0, 0x51, 0x2A, 0xBB, 0xC9, 0x58, 0x2D, 0xBC, 0xCE, 0x5F, + 0x70, 0xE1, 0x93, 0x02, 0x77, 0xE6, 0x94, 0x05, 0x7E, 0xEF, 0x9D, 0x0C, 0x79, 0xE8, 0x9A, 0x0B, + 0x6C, 0xFD, 0x8F, 0x1E, 0x6B, 0xFA, 0x88, 0x19, 0x62, 0xF3, 0x81, 0x10, 0x65, 0xF4, 0x86, 0x17, + 0x48, 0xD9, 0xAB, 0x3A, 0x4F, 0xDE, 0xAC, 0x3D, 0x46, 0xD7, 0xA5, 0x34, 0x41, 0xD0, 0xA2, 0x33, + 0x54, 0xC5, 0xB7, 0x26, 0x53, 0xC2, 0xB0, 0x21, 0x5A, 0xCB, 0xB9, 0x28, 0x5D, 0xCC, 0xBE, 0x2F, + 0xE0, 0x71, 0x03, 0x92, 0xE7, 0x76, 0x04, 0x95, 0xEE, 0x7F, 0x0D, 0x9C, 0xE9, 0x78, 0x0A, 0x9B, + 0xFC, 0x6D, 0x1F, 0x8E, 0xFB, 0x6A, 0x18, 0x89, 0xF2, 0x63, 0x11, 0x80, 0xF5, 0x64, 0x16, 0x87, + 0xD8, 0x49, 0x3B, 0xAA, 0xDF, 0x4E, 0x3C, 0xAD, 0xD6, 0x47, 0x35, 0xA4, 0xD1, 0x40, 0x32, 0xA3, + 0xC4, 0x55, 0x27, 0xB6, 0xC3, 0x52, 0x20, 0xB1, 0xCA, 0x5B, 0x29, 0xB8, 0xCD, 0x5C, 0x2E, 0xBF, + 0x90, 0x01, 0x73, 0xE2, 0x97, 0x06, 0x74, 0xE5, 0x9E, 0x0F, 0x7D, 0xEC, 0x99, 0x08, 0x7A, 0xEB, + 0x8C, 0x1D, 0x6F, 0xFE, 0x8B, 0x1A, 0x68, 0xF9, 0x82, 0x13, 0x61, 0xF0, 0x85, 0x14, 0x66, 0xF7, + 0xA8, 0x39, 0x4B, 0xDA, 0xAF, 0x3E, 0x4C, 0xDD, 0xA6, 0x37, 0x45, 0xD4, 0xA1, 0x30, 0x42, 0xD3, + 0xB4, 0x25, 0x57, 0xC6, 0xB3, 0x22, 0x50, 0xC1, 0xBA, 0x2B, 0x59, 0xC8, 0xBD, 0x2C, 0x5E, 0xCF, +}; +#endif + +/**************************************************************** Cache Implementation *************************************************************************/ +#if TMC5160_CACHE == 0 +static inline bool tmc5160_cache(uint16_t icID, TMC5160CacheOp operation, uint8_t address, uint32_t *value) +{ + UNUSED(icID); + UNUSED(address); + UNUSED(operation); + return false; +} +#else +#if TMC5160_ENABLE_TMC_CACHE == 1 +uint8_t tmc5160_dirtyBits[TMC5160_IC_CACHE_COUNT][TMC5160_REGISTER_COUNT/8]= {0}; +int32_t tmc5160_shadowRegister[TMC5160_IC_CACHE_COUNT][TMC5160_REGISTER_COUNT]; + +void tmc5160_setDirtyBit(uint16_t icID, uint8_t index, bool value) +{ + if(index >= TMC5160_REGISTER_COUNT) + return; + + uint8_t *tmp = &tmc5160_dirtyBits[icID][index / 8]; + uint8_t shift = (index % 8); + uint8_t mask = 1 << shift; + *tmp = (((*tmp) & (~(mask))) | (((value) << (shift)) & (mask))); +} + +bool tmc5160_getDirtyBit(uint16_t icID, uint8_t index) +{ + if(index >= TMC5160_REGISTER_COUNT) + return false; + + uint8_t *tmp = &tmc5160_dirtyBits[icID][index / 8]; + uint8_t shift = (index % 8); + return ((*tmp) >> shift) & 1; +} + +/* + * This function is used to cache the value written to the Write-Only registers in the form of shadow array. + * The shadow copy is then used to read these kinds of registers. + */ +bool tmc5160_cache(uint16_t icID, TMC5160CacheOp operation, uint8_t address, uint32_t *value) +{ + if (operation == TMC5160_CACHE_READ) + { + // Check if the value should come from cache + + // Only supported chips have a cache + if (icID >= TMC5160_IC_CACHE_COUNT) + return false; + + // Only non-readable registers care about caching + // Note: This could also be used to cache i.e. RW config registers to reduce bus accesses + if (TMC5160_IS_READABLE(tmc5160_registerAccess[address])) + return false; + + // Grab the value from the cache + *value = tmc5160_shadowRegister[icID][address]; + return true; + } + else if (operation == TMC5160_CACHE_WRITE || operation == TMC5160_CACHE_FILL_DEFAULT) + { + // Fill the cache + + // only supported chips have a cache + if (icID >= TMC5160_IC_CACHE_COUNT) + return false; + + // Write to the shadow register and mark the register dirty + tmc5160_shadowRegister[icID][address] = *value; + if (operation == TMC5160_CACHE_WRITE) + { + tmc5160_setDirtyBit(icID, address, true); + } + return true; + } + return false; +} +void tmc5160_initCache() +{ + // Check if we have constants defined + if(ARRAY_SIZE(tmc5160_RegisterConstants) == 0) + return; + + size_t i, j, id; + + for(i = 0, j = 0; i < TMC5160_REGISTER_COUNT; i++) + { + // We only need to worry about hardware preset, write-only registers + // that have not yet been written (no dirty bit) here. + if(tmc5160_registerAccess[i] != TMC5160_ACCESS_W_PRESET) + continue; + + // Search the constant list for the current address. With the constant + // list being sorted in ascended order, we can walk through the list + // until the entry with an address equal or greater than i + while(j < ARRAY_SIZE(tmc5160_RegisterConstants) && (tmc5160_RegisterConstants[j].address < i)) + j++; + + // Abort when we reach the end of the constant list + if (j == ARRAY_SIZE(tmc5160_RegisterConstants)) + break; + + // If we have an entry for our current address, write the constant + if(tmc5160_RegisterConstants[j].address == i) + { + for (id = 0; id < TMC5160_IC_CACHE_COUNT; id++) + { + uint32_t temp = tmc5160_RegisterConstants[j].value; + tmc5160_cache(id, TMC5160_CACHE_FILL_DEFAULT, i, &temp); + } + } + } +} +#else +// User must implement their own cache +extern bool tmc5160_cache(uint16_t icID, TMC5160CacheOp operation, uint8_t address, uint32_t *value); +#endif +#endif +/************************************************************** Register read / write Implementation ******************************************************************/ +static int32_t readRegisterSPI(uint16_t icID, uint8_t address); +static void writeRegisterSPI(uint16_t icID, uint8_t address, int32_t value); +static int32_t readRegisterUART(uint16_t icID, uint8_t registerAddress); +static void writeRegisterUART(uint16_t icID, uint8_t registerAddress, int32_t value); +static uint8_t CRC8(uint8_t *data, uint32_t bytes); + +int32_t tmc5160_readRegister(uint16_t icID, uint8_t address) +{ + uint32_t value; + + // Read from cache for registers with write-only access + if (tmc5160_cache(icID, TMC5160_CACHE_READ, address, &value)) + return value; + + TMC5160BusType bus = tmc5160_getBusType(icID); + + if(bus == IC_BUS_SPI) + { + return readRegisterSPI(icID, address); + } + else if (bus == IC_BUS_UART) + { + return readRegisterUART(icID, address); + } + + //ToDo: Error handling + return -1; +} + +void tmc5160_writeRegister(uint16_t icID, uint8_t address, int32_t value) +{ + TMC5160BusType bus = tmc5160_getBusType(icID); + + if(bus == IC_BUS_SPI) + { + writeRegisterSPI(icID, address, value); + } + else if(bus == IC_BUS_UART) + { + writeRegisterUART(icID, address, value); + + } +} + +int32_t readRegisterSPI(uint16_t icID, uint8_t address) +{ + uint8_t data[5] = { 0 }; + + address = address & TMC5160_ADDRESS_MASK; + + // clear write bit + data[0] = address; + + // Send the read request + tmc5160_readWriteSPI(icID, &data[0], sizeof(data)); + + // Rewrite address and clear write bit + data[0] = address; + + // Send another request to receive the read reply + tmc5160_readWriteSPI(icID, &data[0], sizeof(data)); + + return ((uint32_t)data[1] << 24) | ((uint32_t) data[2] << 16) | ( data[3] << 8) | ( data[4]); +} + +void writeRegisterSPI(uint16_t icID, uint8_t address, int32_t value) +{ + uint8_t data[5] = { 0 }; + + data[0] = address | TMC5160_WRITE_BIT; + data[1] = 0xFF & (value>>24); + data[2] = 0xFF & (value>>16); + data[3] = 0xFF & (value>>8); + data[4] = 0xFF & (value>>0); + + // Send the write request + tmc5160_readWriteSPI(icID, &data[0], sizeof(data)); + + //Cache the registers with write-only access + tmc5160_cache(icID, TMC5160_CACHE_WRITE, address, (uint32_t *)&value); +} + +int32_t readRegisterUART(uint16_t icID, uint8_t address) +{ + uint8_t data[8] = { 0 }; + + address = address & TMC5160_ADDRESS_MASK; + data[0] = 0x05; + data[1] = tmc5160_getNodeAddress(icID); //targetAddressUart; + data[2] = address; + data[3] = CRC8(data, 3); + + if (!tmc5160_readWriteUART(icID, &data[0], 4, 8)) + return 0; + + // Byte 0: Sync nibble correct? + if (data[0] != 0x05) + return 0; + + // Byte 1: Master address correct? + if (data[1] != 0xFF) + return 0; + + // Byte 2: Address correct? + if (data[2] != address) + return 0; + + // Byte 7: CRC correct? + if (data[7] != CRC8(data, 7)) + return 0; + + return ((uint32_t)data[3] << 24) | ((uint32_t)data[4] << 16) | (data[5] << 8) | data[6]; +} + +void writeRegisterUART(uint16_t icID, uint8_t address, int32_t value) +{ + uint8_t data[8]; + + data[0] = 0x05; + data[1] = tmc5160_getNodeAddress(icID); //targetAddressUart; + data[2] = address | TMC5160_WRITE_BIT; + data[3] = (value >> 24) & 0xFF; + data[4] = (value >> 16) & 0xFF; + data[5] = (value >> 8 ) & 0xFF; + data[6] = (value ) & 0xFF; + data[7] = CRC8(data, 7); + + tmc5160_readWriteUART(icID, &data[0], 8, 0); + + //Cache the registers with write-only access + tmc5160_cache(icID, TMC5160_CACHE_WRITE, address, (uint32_t *)&value); +} + +void tmc5160_rotateMotor(uint16_t icID, uint8_t motor, int32_t velocity) +{ + if(motor >= TMC5160_MOTORS) + return; + + tmc5160_writeRegister(icID, TMC5160_VMAX, (velocity >= 0)? velocity : -velocity); + tmc5160_fieldWrite(icID, TMC5160_RAMPMODE_FIELD, (velocity >= 0) ? TMC5160_MODE_VELPOS : TMC5160_MODE_VELNEG); +} + +static uint8_t CRC8(uint8_t *data, uint32_t bytes) +{ + uint8_t result = 0; + while(bytes--) + result = tmcCRCTable_Poly7Reflected[result ^ *data++]; + + // Flip the result around + // swap odd and even bits + result = ((result >> 1) & 0x55) | ((result & 0x55) << 1); + // swap consecutive pairs + result = ((result >> 2) & 0x33) | ((result & 0x33) << 2); + // swap nibbles ... + result = ((result >> 4) & 0x0F) | ((result & 0x0F) << 4); + + return result; +} + diff --git a/firmware/lib/tmc/ic/TMC5160/TMC5160.h b/firmware/lib/tmc/ic/TMC5160/TMC5160.h new file mode 100755 index 0000000..4543055 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5160/TMC5160.h @@ -0,0 +1,229 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#ifndef TMC_IC_TMC5160_H_ +#define TMC_IC_TMC5160_H_ + +#include "TMC5160_HW_Abstraction.h" +#include +#include +#include + +/******************************************************************************* +* API Configuration Defines +* These control optional features of the TMC-API implementation. +* These can be commented in/out here or defined from the build system. +*******************************************************************************/ + +// Uncomment if you want to save space..... +// and put the table into your own .c file +//#define TMC_API_EXTERNAL_CRC_TABLE 1 + +#ifndef TMC5160_CACHE +#define TMC5160_CACHE 1 +//#define TMC5160_CACHE 0 +#endif + +// To use the caching mechanism already implemented by the TMC-API, set TMC5160_ENABLE_TMC_CACHE to '1'. +// Set TMC5160_ENABLE_TMC_CACHE to '0' if one wants to have their own cache implementation. +#ifndef TMC5160_ENABLE_TMC_CACHE +#define TMC5160_ENABLE_TMC_CACHE 1 +//#define TMC5160_ENABLE_TMC_CACHE 0 +#endif + +/******************************************************************************/ + +typedef enum { + IC_BUS_SPI, + IC_BUS_UART, +} TMC5160BusType; + +typedef struct +{ + uint32_t mask; + uint8_t shift; + uint8_t address; + bool isSigned; +} RegisterField; + +// => TMC-API wrapper +extern void tmc5160_readWriteSPI(uint16_t icID, uint8_t *data, size_t dataLength); +extern bool tmc5160_readWriteUART(uint16_t icID, uint8_t *data, size_t writeLength, size_t readLength); +extern TMC5160BusType tmc5160_getBusType(uint16_t icID); +extern uint8_t tmc5160_getNodeAddress(uint16_t icID); +// => TMC-API wrapper + +int32_t tmc5160_readRegister(uint16_t icID, uint8_t address); +void tmc5160_writeRegister(uint16_t icID, uint8_t address, int32_t value); +void tmc5160_rotateMotor(uint16_t icID, uint8_t motor, int32_t velocity); + +static inline uint32_t tmc5160_fieldExtract(uint32_t data, RegisterField field) +{ + uint32_t value = (data & field.mask) >> field.shift; + + if (field.isSigned) + { + // Apply signedness conversion + uint32_t baseMask = field.mask >> field.shift; + uint32_t signMask = baseMask & (~baseMask >> 1); + value = (value ^ signMask) - signMask; + } + + return value; +} + +static inline uint32_t tmc5160_fieldRead(uint16_t icID, RegisterField field) +{ + uint32_t value = tmc5160_readRegister(icID, field.address); + + return tmc5160_fieldExtract(value, field); +} + +static inline uint32_t tmc5160_fieldUpdate(uint32_t data, RegisterField field, uint32_t value) +{ + return (data & (~field.mask)) | ((value << field.shift) & field.mask); +} + +static inline void tmc5160_fieldWrite(uint16_t icID, RegisterField field, uint32_t value) +{ + uint32_t regValue = tmc5160_readRegister(icID, field.address); + + regValue = tmc5160_fieldUpdate(regValue, field, value); + + tmc5160_writeRegister(icID, field.address, regValue); +} + +/**************************************************************** Cache Implementation *************************************************************************/ + +#if TMC5160_CACHE == 1 +#if TMC5160_ENABLE_TMC_CACHE == 1 + +// By default, support one IC in the cache +#ifndef TMC5160_IC_CACHE_COUNT +#define TMC5160_IC_CACHE_COUNT 1 +#endif + +typedef enum { + TMC5160_CACHE_READ, + TMC5160_CACHE_WRITE, + + // Special operation: Put content into the cache without marking the entry as dirty. + // Only used to initialize the cache with hardware defaults. This will allow reading + // from write-only registers that have a value inside them on reset. When using this + // operation, a restore will *not* rewrite that filled register! + TMC5160_CACHE_FILL_DEFAULT + +} TMC5160CacheOp; + +typedef struct +{ + uint8_t address; + uint32_t value; +} TMC5160RegisterConstants; + +#define TMC5160_ACCESS_DIRTY 0x08 // Register has been written since reset -> shadow register is valid for restore +#define TMC5160_ACCESS_READ 0x01 +#define TMC5160_ACCESS_W_PRESET 0x42 +#define TMC5160_IS_READABLE(x) ((x) & TMC5160_ACCESS_READ) +#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) + +// Default Register values +#define R00 0x00000008 // GCONF +#define R09 0x00010606 // SHORTCONF +#define R0A 0x00080400 // DRVCONF +#define R10 0x00070A03 // IHOLD_IRUN +#define R11 0x0000000A // TPOWERDOWN +#define R2B 0x00000001 // VSTOP +#define R3A 0x00010000 // ENC_CONST +#define R6C 0x00410153 // CHOPCONF +#define R70 0xC40C001E // PWMCONF + +#define ____ 0x00 +#ifndef N_A + #define N_A 0x00 +#endif + +static const int32_t tmc5160_sampleRegisterPreset[TMC5160_REGISTER_COUNT] = +{ +// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F + R00, 0, 0, 0, 0, 0, 0, 0, 0, R09, R0A, 0, 0, 0, 0, 0, // 0x00 - 0x0F + R10, R11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x10 - 0x1F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, R2B, 0, 0, 0, 0, // 0x20 - 0x2F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, R3A, 0, 0, 0, 0, 0, // 0x30 - 0x3F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x40 - 0x4F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x50 - 0x5F + N_A, N_A, N_A, N_A, N_A, N_A, N_A, N_A, N_A, N_A, 0, 0, R6C, 0, 0, 0, // 0x60 - 0x6F + N_A, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x70 - 0x7F +}; + +// Undefine the default register values. +// This prevents warnings in case multiple TMC-API chip headers are included at once +#undef R00 +#undef R09 +#undef R0A +#undef R10 +#undef R11 +#undef R2B +#undef R3A +#undef R6C +#undef R70 + + +// Register access permissions: +// 0x00: none (reserved) +// 0x01: read +// 0x02: write +// 0x03: read/write +// 0x13: read/write, separate functions/values for reading or writing +// 0x23: read/write, flag register (write to clear) +// 0x42: write, has hardware presets on reset +static const uint8_t tmc5160_registerAccess[TMC5160_REGISTER_COUNT] = +{ +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0x03, 0x23, 0x01, 0x02, 0x13, 0x02, 0x02, 0x01, 0x03, 0x02, 0x02, 0x02, 0x01, ____, ____, ____, // 0x00 - 0x0F + 0x02, 0x02, 0x01, 0x02, 0x02, 0x02, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x10 - 0x1F + 0x03, 0x03, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, ____, 0x02, 0x02, 0x02, 0x03, ____, ____, // 0x20 - 0x2F + ____, ____, ____, 0x02, 0x03, 0x23, 0x01, ____, 0x03, 0x03, 0x02, 0x23, 0x01, 0x02, ____, ____, // 0x30 - 0x3F + ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x40 - 0x4F + ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x50 - 0x5F + 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x01, 0x01, 0x03, 0x02, 0x02, 0x01, // 0x60 - 0x6F + 0x42, 0x01, 0x01, 0x01, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____ // 0x70 - 0x7F +}; + +// Register constants (only required for 0x42 registers, since we do not have +// any way to find out the content but want to hold the actual value in the +// shadow register so an application (i.e. the TMCL IDE) can still display +// the values. This only works when the register content is constant. +static const TMC5160RegisterConstants tmc5160_RegisterConstants[] = +{ // Use ascending addresses! + { 0x60, 0xAAAAB554 }, // MSLUT[0] + { 0x61, 0x4A9554AA }, // MSLUT[1] + { 0x62, 0x24492929 }, // MSLUT[2] + { 0x63, 0x10104222 }, // MSLUT[3] + { 0x64, 0xFBFFFFFF }, // MSLUT[4] + { 0x65, 0xB5BB777D }, // MSLUT[5] + { 0x66, 0x49295556 }, // MSLUT[6] + { 0x67, 0x00404222 }, // MSLUT[7] + { 0x68, 0xFFFF8056 }, // MSLUTSEL + { 0x69, 0x00F70000 }, // MSLUTSTART + { 0x70, 0xC40C001E } // PWMCONF +}; + +extern uint8_t tmc5160_dirtyBits[TMC5160_IC_CACHE_COUNT][TMC5160_REGISTER_COUNT/8]; +extern int32_t tmc5160_shadowRegister[TMC5160_IC_CACHE_COUNT][TMC5160_REGISTER_COUNT]; +void tmc5160_setDirtyBit(uint16_t icID, uint8_t index, bool value); +bool tmc5160_getDirtyBit(uint16_t icID, uint8_t index); +extern bool tmc5160_cache(uint16_t icID, TMC5160CacheOp operation, uint8_t address, uint32_t *value); +void tmc5160_initCache(void); +#endif +#endif + +/***************************************************************************************************************************************************/ + +#endif /* TMC_IC_TMC5160_H_ */ diff --git a/firmware/lib/tmc/ic/TMC5160/TMC5160_HW_Abstraction.h b/firmware/lib/tmc/ic/TMC5160/TMC5160_HW_Abstraction.h new file mode 100755 index 0000000..722847e --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5160/TMC5160_HW_Abstraction.h @@ -0,0 +1,1619 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + +#ifndef TMC5160_HW_ABSTRACTION +#define TMC5160_HW_ABSTRACTION + +// constants + +#define TMC5160_REGISTER_COUNT 128 +#define TMC5160_MOTORS 1 +#define TMC5160_WRITE_BIT 0x80 +#define TMC5160_ADDRESS_MASK 0x7F +#define TMC5160_MAX_VELOCITY 8388096 +#define TMC5160_MAX_ACCELERATION 65535 + +// ramp modes (Register TMC5160_RAMPMODE) +#define TMC5160_MODE_POSITION 0 +#define TMC5160_MODE_VELPOS 1 +#define TMC5160_MODE_VELNEG 2 +#define TMC5160_MODE_HOLD 3 + +// limit switch mode bits (Register TMC5160_SWMODE) +#define TMC5160_SW_STOPL_ENABLE 0x0001 +#define TMC5160_SW_STOPR_ENABLE 0x0002 +#define TMC5160_SW_STOPL_POLARITY 0x0004 +#define TMC5160_SW_STOPR_POLARITY 0x0008 +#define TMC5160_SW_SWAP_LR 0x0010 +#define TMC5160_SW_LATCH_L_ACT 0x0020 +#define TMC5160_SW_LATCH_L_INACT 0x0040 +#define TMC5160_SW_LATCH_R_ACT 0x0080 +#define TMC5160_SW_LATCH_R_INACT 0x0100 +#define TMC5160_SW_LATCH_ENC 0x0200 +#define TMC5160_SW_SG_STOP 0x0400 +#define TMC5160_SW_SOFTSTOP 0x0800 + +// Status bits (Register TMC5160_RAMPSTAT) +#define TMC5160_RS_STOPL 0x0001 +#define TMC5160_RS_STOPR 0x0002 +#define TMC5160_RS_LATCHL 0x0004 +#define TMC5160_RS_LATCHR 0x0008 +#define TMC5160_RS_EV_STOPL 0x0010 +#define TMC5160_RS_EV_STOPR 0x0020 +#define TMC5160_RS_EV_STOP_SG 0x0040 +#define TMC5160_RS_EV_POSREACHED 0x0080 +#define TMC5160_RS_VELREACHED 0x0100 +#define TMC5160_RS_POSREACHED 0x0200 +#define TMC5160_RS_VZERO 0x0400 +#define TMC5160_RS_ZEROWAIT 0x0800 +#define TMC5160_RS_SECONDMOVE 0x1000 +#define TMC5160_RS_SG 0x2000 + +// Encoderbits (Register TMC5160_ENCMODE) +#define TMC5160_EM_DECIMAL 0x0400 +#define TMC5160_EM_LATCH_XACT 0x0200 +#define TMC5160_EM_CLR_XENC 0x0100 +#define TMC5160_EM_NEG_EDGE 0x0080 +#define TMC5160_EM_POS_EDGE 0x0040 +#define TMC5160_EM_CLR_ONCE 0x0020 +#define TMC5160_EM_CLR_CONT 0x0010 +#define TMC5160_EM_IGNORE_AB 0x0008 +#define TMC5160_EM_POL_N 0x0004 +#define TMC5160_EM_POL_B 0x0002 +#define TMC5160_EM_POL_A 0x0001 + + +// Registers in TMC5160 + +#define TMC5160_GCONF 0x00 +#define TMC5160_GSTAT 0x01 +#define TMC5160_IFCNT 0x02 +#define TMC5160_SLAVECONF 0x03 +#define TMC5160_INP_OUT 0x04 +#define TMC5160_X_COMPARE 0x05 +#define TMC5160_OTP_PROG 0x06 +#define TMC5160_OTP_READ 0x07 +#define TMC5160_FACTORY_CONF 0x08 +#define TMC5160_SHORT_CONF 0x09 +#define TMC5160_DRV_CONF 0x0A +#define TMC5160_GLOBAL_SCALER 0x0B +#define TMC5160_OFFSET_READ 0x0C +#define TMC5160_IHOLD_IRUN 0x10 +#define TMC5160_TPOWERDOWN 0x11 +#define TMC5160_TSTEP 0x12 +#define TMC5160_TPWMTHRS 0x13 +#define TMC5160_TCOOLTHRS 0x14 +#define TMC5160_THIGH 0x15 + +#define TMC5160_RAMPMODE 0x20 +#define TMC5160_XACTUAL 0x21 +#define TMC5160_VACTUAL 0x22 +#define TMC5160_VSTART 0x23 +#define TMC5160_A1 0x24 +#define TMC5160_V1 0x25 +#define TMC5160_AMAX 0x26 +#define TMC5160_VMAX 0x27 +#define TMC5160_DMAX 0x28 +#define TMC5160_D1 0x2A +#define TMC5160_VSTOP 0x2B +#define TMC5160_TZEROWAIT 0x2C +#define TMC5160_XTARGET 0x2D + +#define TMC5160_VDCMIN 0x33 +#define TMC5160_SWMODE 0x34 +#define TMC5160_RAMPSTAT 0x35 +#define TMC5160_XLATCH 0x36 +#define TMC5160_ENCMODE 0x38 +#define TMC5160_XENC 0x39 +#define TMC5160_ENC_CONST 0x3A +#define TMC5160_ENC_STATUS 0x3B +#define TMC5160_ENC_LATCH 0x3C +#define TMC5160_ENC_DEVIATION 0x3D + +#define TMC5160_MSLUT0 0x60 +#define TMC5160_MSLUT1 0x61 +#define TMC5160_MSLUT2 0x62 +#define TMC5160_MSLUT3 0x63 +#define TMC5160_MSLUT4 0x64 +#define TMC5160_MSLUT5 0x65 +#define TMC5160_MSLUT6 0x66 +#define TMC5160_MSLUT7 0x67 +#define TMC5160_MSLUTSEL 0x68 +#define TMC5160_MSLUTSTART 0x69 +#define TMC5160_MSCNT 0x6A +#define TMC5160_MSCURACT 0x6B +#define TMC5160_CHOPCONF 0x6C +#define TMC5160_COOLCONF 0x6D +#define TMC5160_DCCTRL 0x6E +#define TMC5160_DRV_STATUS 0x6F +#define TMC5160_PWMCONF 0x70 +#define TMC5160_PWM_SCALE 0x71 +#define TMC5160_PWM_AUTO 0x72 +#define TMC5160_LOST_STEPS 0x73 + + +// Fields in TMC5160 + +// Status fields returned with every SPI transaction +#define TMC5160_SPI_STATUS_RESET_FLAG_MASK 0x01 /* GSTAT0 - 1: Signals, that a reset has occurred (clear by reading GSTAT) */ +#define TMC5160_SPI_STATUS_RESET_FLAG_SHIFT 0 +#define TMC5160_SPI_STATUS_RESET_FLAG_FIELD ((RegisterField) {TMC5160_SPI_STATUS_RESET_FLAG_MASK, TMC5160_SPI_STATUS_RESET_FLAG_SHIFT, TMC5160_GSTAT, false}) +#define TMC5160_SPI_STATUS_DRIVER_ERROR_MASK 0x02 /* GSTAT1 – 1: Signals driver 1 driver error (clear by reading GSTAT) */ +#define TMC5160_SPI_STATUS_DRIVER_ERROR_SHIFT 1 +#define TMC5160_SPI_STATUS_DRIVER_ERROR_FIELD ((RegisterField) {TMC5160_SPI_STATUS_DRIVER_ERROR_MASK, TMC5160_SPI_STATUS_DRIVER_ERROR_SHIFT, TMC5160_GSTAT, false}) +#define TMC5160_SPI_STATUS_SG2_MASK 0x04 /* DRV_STATUS[24] – 1: Signals StallGuard flag active */ +#define TMC5160_SPI_STATUS_SG2_SHIFT 2 +#define TMC5160_SPI_STATUS_SG2_FIELD ((RegisterField) {TMC5160_SPI_STATUS_SG2_MASK, TMC5160_SPI_STATUS_SG2_SHIFT, TMC5160_DRV_STATUS, false}) +#define TMC5160_SPI_STATUS_STANDSTILL_MASK 0x08 /* DRV_STATUS[31] – 1: Signals motor stand still */ +#define TMC5160_SPI_STATUS_STANDSTILL_SHIFT 3 +#define TMC5160_SPI_STATUS_STANDSTILL_FIELD ((RegisterField) {TMC5160_SPI_STATUS_STANDSTILL_MASK, TMC5160_SPI_STATUS_STANDSTILL_SHIFT, TMC5160_DRV_STATUS, false}) +#define TMC5160_SPI_STATUS_VELOCITY_REACHED_MASK 0x10 /* RAMPSTAT[8] – 1: Signals target velocity reached (motion controller only) */ +#define TMC5160_SPI_STATUS_VELOCITY_REACHED_SHIFT 4 +#define TMC5160_SPI_STATUS_VELOCITY_REACHED_FIELD ((RegisterField) {TMC5160_SPI_STATUS_VELOCITY_REACHED_MASK, TMC5160_SPI_STATUS_VELOCITY_REACHED_SHIFT, TMC5160_RAMPSTAT, false}) +#define TMC5160_SPI_STATUS_POSITION_REACHED_MASK 0x20 /* RAMPSTAT[9] – 1: Signals target position reached (motion controller only) */ +#define TMC5160_SPI_STATUS_POSITION_REACHED_SHIFT 5 +#define TMC5160_SPI_STATUS_POSITION_REACHED_FIELD ((RegisterField) {TMC5160_SPI_STATUS_POSITION_REACHED_MASK, TMC5160_SPI_STATUS_POSITION_REACHED_SHIFT, TMC5160_RAMPSTAT, false}) +#define TMC5160_SPI_STATUS_STATUS_STOP_L_MASK 0x40 /* RAMPSTAT0 – 1: Signals stop left switch status (motion controller only) */ +#define TMC5160_SPI_STATUS_STATUS_STOP_L_SHIFT 6 +#define TMC5160_SPI_STATUS_STATUS_STOP_L_FIELD ((RegisterField) {TMC5160_SPI_STATUS_STATUS_STOP_L_MASK, TMC5160_SPI_STATUS_STATUS_STOP_L_SHIFT, TMC5160_RAMPSTAT, false}) +#define TMC5160_SPI_STATUS_STATUS_STOP_R_MASK 0x80 /* RAMPSTAT1 – 1: Signals stop right switch status (motion controller only) */ +#define TMC5160_SPI_STATUS_STATUS_STOP_R_SHIFT 7 +#define TMC5160_SPI_STATUS_STATUS_STOP_R_FIELD ((RegisterField) {TMC5160_SPI_STATUS_STATUS_STOP_R_MASK, TMC5160_SPI_STATUS_STATUS_STOP_R_SHIFT, TMC5160_RAMPSTAT, false}) + +// Register fields in TMC5160 +#define TMC5160_RECALIBRATE_MASK 0x00000001 +#define TMC5160_RECALIBRATE_SHIFT 0 +#define TMC5160_RECALIBRATE_FIELD ((RegisterField) {TMC5160_RECALIBRATE_MASK, TMC5160_RECALIBRATE_SHIFT, TMC5160_GCONF, false}) +#define TMC5160_FASTSTANDSTILL_MASK 0x00000002 +#define TMC5160_FASTSTANDSTILL_SHIFT 1 +#define TMC5160_FASTSTANDSTILL_FIELD ((RegisterField) {TMC5160_FASTSTANDSTILL_MASK, TMC5160_FASTSTANDSTILL_SHIFT, TMC5160_GCONF, false}) +#define TMC5160_EN_PWM_MODE_MASK 0x00000004 +#define TMC5160_EN_PWM_MODE_SHIFT 2 +#define TMC5160_EN_PWM_MODE_FIELD ((RegisterField) {TMC5160_EN_PWM_MODE_MASK, TMC5160_EN_PWM_MODE_SHIFT, TMC5160_GCONF, false}) +#define TMC5160_MULTISTEP_FILT_MASK 0x00000008 +#define TMC5160_MULTISTEP_FILT_SHIFT 3 +#define TMC5160_MULTISTEP_FILT_FIELD ((RegisterField) {TMC5160_MULTISTEP_FILT_MASK, TMC5160_MULTISTEP_FILT_SHIFT, TMC5160_GCONF, false}) +#define TMC5160_SHAFT_MASK 0x00000010 +#define TMC5160_SHAFT_SHIFT 4 +#define TMC5160_SHAFT_FIELD ((RegisterField) {TMC5160_SHAFT_MASK, TMC5160_SHAFT_SHIFT, TMC5160_GCONF, false}) +#define TMC5160_DIAG0_ERROR__ONLY_WITH_SD_MODE_1__MASK 0x00000020 +#define TMC5160_DIAG0_ERROR__ONLY_WITH_SD_MODE_1__SHIFT 5 +#define TMC5160_DIAG0_ERROR__ONLY_WITH_SD_MODE_1__FIELD ((RegisterField) {TMC5160_DIAG0_ERROR__ONLY_WITH_SD_MODE_1__MASK, TMC5160_DIAG0_ERROR__ONLY_WITH_SD_MODE_1__SHIFT, TMC5160_GCONF, false}) +#define TMC5160_DIAG0_OTPW__ONLY_WITH_SD_MODE_1__MASK 0x00000040 +#define TMC5160_DIAG0_OTPW__ONLY_WITH_SD_MODE_1__SHIFT 6 +#define TMC5160_DIAG0_OTPW__ONLY_WITH_SD_MODE_1__FIELD ((RegisterField) {TMC5160_DIAG0_OTPW__ONLY_WITH_SD_MODE_1__MASK, TMC5160_DIAG0_OTPW__ONLY_WITH_SD_MODE_1__SHIFT, TMC5160_GCONF, false}) +#define TMC5160_DIAG0_STALL_MASK 0x00000080 +#define TMC5160_DIAG0_STALL_SHIFT 7 +#define TMC5160_DIAG0_STALL_FIELD ((RegisterField) {TMC5160_DIAG0_STALL_MASK, TMC5160_DIAG0_STALL_SHIFT, TMC5160_GCONF, false}) +#define TMC5160_DIAG1_STALL_MASK 0x00000100 +#define TMC5160_DIAG1_STALL_SHIFT 8 +#define TMC5160_DIAG1_STALL_FIELD ((RegisterField) {TMC5160_DIAG1_STALL_MASK, TMC5160_DIAG1_STALL_SHIFT, TMC5160_GCONF, false}) +#define TMC5160_DIAG1_INDEX_MASK 0x00000200 +#define TMC5160_DIAG1_INDEX_SHIFT 9 +#define TMC5160_DIAG1_INDEX_FIELD ((RegisterField) {TMC5160_DIAG1_INDEX_MASK, TMC5160_DIAG1_INDEX_SHIFT, TMC5160_GCONF, false}) +#define TMC5160_DIAG1_ONSTATE_MASK 0x00000400 +#define TMC5160_DIAG1_ONSTATE_SHIFT 10 +#define TMC5160_DIAG1_ONSTATE_FIELD ((RegisterField) {TMC5160_DIAG1_ONSTATE_MASK, TMC5160_DIAG1_ONSTATE_SHIFT, TMC5160_GCONF, false}) +#define TMC5160_DIAG1_STEPS_SKIPPED_MASK 0x00000800 +#define TMC5160_DIAG1_STEPS_SKIPPED_SHIFT 11 +#define TMC5160_DIAG1_STEPS_SKIPPED_FIELD ((RegisterField) {TMC5160_DIAG1_STEPS_SKIPPED_MASK, TMC5160_DIAG1_STEPS_SKIPPED_SHIFT, TMC5160_GCONF, false}) +#define TMC5160_DIAG0_INT_PUSHPULL_MASK 0x00001000 +#define TMC5160_DIAG0_INT_PUSHPULL_SHIFT 12 +#define TMC5160_DIAG0_INT_PUSHPULL_FIELD ((RegisterField) {TMC5160_DIAG0_INT_PUSHPULL_MASK, TMC5160_DIAG0_INT_PUSHPULL_SHIFT, TMC5160_GCONF, false}) +#define TMC5160_DIAG1_POSCOMP_PUSHPULL_MASK 0x00002000 +#define TMC5160_DIAG1_POSCOMP_PUSHPULL_SHIFT 13 +#define TMC5160_DIAG1_POSCOMP_PUSHPULL_FIELD ((RegisterField) {TMC5160_DIAG1_POSCOMP_PUSHPULL_MASK, TMC5160_DIAG1_POSCOMP_PUSHPULL_SHIFT, TMC5160_GCONF, false}) +#define TMC5160_SMALL_HYSTERESIS_MASK 0x00004000 +#define TMC5160_SMALL_HYSTERESIS_SHIFT 14 +#define TMC5160_SMALL_HYSTERESIS_FIELD ((RegisterField) {TMC5160_SMALL_HYSTERESIS_MASK, TMC5160_SMALL_HYSTERESIS_SHIFT, TMC5160_GCONF, false}) +#define TMC5160_STOP_ENABLE_MASK 0x00008000 +#define TMC5160_STOP_ENABLE_SHIFT 15 +#define TMC5160_STOP_ENABLE_FIELD ((RegisterField) {TMC5160_STOP_ENABLE_MASK, TMC5160_STOP_ENABLE_SHIFT, TMC5160_GCONF, false}) +#define TMC5160_DIRECT_MODE_MASK 0x00010000 +#define TMC5160_DIRECT_MODE_SHIFT 16 +#define TMC5160_DIRECT_MODE_FIELD ((RegisterField) {TMC5160_DIRECT_MODE_MASK, TMC5160_DIRECT_MODE_SHIFT, TMC5160_GCONF, false}) +#define TMC5160_TEST_MODE_MASK 0x00020000 +#define TMC5160_TEST_MODE_SHIFT 17 +#define TMC5160_TEST_MODE_FIELD ((RegisterField) {TMC5160_TEST_MODE_MASK, TMC5160_TEST_MODE_SHIFT, TMC5160_GCONF, false}) +#define TMC5160_RECALIBRATE_MASK 0x00000001 +#define TMC5160_RECALIBRATE_SHIFT 0 +#define TMC5160_RECALIBRATE_FIELD ((RegisterField) {TMC5160_RECALIBRATE_MASK, TMC5160_RECALIBRATE_SHIFT, TMC5160_GCONF, false}) +#define TMC5160_FASTSTANDSTILL_MASK 0x00000002 +#define TMC5160_FASTSTANDSTILL_SHIFT 1 +#define TMC5160_FASTSTANDSTILL_FIELD ((RegisterField) {TMC5160_FASTSTANDSTILL_MASK, TMC5160_FASTSTANDSTILL_SHIFT, TMC5160_GCONF, false}) +#define TMC5160_EN_PWM_MODE_MASK 0x00000004 +#define TMC5160_EN_PWM_MODE_SHIFT 2 +#define TMC5160_EN_PWM_MODE_FIELD ((RegisterField) {TMC5160_EN_PWM_MODE_MASK, TMC5160_EN_PWM_MODE_SHIFT, TMC5160_GCONF, false}) +#define TMC5160_MULTISTEP_FILT_MASK 0x00000008 +#define TMC5160_MULTISTEP_FILT_SHIFT 3 +#define TMC5160_MULTISTEP_FILT_FIELD ((RegisterField) {TMC5160_MULTISTEP_FILT_MASK, TMC5160_MULTISTEP_FILT_SHIFT, TMC5160_GCONF, false}) +#define TMC5160_SHAFT_MASK 0x00000010 +#define TMC5160_SHAFT_SHIFT 4 +#define TMC5160_SHAFT_FIELD ((RegisterField) {TMC5160_SHAFT_MASK, TMC5160_SHAFT_SHIFT, TMC5160_GCONF, false}) +#define TMC5160_DIAG0_STEP_MASK 0x00000080 +#define TMC5160_DIAG0_STEP_SHIFT 7 +#define TMC5160_DIAG0_STEP_FIELD ((RegisterField) {TMC5160_DIAG0_STEP_MASK, TMC5160_DIAG0_STEP_SHIFT, TMC5160_GCONF, false}) +#define TMC5160_DIAG1_DIR_MASK 0x00000100 +#define TMC5160_DIAG1_DIR_SHIFT 8 +#define TMC5160_DIAG1_DIR_FIELD ((RegisterField) {TMC5160_DIAG1_DIR_MASK, TMC5160_DIAG1_DIR_SHIFT, TMC5160_GCONF, false}) +#define TMC5160_DIAG0_INT_PUSHPULL_MASK 0x00001000 +#define TMC5160_DIAG0_INT_PUSHPULL_SHIFT 12 +#define TMC5160_DIAG0_INT_PUSHPULL_FIELD ((RegisterField) {TMC5160_DIAG0_INT_PUSHPULL_MASK, TMC5160_DIAG0_INT_PUSHPULL_SHIFT, TMC5160_GCONF, false}) +#define TMC5160_DIAG1_POSCOMP_PUSHPULL_MASK 0x00002000 +#define TMC5160_DIAG1_POSCOMP_PUSHPULL_SHIFT 13 +#define TMC5160_DIAG1_POSCOMP_PUSHPULL_FIELD ((RegisterField) {TMC5160_DIAG1_POSCOMP_PUSHPULL_MASK, TMC5160_DIAG1_POSCOMP_PUSHPULL_SHIFT, TMC5160_GCONF, false}) +#define TMC5160_SMALL_HYSTERESIS_MASK 0x00004000 +#define TMC5160_SMALL_HYSTERESIS_SHIFT 14 +#define TMC5160_SMALL_HYSTERESIS_FIELD ((RegisterField) {TMC5160_SMALL_HYSTERESIS_MASK, TMC5160_SMALL_HYSTERESIS_SHIFT, TMC5160_GCONF, false}) +#define TMC5160_STOP_ENABLE_MASK 0x00008000 +#define TMC5160_STOP_ENABLE_SHIFT 15 +#define TMC5160_STOP_ENABLE_FIELD ((RegisterField) {TMC5160_STOP_ENABLE_MASK, TMC5160_STOP_ENABLE_SHIFT, TMC5160_GCONF, false}) +#define TMC5160_DIRECT_MODE_MASK 0x00010000 +#define TMC5160_DIRECT_MODE_SHIFT 16 +#define TMC5160_DIRECT_MODE_FIELD ((RegisterField) {TMC5160_DIRECT_MODE_MASK, TMC5160_DIRECT_MODE_SHIFT, TMC5160_GCONF, false}) +#define TMC5160_TEST_MODE_MASK 0x00020000 +#define TMC5160_TEST_MODE_SHIFT 17 +#define TMC5160_TEST_MODE_FIELD ((RegisterField) {TMC5160_TEST_MODE_MASK, TMC5160_TEST_MODE_SHIFT, TMC5160_GCONF, false}) +#define TMC5160_RESET_MASK 0x00000001 +#define TMC5160_RESET_SHIFT 0 +#define TMC5160_RESET_FIELD ((RegisterField) {TMC5160_RESET_MASK, TMC5160_RESET_SHIFT, TMC5160_GSTAT, false}) +#define TMC5160_DRV_ERR_MASK 0x00000002 +#define TMC5160_DRV_ERR_SHIFT 1 +#define TMC5160_DRV_ERR_FIELD ((RegisterField) {TMC5160_DRV_ERR_MASK, TMC5160_DRV_ERR_SHIFT, TMC5160_GSTAT, false}) +#define TMC5160_UV_CP_MASK 0x00000004 +#define TMC5160_UV_CP_SHIFT 2 +#define TMC5160_UV_CP_FIELD ((RegisterField) {TMC5160_UV_CP_MASK, TMC5160_UV_CP_SHIFT, TMC5160_GSTAT, false}) +#define TMC5160_IFCNT_MASK 0x000000FF +#define TMC5160_IFCNT_SHIFT 0 +#define TMC5160_IFCNT_FIELD ((RegisterField) {TMC5160_IFCNT_MASK, TMC5160_IFCNT_SHIFT, TMC5160_IFCNT, false}) +#define TMC5160_SLAVEADDR_MASK 0x000000FF +#define TMC5160_SLAVEADDR_SHIFT 0 +#define TMC5160_SLAVEADDR_FIELD ((RegisterField) {TMC5160_SLAVEADDR_MASK, TMC5160_SLAVEADDR_SHIFT, TMC5160_SLAVECONF, false}) +#define TMC5160_SENDDELAY_MASK 0x00000F00 +#define TMC5160_SENDDELAY_SHIFT 8 +#define TMC5160_SENDDELAY_FIELD ((RegisterField) {TMC5160_SENDDELAY_MASK, TMC5160_SENDDELAY_SHIFT, TMC5160_SLAVECONF, false}) +#define TMC5160_REFL_STEP_MASK 0x00000001 +#define TMC5160_REFL_STEP_SHIFT 0 +#define TMC5160_REFL_STEP_FIELD ((RegisterField) {TMC5160_REFL_STEP_MASK, TMC5160_REFL_STEP_SHIFT, TMC5160_INP_OUT, false}) +#define TMC5160_REFR_DIR_MASK 0x00000002 +#define TMC5160_REFR_DIR_SHIFT 1 +#define TMC5160_REFR_DIR_FIELD ((RegisterField) {TMC5160_REFR_DIR_MASK, TMC5160_REFR_DIR_SHIFT, TMC5160_INP_OUT, false}) +#define TMC5160_ENCB_DCEN_CFG4_MASK 0x00000004 +#define TMC5160_ENCB_DCEN_CFG4_SHIFT 2 +#define TMC5160_ENCB_DCEN_CFG4_FIELD ((RegisterField) {TMC5160_ENCB_DCEN_CFG4_MASK, TMC5160_ENCB_DCEN_CFG4_SHIFT, TMC5160_INP_OUT, false}) +#define TMC5160_ENCA_DCIN_CFG5_MASK 0x00000008 +#define TMC5160_ENCA_DCIN_CFG5_SHIFT 3 +#define TMC5160_ENCA_DCIN_CFG5_FIELD ((RegisterField) {TMC5160_ENCA_DCIN_CFG5_MASK, TMC5160_ENCA_DCIN_CFG5_SHIFT, TMC5160_INP_OUT, false}) +#define TMC5160_DRV_ENN_CFG6_MASK 0x00000010 +#define TMC5160_DRV_ENN_CFG6_SHIFT 4 +#define TMC5160_DRV_ENN_CFG6_FIELD ((RegisterField) {TMC5160_DRV_ENN_CFG6_MASK, TMC5160_DRV_ENN_CFG6_SHIFT, TMC5160_INP_OUT, false}) +#define TMC5160_ENC_N_DCO_MASK 0x00000020 +#define TMC5160_ENC_N_DCO_SHIFT 5 +#define TMC5160_ENC_N_DCO_FIELD ((RegisterField) {TMC5160_ENC_N_DCO_MASK, TMC5160_ENC_N_DCO_SHIFT, TMC5160_INP_OUT, false}) +#define TMC5160_SD_MODE_MASK 0x00000040 +#define TMC5160_SD_MODE_SHIFT 6 +#define TMC5160_SD_MODE_FIELD ((RegisterField) {TMC5160_SD_MODE_MASK, TMC5160_SD_MODE_SHIFT, TMC5160_INP_OUT, false}) +#define TMC5160_SWCOMP_IN_MASK 0x00000080 +#define TMC5160_SWCOMP_IN_SHIFT 7 +#define TMC5160_SWCOMP_IN_FIELD ((RegisterField) {TMC5160_SWCOMP_IN_MASK, TMC5160_SWCOMP_IN_SHIFT, TMC5160_INP_OUT, false}) +#define TMC5160_VERSION_MASK 0xFF000000 +#define TMC5160_VERSION_SHIFT 24 +#define TMC5160_VERSION_FIELD ((RegisterField) {TMC5160_VERSION_MASK, TMC5160_VERSION_SHIFT, TMC5160_INP_OUT, false}) +#define TMC5160_OUTPUT_PIN_POLARITY_MASK 0x00000001 +#define TMC5160_OUTPUT_PIN_POLARITY_SHIFT 0 +#define TMC5160_OUTPUT_PIN_POLARITY_FIELD ((RegisterField) {TMC5160_OUTPUT_PIN_POLARITY_MASK, TMC5160_OUTPUT_PIN_POLARITY_SHIFT, TMC5160_INP_OUT, false}) +#define TMC5160_X_COMPARE_MASK 0xFFFFFFFF +#define TMC5160_X_COMPARE_SHIFT 0 +#define TMC5160_X_COMPARE_FIELD ((RegisterField) {TMC5160_X_COMPARE_MASK, TMC5160_X_COMPARE_SHIFT, TMC5160_X_COMPARE, false}) +#define TMC5160_OTPBIT_MASK 0x00000007 +#define TMC5160_OTPBIT_SHIFT 0 +#define TMC5160_OTPBIT_FIELD ((RegisterField) {TMC5160_OTPBIT_MASK, TMC5160_OTPBIT_SHIFT, TMC5160_OTP_PROG, false}) +#define TMC5160_OTPBYTE_MASK 0x00000030 +#define TMC5160_OTPBYTE_SHIFT 4 +#define TMC5160_OTPBYTE_FIELD ((RegisterField) {TMC5160_OTPBYTE_MASK, TMC5160_OTPBYTE_SHIFT, TMC5160_OTP_PROG, false}) +#define TMC5160_OTPMAGIC_MASK 0x0000FF00 +#define TMC5160_OTPMAGIC_SHIFT 8 +#define TMC5160_OTPMAGIC_FIELD ((RegisterField) {TMC5160_OTPMAGIC_MASK, TMC5160_OTPMAGIC_SHIFT, TMC5160_OTP_PROG, false}) +#define TMC5160_OTP_TBL_MASK 0x00000080 +#define TMC5160_OTP_TBL_SHIFT 7 +#define TMC5160_OTP_TBL_FIELD ((RegisterField) {TMC5160_OTP_TBL_MASK, TMC5160_OTP_TBL_SHIFT, TMC5160_OTP_READ, false}) +#define TMC5160_OTP_BBM_MASK 0x00000040 +#define TMC5160_OTP_BBM_SHIFT 6 +#define TMC5160_OTP_BBM_FIELD ((RegisterField) {TMC5160_OTP_BBM_MASK, TMC5160_OTP_BBM_SHIFT, TMC5160_OTP_READ, false}) +#define TMC5160_OTP_S2_LEVEL_MASK 0x00000020 +#define TMC5160_OTP_S2_LEVEL_SHIFT 5 +#define TMC5160_OTP_S2_LEVEL_FIELD ((RegisterField) {TMC5160_OTP_S2_LEVEL_MASK, TMC5160_OTP_S2_LEVEL_SHIFT, TMC5160_OTP_READ, false}) +#define TMC5160_OTP_FCLKTRIM_MASK 0x0000001F +#define TMC5160_OTP_FCLKTRIM_SHIFT 0 +#define TMC5160_OTP_FCLKTRIM_FIELD ((RegisterField) {TMC5160_OTP_FCLKTRIM_MASK, TMC5160_OTP_FCLKTRIM_SHIFT, TMC5160_OTP_READ, false}) +#define TMC5160_FCLKTRIM_MASK 0x0000001F +#define TMC5160_FCLKTRIM_SHIFT 0 +#define TMC5160_FCLKTRIM_FIELD ((RegisterField) {TMC5160_FCLKTRIM_MASK, TMC5160_FCLKTRIM_SHIFT, TMC5160_FACTORY_CONF, false}) +#define TMC5160_S2VS_LEVEL_MASK 0x0000000F +#define TMC5160_S2VS_LEVEL_SHIFT 0 +#define TMC5160_S2VS_LEVEL_FIELD ((RegisterField) {TMC5160_S2VS_LEVEL_MASK, TMC5160_S2VS_LEVEL_SHIFT, TMC5160_SHORT_CONF, false}) +#define TMC5160_S2GND_LEVEL_MASK 0x00000F00 +#define TMC5160_S2GND_LEVEL_SHIFT 8 +#define TMC5160_S2GND_LEVEL_FIELD ((RegisterField) {TMC5160_S2GND_LEVEL_MASK, TMC5160_S2GND_LEVEL_SHIFT, TMC5160_SHORT_CONF, false}) +#define TMC5160_SHORTFILTER_MASK 0x00030000 +#define TMC5160_SHORTFILTER_SHIFT 16 +#define TMC5160_SHORTFILTER_FIELD ((RegisterField) {TMC5160_SHORTFILTER_MASK, TMC5160_SHORTFILTER_SHIFT, TMC5160_SHORT_CONF, false}) +#define TMC5160_SHORTDELAY_MASK 0x00040000 +#define TMC5160_SHORTDELAY_SHIFT 18 +#define TMC5160_SHORTDELAY_FIELD ((RegisterField) {TMC5160_SHORTDELAY_MASK, TMC5160_SHORTDELAY_SHIFT, TMC5160_SHORT_CONF, false}) +#define TMC5160_BBMTIME_MASK 0x0000001F +#define TMC5160_BBMTIME_SHIFT 0 +#define TMC5160_BBMTIME_FIELD ((RegisterField) {TMC5160_BBMTIME_MASK, TMC5160_BBMTIME_SHIFT, TMC5160_DRV_CONF, false}) +#define TMC5160_BBMCLKS_MASK 0x00000F00 +#define TMC5160_BBMCLKS_SHIFT 8 +#define TMC5160_BBMCLKS_FIELD ((RegisterField) {TMC5160_BBMCLKS_MASK, TMC5160_BBMCLKS_SHIFT, TMC5160_DRV_CONF, false}) +#define TMC5160_OTSELECT_MASK 0x00030000 +#define TMC5160_OTSELECT_SHIFT 16 +#define TMC5160_OTSELECT_FIELD ((RegisterField) {TMC5160_OTSELECT_MASK, TMC5160_OTSELECT_SHIFT, TMC5160_DRV_CONF, false}) +#define TMC5160_DRVSTRENGTH_MASK 0x000C0000 +#define TMC5160_DRVSTRENGTH_SHIFT 18 +#define TMC5160_DRVSTRENGTH_FIELD ((RegisterField) {TMC5160_DRVSTRENGTH_MASK, TMC5160_DRVSTRENGTH_SHIFT, TMC5160_DRV_CONF, false}) +#define TMC5160_FILT_ISENSE_MASK 0x00300000 +#define TMC5160_FILT_ISENSE_SHIFT 20 +#define TMC5160_FILT_ISENSE_FIELD ((RegisterField) {TMC5160_FILT_ISENSE_MASK, TMC5160_FILT_ISENSE_SHIFT, TMC5160_DRV_CONF, false}) +#define TMC5160_GLOBAL_SCALER_MASK 0x000000FF +#define TMC5160_GLOBAL_SCALER_SHIFT 0 +#define TMC5160_GLOBAL_SCALER_FIELD ((RegisterField) {TMC5160_GLOBAL_SCALER_MASK, TMC5160_GLOBAL_SCALER_SHIFT, TMC5160_GLOBAL_SCALER, false}) +#define TMC5160_OFFSET_READ_A_MASK 0x0000FF00 +#define TMC5160_OFFSET_READ_A_SHIFT 8 +#define TMC5160_OFFSET_READ_A_FIELD ((RegisterField) {TMC5160_OFFSET_READ_A_MASK, TMC5160_OFFSET_READ_A_SHIFT, TMC5160_OFFSET_READ, true}) +#define TMC5160_OFFSET_READ_B_MASK 0x000000FF +#define TMC5160_OFFSET_READ_B_SHIFT 0 +#define TMC5160_OFFSET_READ_B_FIELD ((RegisterField) {TMC5160_OFFSET_READ_B_MASK, TMC5160_OFFSET_READ_B_SHIFT, TMC5160_OFFSET_READ, true}) +#define TMC5160_IHOLD_MASK 0x0000001F +#define TMC5160_IHOLD_SHIFT 0 +#define TMC5160_IHOLD_FIELD ((RegisterField) {TMC5160_IHOLD_MASK, TMC5160_IHOLD_SHIFT, TMC5160_IHOLD_IRUN, false}) +#define TMC5160_IRUN_MASK 0x00001F00 +#define TMC5160_IRUN_SHIFT 8 +#define TMC5160_IRUN_FIELD ((RegisterField) {TMC5160_IRUN_MASK, TMC5160_IRUN_SHIFT, TMC5160_IHOLD_IRUN, false}) +#define TMC5160_IHOLDDELAY_MASK 0x000F0000 +#define TMC5160_IHOLDDELAY_SHIFT 16 +#define TMC5160_IHOLDDELAY_FIELD ((RegisterField) {TMC5160_IHOLDDELAY_MASK, TMC5160_IHOLDDELAY_SHIFT, TMC5160_IHOLD_IRUN, false}) +#define TMC5160_TPOWERDOWN_MASK 0x000000FF +#define TMC5160_TPOWERDOWN_SHIFT 0 +#define TMC5160_TPOWERDOWN_FIELD ((RegisterField) {TMC5160_TPOWERDOWN_MASK, TMC5160_TPOWERDOWN_SHIFT, TMC5160_TPOWERDOWN, false}) +#define TMC5160_TSTEP_MASK 0x000FFFFF +#define TMC5160_TSTEP_SHIFT 0 +#define TMC5160_TSTEP_FIELD ((RegisterField) {TMC5160_TSTEP_MASK, TMC5160_TSTEP_SHIFT, TMC5160_TSTEP, false}) +#define TMC5160_TPWMTHRS_MASK 0x000FFFFF +#define TMC5160_TPWMTHRS_SHIFT 0 +#define TMC5160_TPWMTHRS_FIELD ((RegisterField) {TMC5160_TPWMTHRS_MASK, TMC5160_TPWMTHRS_SHIFT, TMC5160_TPWMTHRS, false}) +#define TMC5160_TCOOLTHRS_MASK 0x000FFFFF +#define TMC5160_TCOOLTHRS_SHIFT 0 +#define TMC5160_TCOOLTHRS_FIELD ((RegisterField) {TMC5160_TCOOLTHRS_MASK, TMC5160_TCOOLTHRS_SHIFT, TMC5160_TCOOLTHRS, false}) +#define TMC5160_THIGH_MASK 0x000FFFFF +#define TMC5160_THIGH_SHIFT 0 +#define TMC5160_THIGH_FIELD ((RegisterField) {TMC5160_THIGH_MASK, TMC5160_THIGH_SHIFT, TMC5160_THIGH, false}) +#define TMC5160_RAMPMODE_MASK 0x00000003 +#define TMC5160_RAMPMODE_SHIFT 0 +#define TMC5160_RAMPMODE_FIELD ((RegisterField) {TMC5160_RAMPMODE_MASK, TMC5160_RAMPMODE_SHIFT, TMC5160_RAMPMODE, false}) +#define TMC5160_XACTUAL_MASK 0xFFFFFFFF +#define TMC5160_XACTUAL_SHIFT 0 +#define TMC5160_XACTUAL_FIELD ((RegisterField) {TMC5160_XACTUAL_MASK, TMC5160_XACTUAL_SHIFT, TMC5160_XACTUAL, true}) +#define TMC5160_VACTUAL_MASK 0x00FFFFFF +#define TMC5160_VACTUAL_SHIFT 0 +#define TMC5160_VACTUAL_FIELD ((RegisterField) {TMC5160_VACTUAL_MASK, TMC5160_VACTUAL_SHIFT, TMC5160_VACTUAL, true}) +#define TMC5160_VSTART_MASK 0x0003FFFF +#define TMC5160_VSTART_SHIFT 0 +#define TMC5160_VSTART_FIELD ((RegisterField) {TMC5160_VSTART_MASK, TMC5160_VSTART_SHIFT, TMC5160_VSTART, false}) +#define TMC5160_A1_MASK 0x0000FFFF +#define TMC5160_A1_SHIFT 0 +#define TMC5160_A1_FIELD ((RegisterField) {TMC5160_A1_MASK, TMC5160_A1_SHIFT, TMC5160_A1, false}) +#define TMC5160_V1__MASK 0x000FFFFF +#define TMC5160_V1__SHIFT 0 +#define TMC5160_V1__FIELD ((RegisterField) {TMC5160_V1__MASK, TMC5160_V1__SHIFT, TMC5160_V1, false}) +#define TMC5160_AMAX_MASK 0x0000FFFF +#define TMC5160_AMAX_SHIFT 0 +#define TMC5160_AMAX_FIELD ((RegisterField) {TMC5160_AMAX_MASK, TMC5160_AMAX_SHIFT, TMC5160_AMAX, false}) +#define TMC5160_VMAX_MASK 0x007FFFFF +#define TMC5160_VMAX_SHIFT 0 +#define TMC5160_VMAX_FIELD ((RegisterField) {TMC5160_VMAX_MASK, TMC5160_VMAX_SHIFT, TMC5160_VMAX, false}) +#define TMC5160_DMAX_MASK 0x0000FFFF +#define TMC5160_DMAX_SHIFT 0 +#define TMC5160_DMAX_FIELD ((RegisterField) {TMC5160_DMAX_MASK, TMC5160_DMAX_SHIFT, TMC5160_DMAX, false}) +#define TMC5160_D1_MASK 0x0000FFFF +#define TMC5160_D1_SHIFT 0 +#define TMC5160_D1_FIELD ((RegisterField) {TMC5160_D1_MASK, TMC5160_D1_SHIFT, TMC5160_D1, false}) +#define TMC5160_VSTOP_MASK 0x0003FFFF +#define TMC5160_VSTOP_SHIFT 0 +#define TMC5160_VSTOP_FIELD ((RegisterField) {TMC5160_VSTOP_MASK, TMC5160_VSTOP_SHIFT, TMC5160_VSTOP, false}) +#define TMC5160_TZEROWAIT_MASK 0x0000FFFF +#define TMC5160_TZEROWAIT_SHIFT 0 +#define TMC5160_TZEROWAIT_FIELD ((RegisterField) {TMC5160_TZEROWAIT_MASK, TMC5160_TZEROWAIT_SHIFT, TMC5160_TZEROWAIT, false}) +#define TMC5160_XTARGET_MASK 0xFFFFFFFF +#define TMC5160_XTARGET_SHIFT 0 +#define TMC5160_XTARGET_FIELD ((RegisterField) {TMC5160_XTARGET_MASK, TMC5160_XTARGET_SHIFT, TMC5160_XTARGET, true}) +#define TMC5160_VDCMIN_MASK 0x007FFFFF +#define TMC5160_VDCMIN_SHIFT 0 +#define TMC5160_VDCMIN_FIELD ((RegisterField) {TMC5160_VDCMIN_MASK, TMC5160_VDCMIN_SHIFT, TMC5160_VDCMIN, false}) +#define TMC5160_STOP_L_ENABLE_MASK 0x00000001 +#define TMC5160_STOP_L_ENABLE_SHIFT 0 +#define TMC5160_STOP_L_ENABLE_FIELD ((RegisterField) {TMC5160_STOP_L_ENABLE_MASK, TMC5160_STOP_L_ENABLE_SHIFT, TMC5160_SWMODE, false}) +#define TMC5160_STOP_R_ENABLE_MASK 0x00000002 +#define TMC5160_STOP_R_ENABLE_SHIFT 1 +#define TMC5160_STOP_R_ENABLE_FIELD ((RegisterField) {TMC5160_STOP_R_ENABLE_MASK, TMC5160_STOP_R_ENABLE_SHIFT, TMC5160_SWMODE, false}) +#define TMC5160_POL_STOP_L_MASK 0x00000004 +#define TMC5160_POL_STOP_L_SHIFT 2 +#define TMC5160_POL_STOP_L_FIELD ((RegisterField) {TMC5160_POL_STOP_L_MASK, TMC5160_POL_STOP_L_SHIFT, TMC5160_SWMODE, false}) +#define TMC5160_POL_STOP_R_MASK 0x00000008 +#define TMC5160_POL_STOP_R_SHIFT 3 +#define TMC5160_POL_STOP_R_FIELD ((RegisterField) {TMC5160_POL_STOP_R_MASK, TMC5160_POL_STOP_R_SHIFT, TMC5160_SWMODE, false}) +#define TMC5160_SWAP_LR_MASK 0x00000010 +#define TMC5160_SWAP_LR_SHIFT 4 +#define TMC5160_SWAP_LR_FIELD ((RegisterField) {TMC5160_SWAP_LR_MASK, TMC5160_SWAP_LR_SHIFT, TMC5160_SWMODE, false}) +#define TMC5160_LATCH_L_ACTIVE_MASK 0x00000020 +#define TMC5160_LATCH_L_ACTIVE_SHIFT 5 +#define TMC5160_LATCH_L_ACTIVE_FIELD ((RegisterField) {TMC5160_LATCH_L_ACTIVE_MASK, TMC5160_LATCH_L_ACTIVE_SHIFT, TMC5160_SWMODE, false}) +#define TMC5160_LATCH_L_INACTIVE_MASK 0x00000040 +#define TMC5160_LATCH_L_INACTIVE_SHIFT 6 +#define TMC5160_LATCH_L_INACTIVE_FIELD ((RegisterField) {TMC5160_LATCH_L_INACTIVE_MASK, TMC5160_LATCH_L_INACTIVE_SHIFT, TMC5160_SWMODE, false}) +#define TMC5160_LATCH_R_ACTIVE_MASK 0x00000080 +#define TMC5160_LATCH_R_ACTIVE_SHIFT 7 +#define TMC5160_LATCH_R_ACTIVE_FIELD ((RegisterField) {TMC5160_LATCH_R_ACTIVE_MASK, TMC5160_LATCH_R_ACTIVE_SHIFT, TMC5160_SWMODE, false}) +#define TMC5160_LATCH_R_INACTIVE_MASK 0x00000100 +#define TMC5160_LATCH_R_INACTIVE_SHIFT 8 +#define TMC5160_LATCH_R_INACTIVE_FIELD ((RegisterField) {TMC5160_LATCH_R_INACTIVE_MASK, TMC5160_LATCH_R_INACTIVE_SHIFT, TMC5160_SWMODE, false}) +#define TMC5160_EN_LATCH_ENCODER_MASK 0x00000200 +#define TMC5160_EN_LATCH_ENCODER_SHIFT 9 +#define TMC5160_EN_LATCH_ENCODER_FIELD ((RegisterField) {TMC5160_EN_LATCH_ENCODER_MASK, TMC5160_EN_LATCH_ENCODER_SHIFT, TMC5160_SWMODE, false}) +#define TMC5160_SG_STOP_MASK 0x00000400 +#define TMC5160_SG_STOP_SHIFT 10 +#define TMC5160_SG_STOP_FIELD ((RegisterField) {TMC5160_SG_STOP_MASK, TMC5160_SG_STOP_SHIFT, TMC5160_SWMODE, false}) +#define TMC5160_EN_SOFTSTOP_MASK 0x00000800 +#define TMC5160_EN_SOFTSTOP_SHIFT 11 +#define TMC5160_EN_SOFTSTOP_FIELD ((RegisterField) {TMC5160_EN_SOFTSTOP_MASK, TMC5160_EN_SOFTSTOP_SHIFT, TMC5160_SWMODE, false}) +#define TMC5160_STATUS_STOP_L_MASK 0x00000001 +#define TMC5160_STATUS_STOP_L_SHIFT 0 +#define TMC5160_STATUS_STOP_L_FIELD ((RegisterField) {TMC5160_STATUS_STOP_L_MASK, TMC5160_STATUS_STOP_L_SHIFT, TMC5160_RAMPSTAT, false}) +#define TMC5160_STATUS_STOP_R_MASK 0x00000002 +#define TMC5160_STATUS_STOP_R_SHIFT 1 +#define TMC5160_STATUS_STOP_R_FIELD ((RegisterField) {TMC5160_STATUS_STOP_R_MASK, TMC5160_STATUS_STOP_R_SHIFT, TMC5160_RAMPSTAT, false}) +#define TMC5160_STATUS_LATCH_L_MASK 0x00000004 +#define TMC5160_STATUS_LATCH_L_SHIFT 2 +#define TMC5160_STATUS_LATCH_L_FIELD ((RegisterField) {TMC5160_STATUS_LATCH_L_MASK, TMC5160_STATUS_LATCH_L_SHIFT, TMC5160_RAMPSTAT, false}) +#define TMC5160_STATUS_LATCH_R_MASK 0x00000008 +#define TMC5160_STATUS_LATCH_R_SHIFT 3 +#define TMC5160_STATUS_LATCH_R_FIELD ((RegisterField) {TMC5160_STATUS_LATCH_R_MASK, TMC5160_STATUS_LATCH_R_SHIFT, TMC5160_RAMPSTAT, false}) +#define TMC5160_EVENT_STOP_L_MASK 0x00000010 +#define TMC5160_EVENT_STOP_L_SHIFT 4 +#define TMC5160_EVENT_STOP_L_FIELD ((RegisterField) {TMC5160_EVENT_STOP_L_MASK, TMC5160_EVENT_STOP_L_SHIFT, TMC5160_RAMPSTAT, false}) +#define TMC5160_EVENT_STOP_R_MASK 0x00000020 +#define TMC5160_EVENT_STOP_R_SHIFT 5 +#define TMC5160_EVENT_STOP_R_FIELD ((RegisterField) {TMC5160_EVENT_STOP_R_MASK, TMC5160_EVENT_STOP_R_SHIFT, TMC5160_RAMPSTAT, false}) +#define TMC5160_EVENT_STOP_SG_MASK 0x00000040 +#define TMC5160_EVENT_STOP_SG_SHIFT 6 +#define TMC5160_EVENT_STOP_SG_FIELD ((RegisterField) {TMC5160_EVENT_STOP_SG_MASK, TMC5160_EVENT_STOP_SG_SHIFT, TMC5160_RAMPSTAT, false}) +#define TMC5160_EVENT_POS_REACHED_MASK 0x00000080 +#define TMC5160_EVENT_POS_REACHED_SHIFT 7 +#define TMC5160_EVENT_POS_REACHED_FIELD ((RegisterField) {TMC5160_EVENT_POS_REACHED_MASK, TMC5160_EVENT_POS_REACHED_SHIFT, TMC5160_RAMPSTAT, false}) +#define TMC5160_VELOCITY_REACHED_MASK 0x00000100 +#define TMC5160_VELOCITY_REACHED_SHIFT 8 +#define TMC5160_VELOCITY_REACHED_FIELD ((RegisterField) {TMC5160_VELOCITY_REACHED_MASK, TMC5160_VELOCITY_REACHED_SHIFT, TMC5160_RAMPSTAT, false}) +#define TMC5160_POSITION_REACHED_MASK 0x00000200 +#define TMC5160_POSITION_REACHED_SHIFT 9 +#define TMC5160_POSITION_REACHED_FIELD ((RegisterField) {TMC5160_POSITION_REACHED_MASK, TMC5160_POSITION_REACHED_SHIFT, TMC5160_RAMPSTAT, false}) +#define TMC5160_VZERO_MASK 0x00000400 +#define TMC5160_VZERO_SHIFT 10 +#define TMC5160_VZERO_FIELD ((RegisterField) {TMC5160_VZERO_MASK, TMC5160_VZERO_SHIFT, TMC5160_RAMPSTAT, false}) +#define TMC5160_T_ZEROWAIT_ACTIVE_MASK 0x00000800 +#define TMC5160_T_ZEROWAIT_ACTIVE_SHIFT 11 +#define TMC5160_T_ZEROWAIT_ACTIVE_FIELD ((RegisterField) {TMC5160_T_ZEROWAIT_ACTIVE_MASK, TMC5160_T_ZEROWAIT_ACTIVE_SHIFT, TMC5160_RAMPSTAT, false}) +#define TMC5160_SECOND_MOVE_MASK 0x00001000 +#define TMC5160_SECOND_MOVE_SHIFT 12 +#define TMC5160_SECOND_MOVE_FIELD ((RegisterField) {TMC5160_SECOND_MOVE_MASK, TMC5160_SECOND_MOVE_SHIFT, TMC5160_RAMPSTAT, false}) +#define TMC5160_STATUS_SG_MASK 0x00002000 +#define TMC5160_STATUS_SG_SHIFT 13 +#define TMC5160_STATUS_SG_FIELD ((RegisterField) {TMC5160_STATUS_SG_MASK, TMC5160_STATUS_SG_SHIFT, TMC5160_RAMPSTAT, false}) +#define TMC5160_XLATCH_MASK 0xFFFFFFFF +#define TMC5160_XLATCH_SHIFT 0 +#define TMC5160_XLATCH_FIELD ((RegisterField) {TMC5160_XLATCH_MASK, TMC5160_XLATCH_SHIFT, TMC5160_XLATCH, false}) +#define TMC5160_POL_A_MASK 0x00000001 +#define TMC5160_POL_A_SHIFT 0 +#define TMC5160_POL_A_FIELD ((RegisterField) {TMC5160_POL_A_MASK, TMC5160_POL_A_SHIFT, TMC5160_ENCMODE, false}) +#define TMC5160_POL_B_MASK 0x00000002 +#define TMC5160_POL_B_SHIFT 1 +#define TMC5160_POL_B_FIELD ((RegisterField) {TMC5160_POL_B_MASK, TMC5160_POL_B_SHIFT, TMC5160_ENCMODE, false}) +#define TMC5160_POL_N_MASK 0x00000004 +#define TMC5160_POL_N_SHIFT 2 +#define TMC5160_POL_N_FIELD ((RegisterField) {TMC5160_POL_N_MASK, TMC5160_POL_N_SHIFT, TMC5160_ENCMODE, false}) +#define TMC5160_IGNORE_AB_MASK 0x00000008 +#define TMC5160_IGNORE_AB_SHIFT 3 +#define TMC5160_IGNORE_AB_FIELD ((RegisterField) {TMC5160_IGNORE_AB_MASK, TMC5160_IGNORE_AB_SHIFT, TMC5160_ENCMODE, false}) +#define TMC5160_CLR_CONT_MASK 0x00000010 +#define TMC5160_CLR_CONT_SHIFT 4 +#define TMC5160_CLR_CONT_FIELD ((RegisterField) {TMC5160_CLR_CONT_MASK, TMC5160_CLR_CONT_SHIFT, TMC5160_ENCMODE, false}) +#define TMC5160_CLR_ONCE_MASK 0x00000020 +#define TMC5160_CLR_ONCE_SHIFT 5 +#define TMC5160_CLR_ONCE_FIELD ((RegisterField) {TMC5160_CLR_ONCE_MASK, TMC5160_CLR_ONCE_SHIFT, TMC5160_ENCMODE, false}) +#define TMC5160_POS_EDGE_NEG_EDGE_MASK 0x000000C0 +#define TMC5160_POS_EDGE_NEG_EDGE_SHIFT 6 +#define TMC5160_POS_EDGE_NEG_EDGE_FIELD ((RegisterField) {TMC5160_POS_EDGE_NEG_EDGE_MASK, TMC5160_POS_EDGE_NEG_EDGE_SHIFT, TMC5160_ENCMODE, false}) +#define TMC5160_CLR_ENC_X_MASK 0x00000100 +#define TMC5160_CLR_ENC_X_SHIFT 8 +#define TMC5160_CLR_ENC_X_FIELD ((RegisterField) {TMC5160_CLR_ENC_X_MASK, TMC5160_CLR_ENC_X_SHIFT, TMC5160_ENCMODE, false}) +#define TMC5160_LATCH_X_ACT_MASK 0x00000200 +#define TMC5160_LATCH_X_ACT_SHIFT 9 +#define TMC5160_LATCH_X_ACT_FIELD ((RegisterField) {TMC5160_LATCH_X_ACT_MASK, TMC5160_LATCH_X_ACT_SHIFT, TMC5160_ENCMODE, false}) +#define TMC5160_ENC_SEL_DECIMAL_MASK 0x00000400 +#define TMC5160_ENC_SEL_DECIMAL_SHIFT 10 +#define TMC5160_ENC_SEL_DECIMAL_FIELD ((RegisterField) {TMC5160_ENC_SEL_DECIMAL_MASK, TMC5160_ENC_SEL_DECIMAL_SHIFT, TMC5160_ENCMODE, false}) +#define TMC5160_X_ENC_MASK 0xFFFFFFFF +#define TMC5160_X_ENC_SHIFT 0 +#define TMC5160_X_ENC_FIELD ((RegisterField) {TMC5160_X_ENC_MASK, TMC5160_X_ENC_SHIFT, TMC5160_X_ENC, true}) +#define TMC5160_INTEGER_MASK 0xFFFF0000 +#define TMC5160_INTEGER_SHIFT 16 +#define TMC5160_INTEGER_FIELD ((RegisterField) {TMC5160_INTEGER_MASK, TMC5160_INTEGER_SHIFT, TMC5160_ENC_CONST, false}) +#define TMC5160_FRACTIONAL_MASK 0x0000FFFF +#define TMC5160_FRACTIONAL_SHIFT 0 +#define TMC5160_FRACTIONAL_FIELD ((RegisterField) {TMC5160_FRACTIONAL_MASK, TMC5160_FRACTIONAL_SHIFT, TMC5160_ENC_CONST, false}) +#define TMC5160_N_EVENT_MASK 0x00000001 +#define TMC5160_N_EVENT_SHIFT 0 +#define TMC5160_N_EVENT_FIELD ((RegisterField) {TMC5160_N_EVENT_MASK, TMC5160_N_EVENT_SHIFT, TMC5160_ENC_STATUS, false}) +#define TMC5160_DEVIATION_WARN_MASK 0x00000002 +#define TMC5160_DEVIATION_WARN_SHIFT 1 +#define TMC5160_DEVIATION_WARN_FIELD ((RegisterField) {TMC5160_DEVIATION_WARN_MASK, TMC5160_DEVIATION_WARN_SHIFT, TMC5160_ENC_STATUS, false}) +#define TMC5160_ENC_LATCH_MASK 0xFFFFFFFF +#define TMC5160_ENC_LATCH_SHIFT 0 +#define TMC5160_ENC_LATCH_FIELD ((RegisterField) {TMC5160_ENC_LATCH_MASK, TMC5160_ENC_LATCH_SHIFT, TMC5160_ENC_LATCH, true}) +#define TMC5160_ENC_DEVIATION_MASK 0x000FFFFF +#define TMC5160_ENC_DEVIATION_SHIFT 0 +#define TMC5160_ENC_DEVIATION_FIELD ((RegisterField) {TMC5160_ENC_DEVIATION_MASK, TMC5160_ENC_DEVIATION_SHIFT, TMC5160_ENC_DEVIATION, false}) +#define TMC5160_OFS0_MASK 0x00000001 +#define TMC5160_OFS0_SHIFT 0 +#define TMC5160_OFS0_FIELD ((RegisterField) {TMC5160_OFS0_MASK, TMC5160_OFS0_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS1_MASK 0x00000002 +#define TMC5160_OFS1_SHIFT 1 +#define TMC5160_OFS1_FIELD ((RegisterField) {TMC5160_OFS1_MASK, TMC5160_OFS1_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS2_MASK 0x00000004 +#define TMC5160_OFS2_SHIFT 2 +#define TMC5160_OFS2_FIELD ((RegisterField) {TMC5160_OFS2_MASK, TMC5160_OFS2_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS3_MASK 0x00000008 +#define TMC5160_OFS3_SHIFT 3 +#define TMC5160_OFS3_FIELD ((RegisterField) {TMC5160_OFS3_MASK, TMC5160_OFS3_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS4_MASK 0x00000010 +#define TMC5160_OFS4_SHIFT 4 +#define TMC5160_OFS4_FIELD ((RegisterField) {TMC5160_OFS4_MASK, TMC5160_OFS4_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS5_MASK 0x00000020 +#define TMC5160_OFS5_SHIFT 5 +#define TMC5160_OFS5_FIELD ((RegisterField) {TMC5160_OFS5_MASK, TMC5160_OFS5_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS6_MASK 0x00000040 +#define TMC5160_OFS6_SHIFT 6 +#define TMC5160_OFS6_FIELD ((RegisterField) {TMC5160_OFS6_MASK, TMC5160_OFS6_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS7_MASK 0x00000080 +#define TMC5160_OFS7_SHIFT 7 +#define TMC5160_OFS7_FIELD ((RegisterField) {TMC5160_OFS7_MASK, TMC5160_OFS7_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS8_MASK 0x00000100 +#define TMC5160_OFS8_SHIFT 8 +#define TMC5160_OFS8_FIELD ((RegisterField) {TMC5160_OFS8_MASK, TMC5160_OFS8_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS9_MASK 0x00000200 +#define TMC5160_OFS9_SHIFT 9 +#define TMC5160_OFS9_FIELD ((RegisterField) {TMC5160_OFS9_MASK, TMC5160_OFS9_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS10_MASK 0x00000400 +#define TMC5160_OFS10_SHIFT 10 +#define TMC5160_OFS10_FIELD ((RegisterField) {TMC5160_OFS10_MASK, TMC5160_OFS10_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS11_MASK 0x00000800 +#define TMC5160_OFS11_SHIFT 11 +#define TMC5160_OFS11_FIELD ((RegisterField) {TMC5160_OFS11_MASK, TMC5160_OFS11_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS12_MASK 0x00001000 +#define TMC5160_OFS12_SHIFT 12 +#define TMC5160_OFS12_FIELD ((RegisterField) {TMC5160_OFS12_MASK, TMC5160_OFS12_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS13_MASK 0x00002000 +#define TMC5160_OFS13_SHIFT 13 +#define TMC5160_OFS13_FIELD ((RegisterField) {TMC5160_OFS13_MASK, TMC5160_OFS13_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS14_MASK 0x00004000 +#define TMC5160_OFS14_SHIFT 14 +#define TMC5160_OFS14_FIELD ((RegisterField) {TMC5160_OFS14_MASK, TMC5160_OFS14_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS15_MASK 0x00008000 +#define TMC5160_OFS15_SHIFT 15 +#define TMC5160_OFS15_FIELD ((RegisterField) {TMC5160_OFS15_MASK, TMC5160_OFS15_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS16_MASK 0x00010000 +#define TMC5160_OFS16_SHIFT 16 +#define TMC5160_OFS16_FIELD ((RegisterField) {TMC5160_OFS16_MASK, TMC5160_OFS16_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS17_MASK 0x00020000 +#define TMC5160_OFS17_SHIFT 17 +#define TMC5160_OFS17_FIELD ((RegisterField) {TMC5160_OFS17_MASK, TMC5160_OFS17_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS18_MASK 0x00040000 +#define TMC5160_OFS18_SHIFT 18 +#define TMC5160_OFS18_FIELD ((RegisterField) {TMC5160_OFS18_MASK, TMC5160_OFS18_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS19_MASK 0x00080000 +#define TMC5160_OFS19_SHIFT 19 +#define TMC5160_OFS19_FIELD ((RegisterField) {TMC5160_OFS19_MASK, TMC5160_OFS19_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS20_MASK 0x00100000 +#define TMC5160_OFS20_SHIFT 20 +#define TMC5160_OFS20_FIELD ((RegisterField) {TMC5160_OFS20_MASK, TMC5160_OFS20_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS21_MASK 0x00200000 +#define TMC5160_OFS21_SHIFT 21 +#define TMC5160_OFS21_FIELD ((RegisterField) {TMC5160_OFS21_MASK, TMC5160_OFS21_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS22_MASK 0x00400000 +#define TMC5160_OFS22_SHIFT 22 +#define TMC5160_OFS22_FIELD ((RegisterField) {TMC5160_OFS22_MASK, TMC5160_OFS22_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS23_MASK 0x00800000 +#define TMC5160_OFS23_SHIFT 23 +#define TMC5160_OFS23_FIELD ((RegisterField) {TMC5160_OFS23_MASK, TMC5160_OFS23_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS24_MASK 0x01000000 +#define TMC5160_OFS24_SHIFT 24 +#define TMC5160_OFS24_FIELD ((RegisterField) {TMC5160_OFS24_MASK, TMC5160_OFS24_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS25_MASK 0x02000000 +#define TMC5160_OFS25_SHIFT 25 +#define TMC5160_OFS25_FIELD ((RegisterField) {TMC5160_OFS25_MASK, TMC5160_OFS25_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS26_MASK 0x04000000 +#define TMC5160_OFS26_SHIFT 26 +#define TMC5160_OFS26_FIELD ((RegisterField) {TMC5160_OFS26_MASK, TMC5160_OFS26_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS27_MASK 0x08000000 +#define TMC5160_OFS27_SHIFT 27 +#define TMC5160_OFS27_FIELD ((RegisterField) {TMC5160_OFS27_MASK, TMC5160_OFS27_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS28_MASK 0x10000000 +#define TMC5160_OFS28_SHIFT 28 +#define TMC5160_OFS28_FIELD ((RegisterField) {TMC5160_OFS28_MASK, TMC5160_OFS28_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS29_MASK 0x20000000 +#define TMC5160_OFS29_SHIFT 29 +#define TMC5160_OFS29_FIELD ((RegisterField) {TMC5160_OFS29_MASK, TMC5160_OFS29_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS30_MASK 0x40000000 +#define TMC5160_OFS30_SHIFT 30 +#define TMC5160_OFS30_FIELD ((RegisterField) {TMC5160_OFS30_MASK, TMC5160_OFS30_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS31_MASK 0x80000000 +#define TMC5160_OFS31_SHIFT 31 +#define TMC5160_OFS31_FIELD ((RegisterField) {TMC5160_OFS31_MASK, TMC5160_OFS31_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS32_MASK 0x00000001 +#define TMC5160_OFS32_SHIFT 0 +#define TMC5160_OFS32_FIELD ((RegisterField) {TMC5160_OFS32_MASK, TMC5160_OFS32_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS33_MASK 0x00000002 +#define TMC5160_OFS33_SHIFT 1 +#define TMC5160_OFS33_FIELD ((RegisterField) {TMC5160_OFS33_MASK, TMC5160_OFS33_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS34_MASK 0x00000004 +#define TMC5160_OFS34_SHIFT 2 +#define TMC5160_OFS34_FIELD ((RegisterField) {TMC5160_OFS34_MASK, TMC5160_OFS34_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS35_MASK 0x00000008 +#define TMC5160_OFS35_SHIFT 3 +#define TMC5160_OFS35_FIELD ((RegisterField) {TMC5160_OFS35_MASK, TMC5160_OFS35_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS36_MASK 0x00000010 +#define TMC5160_OFS36_SHIFT 4 +#define TMC5160_OFS36_FIELD ((RegisterField) {TMC5160_OFS36_MASK, TMC5160_OFS36_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS37_MASK 0x00000020 +#define TMC5160_OFS37_SHIFT 5 +#define TMC5160_OFS37_FIELD ((RegisterField) {TMC5160_OFS37_MASK, TMC5160_OFS37_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS38_MASK 0x00000040 +#define TMC5160_OFS38_SHIFT 6 +#define TMC5160_OFS38_FIELD ((RegisterField) {TMC5160_OFS38_MASK, TMC5160_OFS38_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS39_MASK 0x00000080 +#define TMC5160_OFS39_SHIFT 7 +#define TMC5160_OFS39_FIELD ((RegisterField) {TMC5160_OFS39_MASK, TMC5160_OFS39_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS40_MASK 0x00000100 +#define TMC5160_OFS40_SHIFT 8 +#define TMC5160_OFS40_FIELD ((RegisterField) {TMC5160_OFS40_MASK, TMC5160_OFS40_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS41_MASK 0x00000200 +#define TMC5160_OFS41_SHIFT 9 +#define TMC5160_OFS41_FIELD ((RegisterField) {TMC5160_OFS41_MASK, TMC5160_OFS41_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS42_MASK 0x00000400 +#define TMC5160_OFS42_SHIFT 10 +#define TMC5160_OFS42_FIELD ((RegisterField) {TMC5160_OFS42_MASK, TMC5160_OFS42_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS43_MASK 0x00000800 +#define TMC5160_OFS43_SHIFT 11 +#define TMC5160_OFS43_FIELD ((RegisterField) {TMC5160_OFS43_MASK, TMC5160_OFS43_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS44_MASK 0x00001000 +#define TMC5160_OFS44_SHIFT 12 +#define TMC5160_OFS44_FIELD ((RegisterField) {TMC5160_OFS44_MASK, TMC5160_OFS44_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS45_MASK 0x00002000 +#define TMC5160_OFS45_SHIFT 13 +#define TMC5160_OFS45_FIELD ((RegisterField) {TMC5160_OFS45_MASK, TMC5160_OFS45_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS46_MASK 0x00004000 +#define TMC5160_OFS46_SHIFT 14 +#define TMC5160_OFS46_FIELD ((RegisterField) {TMC5160_OFS46_MASK, TMC5160_OFS46_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS47_MASK 0x00008000 +#define TMC5160_OFS47_SHIFT 15 +#define TMC5160_OFS47_FIELD ((RegisterField) {TMC5160_OFS47_MASK, TMC5160_OFS47_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS48_MASK 0x00010000 +#define TMC5160_OFS48_SHIFT 16 +#define TMC5160_OFS48_FIELD ((RegisterField) {TMC5160_OFS48_MASK, TMC5160_OFS48_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS49_MASK 0x00020000 +#define TMC5160_OFS49_SHIFT 17 +#define TMC5160_OFS49_FIELD ((RegisterField) {TMC5160_OFS49_MASK, TMC5160_OFS49_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS50_MASK 0x00040000 +#define TMC5160_OFS50_SHIFT 18 +#define TMC5160_OFS50_FIELD ((RegisterField) {TMC5160_OFS50_MASK, TMC5160_OFS50_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS51_MASK 0x00080000 +#define TMC5160_OFS51_SHIFT 19 +#define TMC5160_OFS51_FIELD ((RegisterField) {TMC5160_OFS51_MASK, TMC5160_OFS51_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS52_MASK 0x00100000 +#define TMC5160_OFS52_SHIFT 20 +#define TMC5160_OFS52_FIELD ((RegisterField) {TMC5160_OFS52_MASK, TMC5160_OFS52_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS53_MASK 0x00200000 +#define TMC5160_OFS53_SHIFT 21 +#define TMC5160_OFS53_FIELD ((RegisterField) {TMC5160_OFS53_MASK, TMC5160_OFS53_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS54_MASK 0x00400000 +#define TMC5160_OFS54_SHIFT 22 +#define TMC5160_OFS54_FIELD ((RegisterField) {TMC5160_OFS54_MASK, TMC5160_OFS54_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS55_MASK 0x00800000 +#define TMC5160_OFS55_SHIFT 23 +#define TMC5160_OFS55_FIELD ((RegisterField) {TMC5160_OFS55_MASK, TMC5160_OFS55_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS56_MASK 0x01000000 +#define TMC5160_OFS56_SHIFT 24 +#define TMC5160_OFS56_FIELD ((RegisterField) {TMC5160_OFS56_MASK, TMC5160_OFS56_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS57_MASK 0x02000000 +#define TMC5160_OFS57_SHIFT 25 +#define TMC5160_OFS57_FIELD ((RegisterField) {TMC5160_OFS57_MASK, TMC5160_OFS57_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS58_MASK 0x04000000 +#define TMC5160_OFS58_SHIFT 26 +#define TMC5160_OFS58_FIELD ((RegisterField) {TMC5160_OFS58_MASK, TMC5160_OFS58_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS59_MASK 0x08000000 +#define TMC5160_OFS59_SHIFT 27 +#define TMC5160_OFS59_FIELD ((RegisterField) {TMC5160_OFS59_MASK, TMC5160_OFS59_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS60_MASK 0x10000000 +#define TMC5160_OFS60_SHIFT 28 +#define TMC5160_OFS60_FIELD ((RegisterField) {TMC5160_OFS60_MASK, TMC5160_OFS60_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS61_MASK 0x20000000 +#define TMC5160_OFS61_SHIFT 29 +#define TMC5160_OFS61_FIELD ((RegisterField) {TMC5160_OFS61_MASK, TMC5160_OFS61_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS62_MASK 0x40000000 +#define TMC5160_OFS62_SHIFT 30 +#define TMC5160_OFS62_FIELD ((RegisterField) {TMC5160_OFS62_MASK, TMC5160_OFS62_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS63_MASK 0x80000000 +#define TMC5160_OFS63_SHIFT 31 +#define TMC5160_OFS63_FIELD ((RegisterField) {TMC5160_OFS63_MASK, TMC5160_OFS63_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS64_MASK 0x00000001 +#define TMC5160_OFS64_SHIFT 0 +#define TMC5160_OFS64_FIELD ((RegisterField) {TMC5160_OFS64_MASK, TMC5160_OFS64_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS65_MASK 0x00000002 +#define TMC5160_OFS65_SHIFT 1 +#define TMC5160_OFS65_FIELD ((RegisterField) {TMC5160_OFS65_MASK, TMC5160_OFS65_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS66_MASK 0x00000004 +#define TMC5160_OFS66_SHIFT 2 +#define TMC5160_OFS66_FIELD ((RegisterField) {TMC5160_OFS66_MASK, TMC5160_OFS66_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS67_MASK 0x00000008 +#define TMC5160_OFS67_SHIFT 3 +#define TMC5160_OFS67_FIELD ((RegisterField) {TMC5160_OFS67_MASK, TMC5160_OFS67_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS68_MASK 0x00000010 +#define TMC5160_OFS68_SHIFT 4 +#define TMC5160_OFS68_FIELD ((RegisterField) {TMC5160_OFS68_MASK, TMC5160_OFS68_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS69_MASK 0x00000020 +#define TMC5160_OFS69_SHIFT 5 +#define TMC5160_OFS69_FIELD ((RegisterField) {TMC5160_OFS69_MASK, TMC5160_OFS69_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS70_MASK 0x00000040 +#define TMC5160_OFS70_SHIFT 6 +#define TMC5160_OFS70_FIELD ((RegisterField) {TMC5160_OFS70_MASK, TMC5160_OFS70_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS71_MASK 0x00000080 +#define TMC5160_OFS71_SHIFT 7 +#define TMC5160_OFS71_FIELD ((RegisterField) {TMC5160_OFS71_MASK, TMC5160_OFS71_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS72_MASK 0x00000100 +#define TMC5160_OFS72_SHIFT 8 +#define TMC5160_OFS72_FIELD ((RegisterField) {TMC5160_OFS72_MASK, TMC5160_OFS72_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS73_MASK 0x00000200 +#define TMC5160_OFS73_SHIFT 9 +#define TMC5160_OFS73_FIELD ((RegisterField) {TMC5160_OFS73_MASK, TMC5160_OFS73_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS74_MASK 0x00000400 +#define TMC5160_OFS74_SHIFT 10 +#define TMC5160_OFS74_FIELD ((RegisterField) {TMC5160_OFS74_MASK, TMC5160_OFS74_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS75_MASK 0x00000800 +#define TMC5160_OFS75_SHIFT 11 +#define TMC5160_OFS75_FIELD ((RegisterField) {TMC5160_OFS75_MASK, TMC5160_OFS75_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS76_MASK 0x00001000 +#define TMC5160_OFS76_SHIFT 12 +#define TMC5160_OFS76_FIELD ((RegisterField) {TMC5160_OFS76_MASK, TMC5160_OFS76_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS77_MASK 0x00002000 +#define TMC5160_OFS77_SHIFT 13 +#define TMC5160_OFS77_FIELD ((RegisterField) {TMC5160_OFS77_MASK, TMC5160_OFS77_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS78_MASK 0x00004000 +#define TMC5160_OFS78_SHIFT 14 +#define TMC5160_OFS78_FIELD ((RegisterField) {TMC5160_OFS78_MASK, TMC5160_OFS78_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS79_MASK 0x00008000 +#define TMC5160_OFS79_SHIFT 15 +#define TMC5160_OFS79_FIELD ((RegisterField) {TMC5160_OFS79_MASK, TMC5160_OFS79_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS80_MASK 0x00010000 +#define TMC5160_OFS80_SHIFT 16 +#define TMC5160_OFS80_FIELD ((RegisterField) {TMC5160_OFS80_MASK, TMC5160_OFS80_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS81_MASK 0x00020000 +#define TMC5160_OFS81_SHIFT 17 +#define TMC5160_OFS81_FIELD ((RegisterField) {TMC5160_OFS81_MASK, TMC5160_OFS81_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS82_MASK 0x00040000 +#define TMC5160_OFS82_SHIFT 18 +#define TMC5160_OFS82_FIELD ((RegisterField) {TMC5160_OFS82_MASK, TMC5160_OFS82_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS83_MASK 0x00080000 +#define TMC5160_OFS83_SHIFT 19 +#define TMC5160_OFS83_FIELD ((RegisterField) {TMC5160_OFS83_MASK, TMC5160_OFS83_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS84_MASK 0x00100000 +#define TMC5160_OFS84_SHIFT 20 +#define TMC5160_OFS84_FIELD ((RegisterField) {TMC5160_OFS84_MASK, TMC5160_OFS84_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS85_MASK 0x00200000 +#define TMC5160_OFS85_SHIFT 21 +#define TMC5160_OFS85_FIELD ((RegisterField) {TMC5160_OFS85_MASK, TMC5160_OFS85_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS86_MASK 0x00400000 +#define TMC5160_OFS86_SHIFT 22 +#define TMC5160_OFS86_FIELD ((RegisterField) {TMC5160_OFS86_MASK, TMC5160_OFS86_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS87_MASK 0x00800000 +#define TMC5160_OFS87_SHIFT 23 +#define TMC5160_OFS87_FIELD ((RegisterField) {TMC5160_OFS87_MASK, TMC5160_OFS87_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS88_MASK 0x01000000 +#define TMC5160_OFS88_SHIFT 24 +#define TMC5160_OFS88_FIELD ((RegisterField) {TMC5160_OFS88_MASK, TMC5160_OFS88_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS89_MASK 0x02000000 +#define TMC5160_OFS89_SHIFT 25 +#define TMC5160_OFS89_FIELD ((RegisterField) {TMC5160_OFS89_MASK, TMC5160_OFS89_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS90_MASK 0x04000000 +#define TMC5160_OFS90_SHIFT 26 +#define TMC5160_OFS90_FIELD ((RegisterField) {TMC5160_OFS90_MASK, TMC5160_OFS90_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS91_MASK 0x08000000 +#define TMC5160_OFS91_SHIFT 27 +#define TMC5160_OFS91_FIELD ((RegisterField) {TMC5160_OFS91_MASK, TMC5160_OFS91_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS92_MASK 0x10000000 +#define TMC5160_OFS92_SHIFT 28 +#define TMC5160_OFS92_FIELD ((RegisterField) {TMC5160_OFS92_MASK, TMC5160_OFS92_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS93_MASK 0x20000000 +#define TMC5160_OFS93_SHIFT 29 +#define TMC5160_OFS93_FIELD ((RegisterField) {TMC5160_OFS93_MASK, TMC5160_OFS93_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS94_MASK 0x40000000 +#define TMC5160_OFS94_SHIFT 30 +#define TMC5160_OFS94_FIELD ((RegisterField) {TMC5160_OFS94_MASK, TMC5160_OFS94_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS95_MASK 0x80000000 +#define TMC5160_OFS95_SHIFT 31 +#define TMC5160_OFS95_FIELD ((RegisterField) {TMC5160_OFS95_MASK, TMC5160_OFS95_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS96_MASK 0x00000001 +#define TMC5160_OFS96_SHIFT 0 +#define TMC5160_OFS96_FIELD ((RegisterField) {TMC5160_OFS96_MASK, TMC5160_OFS96_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS97_MASK 0x00000002 +#define TMC5160_OFS97_SHIFT 1 +#define TMC5160_OFS97_FIELD ((RegisterField) {TMC5160_OFS97_MASK, TMC5160_OFS97_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS98_MASK 0x00000004 +#define TMC5160_OFS98_SHIFT 2 +#define TMC5160_OFS98_FIELD ((RegisterField) {TMC5160_OFS98_MASK, TMC5160_OFS98_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS99_MASK 0x00000008 +#define TMC5160_OFS99_SHIFT 3 +#define TMC5160_OFS99_FIELD ((RegisterField) {TMC5160_OFS99_MASK, TMC5160_OFS99_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS100_MASK 0x00000010 +#define TMC5160_OFS100_SHIFT 4 +#define TMC5160_OFS100_FIELD ((RegisterField) {TMC5160_OFS100_MASK, TMC5160_OFS100_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS101_MASK 0x00000020 +#define TMC5160_OFS101_SHIFT 5 +#define TMC5160_OFS101_FIELD ((RegisterField) {TMC5160_OFS101_MASK, TMC5160_OFS101_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS102_MASK 0x00000040 +#define TMC5160_OFS102_SHIFT 6 +#define TMC5160_OFS102_FIELD ((RegisterField) {TMC5160_OFS102_MASK, TMC5160_OFS102_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS103_MASK 0x00000080 +#define TMC5160_OFS103_SHIFT 7 +#define TMC5160_OFS103_FIELD ((RegisterField) {TMC5160_OFS103_MASK, TMC5160_OFS103_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS104_MASK 0x00000100 +#define TMC5160_OFS104_SHIFT 8 +#define TMC5160_OFS104_FIELD ((RegisterField) {TMC5160_OFS104_MASK, TMC5160_OFS104_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS105_MASK 0x00000200 +#define TMC5160_OFS105_SHIFT 9 +#define TMC5160_OFS105_FIELD ((RegisterField) {TMC5160_OFS105_MASK, TMC5160_OFS105_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS106_MASK 0x00000400 +#define TMC5160_OFS106_SHIFT 10 +#define TMC5160_OFS106_FIELD ((RegisterField) {TMC5160_OFS106_MASK, TMC5160_OFS106_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS107_MASK 0x00000800 +#define TMC5160_OFS107_SHIFT 11 +#define TMC5160_OFS107_FIELD ((RegisterField) {TMC5160_OFS107_MASK, TMC5160_OFS107_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS108_MASK 0x00001000 +#define TMC5160_OFS108_SHIFT 12 +#define TMC5160_OFS108_FIELD ((RegisterField) {TMC5160_OFS108_MASK, TMC5160_OFS108_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS109_MASK 0x00002000 +#define TMC5160_OFS109_SHIFT 13 +#define TMC5160_OFS109_FIELD ((RegisterField) {TMC5160_OFS109_MASK, TMC5160_OFS109_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS110_MASK 0x00004000 +#define TMC5160_OFS110_SHIFT 14 +#define TMC5160_OFS110_FIELD ((RegisterField) {TMC5160_OFS110_MASK, TMC5160_OFS110_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS111_MASK 0x00008000 +#define TMC5160_OFS111_SHIFT 15 +#define TMC5160_OFS111_FIELD ((RegisterField) {TMC5160_OFS111_MASK, TMC5160_OFS111_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS112_MASK 0x00010000 +#define TMC5160_OFS112_SHIFT 16 +#define TMC5160_OFS112_FIELD ((RegisterField) {TMC5160_OFS112_MASK, TMC5160_OFS112_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS113_MASK 0x00020000 +#define TMC5160_OFS113_SHIFT 17 +#define TMC5160_OFS113_FIELD ((RegisterField) {TMC5160_OFS113_MASK, TMC5160_OFS113_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS114_MASK 0x00040000 +#define TMC5160_OFS114_SHIFT 18 +#define TMC5160_OFS114_FIELD ((RegisterField) {TMC5160_OFS114_MASK, TMC5160_OFS114_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS115_MASK 0x00080000 +#define TMC5160_OFS115_SHIFT 19 +#define TMC5160_OFS115_FIELD ((RegisterField) {TMC5160_OFS115_MASK, TMC5160_OFS115_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS116_MASK 0x00100000 +#define TMC5160_OFS116_SHIFT 20 +#define TMC5160_OFS116_FIELD ((RegisterField) {TMC5160_OFS116_MASK, TMC5160_OFS116_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS117_MASK 0x00200000 +#define TMC5160_OFS117_SHIFT 21 +#define TMC5160_OFS117_FIELD ((RegisterField) {TMC5160_OFS117_MASK, TMC5160_OFS117_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS118_MASK 0x00400000 +#define TMC5160_OFS118_SHIFT 22 +#define TMC5160_OFS118_FIELD ((RegisterField) {TMC5160_OFS118_MASK, TMC5160_OFS118_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS119_MASK 0x00800000 +#define TMC5160_OFS119_SHIFT 23 +#define TMC5160_OFS119_FIELD ((RegisterField) {TMC5160_OFS119_MASK, TMC5160_OFS119_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS120_MASK 0x01000000 +#define TMC5160_OFS120_SHIFT 24 +#define TMC5160_OFS120_FIELD ((RegisterField) {TMC5160_OFS120_MASK, TMC5160_OFS120_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS121_MASK 0x02000000 +#define TMC5160_OFS121_SHIFT 25 +#define TMC5160_OFS121_FIELD ((RegisterField) {TMC5160_OFS121_MASK, TMC5160_OFS121_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS122_MASK 0x04000000 +#define TMC5160_OFS122_SHIFT 26 +#define TMC5160_OFS122_FIELD ((RegisterField) {TMC5160_OFS122_MASK, TMC5160_OFS122_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS123_MASK 0x08000000 +#define TMC5160_OFS123_SHIFT 27 +#define TMC5160_OFS123_FIELD ((RegisterField) {TMC5160_OFS123_MASK, TMC5160_OFS123_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS124_MASK 0x10000000 +#define TMC5160_OFS124_SHIFT 28 +#define TMC5160_OFS124_FIELD ((RegisterField) {TMC5160_OFS124_MASK, TMC5160_OFS124_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS125_MASK 0x20000000 +#define TMC5160_OFS125_SHIFT 29 +#define TMC5160_OFS125_FIELD ((RegisterField) {TMC5160_OFS125_MASK, TMC5160_OFS125_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS126_MASK 0x40000000 +#define TMC5160_OFS126_SHIFT 30 +#define TMC5160_OFS126_FIELD ((RegisterField) {TMC5160_OFS126_MASK, TMC5160_OFS126_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS127_MASK 0x80000000 +#define TMC5160_OFS127_SHIFT 31 +#define TMC5160_OFS127_FIELD ((RegisterField) {TMC5160_OFS127_MASK, TMC5160_OFS127_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS128_MASK 0x00000001 +#define TMC5160_OFS128_SHIFT 0 +#define TMC5160_OFS128_FIELD ((RegisterField) {TMC5160_OFS128_MASK, TMC5160_OFS128_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS129_MASK 0x00000002 +#define TMC5160_OFS129_SHIFT 1 +#define TMC5160_OFS129_FIELD ((RegisterField) {TMC5160_OFS129_MASK, TMC5160_OFS129_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS130_MASK 0x00000004 +#define TMC5160_OFS130_SHIFT 2 +#define TMC5160_OFS130_FIELD ((RegisterField) {TMC5160_OFS130_MASK, TMC5160_OFS130_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS131_MASK 0x00000008 +#define TMC5160_OFS131_SHIFT 3 +#define TMC5160_OFS131_FIELD ((RegisterField) {TMC5160_OFS131_MASK, TMC5160_OFS131_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS132_MASK 0x00000010 +#define TMC5160_OFS132_SHIFT 4 +#define TMC5160_OFS132_FIELD ((RegisterField) {TMC5160_OFS132_MASK, TMC5160_OFS132_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS133_MASK 0x00000020 +#define TMC5160_OFS133_SHIFT 5 +#define TMC5160_OFS133_FIELD ((RegisterField) {TMC5160_OFS133_MASK, TMC5160_OFS133_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS134_MASK 0x00000040 +#define TMC5160_OFS134_SHIFT 6 +#define TMC5160_OFS134_FIELD ((RegisterField) {TMC5160_OFS134_MASK, TMC5160_OFS134_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS135_MASK 0x00000080 +#define TMC5160_OFS135_SHIFT 7 +#define TMC5160_OFS135_FIELD ((RegisterField) {TMC5160_OFS135_MASK, TMC5160_OFS135_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS136_MASK 0x00000100 +#define TMC5160_OFS136_SHIFT 8 +#define TMC5160_OFS136_FIELD ((RegisterField) {TMC5160_OFS136_MASK, TMC5160_OFS136_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS137_MASK 0x00000200 +#define TMC5160_OFS137_SHIFT 9 +#define TMC5160_OFS137_FIELD ((RegisterField) {TMC5160_OFS137_MASK, TMC5160_OFS137_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS138_MASK 0x00000400 +#define TMC5160_OFS138_SHIFT 10 +#define TMC5160_OFS138_FIELD ((RegisterField) {TMC5160_OFS138_MASK, TMC5160_OFS138_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS139_MASK 0x00000800 +#define TMC5160_OFS139_SHIFT 11 +#define TMC5160_OFS139_FIELD ((RegisterField) {TMC5160_OFS139_MASK, TMC5160_OFS139_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS140_MASK 0x00001000 +#define TMC5160_OFS140_SHIFT 12 +#define TMC5160_OFS140_FIELD ((RegisterField) {TMC5160_OFS140_MASK, TMC5160_OFS140_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS141_MASK 0x00002000 +#define TMC5160_OFS141_SHIFT 13 +#define TMC5160_OFS141_FIELD ((RegisterField) {TMC5160_OFS141_MASK, TMC5160_OFS141_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS142_MASK 0x00004000 +#define TMC5160_OFS142_SHIFT 14 +#define TMC5160_OFS142_FIELD ((RegisterField) {TMC5160_OFS142_MASK, TMC5160_OFS142_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS143_MASK 0x00008000 +#define TMC5160_OFS143_SHIFT 15 +#define TMC5160_OFS143_FIELD ((RegisterField) {TMC5160_OFS143_MASK, TMC5160_OFS143_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS144_MASK 0x00010000 +#define TMC5160_OFS144_SHIFT 16 +#define TMC5160_OFS144_FIELD ((RegisterField) {TMC5160_OFS144_MASK, TMC5160_OFS144_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS145_MASK 0x00020000 +#define TMC5160_OFS145_SHIFT 17 +#define TMC5160_OFS145_FIELD ((RegisterField) {TMC5160_OFS145_MASK, TMC5160_OFS145_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS146_MASK 0x00040000 +#define TMC5160_OFS146_SHIFT 18 +#define TMC5160_OFS146_FIELD ((RegisterField) {TMC5160_OFS146_MASK, TMC5160_OFS146_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS147_MASK 0x00080000 +#define TMC5160_OFS147_SHIFT 19 +#define TMC5160_OFS147_FIELD ((RegisterField) {TMC5160_OFS147_MASK, TMC5160_OFS147_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS148_MASK 0x00100000 +#define TMC5160_OFS148_SHIFT 20 +#define TMC5160_OFS148_FIELD ((RegisterField) {TMC5160_OFS148_MASK, TMC5160_OFS148_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS149_MASK 0x00200000 +#define TMC5160_OFS149_SHIFT 21 +#define TMC5160_OFS149_FIELD ((RegisterField) {TMC5160_OFS149_MASK, TMC5160_OFS149_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS150_MASK 0x00400000 +#define TMC5160_OFS150_SHIFT 22 +#define TMC5160_OFS150_FIELD ((RegisterField) {TMC5160_OFS150_MASK, TMC5160_OFS150_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS151_MASK 0x00800000 +#define TMC5160_OFS151_SHIFT 23 +#define TMC5160_OFS151_FIELD ((RegisterField) {TMC5160_OFS151_MASK, TMC5160_OFS151_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS152_MASK 0x01000000 +#define TMC5160_OFS152_SHIFT 24 +#define TMC5160_OFS152_FIELD ((RegisterField) {TMC5160_OFS152_MASK, TMC5160_OFS152_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS153_MASK 0x02000000 +#define TMC5160_OFS153_SHIFT 25 +#define TMC5160_OFS153_FIELD ((RegisterField) {TMC5160_OFS153_MASK, TMC5160_OFS153_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS154_MASK 0x04000000 +#define TMC5160_OFS154_SHIFT 26 +#define TMC5160_OFS154_FIELD ((RegisterField) {TMC5160_OFS154_MASK, TMC5160_OFS154_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS155_MASK 0x08000000 +#define TMC5160_OFS155_SHIFT 27 +#define TMC5160_OFS155_FIELD ((RegisterField) {TMC5160_OFS155_MASK, TMC5160_OFS155_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS156_MASK 0x10000000 +#define TMC5160_OFS156_SHIFT 28 +#define TMC5160_OFS156_FIELD ((RegisterField) {TMC5160_OFS156_MASK, TMC5160_OFS156_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS157_MASK 0x20000000 +#define TMC5160_OFS157_SHIFT 29 +#define TMC5160_OFS157_FIELD ((RegisterField) {TMC5160_OFS157_MASK, TMC5160_OFS157_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS158_MASK 0x40000000 +#define TMC5160_OFS158_SHIFT 30 +#define TMC5160_OFS158_FIELD ((RegisterField) {TMC5160_OFS158_MASK, TMC5160_OFS158_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS159_MASK 0x80000000 +#define TMC5160_OFS159_SHIFT 31 +#define TMC5160_OFS159_FIELD ((RegisterField) {TMC5160_OFS159_MASK, TMC5160_OFS159_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS160_MASK 0x00000001 +#define TMC5160_OFS160_SHIFT 0 +#define TMC5160_OFS160_FIELD ((RegisterField) {TMC5160_OFS160_MASK, TMC5160_OFS160_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS161_MASK 0x00000002 +#define TMC5160_OFS161_SHIFT 1 +#define TMC5160_OFS161_FIELD ((RegisterField) {TMC5160_OFS161_MASK, TMC5160_OFS161_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS162_MASK 0x00000004 +#define TMC5160_OFS162_SHIFT 2 +#define TMC5160_OFS162_FIELD ((RegisterField) {TMC5160_OFS162_MASK, TMC5160_OFS162_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS163_MASK 0x00000008 +#define TMC5160_OFS163_SHIFT 3 +#define TMC5160_OFS163_FIELD ((RegisterField) {TMC5160_OFS163_MASK, TMC5160_OFS163_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS164_MASK 0x00000010 +#define TMC5160_OFS164_SHIFT 4 +#define TMC5160_OFS164_FIELD ((RegisterField) {TMC5160_OFS164_MASK, TMC5160_OFS164_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS165_MASK 0x00000020 +#define TMC5160_OFS165_SHIFT 5 +#define TMC5160_OFS165_FIELD ((RegisterField) {TMC5160_OFS165_MASK, TMC5160_OFS165_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS166_MASK 0x00000040 +#define TMC5160_OFS166_SHIFT 6 +#define TMC5160_OFS166_FIELD ((RegisterField) {TMC5160_OFS166_MASK, TMC5160_OFS166_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS167_MASK 0x00000080 +#define TMC5160_OFS167_SHIFT 7 +#define TMC5160_OFS167_FIELD ((RegisterField) {TMC5160_OFS167_MASK, TMC5160_OFS167_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS168_MASK 0x00000100 +#define TMC5160_OFS168_SHIFT 8 +#define TMC5160_OFS168_FIELD ((RegisterField) {TMC5160_OFS168_MASK, TMC5160_OFS168_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS169_MASK 0x00000200 +#define TMC5160_OFS169_SHIFT 9 +#define TMC5160_OFS169_FIELD ((RegisterField) {TMC5160_OFS169_MASK, TMC5160_OFS169_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS170_MASK 0x00000400 +#define TMC5160_OFS170_SHIFT 10 +#define TMC5160_OFS170_FIELD ((RegisterField) {TMC5160_OFS170_MASK, TMC5160_OFS170_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS171_MASK 0x00000800 +#define TMC5160_OFS171_SHIFT 11 +#define TMC5160_OFS171_FIELD ((RegisterField) {TMC5160_OFS171_MASK, TMC5160_OFS171_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS172_MASK 0x00001000 +#define TMC5160_OFS172_SHIFT 12 +#define TMC5160_OFS172_FIELD ((RegisterField) {TMC5160_OFS172_MASK, TMC5160_OFS172_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS173_MASK 0x00002000 +#define TMC5160_OFS173_SHIFT 13 +#define TMC5160_OFS173_FIELD ((RegisterField) {TMC5160_OFS173_MASK, TMC5160_OFS173_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS174_MASK 0x00004000 +#define TMC5160_OFS174_SHIFT 14 +#define TMC5160_OFS174_FIELD ((RegisterField) {TMC5160_OFS174_MASK, TMC5160_OFS174_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS175_MASK 0x00008000 +#define TMC5160_OFS175_SHIFT 15 +#define TMC5160_OFS175_FIELD ((RegisterField) {TMC5160_OFS175_MASK, TMC5160_OFS175_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS176_MASK 0x00010000 +#define TMC5160_OFS176_SHIFT 16 +#define TMC5160_OFS176_FIELD ((RegisterField) {TMC5160_OFS176_MASK, TMC5160_OFS176_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS177_MASK 0x00020000 +#define TMC5160_OFS177_SHIFT 17 +#define TMC5160_OFS177_FIELD ((RegisterField) {TMC5160_OFS177_MASK, TMC5160_OFS177_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS178_MASK 0x00040000 +#define TMC5160_OFS178_SHIFT 18 +#define TMC5160_OFS178_FIELD ((RegisterField) {TMC5160_OFS178_MASK, TMC5160_OFS178_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS179_MASK 0x00080000 +#define TMC5160_OFS179_SHIFT 19 +#define TMC5160_OFS179_FIELD ((RegisterField) {TMC5160_OFS179_MASK, TMC5160_OFS179_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS180_MASK 0x00100000 +#define TMC5160_OFS180_SHIFT 20 +#define TMC5160_OFS180_FIELD ((RegisterField) {TMC5160_OFS180_MASK, TMC5160_OFS180_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS181_MASK 0x00200000 +#define TMC5160_OFS181_SHIFT 21 +#define TMC5160_OFS181_FIELD ((RegisterField) {TMC5160_OFS181_MASK, TMC5160_OFS181_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS182_MASK 0x00400000 +#define TMC5160_OFS182_SHIFT 22 +#define TMC5160_OFS182_FIELD ((RegisterField) {TMC5160_OFS182_MASK, TMC5160_OFS182_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS183_MASK 0x00800000 +#define TMC5160_OFS183_SHIFT 23 +#define TMC5160_OFS183_FIELD ((RegisterField) {TMC5160_OFS183_MASK, TMC5160_OFS183_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS184_MASK 0x01000000 +#define TMC5160_OFS184_SHIFT 24 +#define TMC5160_OFS184_FIELD ((RegisterField) {TMC5160_OFS184_MASK, TMC5160_OFS184_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS185_MASK 0x02000000 +#define TMC5160_OFS185_SHIFT 25 +#define TMC5160_OFS185_FIELD ((RegisterField) {TMC5160_OFS185_MASK, TMC5160_OFS185_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS186_MASK 0x04000000 +#define TMC5160_OFS186_SHIFT 26 +#define TMC5160_OFS186_FIELD ((RegisterField) {TMC5160_OFS186_MASK, TMC5160_OFS186_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS187_MASK 0x08000000 +#define TMC5160_OFS187_SHIFT 27 +#define TMC5160_OFS187_FIELD ((RegisterField) {TMC5160_OFS187_MASK, TMC5160_OFS187_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS188_MASK 0x10000000 +#define TMC5160_OFS188_SHIFT 28 +#define TMC5160_OFS188_FIELD ((RegisterField) {TMC5160_OFS188_MASK, TMC5160_OFS188_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS189_MASK 0x20000000 +#define TMC5160_OFS189_SHIFT 29 +#define TMC5160_OFS189_FIELD ((RegisterField) {TMC5160_OFS189_MASK, TMC5160_OFS189_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS190_MASK 0x40000000 +#define TMC5160_OFS190_SHIFT 30 +#define TMC5160_OFS190_FIELD ((RegisterField) {TMC5160_OFS190_MASK, TMC5160_OFS190_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS191_MASK 0x80000000 +#define TMC5160_OFS191_SHIFT 31 +#define TMC5160_OFS191_FIELD ((RegisterField) {TMC5160_OFS191_MASK, TMC5160_OFS191_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS192_MASK 0x00000001 +#define TMC5160_OFS192_SHIFT 0 +#define TMC5160_OFS192_FIELD ((RegisterField) {TMC5160_OFS192_MASK, TMC5160_OFS192_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS193_MASK 0x00000002 +#define TMC5160_OFS193_SHIFT 1 +#define TMC5160_OFS193_FIELD ((RegisterField) {TMC5160_OFS193_MASK, TMC5160_OFS193_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS194_MASK 0x00000004 +#define TMC5160_OFS194_SHIFT 2 +#define TMC5160_OFS194_FIELD ((RegisterField) {TMC5160_OFS194_MASK, TMC5160_OFS194_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS195_MASK 0x00000008 +#define TMC5160_OFS195_SHIFT 3 +#define TMC5160_OFS195_FIELD ((RegisterField) {TMC5160_OFS195_MASK, TMC5160_OFS195_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS196_MASK 0x00000010 +#define TMC5160_OFS196_SHIFT 4 +#define TMC5160_OFS196_FIELD ((RegisterField) {TMC5160_OFS196_MASK, TMC5160_OFS196_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS197_MASK 0x00000020 +#define TMC5160_OFS197_SHIFT 5 +#define TMC5160_OFS197_FIELD ((RegisterField) {TMC5160_OFS197_MASK, TMC5160_OFS197_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS198_MASK 0x00000040 +#define TMC5160_OFS198_SHIFT 6 +#define TMC5160_OFS198_FIELD ((RegisterField) {TMC5160_OFS198_MASK, TMC5160_OFS198_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS199_MASK 0x00000080 +#define TMC5160_OFS199_SHIFT 7 +#define TMC5160_OFS199_FIELD ((RegisterField) {TMC5160_OFS199_MASK, TMC5160_OFS199_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS200_MASK 0x00000100 +#define TMC5160_OFS200_SHIFT 8 +#define TMC5160_OFS200_FIELD ((RegisterField) {TMC5160_OFS200_MASK, TMC5160_OFS200_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS201_MASK 0x00000200 +#define TMC5160_OFS201_SHIFT 9 +#define TMC5160_OFS201_FIELD ((RegisterField) {TMC5160_OFS201_MASK, TMC5160_OFS201_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS202_MASK 0x00000400 +#define TMC5160_OFS202_SHIFT 10 +#define TMC5160_OFS202_FIELD ((RegisterField) {TMC5160_OFS202_MASK, TMC5160_OFS202_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS203_MASK 0x00000800 +#define TMC5160_OFS203_SHIFT 11 +#define TMC5160_OFS203_FIELD ((RegisterField) {TMC5160_OFS203_MASK, TMC5160_OFS203_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS204_MASK 0x00001000 +#define TMC5160_OFS204_SHIFT 12 +#define TMC5160_OFS204_FIELD ((RegisterField) {TMC5160_OFS204_MASK, TMC5160_OFS204_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS205_MASK 0x00002000 +#define TMC5160_OFS205_SHIFT 13 +#define TMC5160_OFS205_FIELD ((RegisterField) {TMC5160_OFS205_MASK, TMC5160_OFS205_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS206_MASK 0x00004000 +#define TMC5160_OFS206_SHIFT 14 +#define TMC5160_OFS206_FIELD ((RegisterField) {TMC5160_OFS206_MASK, TMC5160_OFS206_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS207_MASK 0x00008000 +#define TMC5160_OFS207_SHIFT 15 +#define TMC5160_OFS207_FIELD ((RegisterField) {TMC5160_OFS207_MASK, TMC5160_OFS207_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS208_MASK 0x00010000 +#define TMC5160_OFS208_SHIFT 16 +#define TMC5160_OFS208_FIELD ((RegisterField) {TMC5160_OFS208_MASK, TMC5160_OFS208_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS209_MASK 0x00020000 +#define TMC5160_OFS209_SHIFT 17 +#define TMC5160_OFS209_FIELD ((RegisterField) {TMC5160_OFS209_MASK, TMC5160_OFS209_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS210_MASK 0x00040000 +#define TMC5160_OFS210_SHIFT 18 +#define TMC5160_OFS210_FIELD ((RegisterField) {TMC5160_OFS210_MASK, TMC5160_OFS210_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS211_MASK 0x00080000 +#define TMC5160_OFS211_SHIFT 19 +#define TMC5160_OFS211_FIELD ((RegisterField) {TMC5160_OFS211_MASK, TMC5160_OFS211_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS212_MASK 0x00100000 +#define TMC5160_OFS212_SHIFT 20 +#define TMC5160_OFS212_FIELD ((RegisterField) {TMC5160_OFS212_MASK, TMC5160_OFS212_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS213_MASK 0x00200000 +#define TMC5160_OFS213_SHIFT 21 +#define TMC5160_OFS213_FIELD ((RegisterField) {TMC5160_OFS213_MASK, TMC5160_OFS213_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS214_MASK 0x00400000 +#define TMC5160_OFS214_SHIFT 22 +#define TMC5160_OFS214_FIELD ((RegisterField) {TMC5160_OFS214_MASK, TMC5160_OFS214_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS215_MASK 0x00800000 +#define TMC5160_OFS215_SHIFT 23 +#define TMC5160_OFS215_FIELD ((RegisterField) {TMC5160_OFS215_MASK, TMC5160_OFS215_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS216_MASK 0x01000000 +#define TMC5160_OFS216_SHIFT 24 +#define TMC5160_OFS216_FIELD ((RegisterField) {TMC5160_OFS216_MASK, TMC5160_OFS216_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS217_MASK 0x02000000 +#define TMC5160_OFS217_SHIFT 25 +#define TMC5160_OFS217_FIELD ((RegisterField) {TMC5160_OFS217_MASK, TMC5160_OFS217_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS218_MASK 0x04000000 +#define TMC5160_OFS218_SHIFT 26 +#define TMC5160_OFS218_FIELD ((RegisterField) {TMC5160_OFS218_MASK, TMC5160_OFS218_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS219_MASK 0x08000000 +#define TMC5160_OFS219_SHIFT 27 +#define TMC5160_OFS219_FIELD ((RegisterField) {TMC5160_OFS219_MASK, TMC5160_OFS219_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS220_MASK 0x10000000 +#define TMC5160_OFS220_SHIFT 28 +#define TMC5160_OFS220_FIELD ((RegisterField) {TMC5160_OFS220_MASK, TMC5160_OFS220_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS221_MASK 0x20000000 +#define TMC5160_OFS221_SHIFT 29 +#define TMC5160_OFS221_FIELD ((RegisterField) {TMC5160_OFS221_MASK, TMC5160_OFS221_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS222_MASK 0x40000000 +#define TMC5160_OFS222_SHIFT 30 +#define TMC5160_OFS222_FIELD ((RegisterField) {TMC5160_OFS222_MASK, TMC5160_OFS222_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS223_MASK 0x80000000 +#define TMC5160_OFS223_SHIFT 31 +#define TMC5160_OFS223_FIELD ((RegisterField) {TMC5160_OFS223_MASK, TMC5160_OFS223_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS224_MASK 0x00000001 +#define TMC5160_OFS224_SHIFT 0 +#define TMC5160_OFS224_FIELD ((RegisterField) {TMC5160_OFS224_MASK, TMC5160_OFS224_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS225_MASK 0x00000002 +#define TMC5160_OFS225_SHIFT 1 +#define TMC5160_OFS225_FIELD ((RegisterField) {TMC5160_OFS225_MASK, TMC5160_OFS225_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS226_MASK 0x00000004 +#define TMC5160_OFS226_SHIFT 2 +#define TMC5160_OFS226_FIELD ((RegisterField) {TMC5160_OFS226_MASK, TMC5160_OFS226_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS227_MASK 0x00000008 +#define TMC5160_OFS227_SHIFT 3 +#define TMC5160_OFS227_FIELD ((RegisterField) {TMC5160_OFS227_MASK, TMC5160_OFS227_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS228_MASK 0x00000010 +#define TMC5160_OFS228_SHIFT 4 +#define TMC5160_OFS228_FIELD ((RegisterField) {TMC5160_OFS228_MASK, TMC5160_OFS228_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS229_MASK 0x00000020 +#define TMC5160_OFS229_SHIFT 5 +#define TMC5160_OFS229_FIELD ((RegisterField) {TMC5160_OFS229_MASK, TMC5160_OFS229_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS230_MASK 0x00000040 +#define TMC5160_OFS230_SHIFT 6 +#define TMC5160_OFS230_FIELD ((RegisterField) {TMC5160_OFS230_MASK, TMC5160_OFS230_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS231_MASK 0x00000080 +#define TMC5160_OFS231_SHIFT 7 +#define TMC5160_OFS231_FIELD ((RegisterField) {TMC5160_OFS231_MASK, TMC5160_OFS231_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS232_MASK 0x00000100 +#define TMC5160_OFS232_SHIFT 8 +#define TMC5160_OFS232_FIELD ((RegisterField) {TMC5160_OFS232_MASK, TMC5160_OFS232_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS233_MASK 0x00000200 +#define TMC5160_OFS233_SHIFT 9 +#define TMC5160_OFS233_FIELD ((RegisterField) {TMC5160_OFS233_MASK, TMC5160_OFS233_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS234_MASK 0x00000400 +#define TMC5160_OFS234_SHIFT 10 +#define TMC5160_OFS234_FIELD ((RegisterField) {TMC5160_OFS234_MASK, TMC5160_OFS234_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS235_MASK 0x00000800 +#define TMC5160_OFS235_SHIFT 11 +#define TMC5160_OFS235_FIELD ((RegisterField) {TMC5160_OFS235_MASK, TMC5160_OFS235_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS236_MASK 0x00001000 +#define TMC5160_OFS236_SHIFT 12 +#define TMC5160_OFS236_FIELD ((RegisterField) {TMC5160_OFS236_MASK, TMC5160_OFS236_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS237_MASK 0x00002000 +#define TMC5160_OFS237_SHIFT 13 +#define TMC5160_OFS237_FIELD ((RegisterField) {TMC5160_OFS237_MASK, TMC5160_OFS237_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS238_MASK 0x00004000 +#define TMC5160_OFS238_SHIFT 14 +#define TMC5160_OFS238_FIELD ((RegisterField) {TMC5160_OFS238_MASK, TMC5160_OFS238_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS239_MASK 0x00008000 +#define TMC5160_OFS239_SHIFT 15 +#define TMC5160_OFS239_FIELD ((RegisterField) {TMC5160_OFS239_MASK, TMC5160_OFS239_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS240_MASK 0x00010000 +#define TMC5160_OFS240_SHIFT 16 +#define TMC5160_OFS240_FIELD ((RegisterField) {TMC5160_OFS240_MASK, TMC5160_OFS240_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS241_MASK 0x00020000 +#define TMC5160_OFS241_SHIFT 17 +#define TMC5160_OFS241_FIELD ((RegisterField) {TMC5160_OFS241_MASK, TMC5160_OFS241_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS242_MASK 0x00040000 +#define TMC5160_OFS242_SHIFT 18 +#define TMC5160_OFS242_FIELD ((RegisterField) {TMC5160_OFS242_MASK, TMC5160_OFS242_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS243_MASK 0x00080000 +#define TMC5160_OFS243_SHIFT 19 +#define TMC5160_OFS243_FIELD ((RegisterField) {TMC5160_OFS243_MASK, TMC5160_OFS243_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS244_MASK 0x00100000 +#define TMC5160_OFS244_SHIFT 20 +#define TMC5160_OFS244_FIELD ((RegisterField) {TMC5160_OFS244_MASK, TMC5160_OFS244_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS245_MASK 0x00200000 +#define TMC5160_OFS245_SHIFT 21 +#define TMC5160_OFS245_FIELD ((RegisterField) {TMC5160_OFS245_MASK, TMC5160_OFS245_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS246_MASK 0x00400000 +#define TMC5160_OFS246_SHIFT 22 +#define TMC5160_OFS246_FIELD ((RegisterField) {TMC5160_OFS246_MASK, TMC5160_OFS246_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS247_MASK 0x00800000 +#define TMC5160_OFS247_SHIFT 23 +#define TMC5160_OFS247_FIELD ((RegisterField) {TMC5160_OFS247_MASK, TMC5160_OFS247_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS248_MASK 0x01000000 +#define TMC5160_OFS248_SHIFT 24 +#define TMC5160_OFS248_FIELD ((RegisterField) {TMC5160_OFS248_MASK, TMC5160_OFS248_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS249_MASK 0x02000000 +#define TMC5160_OFS249_SHIFT 25 +#define TMC5160_OFS249_FIELD ((RegisterField) {TMC5160_OFS249_MASK, TMC5160_OFS249_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS250_MASK 0x04000000 +#define TMC5160_OFS250_SHIFT 26 +#define TMC5160_OFS250_FIELD ((RegisterField) {TMC5160_OFS250_MASK, TMC5160_OFS250_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS251_MASK 0x08000000 +#define TMC5160_OFS251_SHIFT 27 +#define TMC5160_OFS251_FIELD ((RegisterField) {TMC5160_OFS251_MASK, TMC5160_OFS251_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS252_MASK 0x10000000 +#define TMC5160_OFS252_SHIFT 28 +#define TMC5160_OFS252_FIELD ((RegisterField) {TMC5160_OFS252_MASK, TMC5160_OFS252_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS253_MASK 0x20000000 +#define TMC5160_OFS253_SHIFT 29 +#define TMC5160_OFS253_FIELD ((RegisterField) {TMC5160_OFS253_MASK, TMC5160_OFS253_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS254_MASK 0x40000000 +#define TMC5160_OFS254_SHIFT 30 +#define TMC5160_OFS254_FIELD ((RegisterField) {TMC5160_OFS254_MASK, TMC5160_OFS254_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS255_MASK 0x80000000 +#define TMC5160_OFS255_SHIFT 31 +#define TMC5160_OFS255_FIELD ((RegisterField) {TMC5160_OFS255_MASK, TMC5160_OFS255_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_W0_MASK 0x00000003 +#define TMC5160_W0_SHIFT 0 +#define TMC5160_W0_FIELD ((RegisterField) {TMC5160_W0_MASK, TMC5160_W0_SHIFT, TMC5160_MSLUTSEL, false}) +#define TMC5160_W1_MASK 0x0000000C +#define TMC5160_W1_SHIFT 2 +#define TMC5160_W1_FIELD ((RegisterField) {TMC5160_W1_MASK, TMC5160_W1_SHIFT, TMC5160_MSLUTSEL, false}) +#define TMC5160_W2_MASK 0x00000030 +#define TMC5160_W2_SHIFT 4 +#define TMC5160_W2_FIELD ((RegisterField) {TMC5160_W2_MASK, TMC5160_W2_SHIFT, TMC5160_MSLUTSEL, false}) +#define TMC5160_W3_MASK 0x000000C0 +#define TMC5160_W3_SHIFT 6 +#define TMC5160_W3_FIELD ((RegisterField) {TMC5160_W3_MASK, TMC5160_W3_SHIFT, TMC5160_MSLUTSEL, false}) +#define TMC5160_X1_MASK 0x0000FF00 +#define TMC5160_X1_SHIFT 8 +#define TMC5160_X1_FIELD ((RegisterField) {TMC5160_X1_MASK, TMC5160_X1_SHIFT, TMC5160_MSLUTSEL, false}) +#define TMC5160_X2_MASK 0x00FF0000 +#define TMC5160_X2_SHIFT 16 +#define TMC5160_X2_FIELD ((RegisterField) {TMC5160_X2_MASK, TMC5160_X2_SHIFT, TMC5160_MSLUTSEL, false}) +#define TMC5160_X3_MASK 0xFF000000 +#define TMC5160_X3_SHIFT 24 +#define TMC5160_X3_FIELD ((RegisterField) {TMC5160_X3_MASK, TMC5160_X3_SHIFT, TMC5160_MSLUTSEL, false}) +#define TMC5160_START_SIN_MASK 0x000000FF +#define TMC5160_START_SIN_SHIFT 0 +#define TMC5160_START_SIN_FIELD ((RegisterField) {TMC5160_START_SIN_MASK, TMC5160_START_SIN_SHIFT, TMC5160_MSLUTSTART, false}) +#define TMC5160_START_SIN90_MASK 0x00FF0000 +#define TMC5160_START_SIN90_SHIFT 16 +#define TMC5160_START_SIN90_FIELD ((RegisterField) {TMC5160_START_SIN90_MASK, TMC5160_START_SIN90_SHIFT, TMC5160_MSLUTSTART, false}) +#define TMC5160_MSCNT_MASK 0x000003FF +#define TMC5160_MSCNT_SHIFT 0 +#define TMC5160_MSCNT_FIELD ((RegisterField) {TMC5160_MSCNT_MASK, TMC5160_MSCNT_SHIFT, TMC5160_MSCNT, false}) +#define TMC5160_CUR_A_MASK 0x000001FF +#define TMC5160_CUR_A_SHIFT 0 +#define TMC5160_CUR_A_FIELD ((RegisterField) {TMC5160_CUR_A_MASK, TMC5160_CUR_A_SHIFT, TMC5160_MSCURACT, true}) +#define TMC5160_CUR_B_MASK 0x01FF0000 +#define TMC5160_CUR_B_SHIFT 16 +#define TMC5160_CUR_B_FIELD ((RegisterField) {TMC5160_CUR_B_MASK, TMC5160_CUR_B_SHIFT, TMC5160_MSCURACT, true}) +#define TMC5160_TOFF_MASK 0x0000000F +#define TMC5160_TOFF_SHIFT 0 +#define TMC5160_TOFF_FIELD ((RegisterField) {TMC5160_TOFF_MASK, TMC5160_TOFF_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_TFD_2__0__MASK 0x00000070 +#define TMC5160_TFD_2__0__SHIFT 4 +#define TMC5160_TFD_2__0__FIELD ((RegisterField) {TMC5160_TFD_2__0__MASK, TMC5160_TFD_2__0__SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_OFFSET_MASK 0x00000780 +#define TMC5160_OFFSET_SHIFT 7 +#define TMC5160_OFFSET_FIELD ((RegisterField) {TMC5160_OFFSET_MASK, TMC5160_OFFSET_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_TFD___MASK 0x00000800 +#define TMC5160_TFD___SHIFT 11 +#define TMC5160_TFD___FIELD ((RegisterField) {TMC5160_TFD___MASK, TMC5160_TFD___SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_DISFDCC_MASK 0x00001000 +#define TMC5160_DISFDCC_SHIFT 12 +#define TMC5160_DISFDCC_FIELD ((RegisterField) {TMC5160_DISFDCC_MASK, TMC5160_DISFDCC_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_CHM_MASK 0x00004000 +#define TMC5160_CHM_SHIFT 14 +#define TMC5160_CHM_FIELD ((RegisterField) {TMC5160_CHM_MASK, TMC5160_CHM_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_TBL_MASK 0x00018000 +#define TMC5160_TBL_SHIFT 15 +#define TMC5160_TBL_FIELD ((RegisterField) {TMC5160_TBL_MASK, TMC5160_TBL_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_VHIGHFS_MASK 0x00040000 +#define TMC5160_VHIGHFS_SHIFT 18 +#define TMC5160_VHIGHFS_FIELD ((RegisterField) {TMC5160_VHIGHFS_MASK, TMC5160_VHIGHFS_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_VHIGHCHM_MASK 0x00080000 +#define TMC5160_VHIGHCHM_SHIFT 19 +#define TMC5160_VHIGHCHM_FIELD ((RegisterField) {TMC5160_VHIGHCHM_MASK, TMC5160_VHIGHCHM_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_TPFD_MASK 0x00F00000 +#define TMC5160_TPFD_SHIFT 20 +#define TMC5160_TPFD_FIELD ((RegisterField) {TMC5160_TPFD_MASK, TMC5160_TPFD_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_MRES_MASK 0x0F000000 +#define TMC5160_MRES_SHIFT 24 +#define TMC5160_MRES_FIELD ((RegisterField) {TMC5160_MRES_MASK, TMC5160_MRES_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_INTPOL_MASK 0x10000000 +#define TMC5160_INTPOL_SHIFT 28 +#define TMC5160_INTPOL_FIELD ((RegisterField) {TMC5160_INTPOL_MASK, TMC5160_INTPOL_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_DEDGE_MASK 0x20000000 +#define TMC5160_DEDGE_SHIFT 29 +#define TMC5160_DEDGE_FIELD ((RegisterField) {TMC5160_DEDGE_MASK, TMC5160_DEDGE_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_DISS2G_MASK 0x40000000 +#define TMC5160_DISS2G_SHIFT 30 +#define TMC5160_DISS2G_FIELD ((RegisterField) {TMC5160_DISS2G_MASK, TMC5160_DISS2G_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_DISS2VS_MASK 0x80000000 +#define TMC5160_DISS2VS_SHIFT 31 +#define TMC5160_DISS2VS_FIELD ((RegisterField) {TMC5160_DISS2VS_MASK, TMC5160_DISS2VS_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_TOFF_MASK 0x0000000F +#define TMC5160_TOFF_SHIFT 0 +#define TMC5160_TOFF_FIELD ((RegisterField) {TMC5160_TOFF_MASK, TMC5160_TOFF_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_TFD_ALL_MASK 0x00000070 +#define TMC5160_TFD_ALL_SHIFT 4 +#define TMC5160_TFD_ALL_FIELD ((RegisterField) {TMC5160_TFD_2__0__MASK, TMC5160_TFD_2__0__SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_OFFSET_MASK 0x00000780 +#define TMC5160_OFFSET_SHIFT 7 +#define TMC5160_OFFSET_FIELD ((RegisterField) {TMC5160_OFFSET_MASK, TMC5160_OFFSET_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_TFD_3_MASK 0x00000800 +#define TMC5160_TFD_3_SHIFT 11 +#define TMC5160_TFD_3_FIELD ((RegisterField) {TMC5160_TFD___MASK, TMC5160_TFD___SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_DISFDCC_MASK 0x00001000 +#define TMC5160_DISFDCC_SHIFT 12 +#define TMC5160_DISFDCC_FIELD ((RegisterField) {TMC5160_DISFDCC_MASK, TMC5160_DISFDCC_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_RNDTF_MASK 0x00002000 +#define TMC5160_RNDTF_SHIFT 13 +#define TMC5160_RNDTF_FIELD ((RegisterField) {TMC5160_RNDTF_MASK, TMC5160_RNDTF_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_CHM_MASK 0x00004000 +#define TMC5160_CHM_SHIFT 14 +#define TMC5160_CHM_FIELD ((RegisterField) {TMC5160_CHM_MASK, TMC5160_CHM_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_TBL_MASK 0x00018000 +#define TMC5160_TBL_SHIFT 15 +#define TMC5160_TBL_FIELD ((RegisterField) {TMC5160_TBL_MASK, TMC5160_TBL_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_VSENSE_MASK 0x00020000 +#define TMC5160_VSENSE_SHIFT 17 +#define TMC5160_VSENSE_FIELD ((RegisterField) {TMC5160_VSENSE_MASK, TMC5160_VSENSE_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_VHIGHFS_MASK 0x00040000 +#define TMC5160_VHIGHFS_SHIFT 18 +#define TMC5160_VHIGHFS_FIELD ((RegisterField) {TMC5160_VHIGHFS_MASK, TMC5160_VHIGHFS_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_VHIGHCHM_MASK 0x00080000 +#define TMC5160_VHIGHCHM_SHIFT 19 +#define TMC5160_VHIGHCHM_FIELD ((RegisterField) {TMC5160_VHIGHCHM_MASK, TMC5160_VHIGHCHM_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_TPFD_MASK 0x00F00000 +#define TMC5160_TPFD_SHIFT 20 +#define TMC5160_TPFD_FIELD ((RegisterField) {TMC5160_TPFD_MASK, TMC5160_TPFD_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_MRES_MASK 0x0F000000 +#define TMC5160_MRES_SHIFT 24 +#define TMC5160_MRES_FIELD ((RegisterField) {TMC5160_MRES_MASK, TMC5160_MRES_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_INTPOL_MASK 0x10000000 +#define TMC5160_INTPOL_SHIFT 28 +#define TMC5160_INTPOL_FIELD ((RegisterField) {TMC5160_INTPOL_MASK, TMC5160_INTPOL_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_DEDGE_MASK 0x20000000 +#define TMC5160_DEDGE_SHIFT 29 +#define TMC5160_DEDGE_FIELD ((RegisterField) {TMC5160_DEDGE_MASK, TMC5160_DEDGE_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_DISS2G_MASK 0x40000000 +#define TMC5160_DISS2G_SHIFT 30 +#define TMC5160_DISS2G_FIELD ((RegisterField) {TMC5160_DISS2G_MASK, TMC5160_DISS2G_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_DISS2VS_MASK 0x80000000 +#define TMC5160_DISS2VS_SHIFT 31 +#define TMC5160_DISS2VS_FIELD ((RegisterField) {TMC5160_DISS2VS_MASK, TMC5160_DISS2VS_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_TOFF_MASK 0x0000000F +#define TMC5160_TOFF_SHIFT 0 +#define TMC5160_TOFF_FIELD ((RegisterField) {TMC5160_TOFF_MASK, TMC5160_TOFF_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_HSTRT_MASK 0x00000070 +#define TMC5160_HSTRT_SHIFT 4 +#define TMC5160_HSTRT_FIELD ((RegisterField) {TMC5160_HSTRT_MASK, TMC5160_HSTRT_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_HEND_MASK 0x00000780 +#define TMC5160_HEND_SHIFT 7 +#define TMC5160_HEND_FIELD ((RegisterField) {TMC5160_HEND_MASK, TMC5160_HEND_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_CHM_MASK 0x00004000 +#define TMC5160_CHM_SHIFT 14 +#define TMC5160_CHM_FIELD ((RegisterField) {TMC5160_CHM_MASK, TMC5160_CHM_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_TBL_MASK 0x00018000 +#define TMC5160_TBL_SHIFT 15 +#define TMC5160_TBL_FIELD ((RegisterField) {TMC5160_TBL_MASK, TMC5160_TBL_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_VHIGHFS_MASK 0x00040000 +#define TMC5160_VHIGHFS_SHIFT 18 +#define TMC5160_VHIGHFS_FIELD ((RegisterField) {TMC5160_VHIGHFS_MASK, TMC5160_VHIGHFS_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_VHIGHCHM_MASK 0x00080000 +#define TMC5160_VHIGHCHM_SHIFT 19 +#define TMC5160_VHIGHCHM_FIELD ((RegisterField) {TMC5160_VHIGHCHM_MASK, TMC5160_VHIGHCHM_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_TPFD_MASK 0x00F00000 +#define TMC5160_TPFD_SHIFT 20 +#define TMC5160_TPFD_FIELD ((RegisterField) {TMC5160_TPFD_MASK, TMC5160_TPFD_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_MRES_MASK 0x0F000000 +#define TMC5160_MRES_SHIFT 24 +#define TMC5160_MRES_FIELD ((RegisterField) {TMC5160_MRES_MASK, TMC5160_MRES_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_INTPOL_MASK 0x10000000 +#define TMC5160_INTPOL_SHIFT 28 +#define TMC5160_INTPOL_FIELD ((RegisterField) {TMC5160_INTPOL_MASK, TMC5160_INTPOL_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_DEDGE_MASK 0x20000000 +#define TMC5160_DEDGE_SHIFT 29 +#define TMC5160_DEDGE_FIELD ((RegisterField) {TMC5160_DEDGE_MASK, TMC5160_DEDGE_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_DISS2G_MASK 0x40000000 +#define TMC5160_DISS2G_SHIFT 30 +#define TMC5160_DISS2G_FIELD ((RegisterField) {TMC5160_DISS2G_MASK, TMC5160_DISS2G_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_DISS2VS_MASK 0x80000000 +#define TMC5160_DISS2VS_SHIFT 31 +#define TMC5160_DISS2VS_FIELD ((RegisterField) {TMC5160_DISS2VS_MASK, TMC5160_DISS2VS_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_SEMIN_MASK 0x0000000F +#define TMC5160_SEMIN_SHIFT 0 +#define TMC5160_SEMIN_FIELD ((RegisterField) {TMC5160_SEMIN_MASK, TMC5160_SEMIN_SHIFT, TMC5160_COOLCONF, false}) +#define TMC5160_SEUP_MASK 0x00000060 +#define TMC5160_SEUP_SHIFT 5 +#define TMC5160_SEUP_FIELD ((RegisterField) {TMC5160_SEUP_MASK, TMC5160_SEUP_SHIFT, TMC5160_COOLCONF, false}) +#define TMC5160_SEMAX_MASK 0x00000F00 +#define TMC5160_SEMAX_SHIFT 8 +#define TMC5160_SEMAX_FIELD ((RegisterField) {TMC5160_SEMAX_MASK, TMC5160_SEMAX_SHIFT, TMC5160_COOLCONF, false}) +#define TMC5160_SEDN_MASK 0x00006000 +#define TMC5160_SEDN_SHIFT 13 +#define TMC5160_SEDN_FIELD ((RegisterField) {TMC5160_SEDN_MASK, TMC5160_SEDN_SHIFT, TMC5160_COOLCONF, false}) +#define TMC5160_SEIMIN_MASK 0x00008000 +#define TMC5160_SEIMIN_SHIFT 15 +#define TMC5160_SEIMIN_FIELD ((RegisterField) {TMC5160_SEIMIN_MASK, TMC5160_SEIMIN_SHIFT, TMC5160_COOLCONF, false}) +#define TMC5160_SGT_MASK 0x007F0000 +#define TMC5160_SGT_SHIFT 16 +#define TMC5160_SGT_FIELD ((RegisterField) {TMC5160_SGT_MASK, TMC5160_SGT_SHIFT, TMC5160_COOLCONF, true}) +#define TMC5160_SFILT_MASK 0x01000000 +#define TMC5160_SFILT_SHIFT 24 +#define TMC5160_SFILT_FIELD ((RegisterField) {TMC5160_SFILT_MASK, TMC5160_SFILT_SHIFT, TMC5160_COOLCONF, false}) +#define TMC5160_DC_TIME_MASK 0x000003FF +#define TMC5160_DC_TIME_SHIFT 0 +#define TMC5160_DC_TIME_FIELD ((RegisterField) {TMC5160_DC_TIME_MASK, TMC5160_DC_TIME_SHIFT, TMC5160_DCCTRL, false}) +#define TMC5160_DC_SG_MASK 0x00FF0000 +#define TMC5160_DC_SG_SHIFT 16 +#define TMC5160_DC_SG_FIELD ((RegisterField) {TMC5160_DC_SG_MASK, TMC5160_DC_SG_SHIFT, TMC5160_DCCTRL, false}) +#define TMC5160_SG_RESULT_MASK 0x000003FF +#define TMC5160_SG_RESULT_SHIFT 0 +#define TMC5160_SG_RESULT_FIELD ((RegisterField) {TMC5160_SG_RESULT_MASK, TMC5160_SG_RESULT_SHIFT, TMC5160_DRV_STATUS, false}) +#define TMC5160_S2VSA_MASK 0x00001000 +#define TMC5160_S2VSA_SHIFT 12 +#define TMC5160_S2VSA_FIELD ((RegisterField) {TMC5160_S2VSA_MASK, TMC5160_S2VSA_SHIFT, TMC5160_DRV_STATUS, false}) +#define TMC5160_S2VSB_MASK 0x00002000 +#define TMC5160_S2VSB_SHIFT 13 +#define TMC5160_S2VSB_FIELD ((RegisterField) {TMC5160_S2VSB_MASK, TMC5160_S2VSB_SHIFT, TMC5160_DRV_STATUS, false}) +#define TMC5160_STEALTH_MASK 0x00004000 +#define TMC5160_STEALTH_SHIFT 14 +#define TMC5160_STEALTH_FIELD ((RegisterField) {TMC5160_STEALTH_MASK, TMC5160_STEALTH_SHIFT, TMC5160_DRV_STATUS, false}) +#define TMC5160_FSACTIVE_MASK 0x00008000 +#define TMC5160_FSACTIVE_SHIFT 15 +#define TMC5160_FSACTIVE_FIELD ((RegisterField) {TMC5160_FSACTIVE_MASK, TMC5160_FSACTIVE_SHIFT, TMC5160_DRV_STATUS, false}) +#define TMC5160_CS_ACTUAL_MASK 0x001F0000 +#define TMC5160_CS_ACTUAL_SHIFT 16 +#define TMC5160_CS_ACTUAL_FIELD ((RegisterField) {TMC5160_CS_ACTUAL_MASK, TMC5160_CS_ACTUAL_SHIFT, TMC5160_DRV_STATUS, false}) +#define TMC5160_STALLGUARD_MASK 0x01000000 +#define TMC5160_STALLGUARD_SHIFT 24 +#define TMC5160_STALLGUARD_FIELD ((RegisterField) {TMC5160_STALLGUARD_MASK, TMC5160_STALLGUARD_SHIFT, TMC5160_DRV_STATUS, false}) +#define TMC5160_OT_MASK 0x02000000 +#define TMC5160_OT_SHIFT 25 +#define TMC5160_OT_FIELD ((RegisterField) {TMC5160_OT_MASK, TMC5160_OT_SHIFT, TMC5160_DRV_STATUS, false}) +#define TMC5160_OTPW_MASK 0x04000000 +#define TMC5160_OTPW_SHIFT 26 +#define TMC5160_OTPW_FIELD ((RegisterField) {TMC5160_OTPW_MASK, TMC5160_OTPW_SHIFT, TMC5160_DRV_STATUS, false}) +#define TMC5160_S2GA_MASK 0x08000000 +#define TMC5160_S2GA_SHIFT 27 +#define TMC5160_S2GA_FIELD ((RegisterField) {TMC5160_S2GA_MASK, TMC5160_S2GA_SHIFT, TMC5160_DRV_STATUS, false}) +#define TMC5160_S2GB_MASK 0x10000000 +#define TMC5160_S2GB_SHIFT 28 +#define TMC5160_S2GB_FIELD ((RegisterField) {TMC5160_S2GB_MASK, TMC5160_S2GB_SHIFT, TMC5160_DRV_STATUS, false}) +#define TMC5160_OLA_MASK 0x20000000 +#define TMC5160_OLA_SHIFT 29 +#define TMC5160_OLA_FIELD ((RegisterField) {TMC5160_OLA_MASK, TMC5160_OLA_SHIFT, TMC5160_DRV_STATUS, false}) +#define TMC5160_OLB_MASK 0x40000000 +#define TMC5160_OLB_SHIFT 30 +#define TMC5160_OLB_FIELD ((RegisterField) {TMC5160_OLB_MASK, TMC5160_OLB_SHIFT, TMC5160_DRV_STATUS, false}) +#define TMC5160_STST_MASK 0x80000000 +#define TMC5160_STST_SHIFT 31 +#define TMC5160_STST_FIELD ((RegisterField) {TMC5160_STST_MASK, TMC5160_STST_SHIFT, TMC5160_DRV_STATUS, false}) +#define TMC5160_PWM_OFS_MASK 0x000000FF +#define TMC5160_PWM_OFS_SHIFT 0 +#define TMC5160_PWM_OFS_FIELD ((RegisterField) {TMC5160_PWM_OFS_MASK, TMC5160_PWM_OFS_SHIFT, TMC5160_PWMCONF, false}) +#define TMC5160_PWM_GRAD_MASK 0x0000FF00 +#define TMC5160_PWM_GRAD_SHIFT 8 +#define TMC5160_PWM_GRAD_FIELD ((RegisterField) {TMC5160_PWM_GRAD_MASK, TMC5160_PWM_GRAD_SHIFT, TMC5160_PWMCONF, false}) +#define TMC5160_PWM_FREQ_MASK 0x00030000 +#define TMC5160_PWM_FREQ_SHIFT 16 +#define TMC5160_PWM_FREQ_FIELD ((RegisterField) {TMC5160_PWM_FREQ_MASK, TMC5160_PWM_FREQ_SHIFT, TMC5160_PWMCONF, false}) +#define TMC5160_PWM_AUTOSCALE_MASK 0x00040000 +#define TMC5160_PWM_AUTOSCALE_SHIFT 18 +#define TMC5160_PWM_AUTOSCALE_FIELD ((RegisterField) {TMC5160_PWM_AUTOSCALE_MASK, TMC5160_PWM_AUTOSCALE_SHIFT, TMC5160_PWMCONF, false}) +#define TMC5160_PWM_AUTOGRAD_MASK 0x00080000 +#define TMC5160_PWM_AUTOGRAD_SHIFT 19 +#define TMC5160_PWM_AUTOGRAD_FIELD ((RegisterField) {TMC5160_PWM_AUTOGRAD_MASK, TMC5160_PWM_AUTOGRAD_SHIFT, TMC5160_PWMCONF, false}) +#define TMC5160_FREEWHEEL_MASK 0x00300000 +#define TMC5160_FREEWHEEL_SHIFT 20 +#define TMC5160_FREEWHEEL_FIELD ((RegisterField) {TMC5160_FREEWHEEL_MASK, TMC5160_FREEWHEEL_SHIFT, TMC5160_PWMCONF, false}) +#define TMC5160_PWM_REG_MASK 0x0F000000 +#define TMC5160_PWM_REG_SHIFT 24 +#define TMC5160_PWM_REG_FIELD ((RegisterField) {TMC5160_PWM_REG_MASK, TMC5160_PWM_REG_SHIFT, TMC5160_PWMCONF, false}) +#define TMC5160_PWM_LIM_MASK 0xF0000000 +#define TMC5160_PWM_LIM_SHIFT 28 +#define TMC5160_PWM_LIM_FIELD ((RegisterField) {TMC5160_PWM_LIM_MASK, TMC5160_PWM_LIM_SHIFT, TMC5160_PWMCONF, false}) +#define TMC5160_PWM_SCALE_SUM_MASK 0x000000FF +#define TMC5160_PWM_SCALE_SUM_SHIFT 0 +#define TMC5160_PWM_SCALE_SUM_FIELD ((RegisterField) {TMC5160_PWM_SCALE_SUM_MASK, TMC5160_PWM_SCALE_SUM_SHIFT, TMC5160_PWM_SCALE, false}) +#define TMC5160_PWM_SCALE_AUTO_MASK 0x01FF0000 +#define TMC5160_PWM_SCALE_AUTO_SHIFT 16 +#define TMC5160_PWM_SCALE_AUTO_FIELD ((RegisterField) {TMC5160_PWM_SCALE_AUTO_MASK, TMC5160_PWM_SCALE_AUTO_SHIFT, TMC5160_PWM_SCALE, true}) +#define TMC5160_PWM_OFS_AUTO_MASK 0x000000FF +#define TMC5160_PWM_OFS_AUTO_SHIFT 0 +#define TMC5160_PWM_OFS_AUTO_FIELD ((RegisterField) {TMC5160_PWM_OFS_AUTO_MASK, TMC5160_PWM_OFS_AUTO_SHIFT, TMC5160_PWM_AUTO, false}) +#define TMC5160_PWM_GRAD_AUTO_MASK 0x00FF0000 +#define TMC5160_PWM_GRAD_AUTO_SHIFT 16 +#define TMC5160_PWM_GRAD_AUTO_FIELD ((RegisterField) {TMC5160_PWM_GRAD_AUTO_MASK, TMC5160_PWM_GRAD_AUTO_SHIFT, TMC5160_PWM_AUTO, false}) +#define TMC5160_LOST_STEPS_MASK 0x000FFFFF +#define TMC5160_LOST_STEPS_SHIFT 0 +#define TMC5160_LOST_STEPS_FIELD ((RegisterField) {TMC5160_LOST_STEPS_MASK, TMC5160_LOST_STEPS_SHIFT, TMC5160_LOST_STEPS, false}) + +#endif diff --git a/firmware/lib/tmc/ic/TMC5160/registercall_hierarchy_flowchart_SPI.svg b/firmware/lib/tmc/ic/TMC5160/registercall_hierarchy_flowchart_SPI.svg new file mode 100755 index 0000000..cbad58f --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5160/registercall_hierarchy_flowchart_SPI.svg @@ -0,0 +1,3 @@ + + +

HAL

HAL

APP (Eval)

APP (Eval)

API

API
Read a register
  •  Call tmcXXXX_readRegister function
Read a register...
Returns the register read value
Returns the register read value
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
tmcXXXX.c
tmcXXXX.c
SPI.c
SPI.c
tmcXXXX_eval.c
tmcXXXX_eval.c

 Implementation of SPI_readWrite
  • Sends and receives bytes on the SPI bus
Implementation of SPI_readWrite...
Returns the raw reply data
Returns the raw reply data

Implementation of tmcXXXX_readWriteSPI
  • Sets the CSN pin to LOW
  • Takes the array of data to write
  • Calls hardware function SPI_readWrite
  • Upon completion of data transfer,
    sets CSN to 
    HIGH
Implementation of tmcXXXX_readWriteSPI...
Passes on the raw reply data to the API
Passes on the raw reply data to the API
Implementation of readRegisterSPI
  • Constructs the datagram
  • Calls HAL wrapper function 
Implementation of readRegisterSPI...
tmcXXXX_readWriteSPI
tmcXXXX_readWriteSPI
Parses the reply and returns the register value
Parses the reply and returns the register value
Implementation of tmcXXXX_readRegister 
  • Check which bus is active SPI/UART. (e.g. SPI)
  • Calls bus-specific function (e.g. readRegisterSPI)
 
Implementation of tmcXXXX_readRegister...
Returns the register read value
Returns the register read value
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC5160/registercall_hierarchy_flowchart_UART.svg b/firmware/lib/tmc/ic/TMC5160/registercall_hierarchy_flowchart_UART.svg new file mode 100755 index 0000000..425f60a --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5160/registercall_hierarchy_flowchart_UART.svg @@ -0,0 +1,3 @@ + + +

HAL

HAL

APP (Eval)

APP (Eval)

API

API
Read a register
  •  Call tmcXXXX_readRegister function
Read a register...
Returns the register read value
Returns the register read value
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
tmcXXXX.c
tmcXXXX.c
UART.c
UART.c
tmcXXXX_eval.c
tmcXXXX_eval.c

 Implementation of UART_readWrite
  • Sends and receives bytes on the UART bus
Implementation of UART_readWrite...
Returns the raw reply data
Returns the raw reply data

Implementation of tmcXXXX_readWriteUART
  • Takes the array of data to write
  • Calls hardware function UART_readWrite
Implementation of tmcXXXX_readWriteUART...
Passes on the raw reply data to the API
Passes on the raw reply data to the API
Implementation of readRegisterUART
  • Constructs the datagram
  • Calls HAL wrapper function 
Implementation of readRegisterUART...
tmcXXXX_readWriteUART
tmcXXXX_readWriteUART
Parses the reply and returns the register value
Parses the reply and returns the register value
Implementation of tmcXXXX_readRegister 
  • Check which bus is active SPI/UART. (e.g. UART)
  • Calls bus-specific function (e.g. readRegisterUART)
 
Implementation of tmcXXXX_readRegister...
Returns the register read value
Returns the register read value
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC5160/uml-tmc-api.svg b/firmware/lib/tmc/ic/TMC5160/uml-tmc-api.svg new file mode 100755 index 0000000..5a5f8dd --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5160/uml-tmc-api.svg @@ -0,0 +1,3 @@ + + +

TMCXXXX_HW_Abstraction.h



TMCXXXX_HW_Abstraction.h...
// Constants
#define TMCXXXX_MOTORS              
                          
// Register definitions
#define TMCXXXX_GCONF        
                          ⋮
// Register fields definitions
#define TMCXXXX_GCONF_OTPW_FIELD
                     
// Constants...

TMCXXXX.h



TMCXXXX.h...
extern void tmcXXXX_readWriteSPI();
extern void tmcXXXX_readWriteUART();
extern TMCXXXXBusType tmcXXXX_getBusType();
extern uint8_t tmcXXXX_getNodeAddress();
                                  ⋮
tmcXXXX_readRegister();
tmcXXXX_writeRegister();
                                  ⋮
extern void tmcXXXX_readWriteSPI();...

TMCXXXX.c



TMCXXXX.c...
const uint8_t tmcCRCTable_Poly7Reflected[256] = {...};
int32_t tmcXXXX_readRegister(){
/* Call tmcXXXX_getBusType();
 * Based on bus type, call readRegisterSPI/UART() that
 * further calls tmcXXXX_readWriteSPI/UART();
 * For UART it also calls tmcXXXX_getNodeAddress();
                                           ⋮
}
                                           ⋮
const uint8_t tmcCRCTable_Poly7Reflected[256] = {.....
TMC-API
TMC-API

TMCXXXX_Simple_Rotation.h


TMCXXXX_Simple_Rotation.h...
void initAllMotors();
             ⋮
  
void initAllMotors()...

TMCXXXX_Simple_Rotation.c


TMCXXXX_Simple_Rotation.c...
void initAllMotors(){

// Configuring registers to enable motor drivers etc..
tmcXXXX_writeRegister();
                    ⋮
}
                    ⋮
void initAllMotors(){...
Examples
Examples
User Project
User Project

User_Project.h


User_Project.h

User_Project.c








User_Project.c...

void tmcXXXX_readWriteSPI(){
                           ⋮
}
void tmcXXXX_readWriteUART(){
                           ⋮
}
TMCXXXXBusType tmcXXXX_getBusType(){
                           ⋮
}
uint8_t tmcXXXX_getNodeAddress(){
                           ⋮
}

// User Code
                           ⋮
void tmcXXXX_readWriteSPI(){...
#include "TMCXXXX_HW_Abstraction.h"
#include "TMCXXXX.h"
#include "TMCXXXX_Simple_Rotation.h"
                                ⋮
TMCXXXXBusType bus = IC_BUS_SPI/UART;
uint8_t nodeAddress = <nodeAddress>;
                                ⋮
#include "TMCXXXX_HW_Abstraction.h"...
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC5240/README.md b/firmware/lib/tmc/ic/TMC5240/README.md new file mode 100755 index 0000000..9967b1d --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5240/README.md @@ -0,0 +1,57 @@ +# TMC5240 + + +## How to use + +To access the TMC5240's registers, the TMC-API offers two functions: **tmc5240_readRegister** and **tmc5240_writeRegister**. +Each of these functions takes in an **icID**, which is used to identify the IC when multiple ICs are connected. This identifier is passed down to the callback functions (see How to Integrate). + +## How to integrate: overview + +1. Include all the files of the TMC-API/ic/tmc/TMC5240 folder into the custom project. +2. Include the TMC5240.h file in the custom source code. +3. Implement the necessary callback functions (see below). +4. (optional): Take a look at the Examples subfolder for ready-made examples of the TMC-API usage. + +## Accessing the TMC5240 via UART +The following diagram depicts how to access the TMC5240 via UART using the TMC-API. + +![screenshot](registercall_hierarchy_flowchart_UART.svg) + +The description of the functions, in the above flowchart, are as follows: +- The functions tmc5240_readRegister and tmc5240_writeRegister are used to read and write the registers respectively. These functions check the current active bus and calls the bus-specific function i.e readRegisterUART or writeRegisterUART. +- These bus specific functions constructs the datagram and further calls the bus specific callback 'tmcXXXX_readWriteUART. +- This callback function further calls the hardware specific read/write function for UART and needs to be implemented externally. + +## Accessing the TMC5240 via SPI +The following diagram depicts how to access the TMC5240 via SPI using the TMC-API. + +![screenshot](registercall_hierarchy_flowchart_SPI.svg) + +The description of the functions, in the above flowchart, are as follows: +- The functions tmc5240_readRegister and tmc5240_writeRegister are used to read and write the registers respectively. These functions check the current active bus and calls the bus-specific function i.e readRegisterSPI or writeRegisterSPI. +- These bus specific functions constructs the datagram and further calls the bus specific callback 'tmcXXXX_readWriteSPI. +- This callback function further calls the hardware specific read/write function for SPI and needs to be implemented externally. + +### How to integrate: Callback functions +To communicate with TMC5240 IC, the TMC-API library needs to know which bus (UART, SPI) it shall use. For that, the callback function **'tmc5240_getBusType()'** needs to be implemented. +Additionally, implement the following callback functions to access the chip via UART: +1. **tmc5240_readWriteUART()**, which is a HAL wrapper function that provides the necessary hardware access. +2. **tmc5240_getNodeAddress()**, that returns the node/slave address. Node address could be set in NODECONF (0x3) register and the address could be incremented as defined by AD0, AD1 and AD2. (Node address + ADx) must be less than 255. For further details please consult the datasheet of TMC5240. + +### Sharing the CRC table with other TMC-API chips +The TMC5240 UART protocol uses an 8 bit CRC. For calculating this, a table-based algorithm is used. This table (tmcCRCTable_Poly7Reflected[256]) is 256 bytes big and identical across multiple different Trinamic chips (i.e. TMC2209). +If multiple Trinamic chips are being used in the same project, avoiding redundant copies of this table could save memory. It is possible to substitute this CRC table with another CRC table. + +## Further info +### Dependency graph for the ICs with new register R/W mechanism +This graph illustrates the relationships between files within the TMC-API library, highlighting dependencies and identifying the files that are essential for integrating the library into the custom projects. + +![screenshot](uml-tmc-api.svg) + +### Example usage: TMC-Evalsystem +**For a reference usage of the TMC-API**, visit the [TMC-Evalsystem](https://github.com/analogdevicesinc/TMC-EvalSystem) + +## Migration status +The TMC5240 has been reworked to the access system described above. For more infos on the status of this and other ICs, check out the [migration page](https://github.com/analogdevicesinc/TMC-API/issues/53). + diff --git a/firmware/lib/tmc/ic/TMC5240/TMC5240.c b/firmware/lib/tmc/ic/TMC5240/TMC5240.c new file mode 100755 index 0000000..731a235 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5240/TMC5240.c @@ -0,0 +1,179 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + +#include "TMC5240.h" + +#ifdef TMC_API_EXTERNAL_CRC_TABLE +extern const uint8_t tmcCRCTable_Poly7Reflected[256]; +#else +const uint8_t tmcCRCTable_Poly7Reflected[256] = { + 0x00, 0x91, 0xE3, 0x72, 0x07, 0x96, 0xE4, 0x75, 0x0E, 0x9F, 0xED, 0x7C, 0x09, 0x98, 0xEA, 0x7B, + 0x1C, 0x8D, 0xFF, 0x6E, 0x1B, 0x8A, 0xF8, 0x69, 0x12, 0x83, 0xF1, 0x60, 0x15, 0x84, 0xF6, 0x67, + 0x38, 0xA9, 0xDB, 0x4A, 0x3F, 0xAE, 0xDC, 0x4D, 0x36, 0xA7, 0xD5, 0x44, 0x31, 0xA0, 0xD2, 0x43, + 0x24, 0xB5, 0xC7, 0x56, 0x23, 0xB2, 0xC0, 0x51, 0x2A, 0xBB, 0xC9, 0x58, 0x2D, 0xBC, 0xCE, 0x5F, + 0x70, 0xE1, 0x93, 0x02, 0x77, 0xE6, 0x94, 0x05, 0x7E, 0xEF, 0x9D, 0x0C, 0x79, 0xE8, 0x9A, 0x0B, + 0x6C, 0xFD, 0x8F, 0x1E, 0x6B, 0xFA, 0x88, 0x19, 0x62, 0xF3, 0x81, 0x10, 0x65, 0xF4, 0x86, 0x17, + 0x48, 0xD9, 0xAB, 0x3A, 0x4F, 0xDE, 0xAC, 0x3D, 0x46, 0xD7, 0xA5, 0x34, 0x41, 0xD0, 0xA2, 0x33, + 0x54, 0xC5, 0xB7, 0x26, 0x53, 0xC2, 0xB0, 0x21, 0x5A, 0xCB, 0xB9, 0x28, 0x5D, 0xCC, 0xBE, 0x2F, + 0xE0, 0x71, 0x03, 0x92, 0xE7, 0x76, 0x04, 0x95, 0xEE, 0x7F, 0x0D, 0x9C, 0xE9, 0x78, 0x0A, 0x9B, + 0xFC, 0x6D, 0x1F, 0x8E, 0xFB, 0x6A, 0x18, 0x89, 0xF2, 0x63, 0x11, 0x80, 0xF5, 0x64, 0x16, 0x87, + 0xD8, 0x49, 0x3B, 0xAA, 0xDF, 0x4E, 0x3C, 0xAD, 0xD6, 0x47, 0x35, 0xA4, 0xD1, 0x40, 0x32, 0xA3, + 0xC4, 0x55, 0x27, 0xB6, 0xC3, 0x52, 0x20, 0xB1, 0xCA, 0x5B, 0x29, 0xB8, 0xCD, 0x5C, 0x2E, 0xBF, + 0x90, 0x01, 0x73, 0xE2, 0x97, 0x06, 0x74, 0xE5, 0x9E, 0x0F, 0x7D, 0xEC, 0x99, 0x08, 0x7A, 0xEB, + 0x8C, 0x1D, 0x6F, 0xFE, 0x8B, 0x1A, 0x68, 0xF9, 0x82, 0x13, 0x61, 0xF0, 0x85, 0x14, 0x66, 0xF7, + 0xA8, 0x39, 0x4B, 0xDA, 0xAF, 0x3E, 0x4C, 0xDD, 0xA6, 0x37, 0x45, 0xD4, 0xA1, 0x30, 0x42, 0xD3, + 0xB4, 0x25, 0x57, 0xC6, 0xB3, 0x22, 0x50, 0xC1, 0xBA, 0x2B, 0x59, 0xC8, 0xBD, 0x2C, 0x5E, 0xCF, +}; +#endif + +/************************************************************** Register read / write Implementation ******************************************************************/ + +static int32_t readRegisterSPI(uint16_t icID, uint8_t address); +static void writeRegisterSPI(uint16_t icID, uint8_t address, int32_t value); +static int32_t readRegisterUART(uint16_t icID, uint8_t registerAddress); +static void writeRegisterUART(uint16_t icID, uint8_t registerAddress, int32_t value); +static uint8_t CRC8(uint8_t *data, uint32_t bytes); + +int32_t tmc5240_readRegister(uint16_t icID, uint8_t address) +{ + TMC5240BusType bus = tmc5240_getBusType(icID); + + if(bus == IC_BUS_SPI) + { + return readRegisterSPI(icID, address); + } + else if (bus == IC_BUS_UART) + { + return readRegisterUART(icID, address); + } + return -1; +} + +void tmc5240_writeRegister(uint16_t icID, uint8_t address, int32_t value) +{ + TMC5240BusType bus = tmc5240_getBusType(icID); + + if(bus == IC_BUS_SPI) + { + writeRegisterSPI(icID, address, value); + } + else if (bus == IC_BUS_UART) + { + writeRegisterUART(icID, address, value); + } +} + +int32_t readRegisterSPI(uint16_t icID, uint8_t address) +{ + uint8_t data[5] = { 0 }; + + // clear write bit + data[0] = address & TMC5240_ADDRESS_MASK; + + // Send the read request + tmc5240_readWriteSPI(icID, &data[0], sizeof(data)); + + // Rewrite address and clear write bit + data[0] = address & TMC5240_ADDRESS_MASK; + + // Send another request to receive the read reply + tmc5240_readWriteSPI(icID, &data[0], sizeof(data)); + + return ((int32_t)data[1] << 24) | ((int32_t) data[2] << 16) | ((int32_t) data[3] << 8) | ((int32_t) data[4]); +} + +void writeRegisterSPI(uint16_t icID, uint8_t address, int32_t value) +{ + uint8_t data[5] = { 0 }; + + data[0] = address | TMC5240_WRITE_BIT; + data[1] = 0xFF & (value>>24); + data[2] = 0xFF & (value>>16); + data[3] = 0xFF & (value>>8); + data[4] = 0xFF & (value>>0); + + // Send the write request + tmc5240_readWriteSPI(icID, &data[0], sizeof(data)); +} + +int32_t readRegisterUART(uint16_t icID, uint8_t registerAddress) +{ + uint8_t data[8] = { 0 }; + + registerAddress = registerAddress & TMC5240_ADDRESS_MASK; + + data[0] = 0x05; + data[1] = tmc5240_getNodeAddress(icID); //targetAddressUart; + data[2] = registerAddress; + data[3] = CRC8(data, 3); + + if (!tmc5240_readWriteUART(icID, &data[0], 4, 8)) + return 0; + + // Byte 0: Sync nibble correct? + if (data[0] != 0x05) + return 0; + + // Byte 1: Master address correct? + if (data[1] != 0xFF) + return 0; + + // Byte 2: Address correct? + if (data[2] != registerAddress) + return 0; + + // Byte 7: CRC correct? + if (data[7] != CRC8(data, 7)) + return 0; + + return ((uint32_t)data[3] << 24) | ((uint32_t)data[4] << 16) | ((uint32_t)data[5] << 8) | data[6]; +} + +void writeRegisterUART(uint16_t icID, uint8_t registerAddress, int32_t value) +{ + uint8_t data[8]; + + data[0] = 0x05; + data[1] = (uint8_t)tmc5240_getNodeAddress(icID); //targetAddressUart; + data[2] = registerAddress | TMC5240_WRITE_BIT; + data[3] = (value >> 24) & 0xFF; + data[4] = (value >> 16) & 0xFF; + data[5] = (value >> 8 ) & 0xFF; + data[6] = (value ) & 0xFF; + data[7] = CRC8(data, 7); + + tmc5240_readWriteUART(icID, &data[0], 8, 0); +} + +void tmc5240_rotateMotor(uint16_t icID, uint8_t motor, int32_t velocity) +{ + if(motor >= TMC5240_MOTORS) + return; + + tmc5240_writeRegister(icID, TMC5240_VMAX, (velocity < 0) ? -velocity : velocity); + tmc5240_fieldWrite(icID, TMC5240_RAMPMODE_FIELD, (velocity >= 0) ? TMC5240_MODE_VELPOS : TMC5240_MODE_VELNEG); +} + +static uint8_t CRC8(uint8_t *data, uint32_t bytes) +{ + uint8_t result = 0; + + while(bytes--) + result = tmcCRCTable_Poly7Reflected[result ^ *data++]; + + // Flip the result around + // swap odd and even bits + result = ((result >> 1) & 0x55) | ((result & 0x55) << 1); + // swap consecutive pairs + result = ((result >> 2) & 0x33) | ((result & 0x33) << 2); + // swap nibbles ... + result = ((result >> 4) & 0x0F) | ((result & 0x0F) << 4); + + return result; +} + diff --git a/firmware/lib/tmc/ic/TMC5240/TMC5240.h b/firmware/lib/tmc/ic/TMC5240/TMC5240.h new file mode 100755 index 0000000..56815b1 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5240/TMC5240.h @@ -0,0 +1,165 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + +#ifndef TMC_IC_TMC5240_H_ +#define TMC_IC_TMC5240_H_ + +#include "TMC5240_HW_Abstraction.h" +#include +#include +#include + +/******************************************************************************* +* API Configuration Defines +* These control optional features of the TMC-API implementation. +* These can be commented in/out here or defined from the build system. +*******************************************************************************/ + +// Uncomment if you want to save space..... +// and put the table into your own .c file +//#define TMC_API_EXTERNAL_CRC_TABLE 1 + +/******************************************************************************/ + +typedef enum { + IC_BUS_SPI, + IC_BUS_UART, + IC_BUS_WLAN +} TMC5240BusType; + +typedef struct +{ + uint32_t mask; + uint8_t shift; + uint8_t address; + bool isSigned; +} RegisterField; + + +// => TMC-API wrapper +extern void tmc5240_readWriteSPI(uint16_t icID, uint8_t *data, size_t dataLength); +extern bool tmc5240_readWriteUART(uint16_t icID, uint8_t *data, size_t writeLength, size_t readLength); +extern TMC5240BusType tmc5240_getBusType(uint16_t icID); +extern uint8_t tmc5240_getNodeAddress(uint16_t icID); +// => TMC-API wrapper + +int32_t tmc5240_readRegister(uint16_t icID, uint8_t address); +void tmc5240_writeRegister(uint16_t icID, uint8_t address, int32_t value); +void tmc5240_rotateMotor(uint16_t icID, uint8_t motor, int32_t velocity); + + +static inline uint32_t tmc5240_fieldExtract(uint32_t data, RegisterField field) +{ + uint32_t value = (data & field.mask) >> field.shift; + + if (field.isSigned) + { + // Apply sign conversion + uint32_t baseMask = field.mask >> field.shift; + uint32_t signMask = baseMask & (~baseMask >> 1); + value = (value ^ signMask) - signMask; + } + + return value; +} + +static inline uint32_t tmc5240_fieldRead(uint16_t icID, RegisterField field) +{ + uint32_t value = tmc5240_readRegister(icID, field.address); + return tmc5240_fieldExtract(value, field); +} + +static inline uint32_t tmc5240_fieldUpdate(uint32_t data, RegisterField field, uint32_t value) +{ + return (data & (~field.mask)) | ((value << field.shift) & field.mask); +} + +static inline void tmc5240_fieldWrite(uint16_t icID, RegisterField field, uint32_t value) +{ + uint32_t regValue = tmc5240_readRegister(icID, field.address); + + regValue = tmc5240_fieldUpdate(regValue, field, value); + + tmc5240_writeRegister(icID, field.address, regValue); +} + +/**************************************************************** DEFAULT REGISTER VALUES *************************************************************************/ + +// Default Register values +#define R00 0x00000008 // GCONF +#define R0A 0x00000020 // DRVCONF +#define R10 0x00070A03 // IHOLD_IRUN +#define R11 0x0000000A // TPOWERDOWN +#define R2A 0x0000000A // D1 +#define R2B 0x0000000A // VSTOP +#define R30 0x0000000A // D2 +#define R3A 0x00010000 // ENC_CONST +#define R52 0x0B920F25 // OTW_OV_VTH +#define R60 0xAAAAB554 // MSLUT[0] +#define R61 0x4A9554AA // MSLUT[1] +#define R62 0x24492929 // MSLUT[2] +#define R63 0x10104222 // MSLUT[3] +#define R64 0xFBFFFFFF // MSLUT[4] +#define R65 0xB5BB777D // MSLUT[5] +#define R66 0x49295556 // MSLUT[6] +#define R67 0x00404222 // MSLUT[7] +#define R68 0xFFFF8056 // MSLUT[8] +#define R69 0x00F70000 // MSLUT[9] +#define R6C 0x00410153 // CHOPCONF +#define R70 0xC44C001E // PWMCONF + +#ifndef ____ + #define ____ 0x00 +#endif +#ifndef N_A + #define N_A 0x00 +#endif + +#define TMC5240_ACCESS_DIRTY 0x08 // Register has been written since reset -> shadow register is valid for restore +#define TMC5240_ACCESS_READ 0x01 +#define TMC5240_IS_READABLE(x) ((x) & TMC5240_ACCESS_READ) +#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) + + +static const int32_t tmc5240_sampleRegisterPreset[TMC5240_REGISTER_COUNT] = +{ +// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F + R00, 0, 0, 0, 0, 0, 0, 0, 0, 0, R0A, 0, 0, 0, 0, 0, // 0x00 - 0x0F + R10, R11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x10 - 0x1F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, R2A, R2B, 0, 0, 0, 0, // 0x20 - 0x2F + R30, 0, 0, 0, 0, 0, 0, 0, 0, 0, R3A, 0, 0, 0, 0, 0, // 0x30 - 0x3F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x40 - 0x4F + 0, 0, R52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x50 - 0x5F + R60, R61, R62, R63, R64, R65, R66, R67, R68, R69, 0, 0, R6C, 0, 0, 0, // 0x60 - 0x6F + R70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x70 - 0x7F +}; + +// Register access permissions: +// 0x00: none (reserved) +// 0x01: read +// 0x02: write +// 0x03: read/write +// 0x13: read/write, separate functions/values for reading or writing +// 0x23: read/write, flag register (write to clear) +// 0x42: write, has hardware presets on reset +static const uint8_t tmc5240_registerAccess[TMC5240_REGISTER_COUNT] = +{ +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0x03, 0x23, 0x01, 0x03, 0x03, 0x03, 0x03, ____, ____, ____, 0x03, 0x03, ____, ____, ____, ____, // 0x00 - 0x0F + 0x03, 0x03, 0x01, 0x03, 0x03, 0x03, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x10 - 0x1F + 0x03, 0x03, 0x01, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, // 0x20 - 0x2F + 0x03, 0x01, ____, 0x03, 0x03, 0x23, 0x01, ____, 0x03, 0x03, 0x03, 0x23, 0x01, 0x03, ____, ____, // 0x30 - 0x3F + ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x40 - 0x4F + 0x01, 0x01, 0x03, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x50 - 0x5F + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x01, 0x01, 0x03, 0x03, 0x03, 0x01, // 0x60 - 0x6F + 0x03, 0x01, 0x01, ____, 0x03, 0x01, 0x01, ____, ____, ____, ____, ____, ____, ____, ____, ____ // 0x70 - 0x7F +}; + +/*******************************************************************************************************************************************************************/ + +#endif /* TMC_IC_TMC5240_H_ */ diff --git a/firmware/lib/tmc/ic/TMC5240/TMC5240_HW_Abstraction.h b/firmware/lib/tmc/ic/TMC5240/TMC5240_HW_Abstraction.h new file mode 100755 index 0000000..12bc6ec --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5240/TMC5240_HW_Abstraction.h @@ -0,0 +1,810 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2023 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + +#ifndef TMC5240_HW_ABSTRACTION +#define TMC5240_HW_ABSTRACTION + +//constants + +#define TMC5240_REGISTER_COUNT 128 +#define TMC5240_MOTORS 1 +#define TMC5240_WRITE_BIT 0x80 +#define TMC5240_ADDRESS_MASK 0x7F +#define TMC5240_MAX_VELOCITY 8388096 +#define TMC5240_MAX_ACCELERATION u16_MAX +#define DEFAULT_ICID 0 + +// ramp modes (Register TMC5240_RAMPMODE) +#define TMC5240_MODE_POSITION 0 +#define TMC5240_MODE_VELPOS 1 +#define TMC5240_MODE_VELNEG 2 +#define TMC5240_MODE_HOLD 3 + +// limit switch mode bits (Register TMC5240_SWMODE) +#define TMC5240_SW_STOPL_ENABLE 0x0001 +#define TMC5240_SW_STOPR_ENABLE 0x0002 +#define TMC5240_SW_STOPL_POLARITY 0x0004 +#define TMC5240_SW_STOPR_POLARITY 0x0008 +#define TMC5240_SW_SWAP_LR 0x0010 +#define TMC5240_SW_LATCH_L_ACT 0x0020 +#define TMC5240_SW_LATCH_L_INACT 0x0040 +#define TMC5240_SW_LATCH_R_ACT 0x0080 +#define TMC5240_SW_LATCH_R_INACT 0x0100 +#define TMC5240_SW_LATCH_ENC 0x0200 +#define TMC5240_SW_SG_STOP 0x0400 +#define TMC5240_SW_SOFTSTOP 0x0800 + +// Status bits (Register TMC5240_RAMPSTAT) +#define TMC5240_RS_STOPL 0x0001 +#define TMC5240_RS_STOPR 0x0002 +#define TMC5240_RS_LATCHL 0x0004 +#define TMC5240_RS_LATCHR 0x0008 +#define TMC5240_RS_EV_STOPL 0x0010 +#define TMC5240_RS_EV_STOPR 0x0020 +#define TMC5240_RS_EV_STOP_SG 0x0040 +#define TMC5240_RS_EV_POSREACHED 0x0080 +#define TMC5240_RS_VELREACHED 0x0100 +#define TMC5240_RS_POSREACHED 0x0200 +#define TMC5240_RS_VZERO 0x0400 +#define TMC5240_RS_ZEROWAIT 0x0800 +#define TMC5240_RS_SECONDMOVE 0x1000 +#define TMC5240_RS_SG 0x2000 + +// Encoderbits (Register TMC5240_ENCMODE) +#define TMC5240_EM_DECIMAL 0x0400 +#define TMC5240_EM_LATCH_XACT 0x0200 +#define TMC5240_EM_CLR_XENC 0x0100 +#define TMC5240_EM_NEG_EDGE 0x0080 +#define TMC5240_EM_POS_EDGE 0x0040 +#define TMC5240_EM_CLR_ONCE 0x0020 +#define TMC5240_EM_CLR_CONT 0x0010 +#define TMC5240_EM_IGNORE_AB 0x0008 +#define TMC5240_EM_POL_N 0x0004 +#define TMC5240_EM_POL_B 0x0002 +#define TMC5240_EM_POL_A 0x0001 + +// Registers in TMC5240 + +#define TMC5240_GCONF 0x00 +#define TMC5240_GSTAT 0x01 +#define TMC5240_IFCNT 0x02 +#define TMC5240_SLAVECONF 0x03 +#define TMC5240_INP_OUT 0x04 +#define TMC5240_X_COMPARE 0x05 +#define TMC5240_X_COMPARE_REPEAT 0x06 +#define TMC5240_DRV_CONF 0x0A +#define TMC5240_GLOBAL_SCALER 0x0B +#define TMC5240_IHOLD_IRUN 0x10 +#define TMC5240_TPOWERDOWN 0x11 +#define TMC5240_TSTEP 0x12 +#define TMC5240_TPWMTHRS 0x13 +#define TMC5240_TCOOLTHRS 0x14 +#define TMC5240_THIGH 0x15 +#define TMC5240_RAMPMODE 0x20 +#define TMC5240_XACTUAL 0x21 +#define TMC5240_VACTUAL 0x22 +#define TMC5240_VSTART 0x23 +#define TMC5240_A1 0x24 +#define TMC5240_V1 0x25 +#define TMC5240_AMAX 0x26 +#define TMC5240_VMAX 0x27 +#define TMC5240_DMAX 0x28 +#define TMC5240_TVMAX 0x29 +#define TMC5240_D1 0x2A +#define TMC5240_VSTOP 0x2B +#define TMC5240_TZEROWAIT 0x2C +#define TMC5240_XTARGET 0x2D +#define TMC5240_V2 0x2E +#define TMC5240_A2 0x2F +#define TMC5240_D2 0x30 +#define TMC5240_AACTUAL 0x31 +#define TMC5240_VDCMIN 0x33 +#define TMC5240_SWMODE 0x34 +#define TMC5240_RAMPSTAT 0x35 +#define TMC5240_XLATCH 0x36 +#define TMC5240_ENCMODE 0x38 +#define TMC5240_XENC 0x39 +#define TMC5240_ENC_CONST 0x3A +#define TMC5240_ENC_STATUS 0x3B +#define TMC5240_ENC_LATCH 0x3C +#define TMC5240_ENC_DEVIATION 0x3D +#define TMC5240_VIRTUAL_STOP_L 0x3E +#define TMC5240_VIRTUAL_STOP_R 0x3F +#define TMC5240_ADC_VSUPPLY_AIN 0x50 +#define TMC5240_ADC_TEMP 0x51 +#define TMC5240_OTW_OV_VTH 0x52 +#define TMC5240_MSLUT0 0x60 +#define TMC5240_MSLUT1 0x61 +#define TMC5240_MSLUT2 0x62 +#define TMC5240_MSLUT3 0x63 +#define TMC5240_MSLUT4 0x64 +#define TMC5240_MSLUT5 0x65 +#define TMC5240_MSLUT6 0x66 +#define TMC5240_MSLUT7 0x67 +#define TMC5240_MSLUTSEL 0x68 +#define TMC5240_MSLUTSTART 0x69 +#define TMC5240_MSCNT 0x6A +#define TMC5240_MSCURACT 0x6B +#define TMC5240_CHOPCONF 0x6C +#define TMC5240_COOLCONF 0x6D +#define TMC5240_DCCTRL 0x6E +#define TMC5240_DRVSTATUS 0x6F +#define TMC5240_PWMCONF 0x70 +#define TMC5240_PWM_SCALE 0x71 +#define TMC5240_PWM_AUTO 0x72 +#define TMC5240_SG4_THRS 0x74 +#define TMC5240_SG4_RESULT 0x75 +#define TMC5240_SG4_IND 0x76 + +// Register fields in TMC5240 + +// Status fields returned with every SPI transaction +#define TMC5240_SPI_STATUS_RESET_FLAG_MASK 0x01 /* GSTAT[0] - 1: Signals, that a reset has occurred (clear by reading GSTAT) */ +#define TMC5240_SPI_STATUS_RESET_FLAG_SHIFT 0 +#define TMC5240_SPI_STATUS_RESET_FLAG_FIELD ((RegisterField) { TMC5240_SPI_STATUS_RESET_FLAG_MASK, TMC5240_SPI_STATUS_RESET_FLAG_SHIFT, TMC5240_GSTAT, false }) +#define TMC5240_SPI_STATUS_DRIVER_ERROR_MASK 0x02 /* GSTAT[1] – 1: Signals driver 1 driver error (clear by reading GSTAT) */ +#define TMC5240_SPI_STATUS_DRIVER_ERROR_SHIFT 1 +#define TMC5240_SPI_STATUS_DRIVER_ERROR_FIELD ((RegisterField) { TMC5240_SPI_STATUS_DRIVER_ERROR_MASK, TMC5240_SPI_STATUS_DRIVER_ERROR_SHIFT, TMC5240_GSTAT, false }) +#define TMC5240_SPI_STATUS_SG2_MASK 0x04 /* DRV_STATUS[24] – 1: Signals StallGuard flag active */ +#define TMC5240_SPI_STATUS_SG2_SHIFT 2 +#define TMC5240_SPI_STATUS_SG2_FIELD ((RegisterField) { TMC5240_SPI_STATUS_SG2_MASK, TMC5240_SPI_STATUS_SG2_SHIFT, TMC5240_DRVSTATUS, false }) +#define TMC5240_SPI_STATUS_STANDSTILL_MASK 0x08 /* DRV_STATUS[31] – 1: Signals motor stand still */ +#define TMC5240_SPI_STATUS_STANDSTILL_SHIFT 3 +#define TMC5240_SPI_STATUS_STANDSTILL_FIELD ((RegisterField) { TMC5240_SPI_STATUS_STANDSTILL_MASK, TMC5240_SPI_STATUS_STANDSTILL_SHIFT, TMC5240_DRVSTATUS, false }) +#define TMC5240_SPI_STATUS_VELOCITY_REACHED_MASK 0x10 /* RAMP_STAT[8] – 1: Signals target velocity reached (motion controller only) */ +#define TMC5240_SPI_STATUS_VELOCITY_REACHED_SHIFT 4 +#define TMC5240_SPI_STATUS_VELOCITY_REACHED_FIELD ((RegisterField) { TMC5240_SPI_STATUS_VELOCITY_REACHED_MASK, TMC5240_SPI_STATUS_VELOCITY_REACHED_SHIFT, TMC5240_RAMPSTAT, false }) +#define TMC5240_SPI_STATUS_POSITION_REACHED_MASK 0x20 /* RAMP_STAT[9] – 1: Signals target position reached (motion controller only) */ +#define TMC5240_SPI_STATUS_POSITION_REACHED_SHIFT 5 +#define TMC5240_SPI_STATUS_POSITION_REACHED_FIELD ((RegisterField) { TMC5240_SPI_STATUS_POSITION_REACHED_MASK, TMC5240_SPI_STATUS_POSITION_REACHED_SHIFT, TMC5240_RAMPSTAT, false }) +#define TMC5240_SPI_STATUS_STATUS_STOP_L_MASK 0x40 /* RAMP_STAT[0] – 1: Signals stop left switch status (motion controller only) */ +#define TMC5240_SPI_STATUS_STATUS_STOP_L_SHIFT 6 +#define TMC5240_SPI_STATUS_STATUS_STOP_L_FIELD ((RegisterField) { TMC5240_SPI_STATUS_STATUS_STOP_L_MASK, TMC5240_SPI_STATUS_STATUS_STOP_L_SHIFT, TMC5240_RAMPSTAT, false }) +#define TMC5240_SPI_STATUS_STATUS_STOP_R_MASK 0x80 /* RAMP_STAT[1] – 1: Signals stop right switch status (motion controller only) */ +#define TMC5240_SPI_STATUS_STATUS_STOP_R_SHIFT 7 +#define TMC5240_SPI_STATUS_STATUS_STOP_R_FIELD ((RegisterField) { TMC5240_SPI_STATUS_STATUS_STOP_R_MASK, TMC5240_SPI_STATUS_STATUS_STOP_R_SHIFT, TMC5240_RAMPSTAT, false }) + +// Configuration & status registers +#define TMC5240_FAST_STANDSTILL_MASK 0x02 // GCONF // Timeout for step execution until standstill detection +#define TMC5240_FAST_STANDSTILL_SHIFT 1 // Timeout for step execution until standstill detection +#define TMC5240_FAST_STANDSTILL_FIELD ((RegisterField) { TMC5240_FAST_STANDSTILL_MASK, TMC5240_FAST_STANDSTILL_SHIFT, TMC5240_GCONF, false }) +#define TMC5240_EN_PWM_MODE_MASK 0x04 // GCONF // Enable the stealthChop(TM) mode +#define TMC5240_EN_PWM_MODE_SHIFT 2 // Enable the stealthChop(TM) mode +#define TMC5240_EN_PWM_MODE_FIELD ((RegisterField) { TMC5240_EN_PWM_MODE_MASK, TMC5240_EN_PWM_MODE_SHIFT, TMC5240_GCONF, false }) +#define TMC5240_MULTISTEP_FILT_MASK 0x08 // GCONF // Enable step input filtering for stealthChop +#define TMC5240_MULTISTEP_FILT_SHIFT 3 // Enable step input filtering for stealthChop +#define TMC5240_MULTISTEP_FILT_FIELD ((RegisterField) { TMC5240_MULTISTEP_FILT_MASK, TMC5240_MULTISTEP_FILT_SHIFT, TMC5240_GCONF, false }) +#define TMC5240_SHAFT_MASK 0x10 // GCONF // Change motor direction / direction sign +#define TMC5240_SHAFT_SHIFT 4 // Change motor direction / direction sign +#define TMC5240_SHAFT_FIELD ((RegisterField) { TMC5240_SHAFT_MASK, TMC5240_SHAFT_SHIFT, TMC5240_GCONF, false }) +#define TMC5240_DIAG0_ERROR_MASK 0x20 // GCONF // DIAG0 output configuration (only with SD_MODE=1).; DIAG0 always shows the reset-status, i.e. is active low during reset condition. +#define TMC5240_DIAG0_ERROR_SHIFT 5 // DIAG0 output configuration (only with SD_MODE=1).; DIAG0 always shows the reset-status, i.e. is active low during reset condition. +#define TMC5240_DIAG0_ERROR_FIELD ((RegisterField) { TMC5240_DIAG0_ERROR_MASK, TMC5240_DIAG0_ERROR_SHIFT, TMC5240_GCONF, false }) +#define TMC5240_DIAG0_OTPW_MASK 0x40 // GCONF // DIAG0 output configuration (only with SD_MODE=1). +#define TMC5240_DIAG0_OTPW_SHIFT 6 // DIAG0 output configuration (only with SD_MODE=1). +#define TMC5240_DIAG0_OTPW_FIELD ((RegisterField) { TMC5240_DIAG0_OTPW_MASK, TMC5240_DIAG0_OTPW_SHIFT, TMC5240_GCONF, false }) +#define TMC5240_DIAG0_STALL_STEP_MASK 0x80 // GCONF // DIAG0 output configuration (see differences depending on SD_MODE setting). +#define TMC5240_DIAG0_STALL_STEP_SHIFT 7 // DIAG0 output configuration (see differences depending on SD_MODE setting). +#define TMC5240_DIAG0_STALL_STEP_FIELD ((RegisterField) { TMC5240_DIAG0_STALL_STEP_MASK, TMC5240_DIAG0_STALL_STEP_SHIFT, TMC5240_GCONF, false }) +#define TMC5240_DIAG1_STALL_DIR_MASK 0x100 // GCONF // DIAG1 output configuration (see differences depending on SD_MODE setting). +#define TMC5240_DIAG1_STALL_DIR_SHIFT 8 // DIAG1 output configuration (see differences depending on SD_MODE setting). +#define TMC5240_DIAG1_STALL_DIR_FIELD ((RegisterField) { TMC5240_DIAG1_STALL_DIR_MASK, TMC5240_DIAG1_STALL_DIR_SHIFT, TMC5240_GCONF, false }) +#define TMC5240_DIAG1_INDEX_MASK 0x200 // GCONF // DIAG1 output configuration. +#define TMC5240_DIAG1_INDEX_SHIFT 9 // DIAG1 output configuration. +#define TMC5240_DIAG1_INDEX_FIELD ((RegisterField) { TMC5240_DIAG1_INDEX_MASK, TMC5240_DIAG1_INDEX_SHIFT, TMC5240_GCONF, false }) +#define TMC5240_DIAG1_ONSTATE_MASK 0x400 // GCONF // DIAG1 output configuration. +#define TMC5240_DIAG1_ONSTATE_SHIFT 10 // DIAG1 output configuration. +#define TMC5240_DIAG1_ONSTATE_FIELD ((RegisterField) { TMC5240_DIAG1_ONSTATE_MASK, TMC5240_DIAG1_ONSTATE_SHIFT, TMC5240_GCONF, false }) +#define TMC5240_DIAG0_INT_PUSHPULL_MASK 0x1000 // GCONF // DIAG0 output type configuration. +#define TMC5240_DIAG0_INT_PUSHPULL_SHIFT 12 // DIAG0 output type configuration. +#define TMC5240_DIAG0_INT_PUSHPULL_FIELD ((RegisterField) { TMC5240_DIAG0_INT_PUSHPULL_MASK, TMC5240_DIAG0_INT_PUSHPULL_SHIFT, TMC5240_GCONF, false }) +#define TMC5240_DIAG1_POSCOMP_PUSHPULL_MASK 0x2000 // GCONF // DIAG1 output type configuration. +#define TMC5240_DIAG1_POSCOMP_PUSHPULL_SHIFT 13 // DIAG1 output type configuration. +#define TMC5240_DIAG1_POSCOMP_PUSHPULL_FIELD ((RegisterField) { TMC5240_DIAG1_POSCOMP_PUSHPULL_MASK, TMC5240_DIAG1_POSCOMP_PUSHPULL_SHIFT, TMC5240_GCONF, false }) +#define TMC5240_SMALL_HYSTERESIS_MASK 0x4000 // GCONF // SMALL_HYSTERESIS +#define TMC5240_SMALL_HYSTERESIS_SHIFT 14 // SMALL_HYSTERESIS +#define TMC5240_SMALL_HYSTERESIS_FIELD ((RegisterField) { TMC5240_SMALL_HYSTERESIS_MASK, TMC5240_SMALL_HYSTERESIS_SHIFT, TMC5240_GCONF, false }) +#define TMC5240_STOP_ENABLE_MASK 0x8000 // GCONF // Motor hard stop function enable. +#define TMC5240_STOP_ENABLE_SHIFT 15 // Motor hard stop function enable. +#define TMC5240_STOP_ENABLE_FIELD ((RegisterField) { TMC5240_STOP_ENABLE_MASK, TMC5240_STOP_ENABLE_SHIFT, TMC5240_GCONF, false }) +#define TMC5240_DIRECT_MODE_MASK 0x10000 // GCONF // Enable direct motor phase current control via serial interface. +#define TMC5240_DIRECT_MODE_SHIFT 16 // Enable direct motor phase current control via serial interface. +#define TMC5240_DIRECT_MODE_FIELD ((RegisterField) { TMC5240_DIRECT_MODE_MASK, TMC5240_DIRECT_MODE_SHIFT, TMC5240_GCONF, false }) +#define TMC5240_LENGTH_STEP_PULSE_MASK 0x1E0000 // GCONF // cDriver only: length_step_pulse = 0: STEP output toggles upon each step;; length_step_pulse = 1...15: STEP pin high time in number of clock cycles +#define TMC5240_LENGTH_STEP_PULSE_SHIFT 17 // cDriver only: length_step_pulse = 0: STEP output toggles upon each step;; length_step_pulse = 1...15: STEP pin high time in number of clock cycles +#define TMC5240_LENGTH_STEP_PULSE_FIELD ((RegisterField) { TMC5240_LENGTH_STEP_PULSE_MASK, TMC5240_LENGTH_STEP_PULSE_SHIFT, TMC5240_GCONF, false }) +#define TMC5240_RESET_MASK 0x01 // GSTAT // Reset flag#type=COW +#define TMC5240_RESET_SHIFT 0 // Reset flag#type=COW +#define TMC5240_RESET_FIELD ((RegisterField) { TMC5240_RESET_MASK, TMC5240_RESET_SHIFT, TMC5240_GSTAT, false }) +#define TMC5240_DRV_ERR_MASK 0x02 // GSTAT // Driver error flag#type=COW +#define TMC5240_DRV_ERR_SHIFT 1 // Driver error flag#type=COW +#define TMC5240_DRV_ERR_FIELD ((RegisterField) { TMC5240_DRV_ERR_MASK, TMC5240_DRV_ERR_SHIFT, TMC5240_GSTAT, false }) +#define TMC5240_UV_CP_MASK 0x04 // GSTAT // Charge pump undervoltage condition flag#type=COW +#define TMC5240_UV_CP_SHIFT 2 // Charge pump undervoltage condition flag#type=COW +#define TMC5240_UV_CP_FIELD ((RegisterField) { TMC5240_UV_CP_MASK, TMC5240_UV_CP_SHIFT, TMC5240_GSTAT, false }) +#define TMC5240_REGISTER_RESET_MASK 0x08 // GSTAT // REGISTER_RESET +#define TMC5240_REGISTER_RESET_SHIFT 3 // REGISTER_RESET +#define TMC5240_REGISTER_RESET_FIELD ((RegisterField) { TMC5240_REGISTER_RESET_MASK, TMC5240_REGISTER_RESET_SHIFT, TMC5240_GSTAT, false }) +#define TMC5240_VM_UVLO_MASK 0x10 // GSTAT // 1: VM undervoltage has occured since last reset. +#define TMC5240_VM_UVLO_SHIFT 4 // 1: VM undervoltage has occured since last reset. +#define TMC5240_VM_UVLO_FIELD ((RegisterField) { TMC5240_VM_UVLO_MASK, TMC5240_VM_UVLO_SHIFT, TMC5240_GSTAT, false }) +#define TMC5240_IFCNT_MASK 0xFF // IFCNT // Interface transmission counter. This register becomes incremented with each successful UART interface write access. It can be read out to check the serial transmission for lost data. Read accesses do not change the content. Disabled in SPI operation. The counter wraps around from 255 to 0. +#define TMC5240_IFCNT_SHIFT 0 // Interface transmission counter. This register becomes incremented with each successful UART interface write access. It can be read out to check the serial transmission for lost data. Read accesses do not change the content. Disabled in SPI operation. The counter wraps around from 255 to 0. +#define TMC5240_IFCNT_FIELD ((RegisterField) { TMC5240_IFCNT_MASK, TMC5240_IFCNT_SHIFT, TMC5240_IFCNT, false }) +#define TMC5240_SLAVEADDR_MASK 0xFF // SLAVECONF // SLAVEADDR:; These eight bits set the address of unit for the UART interface. The address becomes incremented by one, two or three, as defined by SDI and SCK.; SCK, SDI; 00: +0; 01: +1; 10: +2; 11: +3; Range: 0-254 (do not increment beyond 254) +#define TMC5240_SLAVEADDR_SHIFT 0 // SLAVEADDR:; These eight bits set the address of unit for the UART interface. The address becomes incremented by one, two or three, as defined by SDI and SCK.; SCK, SDI; 00: +0; 01: +1; 10: +2; 11: +3; Range: 0-254 (do not increment beyond 254) +#define TMC5240_SLAVEADDR_FIELD ((RegisterField) { TMC5240_SLAVEADDR_MASK, TMC5240_SLAVEADDR_SHIFT, TMC5240_SLAVECONF, false }) +#define TMC5240_SENDDELAY_MASK 0xF00 // SLAVECONF // SWUART Slave Configuration +#define TMC5240_SENDDELAY_SHIFT 8 // SWUART Slave Configuration +#define TMC5240_SENDDELAY_FIELD ((RegisterField) { TMC5240_SENDDELAY_MASK, TMC5240_SENDDELAY_SHIFT, TMC5240_SLAVECONF, false }) +#define TMC5240_REFL_STEP_MASK 0x01 // INP_OUT // REFL_STEP +#define TMC5240_REFL_STEP_SHIFT 0 // REFL_STEP +#define TMC5240_REFL_STEP_FIELD ((RegisterField) { TMC5240_REFL_STEP_MASK, TMC5240_REFL_STEP_SHIFT, TMC5240_INP_OUT, false }) +#define TMC5240_REFR_DIR_MASK 0x02 // INP_OUT // REFR_DIR +#define TMC5240_REFR_DIR_SHIFT 1 // REFR_DIR +#define TMC5240_REFR_DIR_FIELD ((RegisterField) { TMC5240_REFR_DIR_MASK, TMC5240_REFR_DIR_SHIFT, TMC5240_INP_OUT, false }) +#define TMC5240_ENCB_CFG4_MASK 0x04 // INP_OUT // B-channel state +#define TMC5240_ENCB_CFG4_SHIFT 2 // B-channel state +#define TMC5240_ENCB_CFG4_FIELD ((RegisterField) { TMC5240_ENCB_CFG4_MASK, TMC5240_ENCB_CFG4_SHIFT, TMC5240_INP_OUT, false }) +#define TMC5240_ENCA_CFG5_MASK 0x08 // INP_OUT // A-channel state +#define TMC5240_ENCA_CFG5_SHIFT 3 // A-channel state +#define TMC5240_ENCA_CFG5_FIELD ((RegisterField) { TMC5240_ENCA_CFG5_MASK, TMC5240_ENCA_CFG5_SHIFT, TMC5240_INP_OUT, false }) +#define TMC5240_DRV_ENN_MASK 0x10 // INP_OUT // Driver disabled/enabled state. +#define TMC5240_DRV_ENN_SHIFT 4 // Driver disabled/enabled state. +#define TMC5240_DRV_ENN_FIELD ((RegisterField) { TMC5240_DRV_ENN_MASK, TMC5240_DRV_ENN_SHIFT, TMC5240_INP_OUT, false }) +#define TMC5240_ENCN_CFG6_MASK 0x20 // INP_OUT // N-channel state +#define TMC5240_ENCN_CFG6_SHIFT 5 // N-channel state +#define TMC5240_ENCN_CFG6_FIELD ((RegisterField) { TMC5240_ENCN_CFG6_MASK, TMC5240_ENCN_CFG6_SHIFT, TMC5240_INP_OUT, false }) +#define TMC5240_UART_EN_MASK 0x40 // INP_OUT // 1 = UART interface is enabled +#define TMC5240_UART_EN_SHIFT 6 // 1 = UART interface is enabled +#define TMC5240_UART_EN_FIELD ((RegisterField) { TMC5240_UART_EN_MASK, TMC5240_UART_EN_SHIFT, TMC5240_INP_OUT, false }) +#define TMC5240_COMP_A_MASK 0x100 // INP_OUT // COMP_A (chopper comparator A, for IC test) +#define TMC5240_COMP_A_SHIFT 8 // COMP_A (chopper comparator A, for IC test) +#define TMC5240_COMP_A_FIELD ((RegisterField) { TMC5240_COMP_A_MASK, TMC5240_COMP_A_SHIFT, TMC5240_INP_OUT, false }) +#define TMC5240_COMP_B_MASK 0x200 // INP_OUT // COMP_B (chopper comparator B, for IC test) +#define TMC5240_COMP_B_SHIFT 9 // COMP_B (chopper comparator B, for IC test) +#define TMC5240_COMP_B_FIELD ((RegisterField) { TMC5240_COMP_B_MASK, TMC5240_COMP_B_SHIFT, TMC5240_INP_OUT, false }) +#define TMC5240_COMP_A1_A2_MASK 0x400 // INP_OUT // COMP_A1_A2 (StallGuard4 comparator A, for IC test) +#define TMC5240_COMP_A1_A2_SHIFT 10 // COMP_A1_A2 (StallGuard4 comparator A, for IC test) +#define TMC5240_COMP_A1_A2_FIELD ((RegisterField) { TMC5240_COMP_A1_A2_MASK, TMC5240_COMP_A1_A2_SHIFT, TMC5240_INP_OUT, false }) +#define TMC5240_COMP_B1_B2_MASK 0x800 // INP_OUT // COMP_B1_B2 (StallGuard4 comparator B, for IC test) +#define TMC5240_COMP_B1_B2_SHIFT 11 // COMP_B1_B2 (StallGuard4 comparator B, for IC test) +#define TMC5240_COMP_B1_B2_FIELD ((RegisterField) { TMC5240_COMP_B1_B2_MASK, TMC5240_COMP_B1_B2_SHIFT, TMC5240_INP_OUT, false }) +#define TMC5240_OUTPUT_MASK 0x1000 // INP_OUT // Output polarity of SDO_CFG0 pin when UART is enabled via pin UART_EN_CFG7. Its main purpose it to use SDO_CFG0 as NAO next address output signal for chain addressing of multiple ICs. Attention: Reset Value is 1 for use as NAO to next IC in single wire chain +#define TMC5240_OUTPUT_SHIFT 12 // Output polarity of SDO_CFG0 pin when UART is enabled via pin UART_EN_CFG7. Its main purpose it to use SDO_CFG0 as NAO next address output signal for chain addressing of multiple ICs. Attention: Reset Value is 1 for use as NAO to next IC in single wire chain +#define TMC5240_OUTPUT_FIELD ((RegisterField) { TMC5240_OUTPUT_MASK, TMC5240_OUTPUT_SHIFT, TMC5240_INP_OUT, false }) +#define TMC5240_EXT_RES_DET_MASK 0x2000 // INP_OUT // 1: External resistor between REF and GND; 0: No external resistor detected +#define TMC5240_EXT_RES_DET_SHIFT 13 // 1: External resistor between REF and GND; 0: No external resistor detected +#define TMC5240_EXT_RES_DET_FIELD ((RegisterField) { TMC5240_EXT_RES_DET_MASK, TMC5240_EXT_RES_DET_SHIFT, TMC5240_INP_OUT, false }) +#define TMC5240_EXT_CLK_MASK 0x4000 // INP_OUT // 0: The internal oscillator is used for generating the clock-signal (12.5 MHz).; 1: The external oscillator is used for generating the clock-signal. +#define TMC5240_EXT_CLK_SHIFT 14 // 0: The internal oscillator is used for generating the clock-signal (12.5 MHz).; 1: The external oscillator is used for generating the clock-signal. +#define TMC5240_EXT_CLK_FIELD ((RegisterField) { TMC5240_EXT_CLK_MASK, TMC5240_EXT_CLK_SHIFT, TMC5240_INP_OUT, false }) +#define TMC5240_ADC_ERR_MASK 0x8000 // INP_OUT // 1: Signals that the ADC is not working correctly. Do not utilize ADC-features.Adc is stuck in configurationmode and very likely does not receive an ACK_OUT +#define TMC5240_ADC_ERR_SHIFT 15 // 1: Signals that the ADC is not working correctly. Do not utilize ADC-features.Adc is stuck in configurationmode and very likely does not receive an ACK_OUT +#define TMC5240_ADC_ERR_FIELD ((RegisterField) { TMC5240_ADC_ERR_MASK, TMC5240_ADC_ERR_SHIFT, TMC5240_INP_OUT, false }) +#define TMC5240_SILICON_RV_MASK 0x70000 // INP_OUT // Silicon revision number +#define TMC5240_SILICON_RV_SHIFT 16 // Silicon revision number +#define TMC5240_SILICON_RV_FIELD ((RegisterField) { TMC5240_SILICON_RV_MASK, TMC5240_SILICON_RV_SHIFT, TMC5240_INP_OUT, false }) +#define TMC5240_VERSION_MASK 0xFF000000 // INP_OUT // 0x40 = first version of the IC; Identical numbers mean full digital compatibility. +#define TMC5240_VERSION_SHIFT 24 // 0x40 = first version of the IC; Identical numbers mean full digital compatibility. +#define TMC5240_VERSION_FIELD ((RegisterField) { TMC5240_VERSION_MASK, TMC5240_VERSION_SHIFT, TMC5240_INP_OUT, false }) +#define TMC5240_X_COMPARE_MASK 0xFFFFFFFF // X_COMPARE // Position comparison register for motion controller position strobe.; X_COMPARE is an absolute position.; The Position pulse is available on output SWP_DIAG1.; XACTUAL = X_COMPARE: Output signal PP (position pulse) becomes high.; It returns to a low state, if the positions mismatch.; If X_COMPARE_REPEAT is >1, X_COMPARE is the position reference for; the periodic position strobe trigger output. +#define TMC5240_X_COMPARE_SHIFT 0 // Position comparison register for motion controller position strobe.; X_COMPARE is an absolute position.; The Position pulse is available on output SWP_DIAG1.; XACTUAL = X_COMPARE: Output signal PP (position pulse) becomes high.; It returns to a low state, if the positions mismatch.; If X_COMPARE_REPEAT is >1, X_COMPARE is the position reference for; the periodic position strobe trigger output. +#define TMC5240_X_COMPARE_FIELD ((RegisterField) { TMC5240_X_COMPARE_MASK, TMC5240_X_COMPARE_SHIFT, TMC5240_X_COMPARE, true }) +#define TMC5240_X_COMPARE_REPEAT_MASK 0xFFFFFF // X_COMPARE_REPEAT // This register defines a relative distance in microsteps (based on MRES confguration).; If set to >1, the position compare pulse is raised every time a multiple of X_PDISTANCE µsteps have been made.; Thereby, the X_COMPARE register defines the base position for the modulo calculation of X_PDISTANCE steps have been made into positive or negative direction. +#define TMC5240_X_COMPARE_REPEAT_SHIFT 0 // This register defines a relative distance in microsteps (based on MRES confguration).; If set to >1, the position compare pulse is raised every time a multiple of X_PDISTANCE µsteps have been made.; Thereby, the X_COMPARE register defines the base position for the modulo calculation of X_PDISTANCE steps have been made into positive or negative direction. +#define TMC5240_X_COMPARE_REPEAT_FIELD ((RegisterField) { TMC5240_X_COMPARE_REPEAT_MASK, TMC5240_X_COMPARE_REPEAT_SHIFT, TMC5240_X_COMPARE_REPEAT, false }) +#define TMC5240_CURRENT_RANGE_MASK 0x03 // DRV_CONF // This setting allows a basic adaptation of the drivers RDSon current sensing to the motor current range. Select the lowest fitting range for best current precision. The value is the peak current setting. +#define TMC5240_CURRENT_RANGE_SHIFT 0 // This setting allows a basic adaptation of the drivers RDSon current sensing to the motor current range. Select the lowest fitting range for best current precision. The value is the peak current setting. +#define TMC5240_CURRENT_RANGE_FIELD ((RegisterField) { TMC5240_CURRENT_RANGE_MASK, TMC5240_CURRENT_RANGE_SHIFT, TMC5240_DRV_CONF, false }) +#define TMC5240_SLOPE_CONTROL_MASK 0x30 // DRV_CONF // Slope Control Setting +#define TMC5240_SLOPE_CONTROL_SHIFT 4 // Slope Control Setting +#define TMC5240_SLOPE_CONTROL_FIELD ((RegisterField) { TMC5240_SLOPE_CONTROL_MASK, TMC5240_SLOPE_CONTROL_SHIFT, TMC5240_DRV_CONF, false }) +#define TMC5240_BBM_CLKS_MASK 0xF00 // DRV_CONF // BBM_CLKS +#define TMC5240_BBM_CLKS_SHIFT 8 // BBM_CLKS +#define TMC5240_BBM_CLKS_FIELD ((RegisterField) { TMC5240_BBM_CLKS_MASK, TMC5240_BBM_CLKS_SHIFT, TMC5240_DRV_CONF, false }) +#define TMC5240_RNDTF_MASK 0x2000 // CHOPCONF // random TOFF time +#define TMC5240_RNDTF_SHIFT 13 // min.: 0, max.: 1, default: 0 +#define TMC5240_RNDTF_FIELD ((RegisterField) { TMC5240_RNDTF_MASK, TMC5240_RNDTF_SHIFT, TMC5240_CHOPCONF, false }) +#define TMC5240_GLOBAL_SCALER_MASK 0xFF // GLOBAL_SCALER // Global scaling of Motor current. This value is multiplied to the current scaling in order to adapt a drive to a certain motor type. This value should be chosen before tuning other settings, because it also influences chopper hysteresis.; 0:; Full Scale (or write 256); 1 … 31:; Not allowed for operation; 32 … 255:; 32/256 … 255/256 of maximum current.; Hint: Values >128 recommended for best results +#define TMC5240_GLOBAL_SCALER_SHIFT 0 // Global scaling of Motor current. This value is multiplied to the current scaling in order to adapt a drive to a certain motor type. This value should be chosen before tuning other settings, because it also influences chopper hysteresis.; 0:; Full Scale (or write 256); 1 … 31:; Not allowed for operation; 32 … 255:; 32/256 … 255/256 of maximum current.; Hint: Values >128 recommended for best results +#define TMC5240_GLOBAL_SCALER_FIELD ((RegisterField) { TMC5240_GLOBAL_SCALER_MASK, TMC5240_GLOBAL_SCALER_SHIFT, TMC5240_GLOBAL_SCALER, false }) +#define TMC5240_IHOLD_MASK 0x1F // IHOLD_IRUN // Standstill current (0=1/32…31=32/32); In combination with StealthChop mode, setting IHOLD=0 allows to choose freewheeling or coil short circuit for motor stand still. +#define TMC5240_IHOLD_SHIFT 0 // Standstill current (0=1/32…31=32/32); In combination with StealthChop mode, setting IHOLD=0 allows to choose freewheeling or coil short circuit for motor stand still. +#define TMC5240_IHOLD_FIELD ((RegisterField) { TMC5240_IHOLD_MASK, TMC5240_IHOLD_SHIFT, TMC5240_IHOLD_IRUN, false }) +#define TMC5240_IRUN_MASK 0x1F00 // IHOLD_IRUN // Motor run current (0=1/32…31=32/32); Hint: Choose sense resistors in a way, that normal IRUN is 16 to 31 for best microstep performance. +#define TMC5240_IRUN_SHIFT 8 // Motor run current (0=1/32…31=32/32); Hint: Choose sense resistors in a way, that normal IRUN is 16 to 31 for best microstep performance. +#define TMC5240_IRUN_FIELD ((RegisterField) { TMC5240_IRUN_MASK, TMC5240_IRUN_SHIFT, TMC5240_IHOLD_IRUN, false }) +#define TMC5240_IHOLDDELAY_MASK 0xF0000 // IHOLD_IRUN // Controls the number of clock cycles for motor power down after a motion as soon as standstill is detected (stst=1) and TPOWERDOWN has expired. The smooth transition avoids a motor jerk upon power down.; 0:; instant power down; 1..15:; Delay per current reduction step in multiple of 2^18 clocks +#define TMC5240_IHOLDDELAY_SHIFT 16 // Controls the number of clock cycles for motor power down after a motion as soon as standstill is detected (stst=1) and TPOWERDOWN has expired. The smooth transition avoids a motor jerk upon power down.; 0:; instant power down; 1..15:; Delay per current reduction step in multiple of 2^18 clocks +#define TMC5240_IHOLDDELAY_FIELD ((RegisterField) { TMC5240_IHOLDDELAY_MASK, TMC5240_IHOLDDELAY_SHIFT, TMC5240_IHOLD_IRUN, false }) +#define TMC5240_IRUNDELAY_MASK 0xF000000 // IHOLD_IRUN // Controls the number of clock cycles for motor power up after start is detected. 0:; instant power up 1..15:; Delay per current increment step in multiple of IRUNDELAY * 512 clocks +#define TMC5240_IRUNDELAY_SHIFT 24 // Controls the number of clock cycles for motor power up after start is detected. 0:; instant power up 1..15:; Delay per current increment step in multiple of IRUNDELAY * 512 clocks +#define TMC5240_IRUNDELAY_FIELD ((RegisterField) { TMC5240_IRUNDELAY_MASK, TMC5240_IRUNDELAY_SHIFT, TMC5240_IHOLD_IRUN, false }) +#define TMC5240_TPOWERDOWN_MASK 0xFF // TPOWERDOWN // TPOWERDOWN sets the delay time after stand still (stst) of the motor to motor current power down. Time range is about 0 to 4 seconds.; Attention: A minimum setting of 2 is required to allow automatic tuning of StealthChop PWM_OFFS_AUTO.; Reset Default = 10; 0…((2^8)-1) * 2^18 tCLK +#define TMC5240_TPOWERDOWN_SHIFT 0 // TPOWERDOWN sets the delay time after stand still (stst) of the motor to motor current power down. Time range is about 0 to 4 seconds.; Attention: A minimum setting of 2 is required to allow automatic tuning of StealthChop PWM_OFFS_AUTO.; Reset Default = 10; 0…((2^8)-1) * 2^18 tCLK +#define TMC5240_TPOWERDOWN_FIELD ((RegisterField) { TMC5240_TPOWERDOWN_MASK, TMC5240_TPOWERDOWN_SHIFT, TMC5240_TPOWERDOWN, false }) +#define TMC5240_TSTEP_MASK 0xFFFFF // TSTEP // Actual measured time between two 1/256 microsteps derived from the step input frequency in units of 1/fCLK. Measured value is (2^20)-1 in case of overflow or stand still.; All TSTEP related thresholds use a hysteresis of 1/16 of the compare value to compensate for jitter in the clock or the step frequency. The flag small_hysteresis modifies the hysteresis to a smaller value of 1/32.; (Txxx*15/16)-1 or; (Txxx*31/32)-1 is used as a second compare value for each comparison value.; This means, that the lower switching velocity equals the calculated setting, but the upper switching velocity is higher as defined by the hysteresis setting.; When working with the motion controller, the measured TSTEP for a given velocity V is in the range; (224 / V) = TSTEP = 224 / V - 1.; In DcStep mode TSTEP will not show the mean velocity of the motor, but the velocities for each microstep, which may not be stable and thus does not represent the real motor velocity in case it runs slower than the target velocity. +#define TMC5240_TSTEP_SHIFT 0 // Actual measured time between two 1/256 microsteps derived from the step input frequency in units of 1/fCLK. Measured value is (2^20)-1 in case of overflow or stand still.; All TSTEP related thresholds use a hysteresis of 1/16 of the compare value to compensate for jitter in the clock or the step frequency. The flag small_hysteresis modifies the hysteresis to a smaller value of 1/32.; (Txxx*15/16)-1 or; (Txxx*31/32)-1 is used as a second compare value for each comparison value.; This means, that the lower switching velocity equals the calculated setting, but the upper switching velocity is higher as defined by the hysteresis setting.; When working with the motion controller, the measured TSTEP for a given velocity V is in the range; (224 / V) = TSTEP = 224 / V - 1.; In DcStep mode TSTEP will not show the mean velocity of the motor, but the velocities for each microstep, which may not be stable and thus does not represent the real motor velocity in case it runs slower than the target velocity. +#define TMC5240_TSTEP_FIELD ((RegisterField) { TMC5240_TSTEP_MASK, TMC5240_TSTEP_SHIFT, TMC5240_TSTEP, false }) +#define TMC5240_TPWMTHRS_MASK 0xFFFFF // TPWMTHRS // This is the upper velocity for StealthChop voltage PWM mode.; TSTEP = TPWMTHRS; StealthChop PWM mode is enabled, if configured; DcStep is disabled +#define TMC5240_TPWMTHRS_SHIFT 0 // This is the upper velocity for StealthChop voltage PWM mode.; TSTEP = TPWMTHRS; StealthChop PWM mode is enabled, if configured; DcStep is disabled +#define TMC5240_TPWMTHRS_FIELD ((RegisterField) { TMC5240_TPWMTHRS_MASK, TMC5240_TPWMTHRS_SHIFT, TMC5240_TPWMTHRS, false }) +#define TMC5240_TCOOLTHRS_MASK 0xFFFFF // TCOOLTHRS // This is the lower threshold velocity for switching on smart energy CoolStep and StallGuard feature. (unsigned); Set this parameter to disable CoolStep at low speeds, where it cannot work reliably. The stop on stall function (enable with sg_stop when using internal motion controller) and the stall output signal become enabled when exceeding this velocity. In non-DcStep mode, it becomes disabled again once the velocity falls below this threshold.; TCOOLTHRS = TSTEP = THIGH:; CoolStep is enabled, if configured; TCOOLTHRS = TSTEP; Stop on stall is enabled, if configured; Stall output signal (DIAG0/1) is enabled, if configured +#define TMC5240_TCOOLTHRS_SHIFT 0 // This is the lower threshold velocity for switching on smart energy CoolStep and StallGuard feature. (unsigned); Set this parameter to disable CoolStep at low speeds, where it cannot work reliably. The stop on stall function (enable with sg_stop when using internal motion controller) and the stall output signal become enabled when exceeding this velocity. In non-DcStep mode, it becomes disabled again once the velocity falls below this threshold.; TCOOLTHRS = TSTEP = THIGH:; CoolStep is enabled, if configured; TCOOLTHRS = TSTEP; Stop on stall is enabled, if configured; Stall output signal (DIAG0/1) is enabled, if configured +#define TMC5240_TCOOLTHRS_FIELD ((RegisterField) { TMC5240_TCOOLTHRS_MASK, TMC5240_TCOOLTHRS_SHIFT, TMC5240_TCOOLTHRS, false }) +#define TMC5240_THIGH_MASK 0xFFFFF // THIGH // This velocity setting allows velocity dependent switching into a different chopper mode and fullstepping to maximize torque. (unsigned); The stall detection feature becomes switched off for 2-3 electrical periods whenever passing THIGH threshold to compensate for the effect of switching modes.; TSTEP = THIGH:; CoolStep is disabled (motor runs with normal current scale); StealthChop voltage PWM mode is disabled; If vhighchm is set, the chopper switches to chm=1 with TFD=0 (constant off time with slow decay, only).; If vhighfs is set, the motor operates in fullstep mode and the stall detection becomes switched over to DcStep stall detection. +#define TMC5240_THIGH_SHIFT 0 // This velocity setting allows velocity dependent switching into a different chopper mode and fullstepping to maximize torque. (unsigned); The stall detection feature becomes switched off for 2-3 electrical periods whenever passing THIGH threshold to compensate for the effect of switching modes.; TSTEP = THIGH:; CoolStep is disabled (motor runs with normal current scale); StealthChop voltage PWM mode is disabled; If vhighchm is set, the chopper switches to chm=1 with TFD=0 (constant off time with slow decay, only).; If vhighfs is set, the motor operates in fullstep mode and the stall detection becomes switched over to DcStep stall detection. +#define TMC5240_THIGH_FIELD ((RegisterField) { TMC5240_THIGH_MASK, TMC5240_THIGH_SHIFT, TMC5240_THIGH, false }) +#define TMC5240_RAMPMODE_MASK 0x03// RAMPMODE // Motion Controller ramping mode +#define TMC5240_RAMPMODE_SHIFT 0 // Motion Controller ramping mode +#define TMC5240_RAMPMODE_FIELD ((RegisterField) { TMC5240_RAMPMODE_MASK, TMC5240_RAMPMODE_SHIFT, TMC5240_RAMPMODE, false }) +#define TMC5240_XACTUAL_MASK 0xFFFFFFFF // XACTUAL // Actual motor position (signed); Hint: This value normally should only be modified, when homing the drive. In positioning mode, modifying the register content will start a motion. +#define TMC5240_XACTUAL_SHIFT 0 // Actual motor position (signed); Hint: This value normally should only be modified, when homing the drive. In positioning mode, modifying the register content will start a motion. +#define TMC5240_XACTUAL_FIELD ((RegisterField) { TMC5240_XACTUAL_MASK, TMC5240_XACTUAL_SHIFT, TMC5240_XACTUAL, true }) +#define TMC5240_VACTUAL_MASK 0xFFFFFF // VACTUAL // Actual motor velocity from ramp generator (signed); The sign matches the motion direction. A negative sign means motion to lower XACTUAL.; +-(2^23)-1; [µsteps / t] +#define TMC5240_VACTUAL_SHIFT 0 // Actual motor velocity from ramp generator (signed); The sign matches the motion direction. A negative sign means motion to lower XACTUAL.; +-(2^23)-1; [µsteps / t] +#define TMC5240_VACTUAL_FIELD ((RegisterField) { TMC5240_VACTUAL_MASK, TMC5240_VACTUAL_SHIFT, TMC5240_VACTUAL, true }) +#define TMC5240_VSTART_MASK 0x3FFFF // VSTART // Motor start velocity (unsigned); For universal use, set VSTOP = VSTART. This is not required if the motion distance is sufficient to ensure deceleration from VSTART to VSTOP.; 0…(2^18)-1; [µsteps / t] +#define TMC5240_VSTART_SHIFT 0 // Motor start velocity (unsigned); For universal use, set VSTOP = VSTART. This is not required if the motion distance is sufficient to ensure deceleration from VSTART to VSTOP.; 0…(2^18)-1; [µsteps / t] +#define TMC5240_VSTART_FIELD ((RegisterField) { TMC5240_VSTART_MASK, TMC5240_VSTART_SHIFT, TMC5240_VSTART, false }) +#define TMC5240_A1_MASK 0x3FFFF // A1 // First acceleration between VSTART and V1 (unsigned); 0…(2^18)-1; [µsteps / ta²] +#define TMC5240_A1_SHIFT 0 // First acceleration between VSTART and V1 (unsigned); 0…(2^18)-1; [µsteps / ta²] +#define TMC5240_A1_FIELD ((RegisterField) { TMC5240_A1_MASK, TMC5240_A1_SHIFT, TMC5240_A1, false }) +#define TMC5240_V1_MASK 0xFFFFF // V1 // First acceleration / deceleration phase threshold velocity (unsigned); 0: Disables A1 and D1 phase, use AMAX, DMAX only; 0…(2^20)-1; [µsteps / t] +#define TMC5240_V1_SHIFT 0 // First acceleration / deceleration phase threshold velocity (unsigned); 0: Disables A1 and D1 phase, use AMAX, DMAX only; 0…(2^20)-1; [µsteps / t] +#define TMC5240_V1_FIELD ((RegisterField) { TMC5240_V1_MASK, TMC5240_V1_SHIFT, TMC5240_V1, false }) +#define TMC5240_AMAX_MASK 0x3FFFF // AMAX // Second acceleration between V1 and VMAX (unsigned); This is the acceleration and deceleration value for velocity mode.; 0…(2^18)-1; [µsteps / ta²] +#define TMC5240_AMAX_SHIFT 0 // Second acceleration between V1 and VMAX (unsigned); This is the acceleration and deceleration value for velocity mode.; 0…(2^18)-1; [µsteps / ta²] +#define TMC5240_AMAX_FIELD ((RegisterField) { TMC5240_AMAX_MASK, TMC5240_AMAX_SHIFT, TMC5240_AMAX, false }) +#define TMC5240_VMAX_MASK 0x7FFFFF // VMAX // Motion ramp target velocity (for positioning ensure VMAX = VSTART) (unsigned); This is the target velocity in velocity mode. It can be changed any time during a motion.; 0…(2^23)-512; [µsteps / t] +#define TMC5240_VMAX_SHIFT 0 // Motion ramp target velocity (for positioning ensure VMAX = VSTART) (unsigned); This is the target velocity in velocity mode. It can be changed any time during a motion.; 0…(2^23)-512; [µsteps / t] +#define TMC5240_VMAX_FIELD ((RegisterField) { TMC5240_VMAX_MASK, TMC5240_VMAX_SHIFT, TMC5240_VMAX, false }) +#define TMC5240_DMAX_MASK 0x3FFFF // DMAX // Deceleration between VMAX and V1 (unsigned); 0…(2^18)-1; [µsteps / ta²] +#define TMC5240_DMAX_SHIFT 0 // Deceleration between VMAX and V1 (unsigned); 0…(2^18)-1; [µsteps / ta²] +#define TMC5240_DMAX_FIELD ((RegisterField) { TMC5240_DMAX_MASK, TMC5240_DMAX_SHIFT, TMC5240_DMAX, false }) +#define TMC5240_TVMAX_MASK 0xFFFF // TVMAX // Minimum time for constant velocity segments in multiple of 512 clocks.; 0: Disables minimum duration setting for constant velocity phase; >0: A minimum duration of constant velocity is inserted in between of any change from acceleration to deceleration or vice versa to reduce jerk; 0…(2^16)-1 * 512 tCLK; Note: Configure this register after setting VMAX when in Positionmode and standstill. Set TVMAX=0 during velocity mode to avoid triggering the TVMAX delay when switching back to ramp mode. +#define TMC5240_TVMAX_SHIFT 0 // Minimum time for constant velocity segments in multiple of 512 clocks.; 0: Disables minimum duration setting for constant velocity phase; >0: A minimum duration of constant velocity is inserted in between of any change from acceleration to deceleration or vice versa to reduce jerk; 0…(2^16)-1 * 512 tCLK; Note: Configure this register after setting VMAX when in Positionmode and standstill. Set TVMAX=0 during velocity mode to avoid triggering the TVMAX delay when switching back to ramp mode. +#define TMC5240_TVMAX_FIELD ((RegisterField) { TMC5240_TVMAX_MASK, TMC5240_TVMAX_SHIFT, TMC5240_TVMAX, false }) +#define TMC5240_D1_MASK 0x3FFFF // D1 // Deceleration between V1 and VSTOP (unsigned); Attention: Do not set 0 in positioning mode, even if V1=0!; 1…(2^16)-1; [µsteps / ta²]; Reset Default = 10 +#define TMC5240_D1_SHIFT 0 // Deceleration between V1 and VSTOP (unsigned); Attention: Do not set 0 in positioning mode, even if V1=0!; 1…(2^16)-1; [µsteps / ta²]; Reset Default = 10 +#define TMC5240_D1_FIELD ((RegisterField) { TMC5240_D1_MASK, TMC5240_D1_SHIFT, TMC5240_D1, false }) +#define TMC5240_VSTOP_MASK 0x3FFFF // VSTOP // Motor stop velocity (unsigned); Hint: Set VSTOP = VSTART to allow positioning for short distances; Attention: Do not set 0 in positioning mode, minimum 10 recommend!; 1…(2^18)-1; [µsteps / t]; Reset Default=10 +#define TMC5240_VSTOP_SHIFT 0 // Motor stop velocity (unsigned); Hint: Set VSTOP = VSTART to allow positioning for short distances; Attention: Do not set 0 in positioning mode, minimum 10 recommend!; 1…(2^18)-1; [µsteps / t]; Reset Default=10 +#define TMC5240_VSTOP_FIELD ((RegisterField) { TMC5240_VSTOP_MASK, TMC5240_VSTOP_SHIFT, TMC5240_VSTOP, false }) +#define TMC5240_TZEROWAIT_MASK 0xFFFF // TZEROWAIT // Defines the waiting time after ramping down to zero velocity before next movement or direction inversion can start. Time range is about 0 to 2 seconds.; This setting avoids excess acceleration e.g. from VSTOP to -VSTART.; 0…(2^16)-1 * 512 tCLK +#define TMC5240_TZEROWAIT_SHIFT 0 // Defines the waiting time after ramping down to zero velocity before next movement or direction inversion can start. Time range is about 0 to 2 seconds.; This setting avoids excess acceleration e.g. from VSTOP to -VSTART.; 0…(2^16)-1 * 512 tCLK +#define TMC5240_TZEROWAIT_FIELD ((RegisterField) { TMC5240_TZEROWAIT_MASK, TMC5240_TZEROWAIT_SHIFT, TMC5240_TZEROWAIT, false }) +#define TMC5240_XTARGET_MASK 0xFFFFFFFF // XTARGET // Target position for ramp mode (signed). Write a new target position to this register in order to activate the ramp generator positioning in RAMPMODE=0. Initialize all velocity, acceleration and deceleration parameters before.; Hint: The position is allowed to wrap around, thus, XTARGET value optionally can be treated as an unsigned number.; Hint: The maximum possible displacement is +/-((2^31)-1).; Hint: When increasing V1, D1 or DMAX during a motion, rewrite XTARGET afterwards in order to trigger a second acceleration phase, if desired.; -2^31…; +(2^31)-1 +#define TMC5240_XTARGET_SHIFT 0 // Target position for ramp mode (signed). Write a new target position to this register in order to activate the ramp generator positioning in RAMPMODE=0. Initialize all velocity, acceleration and deceleration parameters before.; Hint: The position is allowed to wrap around, thus, XTARGET value optionally can be treated as an unsigned number.; Hint: The maximum possible displacement is +/-((2^31)-1).; Hint: When increasing V1, D1 or DMAX during a motion, rewrite XTARGET afterwards in order to trigger a second acceleration phase, if desired.; -2^31…; +(2^31)-1 +#define TMC5240_XTARGET_FIELD ((RegisterField) { TMC5240_XTARGET_MASK, TMC5240_XTARGET_SHIFT, TMC5240_XTARGET, true }) +#define TMC5240_V2_MASK 0xFFFFF // V2 // Velocity difference from VMAX for activation of acceleration segments with AMAX/2 and DMAX/2.; 0: Disables AMAX/2 and DMAX/2 phase, use AMAX, DMAX only; 0…(2^20)-1; [µsteps / t] +#define TMC5240_V2_SHIFT 0 // Velocity difference from VMAX for activation of acceleration segments with AMAX/2 and DMAX/2.; 0: Disables AMAX/2 and DMAX/2 phase, use AMAX, DMAX only; 0…(2^20)-1; [µsteps / t] +#define TMC5240_V2_FIELD ((RegisterField) { TMC5240_V2_MASK, TMC5240_V2_SHIFT, TMC5240_V2, false }) +#define TMC5240_A2_MASK 0x3FFFF // A2 // Acceleration between V1 and V2 (unsigned); 0…(2^18)-1 [µsteps / ta²] +#define TMC5240_A2_SHIFT 0 // Acceleration between V1 and V2 (unsigned); 0…(2^18)-1 [µsteps / ta²] +#define TMC5240_A2_FIELD ((RegisterField) { TMC5240_A2_MASK, TMC5240_A2_SHIFT, TMC5240_A2, false }) +#define TMC5240_D2_MASK 0x3FFFF // D2 // Deceleration between V2 and V1 (unsigned); Attention: Do not set 0 in positioning mode, even if V2=0!; 1…(2^18)-1; [µsteps / ta²]; Reset Default = 10 +#define TMC5240_D2_SHIFT 0 // Deceleration between V2 and V1 (unsigned); Attention: Do not set 0 in positioning mode, even if V2=0!; 1…(2^18)-1; [µsteps / ta²]; Reset Default = 10 +#define TMC5240_D2_FIELD ((RegisterField) { TMC5240_D2_MASK, TMC5240_D2_SHIFT, TMC5240_D2, false }) +#define TMC5240_AACTUAL_MASK 0xFFFFFF // AACTUAL // Current acceleration used by the rampgenerator +#define TMC5240_AACTUAL_SHIFT 0 // Current acceleration used by the rampgenerator +#define TMC5240_AACTUAL_FIELD ((RegisterField) { TMC5240_AACTUAL_MASK, TMC5240_AACTUAL_SHIFT, TMC5240_AACTUAL, true }) +#define TMC5240_VDCMIN_MASK 0x7FFF00 // VDCMIN // Automatic commutation DcStep becomes enabled above velocity VDCMIN (unsigned) (only when using internal ramp generator, not for STEP/DIR interface modes – in STEP/DIR mode, DcStep is not available); In this mode, the actual position is determined by the sensor­less motor commutation and becomes fed back to XACTUAL. In case the motor becomes heavily loaded, VDCMIN also is used as the minimum step velocity. Activate stop on stall (sg_stop) to detect step loss.; 0: Disable, DcStep off; |VACT| = VDCMIN = 256:; Triggers the same actions as exceeding THIGH setting.; Switches on automatic commutation DcStep; Hint: Also set DCCTRL parameters in order to operate DcStep.; (Only bits 22… 8 are used for value and for comparison) +#define TMC5240_VDCMIN_SHIFT 8 // Automatic commutation DcStep becomes enabled above velocity VDCMIN (unsigned) (only when using internal ramp generator, not for STEP/DIR interface modes – in STEP/DIR mode, DcStep is not available); In this mode, the actual position is determined by the sensor­less motor commutation and becomes fed back to XACTUAL. In case the motor becomes heavily loaded, VDCMIN also is used as the minimum step velocity. Activate stop on stall (sg_stop) to detect step loss.; 0: Disable, DcStep off; |VACT| = VDCMIN = 256:; Triggers the same actions as exceeding THIGH setting.; Switches on automatic commutation DcStep; Hint: Also set DCCTRL parameters in order to operate DcStep.; (Only bits 22… 8 are used for value and for comparison) +#define TMC5240_VDCMIN_FIELD ((RegisterField) { TMC5240_VDCMIN_MASK, TMC5240_VDCMIN_SHIFT, TMC5240_VDCMIN, false }) +#define TMC5240_STOP_L_ENABLE_MASK 0x01 // SW_MODE // 1: Enables automatic motor stop during active left reference switch input; Hint: The motor restarts in case the stop switch becomes released. +#define TMC5240_STOP_L_ENABLE_SHIFT 0 // 1: Enables automatic motor stop during active left reference switch input; Hint: The motor restarts in case the stop switch becomes released. +#define TMC5240_STOP_L_ENABLE_FIELD ((RegisterField) { TMC5240_STOP_L_ENABLE_MASK, TMC5240_STOP_L_ENABLE_SHIFT, TMC5240_SWMODE, false }) +#define TMC5240_STOP_R_ENABLE_MASK 0x02 // SW_MODE // 1: Enables automatic motor stop during active right reference switch input; Hint: The motor restarts in case the stop switch becomes released. +#define TMC5240_STOP_R_ENABLE_SHIFT 1 // 1: Enables automatic motor stop during active right reference switch input; Hint: The motor restarts in case the stop switch becomes released. +#define TMC5240_STOP_R_ENABLE_FIELD ((RegisterField) { TMC5240_STOP_R_ENABLE_MASK, TMC5240_STOP_R_ENABLE_SHIFT, TMC5240_SWMODE, false }) +#define TMC5240_POL_STOP_L_MASK 0x04 // SW_MODE // Sets the active polarity of the left reference switch input; 0=non-inverted, high active: a high level on REFL stops the motor; 1=inverted, low active: a low level on REFL stops the motor +#define TMC5240_POL_STOP_L_SHIFT 2 // Sets the active polarity of the left reference switch input; 0=non-inverted, high active: a high level on REFL stops the motor; 1=inverted, low active: a low level on REFL stops the motor +#define TMC5240_POL_STOP_L_FIELD ((RegisterField) { TMC5240_POL_STOP_L_MASK, TMC5240_POL_STOP_L_SHIFT, TMC5240_SWMODE, false }) +#define TMC5240_POL_STOP_R_MASK 0x08 // SW_MODE // Sets the active polarity of the right reference switch input; 0=non-inverted, high active: a high level on REFR stops the motor; 1=inverted, low active: a low level on REFR stops the motor +#define TMC5240_POL_STOP_R_SHIFT 3 // Sets the active polarity of the right reference switch input; 0=non-inverted, high active: a high level on REFR stops the motor; 1=inverted, low active: a low level on REFR stops the motor +#define TMC5240_POL_STOP_R_FIELD ((RegisterField) { TMC5240_POL_STOP_R_MASK, TMC5240_POL_STOP_R_SHIFT, TMC5240_SWMODE, false }) +#define TMC5240_SWAP_LR_MASK 0x10 // SW_MODE // 1: Swap the left and the right reference switch input REFL and REFR +#define TMC5240_SWAP_LR_SHIFT 4 // 1: Swap the left and the right reference switch input REFL and REFR +#define TMC5240_SWAP_LR_FIELD ((RegisterField) { TMC5240_SWAP_LR_MASK, TMC5240_SWAP_LR_SHIFT, TMC5240_SWMODE, false }) +#define TMC5240_LATCH_L_ACTIVE_MASK 0x20 // SW_MODE // 1: Activates latching of the position to XLATCH upon an active going edge on the left reference switch input REFL.; Hint: Activate latch_l_active to detect any spurious stop event by reading status_latch_l. +#define TMC5240_LATCH_L_ACTIVE_SHIFT 5 // 1: Activates latching of the position to XLATCH upon an active going edge on the left reference switch input REFL.; Hint: Activate latch_l_active to detect any spurious stop event by reading status_latch_l. +#define TMC5240_LATCH_L_ACTIVE_FIELD ((RegisterField) { TMC5240_LATCH_L_ACTIVE_MASK, TMC5240_LATCH_L_ACTIVE_SHIFT, TMC5240_SWMODE, false }) +#define TMC5240_LATCH_L_INACTIVE_MASK 0x40 // SW_MODE // 1: Activates latching of the position to XLATCH upon an inactive going edge on the left reference switch input REFL. The active level is defined by pol_stop_l. +#define TMC5240_LATCH_L_INACTIVE_SHIFT 6 // 1: Activates latching of the position to XLATCH upon an inactive going edge on the left reference switch input REFL. The active level is defined by pol_stop_l. +#define TMC5240_LATCH_L_INACTIVE_FIELD ((RegisterField) { TMC5240_LATCH_L_INACTIVE_MASK, TMC5240_LATCH_L_INACTIVE_SHIFT, TMC5240_SWMODE, false }) +#define TMC5240_LATCH_R_ACTIVE_MASK 0x80 // SW_MODE // 1: Activates latching of the position to XLATCH upon an active going edge on the right reference switch input REFR.; Hint: Activate latch_r_active to detect any spurious stop event by reading status_latch_r. +#define TMC5240_LATCH_R_ACTIVE_SHIFT 7 // 1: Activates latching of the position to XLATCH upon an active going edge on the right reference switch input REFR.; Hint: Activate latch_r_active to detect any spurious stop event by reading status_latch_r. +#define TMC5240_LATCH_R_ACTIVE_FIELD ((RegisterField) { TMC5240_LATCH_R_ACTIVE_MASK, TMC5240_LATCH_R_ACTIVE_SHIFT, TMC5240_SWMODE, false }) +#define TMC5240_LATCH_R_INACTIVE_MASK 0x100 // SW_MODE // 1: Activates latching of the position to XLATCH upon an inactive going edge on the right reference switch input REFR. The active level is defined by pol_stop_r. +#define TMC5240_LATCH_R_INACTIVE_SHIFT 8 // 1: Activates latching of the position to XLATCH upon an inactive going edge on the right reference switch input REFR. The active level is defined by pol_stop_r. +#define TMC5240_LATCH_R_INACTIVE_FIELD ((RegisterField) { TMC5240_LATCH_R_INACTIVE_MASK, TMC5240_LATCH_R_INACTIVE_SHIFT, TMC5240_SWMODE, false }) +#define TMC5240_EN_LATCH_ENCODER_MASK 0x200 // SW_MODE // 1: Latch encoder position to ENC_LATCH upon reference switch event. +#define TMC5240_EN_LATCH_ENCODER_SHIFT 9 // 1: Latch encoder position to ENC_LATCH upon reference switch event. +#define TMC5240_EN_LATCH_ENCODER_FIELD ((RegisterField) { TMC5240_EN_LATCH_ENCODER_MASK, TMC5240_EN_LATCH_ENCODER_SHIFT, TMC5240_SWMODE, false }) +#define TMC5240_SG_STOP_MASK 0x400 // SW_MODE // Enable stop by StallGuard2 (also available in DcStep mode). Disable to release motor after stop event. Program TCOOLTHRS for velocity threshold.; Hint: Do not enable during motor spin-up, wait until the motor velocity exceeds a certain value, where StallGuard2 delivers a stable result. This velocity threshold should be programmed using TCOOLTHRS. +#define TMC5240_SG_STOP_SHIFT 10 // Enable stop by StallGuard2 (also available in DcStep mode). Disable to release motor after stop event. Program TCOOLTHRS for velocity threshold.; Hint: Do not enable during motor spin-up, wait until the motor velocity exceeds a certain value, where StallGuard2 delivers a stable result. This velocity threshold should be programmed using TCOOLTHRS. +#define TMC5240_SG_STOP_FIELD ((RegisterField) { TMC5240_SG_STOP_MASK, TMC5240_SG_STOP_SHIFT, TMC5240_SWMODE, false }) +#define TMC5240_EN_SOFTSTOP_MASK 0x800 // SW_MODE // 0: Hard stop; 1: Soft stop; The soft stop mode always uses the deceleration ramp settings DMAX, V1, D1, V2, D2, VSTOP and TZEROWAIT for stopping the motor. A stop occurs when the velocity sign matches the reference switch position (REFL, VIRTUAL_STOP_L for negative velocities, REFR, VIRTUAL_STOP_R for positive velocities) and the respective switch stop function is enabled.; A hard stop also uses TZEROWAIT before the motor becomes released.; Attention: Do not use soft stop in combination with StallGuard2. Use soft stop for StealthChop operation at high velocity. In this case, hard stop must be avoided, as it could result in severe overcurrent. +#define TMC5240_EN_SOFTSTOP_SHIFT 11 // 0: Hard stop; 1: Soft stop; The soft stop mode always uses the deceleration ramp settings DMAX, V1, D1, V2, D2, VSTOP and TZEROWAIT for stopping the motor. A stop occurs when the velocity sign matches the reference switch position (REFL, VIRTUAL_STOP_L for negative velocities, REFR, VIRTUAL_STOP_R for positive velocities) and the respective switch stop function is enabled.; A hard stop also uses TZEROWAIT before the motor becomes released.; Attention: Do not use soft stop in combination with StallGuard2. Use soft stop for StealthChop operation at high velocity. In this case, hard stop must be avoided, as it could result in severe overcurrent. +#define TMC5240_EN_SOFTSTOP_FIELD ((RegisterField) { TMC5240_EN_SOFTSTOP_MASK, TMC5240_EN_SOFTSTOP_SHIFT, TMC5240_SWMODE, false }) +#define TMC5240_EN_VIRTUAL_STOP_L_MASK 0x1000 // SW_MODE // 1: Enables automatic motor stop during active left virtual stop condition +#define TMC5240_EN_VIRTUAL_STOP_L_SHIFT 12 // 1: Enables automatic motor stop during active left virtual stop condition +#define TMC5240_EN_VIRTUAL_STOP_L_FIELD ((RegisterField) { TMC5240_EN_VIRTUAL_STOP_L_MASK, TMC5240_EN_VIRTUAL_STOP_L_SHIFT, TMC5240_SWMODE, false }) +#define TMC5240_EN_VIRTUAL_STOP_R_MASK 0x2000 // SW_MODE // 1: Enables automatic motor stop during active right virtual stop condition +#define TMC5240_EN_VIRTUAL_STOP_R_SHIFT 13 // 1: Enables automatic motor stop during active right virtual stop condition +#define TMC5240_EN_VIRTUAL_STOP_R_FIELD ((RegisterField) { TMC5240_EN_VIRTUAL_STOP_R_MASK, TMC5240_EN_VIRTUAL_STOP_R_SHIFT, TMC5240_SWMODE, false }) +#define TMC5240_VIRTUAL_STOP_ENC_MASK 0x4000 // SW_MODE // Source for virtual stop (VIRTUAL_STOP_L and VIRTUAL_STOP_R); 0: Virtual stop relates to ramp generator position XACTUAL; 1: Virtual stop relates to encoder position X_ENC +#define TMC5240_VIRTUAL_STOP_ENC_SHIFT 14 // Source for virtual stop (VIRTUAL_STOP_L and VIRTUAL_STOP_R); 0: Virtual stop relates to ramp generator position XACTUAL; 1: Virtual stop relates to encoder position X_ENC +#define TMC5240_VIRTUAL_STOP_ENC_FIELD ((RegisterField) { TMC5240_VIRTUAL_STOP_ENC_MASK, TMC5240_VIRTUAL_STOP_ENC_SHIFT, TMC5240_SWMODE, false }) +#define TMC5240_STATUS_STOP_L_MASK 0x01 // RAMP_STAT // Reference switch left status (1=active) +#define TMC5240_STATUS_STOP_L_SHIFT 0 // Reference switch left status (1=active) +#define TMC5240_STATUS_STOP_L_FIELD ((RegisterField) { TMC5240_STATUS_STOP_L_MASK, TMC5240_STATUS_STOP_L_SHIFT, TMC5240_RAMPSTAT, false }) +#define TMC5240_STATUS_STOP_R_MASK 0x02 // RAMP_STAT // Reference switch right status (1=active) +#define TMC5240_STATUS_STOP_R_SHIFT 1 // Reference switch right status (1=active) +#define TMC5240_STATUS_STOP_R_FIELD ((RegisterField) { TMC5240_STATUS_STOP_R_MASK, TMC5240_STATUS_STOP_R_SHIFT, TMC5240_RAMPSTAT, false }) +#define TMC5240_STATUS_LATCH_L_MASK 0x04 // RAMP_STAT // 1: Latch left ready; (enable position latching using SW_MODE settings; latch_l_active or latch_l_inactive); (Write ‘1’ to clear)#type=COW +#define TMC5240_STATUS_LATCH_L_SHIFT 2 // 1: Latch left ready; (enable position latching using SW_MODE settings; latch_l_active or latch_l_inactive); (Write ‘1’ to clear)#type=COW +#define TMC5240_STATUS_LATCH_L_FIELD ((RegisterField) { TMC5240_STATUS_LATCH_L_MASK, TMC5240_STATUS_LATCH_L_SHIFT, TMC5240_RAMPSTAT, false }) +#define TMC5240_STATUS_LATCH_R_MASK 0x08 // RAMP_STAT // 1: Latch right ready; (enable position latching using SW_MODE settings; latch_r_active or latch_r_inactive); (Write ‘1’ to clear)#type=COW +#define TMC5240_STATUS_LATCH_R_SHIFT 3 // 1: Latch right ready; (enable position latching using SW_MODE settings; latch_r_active or latch_r_inactive); (Write ‘1’ to clear)#type=COW +#define TMC5240_STATUS_LATCH_R_FIELD ((RegisterField) { TMC5240_STATUS_LATCH_R_MASK, TMC5240_STATUS_LATCH_R_SHIFT, TMC5240_RAMPSTAT, false}) +#define TMC5240_EVENT_STOP_L_MASK 0x10 // RAMP_STAT // 1: Active stop left condition due to stop switch or virtual stop.; The stop condition and the interrupt condition can be removed by setting RAMP_MODE to hold mode or by commanding a move to the opposite direction. In soft_stop mode, the condition will remain active until the motor has stopped motion into the direction of the stop switch. Disabling the stop switch or the stop function also clears the flag, but the motor will continue motion.; This bit is ORed to the interrupt output signal. +#define TMC5240_EVENT_STOP_L_SHIFT 4 // 1: Active stop left condition due to stop switch or virtual stop.; The stop condition and the interrupt condition can be removed by setting RAMP_MODE to hold mode or by commanding a move to the opposite direction. In soft_stop mode, the condition will remain active until the motor has stopped motion into the direction of the stop switch. Disabling the stop switch or the stop function also clears the flag, but the motor will continue motion.; This bit is ORed to the interrupt output signal. +#define TMC5240_EVENT_STOP_L_FIELD ((RegisterField) { TMC5240_EVENT_STOP_L_MASK, TMC5240_EVENT_STOP_L_SHIFT, TMC5240_RAMPSTAT, false}) +#define TMC5240_EVENT_STOP_R_MASK 0x20 // RAMP_STAT // 1: Active stop right condition due to stop switch or virtual stop.; The stop condition and the interrupt condition can be removed by setting RAMP_MODE to hold mode or by commanding a move to the opposite direction. In soft_stop mode, the condition will remain active until the motor has stopped motion into the direction of the stop switch. Disabling the stop switch or the stop function also clears the flag, but the motor will continue motion.; This bit is ORed to the interrupt output signal. +#define TMC5240_EVENT_STOP_R_SHIFT 5 // 1: Active stop right condition due to stop switch or virtual stop.; The stop condition and the interrupt condition can be removed by setting RAMP_MODE to hold mode or by commanding a move to the opposite direction. In soft_stop mode, the condition will remain active until the motor has stopped motion into the direction of the stop switch. Disabling the stop switch or the stop function also clears the flag, but the motor will continue motion.; This bit is ORed to the interrupt output signal. +#define TMC5240_EVENT_STOP_R_FIELD ((RegisterField) { TMC5240_EVENT_STOP_R_MASK, TMC5240_EVENT_STOP_R_SHIFT, TMC5240_RAMPSTAT, false}) +#define TMC5240_EVENT_STOP_SG_MASK 0x40 // RAMP_STAT // 1: Signals an active StallGuard2 stop event.; Resetting the register will clear the stall condition and the motor may re-start motion, unless the motion controller has been stopped.; (Write ‘1’ to clear flag and interrupt condition); This bit is ORed to the interrupt output signal.#type=COW +#define TMC5240_EVENT_STOP_SG_SHIFT 6 // 1: Signals an active StallGuard2 stop event.; Resetting the register will clear the stall condition and the motor may re-start motion, unless the motion controller has been stopped.; (Write ‘1’ to clear flag and interrupt condition); This bit is ORed to the interrupt output signal.#type=COW +#define TMC5240_EVENT_STOP_SG_FIELD ((RegisterField) { TMC5240_EVENT_STOP_SG_MASK, TMC5240_EVENT_STOP_SG_SHIFT, TMC5240_RAMPSTAT, false}) +#define TMC5240_EVENT_POS_REACHED_MASK 0x80 // RAMP_STAT // 1: Signals, that the target position has been reached (position_reached becoming active).; (Write ‘1’ to clear flag and interrupt condition); This bit is ORed to the interrupt output signal.#type=COW +#define TMC5240_EVENT_POS_REACHED_SHIFT 7 // 1: Signals, that the target position has been reached (position_reached becoming active).; (Write ‘1’ to clear flag and interrupt condition); This bit is ORed to the interrupt output signal.#type=COW +#define TMC5240_EVENT_POS_REACHED_FIELD ((RegisterField) { TMC5240_EVENT_POS_REACHED_MASK, TMC5240_EVENT_POS_REACHED_SHIFT, TMC5240_RAMPSTAT, false}) +#define TMC5240_VELOCITY_REACHED_MASK 0x100 // RAMP_STAT // 1: Signals, that the target velocity is reached.; This flag becomes set while VACTUAL and VMAX match. +#define TMC5240_VELOCITY_REACHED_SHIFT 8 // 1: Signals, that the target velocity is reached.; This flag becomes set while VACTUAL and VMAX match. +#define TMC5240_VELOCITY_REACHED_FIELD ((RegisterField) { TMC5240_VELOCITY_REACHED_MASK, TMC5240_VELOCITY_REACHED_SHIFT, TMC5240_RAMPSTAT, false}) +#define TMC5240_POSITION_REACHED_MASK 0x200 // RAMP_STAT // 1: Signals, that the target position is reached.; This flag becomes set while XACTUAL and XTARGET match. +#define TMC5240_POSITION_REACHED_SHIFT 9 // 1: Signals, that the target position is reached.; This flag becomes set while XACTUAL and XTARGET match. +#define TMC5240_POSITION_REACHED_FIELD ((RegisterField) { TMC5240_POSITION_REACHED_MASK, TMC5240_POSITION_REACHED_SHIFT, TMC5240_RAMPSTAT, false}) +#define TMC5240_VZERO_MASK 0x400 // RAMP_STAT // 1: Signals, that the actual velocity is 0. +#define TMC5240_VZERO_SHIFT 10 // 1: Signals, that the actual velocity is 0. +#define TMC5240_VZERO_FIELD ((RegisterField) { TMC5240_VZERO_MASK, TMC5240_VZERO_SHIFT, TMC5240_RAMPSTAT, false}) +#define TMC5240_T_ZEROWAIT_ACTIVE_MASK 0x800 // RAMP_STAT // 1: Signals, that TZEROWAIT is active after a motor stop. During this time, the motor is in standstill. +#define TMC5240_T_ZEROWAIT_ACTIVE_SHIFT 11 // 1: Signals, that TZEROWAIT is active after a motor stop. During this time, the motor is in standstill. +#define TMC5240_T_ZEROWAIT_ACTIVE_FIELD ((RegisterField) { TMC5240_T_ZEROWAIT_ACTIVE_MASK, TMC5240_T_ZEROWAIT_ACTIVE_SHIFT, TMC5240_RAMPSTAT, false}) +#define TMC5240_SECOND_MOVE_MASK 0x1000 // RAMP_STAT // 1: Signals that the automatic ramp required moving back in the opposite direction, e.g. due to on-the-fly parameter change; (Write ‘1’ to clear)#type=COW +#define TMC5240_SECOND_MOVE_SHIFT 12 // 1: Signals that the automatic ramp required moving back in the opposite direction, e.g. due to on-the-fly parameter change; (Write ‘1’ to clear)#type=COW +#define TMC5240_SECOND_MOVE_FIELD ((RegisterField) { TMC5240_SECOND_MOVE_MASK, TMC5240_SECOND_MOVE_SHIFT, TMC5240_RAMPSTAT, false}) +#define TMC5240_STATUS_SG_MASK 0x2000 // RAMP_STAT // 1: Signals an active StallGuard2 input from the CoolStep driver or from the DcStep unit, if enabled.; Hint: When polling this flag, stall events may be missed – activate sg_stop to be sure not to miss the stall event. +#define TMC5240_STATUS_SG_SHIFT 13 // 1: Signals an active StallGuard2 input from the CoolStep driver or from the DcStep unit, if enabled.; Hint: When polling this flag, stall events may be missed – activate sg_stop to be sure not to miss the stall event. +#define TMC5240_STATUS_SG_FIELD ((RegisterField) { TMC5240_STATUS_SG_MASK, TMC5240_STATUS_SG_SHIFT, TMC5240_RAMPSTAT, false}) +#define TMC5240_STATUS_VIRTUAL_STOP_L_MASK 0x4000 // RAMP_STAT // Virtual reference switch left status (1=active) +#define TMC5240_STATUS_VIRTUAL_STOP_L_SHIFT 14 // Virtual reference switch left status (1=active) +#define TMC5240_STATUS_VIRTUAL_STOP_L_FIELD ((RegisterField) { TMC5240_STATUS_VIRTUAL_STOP_L_MASK, TMC5240_STATUS_VIRTUAL_STOP_L_SHIFT, TMC5240_RAMPSTAT, false}) +#define TMC5240_STATUS_VIRTUAL_STOP_R_MASK 0x8000 // RAMP_STAT // Virtual reference switch right status (1=active) +#define TMC5240_STATUS_VIRTUAL_STOP_R_SHIFT 15 // Virtual reference switch right status (1=active) +#define TMC5240_STATUS_VIRTUAL_STOP_R_FIELD ((RegisterField) { TMC5240_STATUS_VIRTUAL_STOP_R_MASK, TMC5240_STATUS_VIRTUAL_STOP_R_SHIFT, TMC5240_RAMPSTAT, false}) +#define TMC5240_XLATCH_MASK 0xFFFFFFFF // XLATCH // Ramp generator latch position, latches XACTUAL upon a programmable switch event (see SW_MODE).; Hint: The encoder position can be latched to ENC_LATCH together with XLATCH to allow consistency checks. +#define TMC5240_XLATCH_SHIFT 0 // Ramp generator latch position, latches XACTUAL upon a programmable switch event (see SW_MODE).; Hint: The encoder position can be latched to ENC_LATCH together with XLATCH to allow consistency checks. +#define TMC5240_XLATCH_FIELD ((RegisterField) { TMC5240_XLATCH_MASK, TMC5240_XLATCH_SHIFT, TMC5240_XLATCH, true}) +#define TMC5240_POL_A_MASK 0x01 // ENCMODE // Required A polarity for an N channel event +#define TMC5240_POL_A_SHIFT 0 // Required A polarity for an N channel event +#define TMC5240_POL_A_FIELD ((RegisterField) { TMC5240_POL_A_MASK, TMC5240_POL_A_SHIFT, TMC5240_ENCMODE, false}) +#define TMC5240_POL_B_MASK 0x02 // ENCMODE // Required B polarity for an N channel event +#define TMC5240_POL_B_SHIFT 1 // Required B polarity for an N channel event +#define TMC5240_POL_B_FIELD ((RegisterField) { TMC5240_POL_B_MASK, TMC5240_POL_B_SHIFT, TMC5240_ENCMODE, false}) +#define TMC5240_POL_N_MASK 0x04 // ENCMODE // Defines active polarity of N +#define TMC5240_POL_N_SHIFT 2 // Defines active polarity of N +#define TMC5240_POL_N_FIELD ((RegisterField) { TMC5240_POL_N_MASK, TMC5240_POL_N_SHIFT, TMC5240_ENCMODE, false}) +#define TMC5240_IGNORE_AB_MASK 0x08 // ENCMODE // N event configuration +#define TMC5240_IGNORE_AB_SHIFT 3 // N event configuration +#define TMC5240_IGNORE_AB_FIELD ((RegisterField) { TMC5240_IGNORE_AB_MASK, TMC5240_IGNORE_AB_SHIFT, TMC5240_ENCMODE, false}) +#define TMC5240_CLR_CONT_MASK 0x10 // ENCMODE // Position latch configuration +#define TMC5240_CLR_CONT_SHIFT 4 // Position latch configuration +#define TMC5240_CLR_CONT_FIELD ((RegisterField) { TMC5240_CLR_CONT_MASK, TMC5240_CLR_CONT_SHIFT, TMC5240_ENCMODE, false}) +#define TMC5240_CLR_ONCE_MASK 0x20 // ENCMODE // Position latch configuration +#define TMC5240_CLR_ONCE_SHIFT 5 // Position latch configuration +#define TMC5240_CLR_ONCE_FIELD ((RegisterField) { TMC5240_CLR_ONCE_MASK, TMC5240_CLR_ONCE_SHIFT, TMC5240_ENCMODE, false}) +#define TMC5240_POS_NEG_EDGE_MASK 0xC0 // ENCMODE // N channel event sensitivity +#define TMC5240_POS_NEG_EDGE_SHIFT 6 // N channel event sensitivity +#define TMC5240_POS_NEG_EDGE_FIELD ((RegisterField) { TMC5240_POS_NEG_EDGE_MASK, TMC5240_POS_NEG_EDGE_SHIFT, TMC5240_ENCMODE, false}) +#define TMC5240_CLR_ENC_X_MASK 0x100 // ENCMODE // Encoder latch configuration +#define TMC5240_CLR_ENC_X_SHIFT 8 // Encoder latch configuration +#define TMC5240_CLR_ENC_X_FIELD ((RegisterField) { TMC5240_CLR_ENC_X_MASK, TMC5240_CLR_ENC_X_SHIFT, TMC5240_ENCMODE, false}) +#define TMC5240_LATCH_X_ACT_MASK 0x200 // ENCMODE // Position latch configuration +#define TMC5240_LATCH_X_ACT_SHIFT 9 // Position latch configuration +#define TMC5240_LATCH_X_ACT_FIELD ((RegisterField) { TMC5240_LATCH_X_ACT_MASK, TMC5240_LATCH_X_ACT_SHIFT, TMC5240_ENCMODE, false}) +#define TMC5240_ENC_SEL_DECIMAL_MASK 0x400 // ENCMODE // Encoder prescaler mode selection +#define TMC5240_ENC_SEL_DECIMAL_SHIFT 10 // Encoder prescaler mode selection +#define TMC5240_ENC_SEL_DECIMAL_FIELD ((RegisterField) { TMC5240_ENC_SEL_DECIMAL_MASK, TMC5240_ENC_SEL_DECIMAL_SHIFT, TMC5240_ENCMODE, false}) +#define TMC5240_X_ENC_MASK 0xFFFFFFFF // X_ENC // Actual encoder position (signed) +#define TMC5240_X_ENC_SHIFT 0 // Actual encoder position (signed) +#define TMC5240_X_ENC_FIELD ((RegisterField) { TMC5240_X_ENC_MASK, TMC5240_X_ENC_SHIFT, TMC5240_XENC, true}) +#define TMC5240_ENC_CONST_MASK 0xFFFFFFFF // ENC_CONST // Accumulation constant (signed); 16 bit integer part, 16 bit fractional part; X_ENC accumulates; +/- ENC_CONST / (2^16*X_ENC) (binary); or; +/-ENC_CONST / (10^4*X_ENC) (decimal); ENCMODE bit enc_sel_decimal switches between decimal and binary setting.; Use the sign, to match rotation direction!; binary:; ± [µsteps/2^16]; ±(0 …; 32767.999847); decimal:; ±(0.0 … 32767.9999); reset default = 1.0 (=65536) +#define TMC5240_ENC_CONST_SHIFT 0 // Accumulation constant (signed); 16 bit integer part, 16 bit fractional part; X_ENC accumulates; +/- ENC_CONST / (2^16*X_ENC) (binary); or; +/-ENC_CONST / (10^4*X_ENC) (decimal); ENCMODE bit enc_sel_decimal switches between decimal and binary setting.; Use the sign, to match rotation direction!; binary:; ± [µsteps/2^16]; ±(0 …; 32767.999847); decimal:; ±(0.0 … 32767.9999); reset default = 1.0 (=65536) +#define TMC5240_ENC_CONST_FIELD ((RegisterField) { TMC5240_ENC_CONST_MASK, TMC5240_ENC_CONST_SHIFT, TMC5240_ENC_CONST, true}) +#define TMC5240_N_EVENT_MASK 0x01 // ENC_STATUS // #type=COW +#define TMC5240_N_EVENT_SHIFT 0 // #type=COW +#define TMC5240_N_EVENT_FIELD ((RegisterField) { TMC5240_N_EVENT_MASK, TMC5240_N_EVENT_SHIFT, TMC5240_ENC_STATUS, false}) +#define TMC5240_DEVIATION_WARN_MASK 0x02 // ENC_STATUS // #type=COW +#define TMC5240_DEVIATION_WARN_SHIFT 1 // #type=COW +#define TMC5240_DEVIATION_WARN_FIELD ((RegisterField) { TMC5240_DEVIATION_WARN_MASK, TMC5240_DEVIATION_WARN_SHIFT, TMC5240_ENC_STATUS, false}) +#define TMC5240_ENC_LATCH_MASK 0xFFFFFFFF // ENC_LATCH // Encoder position X_ENC latched on N event +#define TMC5240_ENC_LATCH_SHIFT 0 // Encoder position X_ENC latched on N event +#define TMC5240_ENC_LATCH_FIELD ((RegisterField) { TMC5240_ENC_LATCH_MASK, TMC5240_ENC_LATCH_SHIFT, TMC5240_ENC_LATCH, false}) +#define TMC5240_ENC_DEVIATION_MASK 0xFFFFF // ENC_DEVIATION // Maximum number of steps deviation between encoder counter and XACTUAL for deviation warning; Result in flag ENC_STATUS.deviation_warn; 0=Function is off. +#define TMC5240_ENC_DEVIATION_SHIFT 0 // Maximum number of steps deviation between encoder counter and XACTUAL for deviation warning; Result in flag ENC_STATUS.deviation_warn; 0=Function is off. +#define TMC5240_ENC_DEVIATION_FIELD ((RegisterField) { TMC5240_ENC_DEVIATION_MASK, TMC5240_ENC_DEVIATION_SHIFT, TMC5240_ENC_DEVIATION, false}) +#define TMC5240_VIRTUAL_STOP_L_MASK 0xFFFFFFFF // VIRTUAL_STOP_L // Virtual stop switch based on encoder or ramp position. A stop is raised, based on the signed comparison; virtual_stop_enc = 1:; X_ENC VIRTUAL_STOP_L; virtual_stop_enc = 0:; XACTUAL VIRTUAL_STOP_L; -2^31…; +(2^31)-1 +#define TMC5240_VIRTUAL_STOP_L_SHIFT 0 // Virtual stop switch based on encoder or ramp position. A stop is raised, based on the signed comparison; virtual_stop_enc = 1:; X_ENC VIRTUAL_STOP_L; virtual_stop_enc = 0:; XACTUAL VIRTUAL_STOP_L; -2^31…; +(2^31)-1 +#define TMC5240_VIRTUAL_STOP_L_FIELD ((RegisterField) { TMC5240_VIRTUAL_STOP_L_MASK, TMC5240_VIRTUAL_STOP_L_SHIFT, TMC5240_VIRTUAL_STOP_L, true}) +#define TMC5240_VIRTUAL_STOP_R_MASK 0xFFFFFFFF // VIRTUAL_STOP_R // Virtual Stop Switch based on Encoder. A stop is raised, based on the signed comparison; virtual_stop_enc = 1:; X_ENC >= VIRTUAL_STOP_R; virtual_stop_enc = 0:; XACTUAL >= VIRTUAL_STOP_R; -2^31…; +(2^31)-1 +#define TMC5240_VIRTUAL_STOP_R_SHIFT 0 // Virtual Stop Switch based on Encoder. A stop is raised, based on the signed comparison; virtual_stop_enc = 1:; X_ENC >= VIRTUAL_STOP_R; virtual_stop_enc = 0:; XACTUAL >= VIRTUAL_STOP_R; -2^31…; +(2^31)-1 +#define TMC5240_VIRTUAL_STOP_R_FIELD ((RegisterField) { TMC5240_VIRTUAL_STOP_R_MASK, TMC5240_VIRTUAL_STOP_R_SHIFT, TMC5240_VIRTUAL_STOP_R, true}) +#define TMC5240_ADC_VSUPPLY_MASK 0x1FFF // ADC_VSUPPLY_AIN // Actual Value of voltage on VS (filtered with low pass filter), update rate: each 2048 clocks [als Plan für alle 3 Werte, den Rest schicken wir den ADC ins idle] +#define TMC5240_ADC_VSUPPLY_SHIFT 0 // Actual Value of voltage on VS (filtered with low pass filter), update rate: each 2048 clocks [als Plan für alle 3 Werte, den Rest schicken wir den ADC ins idle] +#define TMC5240_ADC_VSUPPLY_FIELD ((RegisterField) { TMC5240_ADC_VSUPPLY_MASK, TMC5240_ADC_VSUPPLY_SHIFT, TMC5240_ADC_VSUPPLY_AIN, true}) +#define TMC5240_ADC_AIN_MASK 0x1FFF0000 // ADC_VSUPPLY_AIN // Value of voltage on ADC_AIN pin in integer +#define TMC5240_ADC_AIN_SHIFT 16 // Value of voltage on ADC_AIN pin in integer +#define TMC5240_ADC_AIN_FIELD ((RegisterField) { TMC5240_ADC_AIN_MASK, TMC5240_ADC_AIN_SHIFT, TMC5240_ADC_VSUPPLY_AIN, true}) +#define TMC5240_ADC_TEMP_MASK 0x1FFF // ADC_TEMP // Analog voltage on general purpose input AIN [zu klären ist der Range – ggf. 0-1.25V ist m.E. der native Bereich des ADCs] +#define TMC5240_ADC_TEMP_SHIFT 0 // Analog voltage on general purpose input AIN [zu klären ist der Range – ggf. 0-1.25V ist m.E. der native Bereich des ADCs] +#define TMC5240_ADC_TEMP_FIELD ((RegisterField) { TMC5240_ADC_TEMP_MASK, TMC5240_ADC_TEMP_SHIFT, TMC5240_ADC_TEMP, true}) +#define TMC5240_OVERVOLTAGE_VTH_MASK 0x1FFF // OTW_OV_VTH // Overvoltage threshold for output OV. Default: 38V, 36 V equals 1.125 V at ADC inputs +#define TMC5240_OVERVOLTAGE_VTH_SHIFT 0 // Overvoltage threshold for output OV. Default: 38V, 36 V equals 1.125 V at ADC inputs +#define TMC5240_OVERVOLTAGE_VTH_FIELD ((RegisterField) { TMC5240_OVERVOLTAGE_VTH_MASK, TMC5240_OVERVOLTAGE_VTH_SHIFT, TMC5240_OTW_OV_VTH, false}) +#define TMC5240_OVERTEMPPREWARNING_VTH_MASK 0x1FFF0000 // OTW_OV_VTH // Overtemperature warning threshold register:; ADC_TEMP >= OVERTEMPPREWARNING_VTH; Overtemperatureprewarning will be triggered; (Reset: 0xB92 equals 120°C) +#define TMC5240_OVERTEMPPREWARNING_VTH_SHIFT 16 // Overtemperature warning threshold register:; ADC_TEMP >= OVERTEMPPREWARNING_VTH; Overtemperatureprewarning will be triggered; (Reset: 0xB92 equals 120°C) +#define TMC5240_OVERTEMPPREWARNING_VTH_FIELD ((RegisterField) { TMC5240_OVERTEMPPREWARNING_VTH_MASK, TMC5240_OVERTEMPPREWARNING_VTH_SHIFT, TMC5240_OTW_OV_VTH, false}) +#define TMC5240_MSLUT_0_MASK 0xFFFFFFFF // MSLUT_0 // Each bit gives the difference between entry x and entry x+1 when combined with the cor­res­ponding MSLUTSEL W bits:; 0: W=; %00: -1; %01: +0; %10: +1; %11: +2; 1: W=; %00: +0; %01: +1; %10: +2; %11: +3; This is the differential coding for the first quarter of a wave. Start values for CUR_A and CUR_B are stored for MSCNT position 0 in START_SIN and START_SIN90.; ofs31, ofs30, …, ofs01, ofs00; …; ofs255, ofs254, …, ofs225, ofs224; reset default= sine wave table +#define TMC5240_MSLUT_0_SHIFT 0 // Each bit gives the difference between entry x and entry x+1 when combined with the cor­res­ponding MSLUTSEL W bits:; 0: W=; %00: -1; %01: +0; %10: +1; %11: +2; 1: W=; %00: +0; %01: +1; %10: +2; %11: +3; This is the differential coding for the first quarter of a wave. Start values for CUR_A and CUR_B are stored for MSCNT position 0 in START_SIN and START_SIN90.; ofs31, ofs30, …, ofs01, ofs00; …; ofs255, ofs254, …, ofs225, ofs224; reset default= sine wave table +#define TMC5240_MSLUT_0_FIELD ((RegisterField) { TMC5240_MSLUT_0_MASK, TMC5240_MSLUT_0_SHIFT, TMC5240_MSLUT0, false}) +#define TMC5240_MSLUT_1_MASK 0xFFFFFFFF // MSLUT_1 // Each bit gives the difference between entry x and entry x+1 when combined with the cor­res­ponding MSLUTSEL W bits:; 0: W=; %00: -1; %01: +0; %10: +1; %11: +2; 1: W=; %00: +0; %01: +1; %10: +2; %11: +3; This is the differential coding for the first quarter of a wave. Start values for CUR_A and CUR_B are stored for MSCNT position 0 in START_SIN and START_SIN90.; ofs31, ofs30, …, ofs01, ofs00; …; ofs255, ofs254, …, ofs225, ofs224; reset default= sine wave table; ??????? +#define TMC5240_MSLUT_1_SHIFT 0 // Each bit gives the difference between entry x and entry x+1 when combined with the cor­res­ponding MSLUTSEL W bits:; 0: W=; %00: -1; %01: +0; %10: +1; %11: +2; 1: W=; %00: +0; %01: +1; %10: +2; %11: +3; This is the differential coding for the first quarter of a wave. Start values for CUR_A and CUR_B are stored for MSCNT position 0 in START_SIN and START_SIN90.; ofs31, ofs30, …, ofs01, ofs00; …; ofs255, ofs254, …, ofs225, ofs224; reset default= sine wave table; ??????? +#define TMC5240_MSLUT_1_FIELD ((RegisterField) { TMC5240_MSLUT_1_MASK, TMC5240_MSLUT_1_SHIFT, TMC5240_MSLUT1, false}) +#define TMC5240_MSLUT_2_MASK 0xFFFFFFFF // MSLUT_2 // Each bit gives the difference between entry x and entry x+1 when combined with the cor­res­ponding MSLUTSEL W bits:; 0: W=; %00: -1; %01: +0; %10: +1; %11: +2; 1: W=; %00: +0; %01: +1; %10: +2; %11: +3; This is the differential coding for the first quarter of a wave. Start values for CUR_A and CUR_B are stored for MSCNT position 0 in START_SIN and START_SIN90.; ofs31, ofs30, …, ofs01, ofs00; …; ofs255, ofs254, …, ofs225, ofs224; reset default= sine wave table; ??????? +#define TMC5240_MSLUT_2_SHIFT 0 // Each bit gives the difference between entry x and entry x+1 when combined with the cor­res­ponding MSLUTSEL W bits:; 0: W=; %00: -1; %01: +0; %10: +1; %11: +2; 1: W=; %00: +0; %01: +1; %10: +2; %11: +3; This is the differential coding for the first quarter of a wave. Start values for CUR_A and CUR_B are stored for MSCNT position 0 in START_SIN and START_SIN90.; ofs31, ofs30, …, ofs01, ofs00; …; ofs255, ofs254, …, ofs225, ofs224; reset default= sine wave table; ??????? +#define TMC5240_MSLUT_2_FIELD ((RegisterField) { TMC5240_MSLUT_2_MASK, TMC5240_MSLUT_2_SHIFT, TMC5240_MSLUT2, false}) +#define TMC5240_MSLUT_3_MASK 0xFFFFFFFF // MSLUT_3 // Each bit gives the difference between entry x and entry x+1 when combined with the cor­res­ponding MSLUTSEL W bits:; 0: W=; %00: -1; %01: +0; %10: +1; %11: +2; 1: W=; %00: +0; %01: +1; %10: +2; %11: +3; This is the differential coding for the first quarter of a wave. Start values for CUR_A and CUR_B are stored for MSCNT position 0 in START_SIN and START_SIN90.; ofs31, ofs30, …, ofs01, ofs00; …; ofs255, ofs254, …, ofs225, ofs224; reset default= sine wave table; ??????? +#define TMC5240_MSLUT_3_SHIFT 0 // Each bit gives the difference between entry x and entry x+1 when combined with the cor­res­ponding MSLUTSEL W bits:; 0: W=; %00: -1; %01: +0; %10: +1; %11: +2; 1: W=; %00: +0; %01: +1; %10: +2; %11: +3; This is the differential coding for the first quarter of a wave. Start values for CUR_A and CUR_B are stored for MSCNT position 0 in START_SIN and START_SIN90.; ofs31, ofs30, …, ofs01, ofs00; …; ofs255, ofs254, …, ofs225, ofs224; reset default= sine wave table; ??????? +#define TMC5240_MSLUT_3_FIELD ((RegisterField) { TMC5240_MSLUT_3_MASK, TMC5240_MSLUT_3_SHIFT, TMC5240_MSLUT3, false}) +#define TMC5240_MSLUT_4_MASK 0xFFFFFFFF // MSLUT_4 // Each bit gives the difference between entry x and entry x+1 when combined with the cor­res­ponding MSLUTSEL W bits:; 0: W=; %00: -1; %01: +0; %10: +1; %11: +2; 1: W=; %00: +0; %01: +1; %10: +2; %11: +3; This is the differential coding for the first quarter of a wave. Start values for CUR_A and CUR_B are stored for MSCNT position 0 in START_SIN and START_SIN90.; ofs31, ofs30, …, ofs01, ofs00; …; ofs255, ofs254, …, ofs225, ofs224; reset default= sine wave table; ??????? +#define TMC5240_MSLUT_4_SHIFT 0 // Each bit gives the difference between entry x and entry x+1 when combined with the cor­res­ponding MSLUTSEL W bits:; 0: W=; %00: -1; %01: +0; %10: +1; %11: +2; 1: W=; %00: +0; %01: +1; %10: +2; %11: +3; This is the differential coding for the first quarter of a wave. Start values for CUR_A and CUR_B are stored for MSCNT position 0 in START_SIN and START_SIN90.; ofs31, ofs30, …, ofs01, ofs00; …; ofs255, ofs254, …, ofs225, ofs224; reset default= sine wave table; ??????? +#define TMC5240_MSLUT_4_FIELD ((RegisterField) { TMC5240_MSLUT_4_MASK, TMC5240_MSLUT_4_SHIFT, TMC5240_MSLUT4, false}) +#define TMC5240_MSLUT_5_MASK 0xFFFFFFFF // MSLUT_5 // Each bit gives the difference between entry x and entry x+1 when combined with the cor­res­ponding MSLUTSEL W bits:; 0: W=; %00: -1; %01: +0; %10: +1; %11: +2; 1: W=; %00: +0; %01: +1; %10: +2; %11: +3; This is the differential coding for the first quarter of a wave. Start values for CUR_A and CUR_B are stored for MSCNT position 0 in START_SIN and START_SIN90.; ofs31, ofs30, …, ofs01, ofs00; …; ofs255, ofs254, …, ofs225, ofs224; reset default= sine wave table; ??????? +#define TMC5240_MSLUT_5_SHIFT 0 // Each bit gives the difference between entry x and entry x+1 when combined with the cor­res­ponding MSLUTSEL W bits:; 0: W=; %00: -1; %01: +0; %10: +1; %11: +2; 1: W=; %00: +0; %01: +1; %10: +2; %11: +3; This is the differential coding for the first quarter of a wave. Start values for CUR_A and CUR_B are stored for MSCNT position 0 in START_SIN and START_SIN90.; ofs31, ofs30, …, ofs01, ofs00; …; ofs255, ofs254, …, ofs225, ofs224; reset default= sine wave table; ??????? +#define TMC5240_MSLUT_5_FIELD ((RegisterField) { TMC5240_MSLUT_5_MASK, TMC5240_MSLUT_5_SHIFT, TMC5240_MSLUT5, false}) +#define TMC5240_MSLUT_6_MASK 0xFFFFFFFF // MSLUT_6 // Each bit gives the difference between entry x and entry x+1 when combined with the cor­res­ponding MSLUTSEL W bits:; 0: W=; %00: -1; %01: +0; %10: +1; %11: +2; 1: W=; %00: +0; %01: +1; %10: +2; %11: +3; This is the differential coding for the first quarter of a wave. Start values for CUR_A and CUR_B are stored for MSCNT position 0 in START_SIN and START_SIN90.; ofs31, ofs30, …, ofs01, ofs00; …; ofs255, ofs254, …, ofs225, ofs224; reset default= sine wave table; ??????? +#define TMC5240_MSLUT_6_SHIFT 0 // Each bit gives the difference between entry x and entry x+1 when combined with the cor­res­ponding MSLUTSEL W bits:; 0: W=; %00: -1; %01: +0; %10: +1; %11: +2; 1: W=; %00: +0; %01: +1; %10: +2; %11: +3; This is the differential coding for the first quarter of a wave. Start values for CUR_A and CUR_B are stored for MSCNT position 0 in START_SIN and START_SIN90.; ofs31, ofs30, …, ofs01, ofs00; …; ofs255, ofs254, …, ofs225, ofs224; reset default= sine wave table; ??????? +#define TMC5240_MSLUT_6_FIELD ((RegisterField) { TMC5240_MSLUT_6_MASK, TMC5240_MSLUT_6_SHIFT, TMC5240_MSLUT6, false}) +#define TMC5240_MSLUT_7_MASK 0xFFFFFFFF // MSLUT_7 // Each bit gives the difference between entry x and entry x+1 when combined with the cor­res­ponding MSLUTSEL W bits:; 0: W=; %00: -1; %01: +0; %10: +1; %11: +2; 1: W=; %00: +0; %01: +1; %10: +2; %11: +3; This is the differential coding for the first quarter of a wave. Start values for CUR_A and CUR_B are stored for MSCNT position 0 in START_SIN and START_SIN90.; ofs31, ofs30, …, ofs01, ofs00; …; ofs255, ofs254, …, ofs225, ofs224; reset default= sine wave table; ??????? +#define TMC5240_MSLUT_7_SHIFT 0 // Each bit gives the difference between entry x and entry x+1 when combined with the cor­res­ponding MSLUTSEL W bits:; 0: W=; %00: -1; %01: +0; %10: +1; %11: +2; 1: W=; %00: +0; %01: +1; %10: +2; %11: +3; This is the differential coding for the first quarter of a wave. Start values for CUR_A and CUR_B are stored for MSCNT position 0 in START_SIN and START_SIN90.; ofs31, ofs30, …, ofs01, ofs00; …; ofs255, ofs254, …, ofs225, ofs224; reset default= sine wave table; ??????? +#define TMC5240_MSLUT_7_FIELD ((RegisterField) { TMC5240_MSLUT_7_MASK, TMC5240_MSLUT_7_SHIFT, TMC5240_MSLUT7, false}) +#define TMC5240_W0_MASK 0x03 // MSLUTSEL // LUT width select from ofs00 to ofs(X1-1); Width control bit coding W0…W3:; %00:; MSLUT entry 0, 1 select: -1, +0; %01:; MSLUT entry 0, 1 select: +0, +1; %10:; MSLUT entry 0, 1 select: +1, +2; %11:; MSLUT entry 0, 1 select: +2, +3 +#define TMC5240_W0_SHIFT 0 // LUT width select from ofs00 to ofs(X1-1); Width control bit coding W0…W3:; %00:; MSLUT entry 0, 1 select: -1, +0; %01:; MSLUT entry 0, 1 select: +0, +1; %10:; MSLUT entry 0, 1 select: +1, +2; %11:; MSLUT entry 0, 1 select: +2, +3 +#define TMC5240_W0_FIELD ((RegisterField) { TMC5240_W0_MASK, TMC5240_W0_SHIFT, TMC5240_MSLUTSEL, false}) +#define TMC5240_W1_MASK 0x0C // MSLUTSEL // LUT width select from ofs(X1) to ofs(X2-1); Width control bit coding W0…W3:; %00:; MSLUT entry 0, 1 select: -1, +0; %01:; MSLUT entry 0, 1 select: +0, +1; %10:; MSLUT entry 0, 1 select: +1, +2; %11:; MSLUT entry 0, 1 select: +2, +3 +#define TMC5240_W1_SHIFT 2 // LUT width select from ofs(X1) to ofs(X2-1); Width control bit coding W0…W3:; %00:; MSLUT entry 0, 1 select: -1, +0; %01:; MSLUT entry 0, 1 select: +0, +1; %10:; MSLUT entry 0, 1 select: +1, +2; %11:; MSLUT entry 0, 1 select: +2, +3 +#define TMC5240_W1_FIELD ((RegisterField) { TMC5240_W1_MASK, TMC5240_W1_SHIFT, TMC5240_MSLUTSEL, false}) +#define TMC5240_W2_MASK 0x30 // MSLUTSEL // LUT width select from ofs(X2) to ofs(X3-1); Width control bit coding W0…W3:; %00:; MSLUT entry 0, 1 select: -1, +0; %01:; MSLUT entry 0, 1 select: +0, +1; %10:; MSLUT entry 0, 1 select: +1, +2; %11:; MSLUT entry 0, 1 select: +2, +3 +#define TMC5240_W2_SHIFT 4 // LUT width select from ofs(X2) to ofs(X3-1); Width control bit coding W0…W3:; %00:; MSLUT entry 0, 1 select: -1, +0; %01:; MSLUT entry 0, 1 select: +0, +1; %10:; MSLUT entry 0, 1 select: +1, +2; %11:; MSLUT entry 0, 1 select: +2, +3 +#define TMC5240_W2_FIELD ((RegisterField) { TMC5240_W2_MASK, TMC5240_W2_SHIFT, TMC5240_MSLUTSEL, false}) +#define TMC5240_W3_MASK 0xC0 // MSLUTSEL // LUT width select from ofs(X3) to ofs255; Width control bit coding W0…W3:; %00:; MSLUT entry 0, 1 select: -1, +0; %01:; MSLUT entry 0, 1 select: +0, +1; %10:; MSLUT entry 0, 1 select: +1, +2; %11:; MSLUT entry 0, 1 select: +2, +3 +#define TMC5240_W3_SHIFT 6 // LUT width select from ofs(X3) to ofs255; Width control bit coding W0…W3:; %00:; MSLUT entry 0, 1 select: -1, +0; %01:; MSLUT entry 0, 1 select: +0, +1; %10:; MSLUT entry 0, 1 select: +1, +2; %11:; MSLUT entry 0, 1 select: +2, +3 +#define TMC5240_W3_FIELD ((RegisterField) { TMC5240_W3_MASK, TMC5240_W3_SHIFT, TMC5240_MSLUTSEL, false}) +#define TMC5240_X1_MASK 0xFF00 // MSLUTSEL // LUT segment 1 start; The sine wave look up table can be divided into up to four segments using an individual step width control entry Wx. The segment borders are selected by X1, X2 and X3.; Segment 0 goes from 0 to X1-1.; Segment 1 goes from X1 to X2-1.; Segment 2 goes from X2 to X3-1.; Segment 3 goes from X3 to 255.; For defined response the values shall satisfy:; 0X1X2X3 +#define TMC5240_X1_SHIFT 8 // LUT segment 1 start; The sine wave look up table can be divided into up to four segments using an individual step width control entry Wx. The segment borders are selected by X1, X2 and X3.; Segment 0 goes from 0 to X1-1.; Segment 1 goes from X1 to X2-1.; Segment 2 goes from X2 to X3-1.; Segment 3 goes from X3 to 255.; For defined response the values shall satisfy:; 0X1X2X3 +#define TMC5240_X1_FIELD ((RegisterField) { TMC5240_X1_MASK, TMC5240_X1_SHIFT, TMC5240_MSLUTSEL, false}) +#define TMC5240_X2_MASK 0xFF0000 // MSLUTSEL // LUT segment 1 start; The sine wave look up table can be divided into up to four segments using an individual step width control entry Wx. The segment borders are selected by X1, X2 and X3.; Segment 0 goes from 0 to X1-1.; Segment 1 goes from X1 to X2-1.; Segment 2 goes from X2 to X3-1.; Segment 3 goes from X3 to 255.; For defined response the values shall satisfy:; 0X1X2X3 +#define TMC5240_X2_SHIFT 16 // LUT segment 1 start; The sine wave look up table can be divided into up to four segments using an individual step width control entry Wx. The segment borders are selected by X1, X2 and X3.; Segment 0 goes from 0 to X1-1.; Segment 1 goes from X1 to X2-1.; Segment 2 goes from X2 to X3-1.; Segment 3 goes from X3 to 255.; For defined response the values shall satisfy:; 0X1X2X3 +#define TMC5240_X2_FIELD ((RegisterField) { TMC5240_X2_MASK, TMC5240_X2_SHIFT, TMC5240_MSLUTSEL, false}) +#define TMC5240_X3_MASK 0xFF000000 // MSLUTSEL // LUT segment 1 start; The sine wave look up table can be divided into up to four segments using an individual step width control entry Wx. The segment borders are selected by X1, X2 and X3.; Segment 0 goes from 0 to X1-1.; Segment 1 goes from X1 to X2-1.; Segment 2 goes from X2 to X3-1.; Segment 3 goes from X3 to 255.; For defined response the values shall satisfy:; 0X1X2X3 +#define TMC5240_X3_SHIFT 24 // LUT segment 1 start; The sine wave look up table can be divided into up to four segments using an individual step width control entry Wx. The segment borders are selected by X1, X2 and X3.; Segment 0 goes from 0 to X1-1.; Segment 1 goes from X1 to X2-1.; Segment 2 goes from X2 to X3-1.; Segment 3 goes from X3 to 255.; For defined response the values shall satisfy:; 0X1X2X3 +#define TMC5240_X3_FIELD ((RegisterField) { TMC5240_X3_MASK, TMC5240_X3_SHIFT, TMC5240_MSLUTSEL, false}) +#define TMC5240_START_SIN_MASK 0xFF // MSLUTSTART // START_SIN gives the absolute value at microstep table entry 0. +#define TMC5240_START_SIN_SHIFT 0 // START_SIN gives the absolute value at microstep table entry 0. +#define TMC5240_START_SIN_FIELD ((RegisterField) { TMC5240_START_SIN_MASK, TMC5240_START_SIN_SHIFT, TMC5240_MSLUTSTART, false}) +#define TMC5240_START_SIN90_MASK 0xFF0000 // MSLUTSTART // START_SIN­90 gives the absolute value for cosine wave microstep table entry at MSCNT=0 (table position 256+OFFSET_SIN90). +#define TMC5240_START_SIN90_SHIFT 16 // START_SIN­90 gives the absolute value for cosine wave microstep table entry at MSCNT=0 (table position 256+OFFSET_SIN90). +#define TMC5240_START_SIN90_FIELD ((RegisterField) { TMC5240_START_SIN90_MASK, TMC5240_START_SIN90_SHIFT, TMC5240_MSLUTSTART, false}) +#define TMC5240_OFFSET_SIN90_MASK 0xFF000000 // MSLUTSTART // Signed offset for cosine wave +-127 microsteps. Adapt START_SIN90 to match the microstep wave table at position MSCNT=0 +#define TMC5240_OFFSET_SIN90_SHIFT 24 // Signed offset for cosine wave +-127 microsteps. Adapt START_SIN90 to match the microstep wave table at position MSCNT=0 +#define TMC5240_OFFSET_SIN90_FIELD ((RegisterField) { TMC5240_OFFSET_SIN90_MASK, TMC5240_OFFSET_SIN90_SHIFT, TMC5240_MSLUTSTART, false}) +#define TMC5240_MSCNT_MASK 0x3FF // MSCNT // Microstep counter. Indicates actual position in the microstep table for CUR_A. CUR_B uses an offset of 256 (2 phase motor).; Hint: Move to a position where MSCNT is zero before re-initializing MSLUTSTART or MSLUT and MSLUTSEL. +#define TMC5240_MSCNT_SHIFT 0 // Microstep counter. Indicates actual position in the microstep table for CUR_A. CUR_B uses an offset of 256 (2 phase motor).; Hint: Move to a position where MSCNT is zero before re-initializing MSLUTSTART or MSLUT and MSLUTSEL. +#define TMC5240_MSCNT_FIELD ((RegisterField) { TMC5240_MSCNT_MASK, TMC5240_MSCNT_SHIFT, TMC5240_MSCNT, false}) +#define TMC5240_CUR_B_MASK 0x1FF // MSCURACT // Actual microstep current for motor phase B (sine wave) as read from MSLUT (not scaled by current) +#define TMC5240_CUR_B_SHIFT 0 // Actual microstep current for motor phase B (sine wave) as read from MSLUT (not scaled by current) +#define TMC5240_CUR_B_FIELD ((RegisterField) { TMC5240_CUR_B_MASK, TMC5240_CUR_B_SHIFT, TMC5240_MSCURACT, true}) +#define TMC5240_CUR_A_MASK 0x1FF0000 // MSCURACT // Actual microstep current for motor phase A (co-sine wave) as read from MSLUT (not scaled by current) +#define TMC5240_CUR_A_SHIFT 16 // Actual microstep current for motor phase A (co-sine wave) as read from MSLUT (not scaled by current) +#define TMC5240_CUR_A_FIELD ((RegisterField) { TMC5240_CUR_A_MASK, TMC5240_CUR_A_SHIFT, TMC5240_MSCURACT, true}) +#define TMC5240_TOFF_MASK 0x0F // CHOPCONF // TOFF off time and driver enable; Off time setting controls duration of slow decay phase; NCLK= 24 + 32*TOFF; %0000: Driver disable, all bridges off; %0001: 1 – use only with TBL = 2; %0010 … %1111: 2 … 15 +#define TMC5240_TOFF_SHIFT 0 // TOFF off time and driver enable; Off time setting controls duration of slow decay phase; NCLK= 24 + 32*TOFF; %0000: Driver disable, all bridges off; %0001: 1 – use only with TBL = 2; %0010 … %1111: 2 … 15 +#define TMC5240_TOFF_FIELD ((RegisterField) { TMC5240_TOFF_MASK, TMC5240_TOFF_SHIFT, TMC5240_CHOPCONF, false}) +#define TMC5240_TFD_ALL_MASK 0x70 // CHOPCONF // with chm=0; HSTRT; hysteresis start value added to HEND; %000 … %111:; Add 1, 2, …, 8 to hysteresis low value HEND; (1/512 of this setting adds to current setting); Attention: Effective HEND+HSTRT = 16.; Hint: Hysteresis decrement is done each 16 clocks; with chm=1; TFD [2..0]; fast decay time setting; Fast decay time setting (MSB:; fd3):; %0000 … %1111:; Fast decay time setting TFD with; NCLK= 32*TFD (%0000: slow decay only) +#define TMC5240_TFD_ALL_SHIFT 4 // with chm=0; HSTRT; hysteresis start value added to HEND; %000 … %111:; Add 1, 2, …, 8 to hysteresis low value HEND; (1/512 of this setting adds to current setting); Attention: Effective HEND+HSTRT = 16.; Hint: Hysteresis decrement is done each 16 clocks; with chm=1; TFD [2..0]; fast decay time setting; Fast decay time setting (MSB:; fd3):; %0000 … %1111:; Fast decay time setting TFD with; NCLK= 32*TFD (%0000: slow decay only) +#define TMC5240_TFD_ALL_FIELD ((RegisterField) { TMC5240_TFD_ALL_MASK, TMC5240_TFD_ALL_SHIFT, TMC5240_CHOPCONF, false}) +#define TMC5240_HEND_OFFSET_MASK 0x780 // CHOPCONF // with chm=0; HEND; hysteresis low value; %0000 … %1111:; Hysteresis is -3, -2, -1, 0, 1, …, 12; (1/512 of this setting adds to current setting); This is the hysteresis value which becomes used for the hysteresis chopper.; with chm=1; OFFSET; sine wave offset; %0000 … %1111:; Offset is -3, -2, -1, 0, 1, …, 12; This is the sine wave offset and 1/512 of the value becomes added to the absolute value of each sine wave entry. +#define TMC5240_HEND_OFFSET_SHIFT 7 // with chm=0; HEND; hysteresis low value; %0000 … %1111:; Hysteresis is -3, -2, -1, 0, 1, …, 12; (1/512 of this setting adds to current setting); This is the hysteresis value which becomes used for the hysteresis chopper.; with chm=1; OFFSET; sine wave offset; %0000 … %1111:; Offset is -3, -2, -1, 0, 1, …, 12; This is the sine wave offset and 1/512 of the value becomes added to the absolute value of each sine wave entry. +#define TMC5240_HEND_OFFSET_FIELD ((RegisterField) { TMC5240_HEND_OFFSET_MASK, TMC5240_HEND_OFFSET_SHIFT, TMC5240_CHOPCONF, false}) +#define TMC5240_FD3_MASK 0x800 // CHOPCONF // TFD[3]; with chm=1:; MSB of fast decay time setting TFD +#define TMC5240_FD3_SHIFT 11 // TFD[3]; with chm=1:; MSB of fast decay time setting TFD +#define TMC5240_FD3_FIELD ((RegisterField) { TMC5240_FD3_MASK, TMC5240_FD3_SHIFT, TMC5240_CHOPCONF, false}) +#define TMC5240_DISFDCC_MASK 0x1000 // CHOPCONF // fast decay mode; with chm=1:; disfdcc=1 disables current comparator usage for termi­nation of the fast decay cycle +#define TMC5240_DISFDCC_SHIFT 12 // fast decay mode; with chm=1:; disfdcc=1 disables current comparator usage for termi­nation of the fast decay cycle +#define TMC5240_DISFDCC_FIELD ((RegisterField) { TMC5240_DISFDCC_MASK, TMC5240_DISFDCC_SHIFT, TMC5240_CHOPCONF, false}) +#define TMC5240_CHM_MASK 0x4000 // CHOPCONF // chopper mode +#define TMC5240_CHM_SHIFT 14 // chopper mode +#define TMC5240_CHM_FIELD ((RegisterField) { TMC5240_CHM_MASK, TMC5240_CHM_SHIFT, TMC5240_CHOPCONF, false}) +#define TMC5240_TBL_MASK 0x18000 // CHOPCONF // TBL / blank time select; %00 … %11:; Set comparator blank time to 16, 24, 36 or 54 clocks; Hint: %01 or %10 is recommended for most applications; (Reset Default: OTP %01 or %10) +#define TMC5240_TBL_SHIFT 15 // TBL / blank time select; %00 … %11:; Set comparator blank time to 16, 24, 36 or 54 clocks; Hint: %01 or %10 is recommended for most applications; (Reset Default: OTP %01 or %10) +#define TMC5240_TBL_FIELD ((RegisterField) { TMC5240_TBL_MASK, TMC5240_TBL_SHIFT, TMC5240_CHOPCONF, false}) +#define TMC5240_VHIGHFS_MASK 0x40000 // CHOPCONF // high velocity fullstep selection; This bit enables switching to fullstep, when VHIGH is exceeded. Switching takes place only at 45° position. The fullstep target current uses the current value from the microstep table at the 45° position. +#define TMC5240_VHIGHFS_SHIFT 18 // high velocity fullstep selection; This bit enables switching to fullstep, when VHIGH is exceeded. Switching takes place only at 45° position. The fullstep target current uses the current value from the microstep table at the 45° position. +#define TMC5240_VHIGHFS_FIELD ((RegisterField) { TMC5240_VHIGHFS_MASK, TMC5240_VHIGHFS_SHIFT, TMC5240_CHOPCONF, false}) +#define TMC5240_VHIGHCHM_MASK 0x80000 // CHOPCONF // high velocity chopper mode; This bit enables switching to chm=1 and fd=0, when VHIGH is exceeded. This way, a higher velocity can be achieved. Can be combined with vhighfs=1. If set, the TOFF setting automatically becomes doubled during high velocity operation in order to avoid doubling of the chopper frequency. +#define TMC5240_VHIGHCHM_SHIFT 19 // high velocity chopper mode; This bit enables switching to chm=1 and fd=0, when VHIGH is exceeded. This way, a higher velocity can be achieved. Can be combined with vhighfs=1. If set, the TOFF setting automatically becomes doubled during high velocity operation in order to avoid doubling of the chopper frequency. +#define TMC5240_VHIGHCHM_FIELD ((RegisterField) { TMC5240_VHIGHCHM_MASK, TMC5240_VHIGHCHM_SHIFT, TMC5240_CHOPCONF, false}) +#define TMC5240_TPFD_MASK 0xF00000 // CHOPCONF // passive fast decay time; TPFD allows dampening of motor mid-range resonances.; Passive fast decay time setting controls duration of the fast decay phase inserted after bridge polarity change; NCLK= 128*TPFD; %0000: Disable; %0001 … %1111: 1 … 15 +#define TMC5240_TPFD_SHIFT 20 // passive fast decay time; TPFD allows dampening of motor mid-range resonances.; Passive fast decay time setting controls duration of the fast decay phase inserted after bridge polarity change; NCLK= 128*TPFD; %0000: Disable; %0001 … %1111: 1 … 15 +#define TMC5240_TPFD_FIELD ((RegisterField) { TMC5240_TPFD_MASK, TMC5240_TPFD_SHIFT, TMC5240_CHOPCONF, false}) +#define TMC5240_MRES_MASK 0xF000000 // CHOPCONF // micro step resolution selection; %0000:; Native 256 microstep setting. Normally use this setting with the internal motion controller.; %0001 … %1000:; 128, 64, 32, 16, 8, 4, 2, FULLSTEP; Reduced microstep resolution esp. for STEP/DIR operation.; The resolution gives the number of microstep entries per sine quarter wave.; The driver automatically uses microstep positions which result in a symmetrical wave, when choosing a lower microstep resolution.; step width=2^MRES [microsteps] +#define TMC5240_MRES_SHIFT 24 // micro step resolution selection; %0000:; Native 256 microstep setting. Normally use this setting with the internal motion controller.; %0001 … %1000:; 128, 64, 32, 16, 8, 4, 2, FULLSTEP; Reduced microstep resolution esp. for STEP/DIR operation.; The resolution gives the number of microstep entries per sine quarter wave.; The driver automatically uses microstep positions which result in a symmetrical wave, when choosing a lower microstep resolution.; step width=2^MRES [microsteps] +#define TMC5240_MRES_FIELD ((RegisterField) { TMC5240_MRES_MASK, TMC5240_MRES_SHIFT, TMC5240_CHOPCONF, false}) +#define TMC5240_INTPOL_MASK 0x10000000 // CHOPCONF // interpolation to 256 microsteps +#define TMC5240_INTPOL_SHIFT 28 // interpolation to 256 microsteps +#define TMC5240_INTPOL_FIELD ((RegisterField) { TMC5240_INTPOL_MASK, TMC5240_INTPOL_SHIFT, TMC5240_CHOPCONF, false}) +#define TMC5240_DEDGE_MASK 0x20000000 // CHOPCONF // enable double edge step pulses +#define TMC5240_DEDGE_SHIFT 29 // enable double edge step pulses +#define TMC5240_DEDGE_FIELD ((RegisterField) { TMC5240_DEDGE_MASK, TMC5240_DEDGE_SHIFT, TMC5240_CHOPCONF, false}) +#define TMC5240_DISS2G_MASK 0x40000000 // CHOPCONF // short to GND protection disable +#define TMC5240_DISS2G_SHIFT 30 // short to GND protection disable +#define TMC5240_DISS2G_FIELD ((RegisterField) { TMC5240_DISS2G_MASK, TMC5240_DISS2G_SHIFT, TMC5240_CHOPCONF, false}) +#define TMC5240_DISS2VS_MASK 0x80000000 // CHOPCONF // short to supply protection disable +#define TMC5240_DISS2VS_SHIFT 31 // short to supply protection disable +#define TMC5240_DISS2VS_FIELD ((RegisterField) { TMC5240_DISS2VS_MASK, TMC5240_DISS2VS_SHIFT, TMC5240_CHOPCONF, false}) +#define TMC5240_SEMIN_MASK 0x0F // COOLCONF // minimum StallGuard2 value for smart current control and; smart current enable; If the StallGuard2 result falls below SEMIN*32, the motor current becomes increased to reduce motor load angle.; %0000: smart current control CoolStep off; %0001 … %1111: 1 … 15 +#define TMC5240_SEMIN_SHIFT 0 // minimum StallGuard2 value for smart current control and; smart current enable; If the StallGuard2 result falls below SEMIN*32, the motor current becomes increased to reduce motor load angle.; %0000: smart current control CoolStep off; %0001 … %1111: 1 … 15 +#define TMC5240_SEMIN_FIELD ((RegisterField) { TMC5240_SEMIN_MASK, TMC5240_SEMIN_SHIFT, TMC5240_COOLCONF, false}) +#define TMC5240_SEUP_MASK 0x60 // COOLCONF // current up step width; Current increment steps per measured StallGuard2 value; %00 … %11: 1, 2, 4, 8 +#define TMC5240_SEUP_SHIFT 5 // current up step width; Current increment steps per measured StallGuard2 value; %00 … %11: 1, 2, 4, 8 +#define TMC5240_SEUP_FIELD ((RegisterField) { TMC5240_SEUP_MASK, TMC5240_SEUP_SHIFT, TMC5240_COOLCONF, false}) +#define TMC5240_SEMAX_MASK 0xF00 // COOLCONF // StallGuard2 hysteresis value for smart current control; If the StallGuard2 result is equal to or above (SEMIN+SEMAX+1)*32, the motor current becomes decreased to save energy.; %0000 … %1111: 0 … 15 +#define TMC5240_SEMAX_SHIFT 8 // StallGuard2 hysteresis value for smart current control; If the StallGuard2 result is equal to or above (SEMIN+SEMAX+1)*32, the motor current becomes decreased to save energy.; %0000 … %1111: 0 … 15 +#define TMC5240_SEMAX_FIELD ((RegisterField) { TMC5240_SEMAX_MASK, TMC5240_SEMAX_SHIFT, TMC5240_COOLCONF, false}) +#define TMC5240_SEDN_MASK 0x6000 // COOLCONF // current down step speed; %00: For each 32 StallGuard2 values decrease by one; %01: For each 8 StallGuard2 values decrease by one; %10: For each 2 StallGuard2 values decrease by one; %11: For each StallGuard2 value decrease by one +#define TMC5240_SEDN_SHIFT 13 // current down step speed; %00: For each 32 StallGuard2 values decrease by one; %01: For each 8 StallGuard2 values decrease by one; %10: For each 2 StallGuard2 values decrease by one; %11: For each StallGuard2 value decrease by one +#define TMC5240_SEDN_FIELD ((RegisterField) { TMC5240_SEDN_MASK, TMC5240_SEDN_SHIFT, TMC5240_COOLCONF, false}) +#define TMC5240_SEIMIN_MASK 0x8000 // COOLCONF // minimum current for smart current control +#define TMC5240_SEIMIN_SHIFT 15 // minimum current for smart current control +#define TMC5240_SEIMIN_FIELD ((RegisterField) { TMC5240_SEIMIN_MASK, TMC5240_SEIMIN_SHIFT, TMC5240_COOLCONF, false}) +#define TMC5240_SGT_MASK 0x7F0000 // COOLCONF // StallGuard2 threshold value; This signed value controls StallGuard2 level for stall output and sets the optimum measurement range for readout. A lower value gives a higher sensitivity. Zero is the starting value working with most motors.; -64 to +63:; A higher value makes StallGuard2 less sensi­tive and requires more torque to indicate a stall. +#define TMC5240_SGT_SHIFT 16 // StallGuard2 threshold value; This signed value controls StallGuard2 level for stall output and sets the optimum measurement range for readout. A lower value gives a higher sensitivity. Zero is the starting value working with most motors.; -64 to +63:; A higher value makes StallGuard2 less sensi­tive and requires more torque to indicate a stall. +#define TMC5240_SGT_FIELD ((RegisterField) { TMC5240_SGT_MASK, TMC5240_SGT_SHIFT, TMC5240_COOLCONF, false}) +#define TMC5240_SFILT_MASK 0x1000000 // COOLCONF // StallGuard2 and StallGuard4 filter enable +#define TMC5240_SFILT_SHIFT 24 // StallGuard2 and StallGuard4 filter enable +#define TMC5240_SFILT_FIELD ((RegisterField) { TMC5240_SFILT_MASK, TMC5240_SFILT_SHIFT, TMC5240_COOLCONF, false}) +#define TMC5240_DC_TIME_MASK 0x3FF // DCCTRL // Upper PWM on time limit for commutation (DC_TIME * 1/fCLK). Set slightly above effective blank time TBL. +#define TMC5240_DC_TIME_SHIFT 0 // Upper PWM on time limit for commutation (DC_TIME * 1/fCLK). Set slightly above effective blank time TBL. +#define TMC5240_DC_TIME_FIELD ((RegisterField) { TMC5240_DC_TIME_MASK, TMC5240_DC_TIME_SHIFT, TMC5240_DCCTRL, false}) +#define TMC5240_DC_SG_MASK 0xFF0000 // DCCTRL // Max. PWM on time for step loss detection using DcStep StallGuard2 in DcStep mode. (DC_SG * 16/fCLK); Set slightly higher than DC_TIME/16; 0=disable +#define TMC5240_DC_SG_SHIFT 16 // Max. PWM on time for step loss detection using DcStep StallGuard2 in DcStep mode. (DC_SG * 16/fCLK); Set slightly higher than DC_TIME/16; 0=disable +#define TMC5240_DC_SG_FIELD ((RegisterField) { TMC5240_DC_SG_MASK, TMC5240_DC_SG_SHIFT, TMC5240_DCCTRL, false}) +#define TMC5240_SG_RESULT_MASK 0x3FF // DRV_STATUS // StallGuard2 result respectively StallGuard4 result (depending on actual chopper mode) resp. PWM on time for coil A in stand still with SpreadCycle for motor temperature detection.; Mechanical load measurement:; The StallGuard2/4 result gives a means to measure mecha­nical motor load. A higher value means lower mecha­nical load. For StallGuard2, a value of 0 signals highest load. With opti­mum SGT setting, this is an indicator for a motor stall. The stall detection compares SG_RESULT to 0 in order to detect a stall. SG_RESULT is used as a base for CoolStep operation, by comparing it to a pro­grammable upper and a lower limit. It is not applicable in StealthChop mode.; StallGuard2 works best with microstep operation or DcStep.; Temperature measurement during SpreadCycle mode:; In standstill, no StallGuard2 result can be obtained. SG_RESULT shows the chopper on-time for motor coil A instead. Move the motor to a determined micro­step position at a certain current setting to get a rough estimation of motor temperature by a reading the chopper on-time. As the motor heats up, its coil resistance rises and the chopper on-time increases. For StallGuard4 specifics, please refer SG4_RESULT. +#define TMC5240_SG_RESULT_SHIFT 0 // StallGuard2 result respectively StallGuard4 result (depending on actual chopper mode) resp. PWM on time for coil A in stand still with SpreadCycle for motor temperature detection.; Mechanical load measurement:; The StallGuard2/4 result gives a means to measure mecha­nical motor load. A higher value means lower mecha­nical load. For StallGuard2, a value of 0 signals highest load. With opti­mum SGT setting, this is an indicator for a motor stall. The stall detection compares SG_RESULT to 0 in order to detect a stall. SG_RESULT is used as a base for CoolStep operation, by comparing it to a pro­grammable upper and a lower limit. It is not applicable in StealthChop mode.; StallGuard2 works best with microstep operation or DcStep.; Temperature measurement during SpreadCycle mode:; In standstill, no StallGuard2 result can be obtained. SG_RESULT shows the chopper on-time for motor coil A instead. Move the motor to a determined micro­step position at a certain current setting to get a rough estimation of motor temperature by a reading the chopper on-time. As the motor heats up, its coil resistance rises and the chopper on-time increases. For StallGuard4 specifics, please refer SG4_RESULT. +#define TMC5240_SG_RESULT_FIELD ((RegisterField) { TMC5240_SG_RESULT_MASK, TMC5240_SG_RESULT_SHIFT, TMC5240_DRVSTATUS, false}) +#define TMC5240_S2VSA_MASK 0x1000 // DRV_STATUS // short to supply indicator phase A +#define TMC5240_S2VSA_SHIFT 12 // short to supply indicator phase A +#define TMC5240_S2VSA_FIELD ((RegisterField) { TMC5240_S2VSA_MASK, TMC5240_S2VSA_SHIFT, TMC5240_DRVSTATUS, false}) +#define TMC5240_S2VSB_MASK 0x2000 // DRV_STATUS // short to supply indicator phase B +#define TMC5240_S2VSB_SHIFT 13 // short to supply indicator phase B +#define TMC5240_S2VSB_FIELD ((RegisterField) { TMC5240_S2VSB_MASK, TMC5240_S2VSB_SHIFT, TMC5240_DRVSTATUS, false}) +#define TMC5240_STEALTH_MASK 0x4000 // DRV_STATUS // StealthChop indicator +#define TMC5240_STEALTH_SHIFT 14 // StealthChop indicator +#define TMC5240_STEALTH_FIELD ((RegisterField) { TMC5240_STEALTH_MASK, TMC5240_STEALTH_SHIFT, TMC5240_DRVSTATUS, false}) +#define TMC5240_FSACTIVE_MASK 0x8000 // DRV_STATUS // full step active indicator +#define TMC5240_FSACTIVE_SHIFT 15 // full step active indicator +#define TMC5240_FSACTIVE_FIELD ((RegisterField) { TMC5240_FSACTIVE_MASK, TMC5240_FSACTIVE_SHIFT, TMC5240_DRVSTATUS, false}) +#define TMC5240_CS_ACTUAL_MASK 0x1F0000 // DRV_STATUS // actual motor current / smart energy current; Actual current control scaling, for monitoring smart energy current scaling controlled via settings in register COOLCONF, or for monitoring the function of the automatic current scaling +#define TMC5240_CS_ACTUAL_SHIFT 16 // actual motor current / smart energy current; Actual current control scaling, for monitoring smart energy current scaling controlled via settings in register COOLCONF, or for monitoring the function of the automatic current scaling +#define TMC5240_CS_ACTUAL_FIELD ((RegisterField) { TMC5240_CS_ACTUAL_MASK, TMC5240_CS_ACTUAL_SHIFT, TMC5240_DRVSTATUS, false}) +#define TMC5240_STALLGUARD_MASK 0x1000000 // DRV_STATUS // StallGuard2/StallGuard4 status +#define TMC5240_STALLGUARD_SHIFT 24 // StallGuard2/StallGuard4 status +#define TMC5240_STALLGUARD_FIELD ((RegisterField) { TMC5240_STALLGUARD_MASK, TMC5240_STALLGUARD_SHIFT, TMC5240_DRVSTATUS, false}) +#define TMC5240_OT_MASK 0x2000000 // DRV_STATUS // overtemperature flag +#define TMC5240_OT_SHIFT 25 // overtemperature flag +#define TMC5240_OT_FIELD ((RegisterField) { TMC5240_OT_MASK, TMC5240_OT_SHIFT, TMC5240_DRVSTATUS, false}) +#define TMC5240_OTPW_MASK 0x4000000 // DRV_STATUS // overtemperature pre-warning flag +#define TMC5240_OTPW_SHIFT 26 // overtemperature pre-warning flag +#define TMC5240_OTPW_FIELD ((RegisterField) { TMC5240_OTPW_MASK, TMC5240_OTPW_SHIFT, TMC5240_DRVSTATUS, false}) +#define TMC5240_S2GA_MASK 0x8000000 // DRV_STATUS // short to ground indicator phase A +#define TMC5240_S2GA_SHIFT 27 // short to ground indicator phase A +#define TMC5240_S2GA_FIELD ((RegisterField) { TMC5240_S2GA_MASK, TMC5240_S2GA_SHIFT, TMC5240_DRVSTATUS, false}) +#define TMC5240_S2GB_MASK 0x10000000 // DRV_STATUS // short to ground indicator phase B +#define TMC5240_S2GB_SHIFT 28 // short to ground indicator phase B +#define TMC5240_S2GB_FIELD ((RegisterField) { TMC5240_S2GB_MASK, TMC5240_S2GB_SHIFT, TMC5240_DRVSTATUS, false}) +#define TMC5240_OLA_MASK 0x20000000 // DRV_STATUS // open load indicator phase A +#define TMC5240_OLA_SHIFT 29 // open load indicator phase A +#define TMC5240_OLA_FIELD ((RegisterField) { TMC5240_OLA_MASK, TMC5240_OLA_SHIFT, TMC5240_DRVSTATUS, false}) +#define TMC5240_OLB_MASK 0x40000000 // DRV_STATUS // open load indicator phase B +#define TMC5240_OLB_SHIFT 30 // open load indicator phase B +#define TMC5240_OLB_FIELD ((RegisterField) { TMC5240_OLB_MASK, TMC5240_OLB_SHIFT, TMC5240_DRVSTATUS, false}) +#define TMC5240_STST_MASK 0x80000000 // DRV_STATUS // standstill indicator; This flag indicates motor stand still in each operation mode. This occurs 2^20 clocks after the last step pulse. +#define TMC5240_STST_SHIFT 31 // standstill indicator; This flag indicates motor stand still in each operation mode. This occurs 2^20 clocks after the last step pulse. +#define TMC5240_STST_FIELD ((RegisterField) { TMC5240_STST_MASK, TMC5240_STST_SHIFT, TMC5240_DRVSTATUS, false}) +#define TMC5240_PWM_OFS_MASK 0xFF // PWMCONF // User defined PWM amplitude offset (0-255) related to full motor current (CS_ACTUAL=31) in stand still.; (Reset default=30); Use PWM_OFS as initial value for automatic scaling to speed up the automatic tuning process. To do this, set PWM_OFS to the determined, application specific value, with pwm_autoscale=0. Only afterwards, set pwm_autoscale=1. Enable StealthChop when finished.; PWM_OFS = 0 will disable scaling down motor current below a motor specific lower measurement threshold. This setting should only be used under certain conditions, i.e. when the power supply voltage can vary up and down by a factor of two or more. It prevents the motor going out of regulation, but it also prevents power down below the regulation limit.; PWM_OFS > 0 allows automatic scaling to low PWM duty cycles even below the lower regulation threshold. This allows low (standstill) current settings based on the actual (hold) current scale (register IHOLD_IRUN). +#define TMC5240_PWM_OFS_SHIFT 0 // User defined PWM amplitude offset (0-255) related to full motor current (CS_ACTUAL=31) in stand still.; (Reset default=30); Use PWM_OFS as initial value for automatic scaling to speed up the automatic tuning process. To do this, set PWM_OFS to the determined, application specific value, with pwm_autoscale=0. Only afterwards, set pwm_autoscale=1. Enable StealthChop when finished.; PWM_OFS = 0 will disable scaling down motor current below a motor specific lower measurement threshold. This setting should only be used under certain conditions, i.e. when the power supply voltage can vary up and down by a factor of two or more. It prevents the motor going out of regulation, but it also prevents power down below the regulation limit.; PWM_OFS > 0 allows automatic scaling to low PWM duty cycles even below the lower regulation threshold. This allows low (standstill) current settings based on the actual (hold) current scale (register IHOLD_IRUN). +#define TMC5240_PWM_OFS_FIELD ((RegisterField) { TMC5240_PWM_OFS_MASK, TMC5240_PWM_OFS_SHIFT, TMC5240_PWMCONF, false}) +#define TMC5240_PWM_GRAD_MASK 0xFF00 // PWMCONF // Velocity dependent gradient for PWM amplitude:; PWM_GRAD * 256 / TSTEP; This value is added to PWM_OFS to compensate for the velocity-dependent motor back-EMF.; Use PWM_GRAD as initial value for automatic scaling to speed up the automatic tuning process. To do this, set PWM_GRAD to the determined, application specific value, with pwm_autoscale=0. Only afterwards, set pwm_autoscale=1. Enable StealthChop when finished.; Hint:; After initial tuning, the required initial value can be read out from PWM_GRAD_AUTO. +#define TMC5240_PWM_GRAD_SHIFT 8 // Velocity dependent gradient for PWM amplitude:; PWM_GRAD * 256 / TSTEP; This value is added to PWM_OFS to compensate for the velocity-dependent motor back-EMF.; Use PWM_GRAD as initial value for automatic scaling to speed up the automatic tuning process. To do this, set PWM_GRAD to the determined, application specific value, with pwm_autoscale=0. Only afterwards, set pwm_autoscale=1. Enable StealthChop when finished.; Hint:; After initial tuning, the required initial value can be read out from PWM_GRAD_AUTO. +#define TMC5240_PWM_GRAD_FIELD ((RegisterField) { TMC5240_PWM_GRAD_MASK, TMC5240_PWM_GRAD_SHIFT, TMC5240_PWMCONF, false}) +#define TMC5240_PWM_FREQ_MASK 0x30000 // PWMCONF // PWM frequency selection:; %00:; fPWM=2/1024 fCLK (Reset default); %01:; fPWM=2/683 fCLK; %10:; fPWM=2/512 fCLK; %11:; fPWM=2/410 fCLK +#define TMC5240_PWM_FREQ_SHIFT 16 // PWM frequency selection:; %00:; fPWM=2/1024 fCLK (Reset default); %01:; fPWM=2/683 fCLK; %10:; fPWM=2/512 fCLK; %11:; fPWM=2/410 fCLK +#define TMC5240_PWM_FREQ_FIELD ((RegisterField) { TMC5240_PWM_FREQ_MASK, TMC5240_PWM_FREQ_SHIFT, TMC5240_PWMCONF, false}) +#define TMC5240_PWM_AUTOSCALE_MASK 0x40000 // PWMCONF // PWM automatic amplitude scaling +#define TMC5240_PWM_AUTOSCALE_SHIFT 18 // PWM automatic amplitude scaling +#define TMC5240_PWM_AUTOSCALE_FIELD ((RegisterField) { TMC5240_PWM_AUTOSCALE_MASK, TMC5240_PWM_AUTOSCALE_SHIFT, TMC5240_PWMCONF, false}) +#define TMC5240_PWM_AUTOGRAD_MASK 0x80000 // PWMCONF // PWM automatic gradient adaptation +#define TMC5240_PWM_AUTOGRAD_SHIFT 19 // PWM automatic gradient adaptation +#define TMC5240_PWM_AUTOGRAD_FIELD ((RegisterField) { TMC5240_PWM_AUTOGRAD_MASK, TMC5240_PWM_AUTOGRAD_SHIFT, TMC5240_PWMCONF, false}) +#define TMC5240_FREEWHEEL_MASK 0x300000 // PWMCONF // Allows different standstill modes; Stand still option when motor current setting is zero (I_HOLD=0).; %00:; Normal operation; %01:; Freewheeling; %10:; Coil shorted using LS drivers; %11:; Coil shorted using HS drivers +#define TMC5240_FREEWHEEL_SHIFT 20 // Allows different standstill modes; Stand still option when motor current setting is zero (I_HOLD=0).; %00:; Normal operation; %01:; Freewheeling; %10:; Coil shorted using LS drivers; %11:; Coil shorted using HS drivers +#define TMC5240_FREEWHEEL_FIELD ((RegisterField) { TMC5240_FREEWHEEL_MASK, TMC5240_FREEWHEEL_SHIFT, TMC5240_PWMCONF, false}) +#define TMC5240_PWM_MEAS_SD_ENABLE_MASK 0x400000 // PWMCONF // Default=0; 1: Uses slow decay phases on low side to measure the motor current to reduce the lower current limit. +#define TMC5240_PWM_MEAS_SD_ENABLE_SHIFT 22 // Default=0; 1: Uses slow decay phases on low side to measure the motor current to reduce the lower current limit. +#define TMC5240_PWM_MEAS_SD_ENABLE_FIELD ((RegisterField) { TMC5240_PWM_MEAS_SD_ENABLE_MASK, TMC5240_PWM_MEAS_SD_ENABLE_SHIFT, TMC5240_PWMCONF, false}) +#define TMC5240_PWM_DIS_REG_STST_MASK 0x800000 // PWMCONF // 1= Disable current regulation when motor is in standstill and current is reduced (less than IRUN). This option eliminates any regulation noise during standstill. +#define TMC5240_PWM_DIS_REG_STST_SHIFT 23 // 1= Disable current regulation when motor is in standstill and current is reduced (less than IRUN). This option eliminates any regulation noise during standstill. +#define TMC5240_PWM_DIS_REG_STST_FIELD ((RegisterField) { TMC5240_PWM_DIS_REG_STST_MASK, TMC5240_PWM_DIS_REG_STST_SHIFT, TMC5240_PWMCONF, false}) +#define TMC5240_PWM_REG_MASK 0xF000000 // PWMCONF // Regulation loop gradient; User defined maximum PWM amplitude change per half wave when using pwm_autoscale=1. (1…15):; 1: 0.5 increments (slowest regulation); 2: 1 increment; 3: 1.5 increments; 4: 2 increments (Reset default)); …; 8: 4 increments; ...; 15: 7.5 increments (fastest regulation) +#define TMC5240_PWM_REG_SHIFT 24 // Regulation loop gradient; User defined maximum PWM amplitude change per half wave when using pwm_autoscale=1. (1…15):; 1: 0.5 increments (slowest regulation); 2: 1 increment; 3: 1.5 increments; 4: 2 increments (Reset default)); …; 8: 4 increments; ...; 15: 7.5 increments (fastest regulation) +#define TMC5240_PWM_REG_FIELD ((RegisterField) { TMC5240_PWM_REG_MASK, TMC5240_PWM_REG_SHIFT, TMC5240_PWMCONF, false}) +#define TMC5240_PWM_LIM_MASK 0xF0000000 // PWMCONF // PWM automatic scale amplitude limit when switching on; Limit for PWM_SCALE_AUTO when switching back from SpreadCycle to StealthChop. This value defines the upper limit for bits 7 to 4 of the automatic current control when switching back. It can be set to reduce the current jerk during mode change back to StealthChop.; It does not limit PWM_GRAD or PWM_GRAD_AUTO offset.; (Default = 12) +#define TMC5240_PWM_LIM_SHIFT 28 // PWM automatic scale amplitude limit when switching on; Limit for PWM_SCALE_AUTO when switching back from SpreadCycle to StealthChop. This value defines the upper limit for bits 7 to 4 of the automatic current control when switching back. It can be set to reduce the current jerk during mode change back to StealthChop.; It does not limit PWM_GRAD or PWM_GRAD_AUTO offset.; (Default = 12) +#define TMC5240_PWM_LIM_FIELD ((RegisterField) { TMC5240_PWM_LIM_MASK, TMC5240_PWM_LIM_SHIFT, TMC5240_PWMCONF, false}) +#define TMC5240_PWM_SCALE_SUM_MASK 0x3FF // PWM_SCALE // Bits: 9...0: [0...1023]PWM_SCALE_SUM: Actual PWM duty cycle. This value is used for scaling the values CUR_A and CUR_B read from the sine wave table. 1023: maximum duty cycle. This value is extended by two bits [1,0] for higher precision of duty cycle read out. Bits 9..2 correspond to the 8 bit values in other PWM duty cycle related registers. +#define TMC5240_PWM_SCALE_SUM_SHIFT 0 // Bits: 9...0: [0...1023]PWM_SCALE_SUM: Actual PWM duty cycle. This value is used for scaling the values CUR_A and CUR_B read from the sine wave table. 1023: maximum duty cycle. This value is extended by two bits [1,0] for higher precision of duty cycle read out. Bits 9..2 correspond to the 8 bit values in other PWM duty cycle related registers. +#define TMC5240_PWM_SCALE_SUM_FIELD ((RegisterField) { TMC5240_PWM_SCALE_SUM_MASK, TMC5240_PWM_SCALE_SUM_SHIFT, TMC5240_PWM_SCALE, false}) +#define TMC5240_PWM_SCALE_AUTO_MASK 0x1FF0000 // PWM_SCALE // PWM_SCALE_AUTO +#define TMC5240_PWM_SCALE_AUTO_SHIFT 16 // PWM_SCALE_AUTO +#define TMC5240_PWM_SCALE_AUTO_FIELD ((RegisterField) { TMC5240_PWM_SCALE_AUTO_MASK, TMC5240_PWM_SCALE_AUTO_SHIFT, TMC5240_PWM_SCALE, false}) +#define TMC5240_PWM_OFS_AUTO_MASK 0xFF // PWM_AUTO // Automatically determined offset value +#define TMC5240_PWM_OFS_AUTO_SHIFT 0 // Automatically determined offset value +#define TMC5240_PWM_OFS_AUTO_FIELD ((RegisterField) { TMC5240_PWM_OFS_AUTO_MASK, TMC5240_PWM_OFS_AUTO_SHIFT, TMC5240_PWM_AUTO, false}) +#define TMC5240_PWM_GRAD_AUTO_MASK 0xFF0000 // PWM_AUTO // Automatically determined gradient value +#define TMC5240_PWM_GRAD_AUTO_SHIFT 16 // Automatically determined gradient value +#define TMC5240_PWM_GRAD_AUTO_FIELD ((RegisterField) { TMC5240_PWM_GRAD_AUTO_MASK, TMC5240_PWM_GRAD_AUTO_SHIFT, TMC5240_PWM_AUTO, false}) +#define TMC5240_SG4_THRS_MASK 0xFF // SG4_THRS // Detection threshold for stall. The StallGuard4 value SG4_RESULT becomes compared to the double of this threshold.; A stall is signaled with; SG_RESULT = SG4_THRS*2 +#define TMC5240_SG4_THRS_SHIFT 0 // Detection threshold for stall. The StallGuard4 value SG4_RESULT becomes compared to the double of this threshold.; A stall is signaled with; SG_RESULT = SG4_THRS*2 +#define TMC5240_SG4_THRS_FIELD ((RegisterField) { TMC5240_SG4_THRS_MASK, TMC5240_SG4_THRS_SHIFT, TMC5240_SG4_THRS, false}) +#define TMC5240_SG4_FILT_EN_MASK 0x100 // SG4_THRS // 1: enable SG4 filter, 0: disable SG4 filter +#define TMC5240_SG4_FILT_EN_SHIFT 8 // 1: enable SG4 filter, 0: disable SG4 filter +#define TMC5240_SG4_FILT_EN_FIELD ((RegisterField) { TMC5240_SG4_FILT_EN_MASK, TMC5240_SG4_FILT_EN_SHIFT, TMC5240_SG4_THRS, false}) +#define TMC5240_SG_ANGLE_OFFSET_MASK 0x200 // SG4_THRS // 1: Automatic phase shift compensation based on StallGuard4, when switching from StealthChop to SpreadCycle controlled via TPWMTHRS +#define TMC5240_SG_ANGLE_OFFSET_SHIFT 9 // 1: Automatic phase shift compensation based on StallGuard4, when switching from StealthChop to SpreadCycle controlled via TPWMTHRS +#define TMC5240_SG_ANGLE_OFFSET_FIELD ((RegisterField) { TMC5240_SG_ANGLE_OFFSET_MASK, TMC5240_SG_ANGLE_OFFSET_SHIFT, TMC5240_SG4_THRS, false}) +#define TMC5240_SG4_RESULT_MASK 0x3FF // SG4_RESULT // StallGuard result for StallGuard4, only.; .; SG4_RESULT becomes updated with each fullstep, independent of TCOOLTHRS and SG4THRS. A higher value signals a lower motor load and more torque headroom.; Intended for StealthChop mode, only. Bits 9 and 0 will always show 0. Scaling to 10 bit is for compatibility to StallGuard2. +#define TMC5240_SG4_RESULT_SHIFT 0 // StallGuard result for StallGuard4, only.; .; SG4_RESULT becomes updated with each fullstep, independent of TCOOLTHRS and SG4THRS. A higher value signals a lower motor load and more torque headroom.; Intended for StealthChop mode, only. Bits 9 and 0 will always show 0. Scaling to 10 bit is for compatibility to StallGuard2. +#define TMC5240_SG4_RESULT_FIELD ((RegisterField) { TMC5240_SG4_RESULT_MASK, TMC5240_SG4_RESULT_SHIFT, TMC5240_SG4_RESULT, false}) +#define TMC5240_SG4_IND_0_MASK 0xFF // SG4_IND // displays SG4 measurement; When SG4_filt_en = 1:; Displays SG4 measurement 0 used as filter input +#define TMC5240_SG4_IND_0_SHIFT 0 // displays SG4 measurement; When SG4_filt_en = 1:; Displays SG4 measurement 0 used as filter input +#define TMC5240_SG4_IND_0_FIELD ((RegisterField) { TMC5240_SG4_IND_0_MASK, TMC5240_SG4_IND_0_SHIFT, TMC5240_SG4_IND, false}) +#define TMC5240_SG4_IND_1_MASK 0xFF00 // SG4_IND // When SG4_filt_en = 1:; Displays SG4 measurement 1 used as filter input +#define TMC5240_SG4_IND_1_SHIFT 8 // When SG4_filt_en = 1:; Displays SG4 measurement 1 used as filter input +#define TMC5240_SG4_IND_1_FIELD ((RegisterField) { TMC5240_SG4_IND_1_MASK, TMC5240_SG4_IND_1_SHIFT, TMC5240_SG4_IND, false}) +#define TMC5240_SG4_IND_2_MASK 0xFF0000 // SG4_IND // When SG4_filt_en = 1:; Displays SG4 measurement 2 used as filter input +#define TMC5240_SG4_IND_2_SHIFT 16 // When SG4_filt_en = 1:; Displays SG4 measurement 2 used as filter input +#define TMC5240_SG4_IND_2_FIELD ((RegisterField) { TMC5240_SG4_IND_2_MASK, TMC5240_SG4_IND_2_SHIFT, TMC5240_SG4_IND, false}) +#define TMC5240_SG4_IND_3_MASK 0xFF000000 // SG4_IND // When SG4_filt_en = 1:; Displays SG4 measurement 3 used as filter input +#define TMC5240_SG4_IND_3_SHIFT 24 // When SG4_filt_en = 1:; Displays SG4 measurement 3 used as filter input +#define TMC5240_SG4_IND_3_FIELD ((RegisterField) { TMC5240_SG4_IND_3_MASK, TMC5240_SG4_IND_3_SHIFT, TMC5240_SG4_IND, false}) + +#endif diff --git a/firmware/lib/tmc/ic/TMC5240/registercall_hierarchy_flowchart_SPI.svg b/firmware/lib/tmc/ic/TMC5240/registercall_hierarchy_flowchart_SPI.svg new file mode 100755 index 0000000..cbad58f --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5240/registercall_hierarchy_flowchart_SPI.svg @@ -0,0 +1,3 @@ + + +

HAL

HAL

APP (Eval)

APP (Eval)

API

API
Read a register
  •  Call tmcXXXX_readRegister function
Read a register...
Returns the register read value
Returns the register read value
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
tmcXXXX.c
tmcXXXX.c
SPI.c
SPI.c
tmcXXXX_eval.c
tmcXXXX_eval.c

 Implementation of SPI_readWrite
  • Sends and receives bytes on the SPI bus
Implementation of SPI_readWrite...
Returns the raw reply data
Returns the raw reply data

Implementation of tmcXXXX_readWriteSPI
  • Sets the CSN pin to LOW
  • Takes the array of data to write
  • Calls hardware function SPI_readWrite
  • Upon completion of data transfer,
    sets CSN to 
    HIGH
Implementation of tmcXXXX_readWriteSPI...
Passes on the raw reply data to the API
Passes on the raw reply data to the API
Implementation of readRegisterSPI
  • Constructs the datagram
  • Calls HAL wrapper function 
Implementation of readRegisterSPI...
tmcXXXX_readWriteSPI
tmcXXXX_readWriteSPI
Parses the reply and returns the register value
Parses the reply and returns the register value
Implementation of tmcXXXX_readRegister 
  • Check which bus is active SPI/UART. (e.g. SPI)
  • Calls bus-specific function (e.g. readRegisterSPI)
 
Implementation of tmcXXXX_readRegister...
Returns the register read value
Returns the register read value
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC5240/registercall_hierarchy_flowchart_UART.svg b/firmware/lib/tmc/ic/TMC5240/registercall_hierarchy_flowchart_UART.svg new file mode 100755 index 0000000..425f60a --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5240/registercall_hierarchy_flowchart_UART.svg @@ -0,0 +1,3 @@ + + +

HAL

HAL

APP (Eval)

APP (Eval)

API

API
Read a register
  •  Call tmcXXXX_readRegister function
Read a register...
Returns the register read value
Returns the register read value
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
tmcXXXX.c
tmcXXXX.c
UART.c
UART.c
tmcXXXX_eval.c
tmcXXXX_eval.c

 Implementation of UART_readWrite
  • Sends and receives bytes on the UART bus
Implementation of UART_readWrite...
Returns the raw reply data
Returns the raw reply data

Implementation of tmcXXXX_readWriteUART
  • Takes the array of data to write
  • Calls hardware function UART_readWrite
Implementation of tmcXXXX_readWriteUART...
Passes on the raw reply data to the API
Passes on the raw reply data to the API
Implementation of readRegisterUART
  • Constructs the datagram
  • Calls HAL wrapper function 
Implementation of readRegisterUART...
tmcXXXX_readWriteUART
tmcXXXX_readWriteUART
Parses the reply and returns the register value
Parses the reply and returns the register value
Implementation of tmcXXXX_readRegister 
  • Check which bus is active SPI/UART. (e.g. UART)
  • Calls bus-specific function (e.g. readRegisterUART)
 
Implementation of tmcXXXX_readRegister...
Returns the register read value
Returns the register read value
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC5240/uml-tmc-api.svg b/firmware/lib/tmc/ic/TMC5240/uml-tmc-api.svg new file mode 100755 index 0000000..5a5f8dd --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5240/uml-tmc-api.svg @@ -0,0 +1,3 @@ + + +

TMCXXXX_HW_Abstraction.h



TMCXXXX_HW_Abstraction.h...
// Constants
#define TMCXXXX_MOTORS              
                          
// Register definitions
#define TMCXXXX_GCONF        
                          ⋮
// Register fields definitions
#define TMCXXXX_GCONF_OTPW_FIELD
                     
// Constants...

TMCXXXX.h



TMCXXXX.h...
extern void tmcXXXX_readWriteSPI();
extern void tmcXXXX_readWriteUART();
extern TMCXXXXBusType tmcXXXX_getBusType();
extern uint8_t tmcXXXX_getNodeAddress();
                                  ⋮
tmcXXXX_readRegister();
tmcXXXX_writeRegister();
                                  ⋮
extern void tmcXXXX_readWriteSPI();...

TMCXXXX.c



TMCXXXX.c...
const uint8_t tmcCRCTable_Poly7Reflected[256] = {...};
int32_t tmcXXXX_readRegister(){
/* Call tmcXXXX_getBusType();
 * Based on bus type, call readRegisterSPI/UART() that
 * further calls tmcXXXX_readWriteSPI/UART();
 * For UART it also calls tmcXXXX_getNodeAddress();
                                           ⋮
}
                                           ⋮
const uint8_t tmcCRCTable_Poly7Reflected[256] = {.....
TMC-API
TMC-API

TMCXXXX_Simple_Rotation.h


TMCXXXX_Simple_Rotation.h...
void initAllMotors();
             ⋮
  
void initAllMotors()...

TMCXXXX_Simple_Rotation.c


TMCXXXX_Simple_Rotation.c...
void initAllMotors(){

// Configuring registers to enable motor drivers etc..
tmcXXXX_writeRegister();
                    ⋮
}
                    ⋮
void initAllMotors(){...
Examples
Examples
User Project
User Project

User_Project.h


User_Project.h

User_Project.c








User_Project.c...

void tmcXXXX_readWriteSPI(){
                           ⋮
}
void tmcXXXX_readWriteUART(){
                           ⋮
}
TMCXXXXBusType tmcXXXX_getBusType(){
                           ⋮
}
uint8_t tmcXXXX_getNodeAddress(){
                           ⋮
}

// User Code
                           ⋮
void tmcXXXX_readWriteSPI(){...
#include "TMCXXXX_HW_Abstraction.h"
#include "TMCXXXX.h"
#include "TMCXXXX_Simple_Rotation.h"
                                ⋮
TMCXXXXBusType bus = IC_BUS_SPI/UART;
uint8_t nodeAddress = <nodeAddress>;
                                ⋮
#include "TMCXXXX_HW_Abstraction.h"...
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC5241/README.md b/firmware/lib/tmc/ic/TMC5241/README.md new file mode 100755 index 0000000..0e37072 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5241/README.md @@ -0,0 +1,57 @@ +# TMC5241 + + +## How to use + +To access the TMC5241's registers, the TMC-API offers two functions: **tmc5241_readRegister** and **tmc5241_writeRegister**. +Each of these functions takes in an **icID**, which is used to identify the IC when multiple ICs are connected. This identifier is passed down to the callback functions (see How to Integrate). + +## How to integrate: overview + +1. Include all the files of the TMC-API/ic/tmc/TMC5241 folder into the custom project. +2. Include the TMC5241.h file in the custom source code. +3. Implement the necessary callback functions (see below). +4. (optional): Take a look at the Examples subfolder for ready-made examples of the TMC-API usage. + +## Accessing the TMC5241 via UART +The following diagram depicts how to access the TMC5241 via UART using the TMC-API. + +![screenshot](registercall_hierarchy_flowchart_UART.svg) + +The description of the functions, in the above flowchart, are as follows: +- The functions tmc5241_readRegister and tmc5241_writeRegister are used to read and write the registers respectively. These functions check the current active bus and calls the bus-specific function i.e readRegisterUART or writeRegisterUART. +- These bus specific functions constructs the datagram and further calls the bus specific callback 'tmcXXXX_readWriteUART. +- This callback function further calls the hardware specific read/write function for UART and needs to be implemented externally. + +## Accessing the TMC5241 via SPI +The following diagram depicts how to access the TMC5241 via SPI using the TMC-API. + +![screenshot](registercall_hierarchy_flowchart_SPI.svg) + +The description of the functions, in the above flowchart, are as follows: +- The functions tmc5241_readRegister and tmc5241_writeRegister are used to read and write the registers respectively. These functions check the current active bus and calls the bus-specific function i.e readRegisterSPI or writeRegisterSPI. +- These bus specific functions constructs the datagram and further calls the bus specific callback 'tmcXXXX_readWriteSPI. +- This callback function further calls the hardware specific read/write function for SPI and needs to be implemented externally. + +### How to integrate: Callback functions +To communicate with TMC5241 IC, the TMC-API library needs to know which bus (UART, SPI) it shall use. For that, the callback function **'tmc5241_getBusType()'** needs to be implemented. +Additionally, implement the following callback functions to access the chip via UART: +1. **tmc5241_readWriteUART()**, which is a HAL wrapper function that provides the necessary hardware access. +2. **tmc5241_getNodeAddress()**, that returns the node/slave address. Node address could be set in NODECONF (0x3) register and the address could be incremented as defined by AD0, AD1 and AD2. (Node address + ADx) must be less than 255. For further details please consult the datasheet of TMC5241. + +### Sharing the CRC table with other TMC-API chips +The TMC5241 UART protocol uses an 8 bit CRC. For calculating this, a table-based algorithm is used. This table (tmcCRCTable_Poly7Reflected[256]) is 256 bytes big and identical across multiple different Trinamic chips (i.e. TMC2209). +If multiple Trinamic chips are being used in the same project, avoiding redundant copies of this table could save memory. It is possible to substitute this CRC table with another CRC table. + +## Further info +### Dependency graph for the ICs with new register R/W mechanism +This graph illustrates the relationships between files within the TMC-API library, highlighting dependencies and identifying the files that are essential for integrating the library into the custom projects. + +![screenshot](uml-tmc-api.svg) + +### Example usage: TMC-Evalsystem +**For a reference usage of the TMC-API**, visit the [TMC-Evalsystem](https://github.com/analogdevicesinc/TMC-EvalSystem) + +## Migration status +The TMC5241 has been reworked to the access system described above. For more infos on the status of this and other ICs, check out the [migration page](https://github.com/analogdevicesinc/TMC-API/issues/53). + diff --git a/firmware/lib/tmc/ic/TMC5241/TMC5241.c b/firmware/lib/tmc/ic/TMC5241/TMC5241.c new file mode 100755 index 0000000..7c1ee8d --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5241/TMC5241.c @@ -0,0 +1,177 @@ +/******************************************************************************* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#include "TMC5241.h" + +#ifdef TMC_API_EXTERNAL_CRC_TABLE +extern const uint8_t tmcCRCTable_Poly7Reflected[256]; +#else +const uint8_t tmcCRCTable_Poly7Reflected[256] = { + 0x00, 0x91, 0xE3, 0x72, 0x07, 0x96, 0xE4, 0x75, 0x0E, 0x9F, 0xED, 0x7C, 0x09, 0x98, 0xEA, 0x7B, + 0x1C, 0x8D, 0xFF, 0x6E, 0x1B, 0x8A, 0xF8, 0x69, 0x12, 0x83, 0xF1, 0x60, 0x15, 0x84, 0xF6, 0x67, + 0x38, 0xA9, 0xDB, 0x4A, 0x3F, 0xAE, 0xDC, 0x4D, 0x36, 0xA7, 0xD5, 0x44, 0x31, 0xA0, 0xD2, 0x43, + 0x24, 0xB5, 0xC7, 0x56, 0x23, 0xB2, 0xC0, 0x51, 0x2A, 0xBB, 0xC9, 0x58, 0x2D, 0xBC, 0xCE, 0x5F, + 0x70, 0xE1, 0x93, 0x02, 0x77, 0xE6, 0x94, 0x05, 0x7E, 0xEF, 0x9D, 0x0C, 0x79, 0xE8, 0x9A, 0x0B, + 0x6C, 0xFD, 0x8F, 0x1E, 0x6B, 0xFA, 0x88, 0x19, 0x62, 0xF3, 0x81, 0x10, 0x65, 0xF4, 0x86, 0x17, + 0x48, 0xD9, 0xAB, 0x3A, 0x4F, 0xDE, 0xAC, 0x3D, 0x46, 0xD7, 0xA5, 0x34, 0x41, 0xD0, 0xA2, 0x33, + 0x54, 0xC5, 0xB7, 0x26, 0x53, 0xC2, 0xB0, 0x21, 0x5A, 0xCB, 0xB9, 0x28, 0x5D, 0xCC, 0xBE, 0x2F, + 0xE0, 0x71, 0x03, 0x92, 0xE7, 0x76, 0x04, 0x95, 0xEE, 0x7F, 0x0D, 0x9C, 0xE9, 0x78, 0x0A, 0x9B, + 0xFC, 0x6D, 0x1F, 0x8E, 0xFB, 0x6A, 0x18, 0x89, 0xF2, 0x63, 0x11, 0x80, 0xF5, 0x64, 0x16, 0x87, + 0xD8, 0x49, 0x3B, 0xAA, 0xDF, 0x4E, 0x3C, 0xAD, 0xD6, 0x47, 0x35, 0xA4, 0xD1, 0x40, 0x32, 0xA3, + 0xC4, 0x55, 0x27, 0xB6, 0xC3, 0x52, 0x20, 0xB1, 0xCA, 0x5B, 0x29, 0xB8, 0xCD, 0x5C, 0x2E, 0xBF, + 0x90, 0x01, 0x73, 0xE2, 0x97, 0x06, 0x74, 0xE5, 0x9E, 0x0F, 0x7D, 0xEC, 0x99, 0x08, 0x7A, 0xEB, + 0x8C, 0x1D, 0x6F, 0xFE, 0x8B, 0x1A, 0x68, 0xF9, 0x82, 0x13, 0x61, 0xF0, 0x85, 0x14, 0x66, 0xF7, + 0xA8, 0x39, 0x4B, 0xDA, 0xAF, 0x3E, 0x4C, 0xDD, 0xA6, 0x37, 0x45, 0xD4, 0xA1, 0x30, 0x42, 0xD3, + 0xB4, 0x25, 0x57, 0xC6, 0xB3, 0x22, 0x50, 0xC1, 0xBA, 0x2B, 0x59, 0xC8, 0xBD, 0x2C, 0x5E, 0xCF, +}; +#endif + +/************************************************************** Register read / write Implementation ******************************************************************/ + +static int32_t readRegisterSPI(uint16_t icID, uint8_t address); +static void writeRegisterSPI(uint16_t icID, uint8_t address, int32_t value); +static int32_t readRegisterUART(uint16_t icID, uint8_t registerAddress); +static void writeRegisterUART(uint16_t icID, uint8_t registerAddress, int32_t value); +static uint8_t CRC8(uint8_t *data, uint32_t bytes); + +int32_t tmc5241_readRegister(uint16_t icID, uint8_t address) +{ + TMC5241BusType bus = tmc5241_getBusType(icID); + + if(bus == IC_BUS_SPI) + { + return readRegisterSPI(icID, address); + } + else if (bus == IC_BUS_UART) + { + return readRegisterUART(icID, address); + } + return -1; +} + +void tmc5241_writeRegister(uint16_t icID, uint8_t address, int32_t value) +{ + TMC5241BusType bus = tmc5241_getBusType(icID); + + if(bus == IC_BUS_SPI) + { + writeRegisterSPI(icID, address, value); + } + else if (bus == IC_BUS_UART) + { + writeRegisterUART(icID, address, value); + } +} + +int32_t readRegisterSPI(uint16_t icID, uint8_t address) +{ + uint8_t data[5] = { 0 }; + + // clear write bit + data[0] = address & TMC5241_ADDRESS_MASK; + + // Send the read request + tmc5241_readWriteSPI(icID, &data[0], sizeof(data)); + + // Rewrite address and clear write bit + data[0] = address & TMC5241_ADDRESS_MASK; + + // Send another request to receive the read reply + tmc5241_readWriteSPI(icID, &data[0], sizeof(data)); + + return ((int32_t)data[1] << 24) | ((int32_t) data[2] << 16) | ((int32_t) data[3] << 8) | ((int32_t) data[4]); +} + +void writeRegisterSPI(uint16_t icID, uint8_t address, int32_t value) +{ + uint8_t data[5] = { 0 }; + + data[0] = address | TMC5241_WRITE_BIT; + data[1] = 0xFF & (value>>24); + data[2] = 0xFF & (value>>16); + data[3] = 0xFF & (value>>8); + data[4] = 0xFF & (value>>0); + + // Send the write request + tmc5241_readWriteSPI(icID, &data[0], sizeof(data)); +} + +int32_t readRegisterUART(uint16_t icID, uint8_t registerAddress) +{ + uint8_t data[8] = { 0 }; + + registerAddress = registerAddress & TMC5241_ADDRESS_MASK; + + data[0] = 0x05; + data[1] = tmc5241_getNodeAddress(icID); //targetAddressUart; + data[2] = registerAddress; + data[3] = CRC8(data, 3); + + if (!tmc5241_readWriteUART(icID, &data[0], 4, 8)) + return 0; + + // Byte 0: Sync nibble correct? + if (data[0] != 0x05) + return 0; + + // Byte 1: Master address correct? + if (data[1] != 0xFF) + return 0; + + // Byte 2: Address correct? + if (data[2] != registerAddress) + return 0; + + // Byte 7: CRC correct? + if (data[7] != CRC8(data, 7)) + return 0; + + return ((uint32_t)data[3] << 24) | ((uint32_t)data[4] << 16) | ((uint32_t)data[5] << 8) | data[6]; +} + +void writeRegisterUART(uint16_t icID, uint8_t registerAddress, int32_t value) +{ + uint8_t data[8]; + + data[0] = 0x05; + data[1] = (uint8_t)tmc5241_getNodeAddress(icID); //targetAddressUart; + data[2] = registerAddress | TMC5241_WRITE_BIT; + data[3] = (value >> 24) & 0xFF; + data[4] = (value >> 16) & 0xFF; + data[5] = (value >> 8 ) & 0xFF; + data[6] = (value ) & 0xFF; + data[7] = CRC8(data, 7); + + tmc5241_readWriteUART(icID, &data[0], 8, 0); +} + +void tmc5241_rotateMotor(uint16_t icID, uint8_t motor, int32_t velocity) +{ + if(motor >= TMC5241_MOTORS) + return; + + tmc5241_writeRegister(icID, TMC5241_VMAX, (velocity < 0) ? -velocity : velocity); + tmc5241_fieldWrite(icID, TMC5241_RAMPMODE_FIELD, (velocity >= 0) ? TMC5241_MODE_VELPOS : TMC5241_MODE_VELNEG); +} + +static uint8_t CRC8(uint8_t *data, uint32_t bytes) +{ + uint8_t result = 0; + + while(bytes--) + result = tmcCRCTable_Poly7Reflected[result ^ *data++]; + + // Flip the result around + // swap odd and even bits + result = ((result >> 1) & 0x55) | ((result & 0x55) << 1); + // swap consecutive pairs + result = ((result >> 2) & 0x33) | ((result & 0x33) << 2); + // swap nibbles ... + result = ((result >> 4) & 0x0F) | ((result & 0x0F) << 4); + + return result; +} + diff --git a/firmware/lib/tmc/ic/TMC5241/TMC5241.h b/firmware/lib/tmc/ic/TMC5241/TMC5241.h new file mode 100755 index 0000000..244fb63 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5241/TMC5241.h @@ -0,0 +1,164 @@ +/******************************************************************************* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#ifndef TMC_IC_TMC5241_H_ +#define TMC_IC_TMC5241_H_ + +#include +#include +#include +#include "TMC5241_HW_Abstraction.h" + +/******************************************************************************* +* API Configuration Defines +* These control optional features of the TMC-API implementation. +* These can be commented in/out here or defined from the build system. +*******************************************************************************/ + +// Uncomment if you want to save space..... +// and put the table into your own .c file +//#define TMC_API_EXTERNAL_CRC_TABLE 1 + +/******************************************************************************/ + +typedef enum { + IC_BUS_SPI, + IC_BUS_UART, + IC_BUS_WLAN +} TMC5241BusType; + +typedef struct +{ + uint32_t mask; + uint8_t shift; + uint8_t address; + bool isSigned; +} RegisterField; + + +// => TMC-API wrapper +extern void tmc5241_readWriteSPI(uint16_t icID, uint8_t *data, size_t dataLength); +extern bool tmc5241_readWriteUART(uint16_t icID, uint8_t *data, size_t writeLength, size_t readLength); +extern TMC5241BusType tmc5241_getBusType(uint16_t icID); +extern uint8_t tmc5241_getNodeAddress(uint16_t icID); +// => TMC-API wrapper + +int32_t tmc5241_readRegister(uint16_t icID, uint8_t address); +void tmc5241_writeRegister(uint16_t icID, uint8_t address, int32_t value); +void tmc5241_rotateMotor(uint16_t icID, uint8_t motor, int32_t velocity); + + +static inline uint32_t tmc5241_fieldExtract(uint32_t data, RegisterField field) +{ + uint32_t value = (data & field.mask) >> field.shift; + + if (field.isSigned) + { + // Apply sign conversion + uint32_t baseMask = field.mask >> field.shift; + uint32_t signMask = baseMask & (~baseMask >> 1); + value = (value ^ signMask) - signMask; + } + + return value; +} + +static inline uint32_t tmc5241_fieldRead(uint16_t icID, RegisterField field) +{ + uint32_t value = tmc5241_readRegister(icID, field.address); + return tmc5241_fieldExtract(value, field); +} + +static inline uint32_t tmc5241_fieldUpdate(uint32_t data, RegisterField field, uint32_t value) +{ + return (data & (~field.mask)) | ((value << field.shift) & field.mask); +} + +static inline void tmc5241_fieldWrite(uint16_t icID, RegisterField field, uint32_t value) +{ + uint32_t regValue = tmc5241_readRegister(icID, field.address); + + regValue = tmc5241_fieldUpdate(regValue, field, value); + + tmc5241_writeRegister(icID, field.address, regValue); +} + +/**************************************************************** DEFAULT REGISTER VALUES *************************************************************************/ + +// Default Register values +#define R00 0x00000008 // GCONF +#define R0A 0x00000020 // DRVCONF +#define R10 0x00070A03 // IHOLD_IRUN +#define R11 0x0000000A // TPOWERDOWN +#define R2A 0x0000000A // D1 +#define R2B 0x0000000A // VSTOP +#define R30 0x0000000A // D2 +#define R3A 0x00010000 // ENC_CONST +#define R52 0x0B920F25 // OTW_OV_VTH +#define R60 0xAAAAB554 // MSLUT[0] +#define R61 0x4A9554AA // MSLUT[1] +#define R62 0x24492929 // MSLUT[2] +#define R63 0x10104222 // MSLUT[3] +#define R64 0xFBFFFFFF // MSLUT[4] +#define R65 0xB5BB777D // MSLUT[5] +#define R66 0x49295556 // MSLUT[6] +#define R67 0x00404222 // MSLUT[7] +#define R68 0xFFFF8056 // MSLUT[8] +#define R69 0x00F70000 // MSLUT[9] +#define R6C 0x00410153 // CHOPCONF +#define R70 0xC44C001E // PWMCONF +#define R74 0x00000000 // PWMCONF + +#ifndef ____ + #define ____ 0x00 +#endif +#ifndef N_A + #define N_A 0x00 +#endif + +#define TMC5241_ACCESS_DIRTY 0x08 // Register has been written since reset -> shadow register is valid for restore +#define TMC5241_ACCESS_READ 0x01 +#define TMC5241_IS_READABLE(x) ((x) & TMC5241_ACCESS_READ) +#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) + + +static const int32_t tmc5241_sampleRegisterPreset[TMC5241_REGISTER_COUNT] = +{ +// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F + R00, 0, 0, 0, 0, 0, 0, 0, 0, 0, R0A, 0, 0, 0, 0, 0, // 0x00 - 0x0F + R10, R11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x10 - 0x1F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, R2A, R2B, 0, 0, 0, 0, // 0x20 - 0x2F + R30, 0, 0, 0, 0, 0, 0, 0, 0, 0, R3A, 0, 0, 0, 0, 0, // 0x30 - 0x3F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x40 - 0x4F + 0, 0, R52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x50 - 0x5F + R60, R61, R62, R63, R64, R65, R66, R67, R68, R69, 0, 0, R6C, 0, 0, 0, // 0x60 - 0x6F + R70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x70 - 0x7F +}; + +// Register access permissions: +// 0x00: none (reserved) +// 0x01: read +// 0x02: write +// 0x03: read/write +// 0x13: read/write, separate functions/values for reading or writing +// 0x23: read/write, flag register (write to clear) +// 0x42: write, has hardware presets on reset +static const uint8_t tmc5241_registerAccess[TMC5241_REGISTER_COUNT] = +{ +// 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0x03, 0x23, 0x01, 0x03, 0x03, 0x03, 0x03, ____, ____, ____, 0x03, 0x03, ____, ____, ____, ____, // 0x00 - 0x0F + 0x03, 0x03, 0x01, 0x03, 0x03, 0x03, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x10 - 0x1F + 0x03, 0x03, 0x01, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, // 0x20 - 0x2F + 0x03, 0x01, ____, 0x03, 0x03, 0x23, 0x01, ____, 0x03, 0x03, 0x03, 0x23, 0x01, 0x03, ____, ____, // 0x30 - 0x3F + ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x40 - 0x4F + 0x01, 0x01, 0x03, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x50 - 0x5F + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x01, 0x01, 0x03, 0x03, 0x03, 0x01, // 0x60 - 0x6F + 0x03, 0x01, 0x01, ____, 0x03, 0x01, 0x01, ____, ____, ____, ____, ____, ____, ____, ____, ____ // 0x70 - 0x7F +}; + +/*******************************************************************************************************************************************************************/ + +#endif /* TMC_IC_TMC5241_H_ */ diff --git a/firmware/lib/tmc/ic/TMC5241/TMC5241_HW_Abstraction.h b/firmware/lib/tmc/ic/TMC5241/TMC5241_HW_Abstraction.h new file mode 100755 index 0000000..3a1ddea --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5241/TMC5241_HW_Abstraction.h @@ -0,0 +1,875 @@ +/******************************************************************************* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#ifndef TMC5241_HW_ABSTRACTION +#define TMC5241_HW_ABSTRACTION + +//constants + +#define TMC5241_REGISTER_COUNT 128 +#define TMC5241_MOTORS 1 +#define TMC5241_WRITE_BIT 0x80 +#define TMC5241_ADDRESS_MASK 0x7F +#define TMC5241_MAX_VELOCITY 8388096 +#define TMC5241_MAX_ACCELERATION u16_MAX +#define DEFAULT_ICID 0 + +// ramp modes (Register TMC5241_RAMPMODE) +#define TMC5241_MODE_POSITION 0 +#define TMC5241_MODE_VELPOS 1 +#define TMC5241_MODE_VELNEG 2 +#define TMC5241_MODE_HOLD 3 + +// limit switch mode bits (Register TMC5241_SWMODE) +#define TMC5241_SW_STOPL_ENABLE 0x0001 +#define TMC5241_SW_STOPR_ENABLE 0x0002 +#define TMC5241_SW_STOPL_POLARITY 0x0004 +#define TMC5241_SW_STOPR_POLARITY 0x0008 +#define TMC5241_SW_SWAP_LR 0x0010 +#define TMC5241_SW_LATCH_L_ACT 0x0020 +#define TMC5241_SW_LATCH_L_INACT 0x0040 +#define TMC5241_SW_LATCH_R_ACT 0x0080 +#define TMC5241_SW_LATCH_R_INACT 0x0100 +#define TMC5241_SW_LATCH_ENC 0x0200 +#define TMC5241_SW_SG_STOP 0x0400 +#define TMC5241_SW_SOFTSTOP 0x0800 + +// Status bits (Register TMC5241_RAMPSTAT) +#define TMC5241_RS_STOPL 0x0001 +#define TMC5241_RS_STOPR 0x0002 +#define TMC5241_RS_LATCHL 0x0004 +#define TMC5241_RS_LATCHR 0x0008 +#define TMC5241_RS_EV_STOPL 0x0010 +#define TMC5241_RS_EV_STOPR 0x0020 +#define TMC5241_RS_EV_STOP_SG 0x0040 +#define TMC5241_RS_EV_POSREACHED 0x0080 +#define TMC5241_RS_VELREACHED 0x0100 +#define TMC5241_RS_POSREACHED 0x0200 +#define TMC5241_RS_VZERO 0x0400 +#define TMC5241_RS_ZEROWAIT 0x0800 +#define TMC5241_RS_SECONDMOVE 0x1000 +#define TMC5241_RS_SG 0x2000 + +// Encoderbits (Register TMC5241_ENCMODE) +#define TMC5241_EM_DECIMAL 0x0400 +#define TMC5241_EM_LATCH_XACT 0x0200 +#define TMC5241_EM_CLR_XENC 0x0100 +#define TMC5241_EM_NEG_EDGE 0x0080 +#define TMC5241_EM_POS_EDGE 0x0040 +#define TMC5241_EM_CLR_ONCE 0x0020 +#define TMC5241_EM_CLR_CONT 0x0010 +#define TMC5241_EM_IGNORE_AB 0x0008 +#define TMC5241_EM_POL_N 0x0004 +#define TMC5241_EM_POL_B 0x0002 +#define TMC5241_EM_POL_A 0x0001 + +// Registers in TMC5241 + +#define TMC5241_GCONF 0x00 +#define TMC5241_GSTAT 0x01 +#define TMC5241_IFCNT 0x02 +#define TMC5241_SLAVECONF 0x03 +#define TMC5241_IOIN 0x04 +#define TMC5241_X_COMPARE 0x05 +#define TMC5241_X_COMPARE_REPEAT 0x06 +#define TMC5241_DIAG_GCONF 0x07 +#define TMC5241_DRV_CONF 0x0A +#define TMC5241_GLOBAL_SCALER 0x0B +#define TMC5241_IHOLD_IRUN 0x10 +#define TMC5241_TPOWERDOWN 0x11 +#define TMC5241_TSTEP 0x12 +#define TMC5241_TPWMTHRS 0x13 +#define TMC5241_TCOOLTHRS 0x14 +#define TMC5241_THIGH 0x15 +#define TMC5241_RAMPMODE 0x20 +#define TMC5241_XACTUAL 0x21 +#define TMC5241_VACTUAL 0x22 +#define TMC5241_VSTART 0x23 +#define TMC5241_A1 0x24 +#define TMC5241_V1 0x25 +#define TMC5241_AMAX 0x26 +#define TMC5241_VMAX 0x27 +#define TMC5241_DMAX 0x28 +#define TMC5241_TVMAX 0x29 +#define TMC5241_D1 0x2A +#define TMC5241_VSTOP 0x2B +#define TMC5241_TZEROWAIT 0x2C +#define TMC5241_XTARGET 0x2D +#define TMC5241_V2 0x2E +#define TMC5241_A2 0x2F +#define TMC5241_D2 0x30 +#define TMC5241_AACTUAL 0x31 +#define TMC5241_VDCMIN 0x33 +#define TMC5241_SW_MODE 0x34 +#define TMC5241_RAMP_STAT 0x35 +#define TMC5241_XLATCH 0x36 +#define TMC5241_ENCMODE 0x38 +#define TMC5241_X_ENC 0x39 +#define TMC5241_ENC_CONST 0x3A +#define TMC5241_ENC_STATUS 0x3B +#define TMC5241_ENC_LATCH 0x3C +#define TMC5241_ENC_DEVIATION 0x3D +#define TMC5241_VIRTUAL_STOP_L 0x3E +#define TMC5241_VIRTUAL_STOP_R 0x3F +#define TMC5241_ADC_VSUPPLY_AIN 0x50 +#define TMC5241_ADC_TEMP 0x51 +#define TMC5241_OTW_OV_VTH 0x52 +#define TMC5241_MSLUT__ 0x60 +//#define TMC5241_MSLUT__ 0x61 +//#define TMC5241_MSLUT__ 0x62 +//#define TMC5241_MSLUT__ 0x63 +//#define TMC5241_MSLUT__ 0x64 +//#define TMC5241_MSLUT__ 0x65 +//#define TMC5241_MSLUT__ 0x66 +//#define TMC5241_MSLUT__ 0x67 +#define TMC5241_MSLUTSEL 0x68 +#define TMC5241_MSLUTSTART 0x69 +#define TMC5241_MSCNT 0x6A +#define TMC5241_MSCURACT 0x6B +#define TMC5241_CHOPCONF 0x6C +#define TMC5241_COOLCONF 0x6D +#define TMC5241_DCCTRL 0x6E +#define TMC5241_DRV_STATUS 0x6F +#define TMC5241_PWMCONF 0x70 +#define TMC5241_PWM_SCALE 0x71 +#define TMC5241_PWM_AUTO 0x72 +#define TMC5241_SG4_THRS 0x74 +#define TMC5241_SG4_RESULT 0x75 +#define TMC5241_SG4_IND 0x76 + + +// Register fields in TMC5241 + +// Status fields returned with every SPI transaction +#define TMC5241_SPI_STATUS_RESET_FLAG_MASK 0x01 /* GSTAT[0] - 1: Signals, that a reset has occurred (clear by reading GSTAT) */ +#define TMC5241_SPI_STATUS_RESET_FLAG_SHIFT 0 +#define TMC5241_SPI_STATUS_RESET_FLAG_FIELD ((RegisterField) { TMC5241_SPI_STATUS_RESET_FLAG_MASK, TMC5241_SPI_STATUS_RESET_FLAG_SHIFT, TMC5241_GSTAT, false }) +#define TMC5241_SPI_STATUS_DRIVER_ERROR_MASK 0x02 /* GSTAT[1] – 1: Signals driver 1 driver error (clear by reading GSTAT) */ +#define TMC5241_SPI_STATUS_DRIVER_ERROR_SHIFT 1 +#define TMC5241_SPI_STATUS_DRIVER_ERROR_FIELD ((RegisterField) { TMC5241_SPI_STATUS_DRIVER_ERROR_MASK, TMC5241_SPI_STATUS_DRIVER_ERROR_SHIFT, TMC5241_GSTAT, false }) +#define TMC5241_SPI_STATUS_SG2_MASK 0x04 /* DRV_STATUS[24] – 1: Signals StallGuard flag active */ +#define TMC5241_SPI_STATUS_SG2_SHIFT 2 +#define TMC5241_SPI_STATUS_SG2_FIELD ((RegisterField) { TMC5241_SPI_STATUS_SG2_MASK, TMC5241_SPI_STATUS_SG2_SHIFT, TMC5241_DRVSTATUS, false }) +#define TMC5241_SPI_STATUS_STANDSTILL_MASK 0x08 /* DRV_STATUS[31] – 1: Signals motor stand still */ +#define TMC5241_SPI_STATUS_STANDSTILL_SHIFT 3 +#define TMC5241_SPI_STATUS_STANDSTILL_FIELD ((RegisterField) { TMC5241_SPI_STATUS_STANDSTILL_MASK, TMC5241_SPI_STATUS_STANDSTILL_SHIFT, TMC5241_DRVSTATUS, false }) +#define TMC5241_SPI_STATUS_VELOCITY_REACHED_MASK 0x10 /* RAMP_STAT[8] – 1: Signals target velocity reached (motion controller only) */ +#define TMC5241_SPI_STATUS_VELOCITY_REACHED_SHIFT 4 +#define TMC5241_SPI_STATUS_VELOCITY_REACHED_FIELD ((RegisterField) { TMC5241_SPI_STATUS_VELOCITY_REACHED_MASK, TMC5241_SPI_STATUS_VELOCITY_REACHED_SHIFT, TMC5241_RAMPSTAT, false }) +#define TMC5241_SPI_STATUS_POSITION_REACHED_MASK 0x20 /* RAMP_STAT[9] – 1: Signals target position reached (motion controller only) */ +#define TMC5241_SPI_STATUS_POSITION_REACHED_SHIFT 5 +#define TMC5241_SPI_STATUS_POSITION_REACHED_FIELD ((RegisterField) { TMC5241_SPI_STATUS_POSITION_REACHED_MASK, TMC5241_SPI_STATUS_POSITION_REACHED_SHIFT, TMC5241_RAMPSTAT, false }) +#define TMC5241_SPI_STATUS_STATUS_STOP_L_MASK 0x40 /* RAMP_STAT[0] – 1: Signals stop left switch status (motion controller only) */ +#define TMC5241_SPI_STATUS_STATUS_STOP_L_SHIFT 6 +#define TMC5241_SPI_STATUS_STATUS_STOP_L_FIELD ((RegisterField) { TMC5241_SPI_STATUS_STATUS_STOP_L_MASK, TMC5241_SPI_STATUS_STATUS_STOP_L_SHIFT, TMC5241_RAMPSTAT, false }) +#define TMC5241_SPI_STATUS_STATUS_STOP_R_MASK 0x80 /* RAMP_STAT[1] – 1: Signals stop right switch status (motion controller only) */ +#define TMC5241_SPI_STATUS_STATUS_STOP_R_SHIFT 7 +#define TMC5241_SPI_STATUS_STATUS_STOP_R_FIELD ((RegisterField) { TMC5241_SPI_STATUS_STATUS_STOP_R_MASK, TMC5241_SPI_STATUS_STATUS_STOP_R_SHIFT, TMC5241_RAMPSTAT, false }) + +// Configuration & status registers +#define TMC5241_FAST_STANDSTILL_MASK 0x00000002 +#define TMC5241_FAST_STANDSTILL_SHIFT 1 +#define TMC5241_FAST_STANDSTILL_FIELD ((RegisterField) {TMC5241_FAST_STANDSTILL_MASK, TMC5241_FAST_STANDSTILL_SHIFT, TMC5241_GCONF, false}) +#define TMC5241_EN_PWM_MODE_MASK 0x00000004 +#define TMC5241_EN_PWM_MODE_SHIFT 2 +#define TMC5241_EN_PWM_MODE_FIELD ((RegisterField) {TMC5241_EN_PWM_MODE_MASK, TMC5241_EN_PWM_MODE_SHIFT, TMC5241_GCONF, false}) +#define TMC5241_MULTISTEP_FILT_MASK 0x00000008 +#define TMC5241_MULTISTEP_FILT_SHIFT 3 +#define TMC5241_MULTISTEP_FILT_FIELD ((RegisterField) {TMC5241_MULTISTEP_FILT_MASK, TMC5241_MULTISTEP_FILT_SHIFT, TMC5241_GCONF, false}) +#define TMC5241_SHAFT_MASK 0x00000010 +#define TMC5241_SHAFT_SHIFT 4 +#define TMC5241_SHAFT_FIELD ((RegisterField) {TMC5241_SHAFT_MASK, TMC5241_SHAFT_SHIFT, TMC5241_GCONF, false}) +#define TMC5241_DIAG0_NINT_STEP_MASK 0x00000080 +#define TMC5241_DIAG0_NINT_STEP_SHIFT 7 +#define TMC5241_DIAG0_NINT_STEP_FIELD ((RegisterField) {TMC5241_DIAG0_NINT_STEP_MASK, TMC5241_DIAG0_NINT_STEP_SHIFT, TMC5241_GCONF, false}) +#define TMC5241_DIAG1_NPOSCOMP_DIR_MASK 0x00000100 +#define TMC5241_DIAG1_NPOSCOMP_DIR_SHIFT 8 +#define TMC5241_DIAG1_NPOSCOMP_DIR_FIELD ((RegisterField) {TMC5241_DIAG1_NPOSCOMP_DIR_MASK, TMC5241_DIAG1_NPOSCOMP_DIR_SHIFT, TMC5241_GCONF, false}) +#define TMC5241_DIAG0_INT_PUSHPULL_MASK 0x00001000 +#define TMC5241_DIAG0_INT_PUSHPULL_SHIFT 12 +#define TMC5241_DIAG0_INT_PUSHPULL_FIELD ((RegisterField) {TMC5241_DIAG0_INT_PUSHPULL_MASK, TMC5241_DIAG0_INT_PUSHPULL_SHIFT, TMC5241_GCONF, false}) +#define TMC5241_DIAG1_POSCOMP_PUSHPULL_MASK 0x00002000 +#define TMC5241_DIAG1_POSCOMP_PUSHPULL_SHIFT 13 +#define TMC5241_DIAG1_POSCOMP_PUSHPULL_FIELD ((RegisterField) {TMC5241_DIAG1_POSCOMP_PUSHPULL_MASK, TMC5241_DIAG1_POSCOMP_PUSHPULL_SHIFT, TMC5241_GCONF, false}) +#define TMC5241_SMALL_HYSTERESIS_MASK 0x00004000 +#define TMC5241_SMALL_HYSTERESIS_SHIFT 14 +#define TMC5241_SMALL_HYSTERESIS_FIELD ((RegisterField) {TMC5241_SMALL_HYSTERESIS_MASK, TMC5241_SMALL_HYSTERESIS_SHIFT, TMC5241_GCONF, false}) +#define TMC5241_STOP_ENABLE_MASK 0x00008000 +#define TMC5241_STOP_ENABLE_SHIFT 15 +#define TMC5241_STOP_ENABLE_FIELD ((RegisterField) {TMC5241_STOP_ENABLE_MASK, TMC5241_STOP_ENABLE_SHIFT, TMC5241_GCONF, false}) +#define TMC5241_DIRECT_MODE_MASK 0x00010000 +#define TMC5241_DIRECT_MODE_SHIFT 16 +#define TMC5241_DIRECT_MODE_FIELD ((RegisterField) {TMC5241_DIRECT_MODE_MASK, TMC5241_DIRECT_MODE_SHIFT, TMC5241_GCONF, false}) +#define TMC5241_LENGTH_STEP_PULSE_MASK 0x001E0000 +#define TMC5241_LENGTH_STEP_PULSE_SHIFT 17 +#define TMC5241_LENGTH_STEP_PULSE_FIELD ((RegisterField) {TMC5241_LENGTH_STEP_PULSE_MASK, TMC5241_LENGTH_STEP_PULSE_SHIFT, TMC5241_GCONF, false}) +#define TMC5241_RESET_MASK 0x00000001 +#define TMC5241_RESET_SHIFT 0 +#define TMC5241_RESET_FIELD ((RegisterField) {TMC5241_RESET_MASK, TMC5241_RESET_SHIFT, TMC5241_GSTAT, false}) +#define TMC5241_DRV_ERR_MASK 0x00000002 +#define TMC5241_DRV_ERR_SHIFT 1 +#define TMC5241_DRV_ERR_FIELD ((RegisterField) {TMC5241_DRV_ERR_MASK, TMC5241_DRV_ERR_SHIFT, TMC5241_GSTAT, false}) +#define TMC5241_UV_CP_MASK 0x00000004 +#define TMC5241_UV_CP_SHIFT 2 +#define TMC5241_UV_CP_FIELD ((RegisterField) {TMC5241_UV_CP_MASK, TMC5241_UV_CP_SHIFT, TMC5241_GSTAT, false}) +#define TMC5241_REGISTER_RESET_MASK 0x00000008 +#define TMC5241_REGISTER_RESET_SHIFT 3 +#define TMC5241_REGISTER_RESET_FIELD ((RegisterField) {TMC5241_REGISTER_RESET_MASK, TMC5241_REGISTER_RESET_SHIFT, TMC5241_GSTAT, false}) +#define TMC5241_VM_UVLO_MASK 0x00000010 +#define TMC5241_VM_UVLO_SHIFT 4 +#define TMC5241_VM_UVLO_FIELD ((RegisterField) {TMC5241_VM_UVLO_MASK, TMC5241_VM_UVLO_SHIFT, TMC5241_GSTAT, false}) +#define TMC5241_IFCNT_MASK 0x000000FF +#define TMC5241_IFCNT_SHIFT 0 +#define TMC5241_IFCNT_FIELD ((RegisterField) {TMC5241_IFCNT_MASK, TMC5241_IFCNT_SHIFT, TMC5241_IFCNT, false}) +#define TMC5241_SLAVEADDR_MASK 0x000000FF +#define TMC5241_SLAVEADDR_SHIFT 0 +#define TMC5241_SLAVEADDR_FIELD ((RegisterField) {TMC5241_SLAVEADDR_MASK, TMC5241_SLAVEADDR_SHIFT, TMC5241_SLAVECONF, false}) +#define TMC5241_SENDDELAY_MASK 0x00000F00 +#define TMC5241_SENDDELAY_SHIFT 8 +#define TMC5241_SENDDELAY_FIELD ((RegisterField) {TMC5241_SENDDELAY_MASK, TMC5241_SENDDELAY_SHIFT, TMC5241_SLAVECONF, false}) +#define TMC5241_REFL_MASK 0x00000001 +#define TMC5241_REFL_SHIFT 0 +#define TMC5241_REFL_FIELD ((RegisterField) {TMC5241_REFL_MASK, TMC5241_REFL_SHIFT, TMC5241_IOIN, false}) +#define TMC5241_REFR_MASK 0x00000002 +#define TMC5241_REFR_SHIFT 1 +#define TMC5241_REFR_FIELD ((RegisterField) {TMC5241_REFR_MASK, TMC5241_REFR_SHIFT, TMC5241_IOIN, false}) +#define TMC5241_ENCB_MASK 0x00000004 +#define TMC5241_ENCB_SHIFT 2 +#define TMC5241_ENCB_FIELD ((RegisterField) {TMC5241_ENCB_MASK, TMC5241_ENCB_SHIFT, TMC5241_IOIN, false}) +#define TMC5241_ENCA_MASK 0x00000008 +#define TMC5241_ENCA_SHIFT 3 +#define TMC5241_ENCA_FIELD ((RegisterField) {TMC5241_ENCA_MASK, TMC5241_ENCA_SHIFT, TMC5241_IOIN, false}) +#define TMC5241_DRV_ENN_MASK 0x00000010 +#define TMC5241_DRV_ENN_SHIFT 4 +#define TMC5241_DRV_ENN_FIELD ((RegisterField) {TMC5241_DRV_ENN_MASK, TMC5241_DRV_ENN_SHIFT, TMC5241_IOIN, false}) +#define TMC5241_ENCN_MASK 0x00000020 +#define TMC5241_ENCN_SHIFT 5 +#define TMC5241_ENCN_FIELD ((RegisterField) {TMC5241_ENCN_MASK, TMC5241_ENCN_SHIFT, TMC5241_IOIN, false}) +#define TMC5241_UART_EN_MASK 0x00000040 +#define TMC5241_UART_EN_SHIFT 6 +#define TMC5241_UART_EN_FIELD ((RegisterField) {TMC5241_UART_EN_MASK, TMC5241_UART_EN_SHIFT, TMC5241_IOIN, false}) +#define TMC5241_RESERVED_MASK 0x00000080 +#define TMC5241_RESERVED_SHIFT 7 +#define TMC5241_RESERVED_FIELD ((RegisterField) {TMC5241_RESERVED_MASK, TMC5241_RESERVED_SHIFT, TMC5241_IOIN, false}) +#define TMC5241_COMP_A_MASK 0x00000100 +#define TMC5241_COMP_A_SHIFT 8 +#define TMC5241_COMP_A_FIELD ((RegisterField) {TMC5241_COMP_A_MASK, TMC5241_COMP_A_SHIFT, TMC5241_IOIN, false}) +#define TMC5241_COMP_B_MASK 0x00000200 +#define TMC5241_COMP_B_SHIFT 9 +#define TMC5241_COMP_B_FIELD ((RegisterField) {TMC5241_COMP_B_MASK, TMC5241_COMP_B_SHIFT, TMC5241_IOIN, false}) +#define TMC5241_COMP_A1_A2_MASK 0x00000400 +#define TMC5241_COMP_A1_A2_SHIFT 10 +#define TMC5241_COMP_A1_A2_FIELD ((RegisterField) {TMC5241_COMP_A1_A2_MASK, TMC5241_COMP_A1_A2_SHIFT, TMC5241_IOIN, false}) +#define TMC5241_COMP_B1_B2_MASK 0x00000800 +#define TMC5241_COMP_B1_B2_SHIFT 11 +#define TMC5241_COMP_B1_B2_FIELD ((RegisterField) {TMC5241_COMP_B1_B2_MASK, TMC5241_COMP_B1_B2_SHIFT, TMC5241_IOIN, false}) +#define TMC5241_OUTPUT_MASK 0x00001000 +#define TMC5241_OUTPUT_SHIFT 12 +#define TMC5241_OUTPUT_FIELD ((RegisterField) {TMC5241_OUTPUT_MASK, TMC5241_OUTPUT_SHIFT, TMC5241_IOIN, false}) +#define TMC5241_EXT_RES_DET_MASK 0x00002000 +#define TMC5241_EXT_RES_DET_SHIFT 13 +#define TMC5241_EXT_RES_DET_FIELD ((RegisterField) {TMC5241_EXT_RES_DET_MASK, TMC5241_EXT_RES_DET_SHIFT, TMC5241_IOIN, false}) +#define TMC5241_EXT_CLK_MASK 0x00004000 +#define TMC5241_EXT_CLK_SHIFT 14 +#define TMC5241_EXT_CLK_FIELD ((RegisterField) {TMC5241_EXT_CLK_MASK, TMC5241_EXT_CLK_SHIFT, TMC5241_IOIN, false}) +#define TMC5241_ADC_ERR_MASK 0x00008000 +#define TMC5241_ADC_ERR_SHIFT 15 +#define TMC5241_ADC_ERR_FIELD ((RegisterField) {TMC5241_ADC_ERR_MASK, TMC5241_ADC_ERR_SHIFT, TMC5241_IOIN, false}) +#define TMC5241_SILICON_RV_MASK 0x00070000 +#define TMC5241_SILICON_RV_SHIFT 16 +#define TMC5241_SILICON_RV_FIELD ((RegisterField) {TMC5241_SILICON_RV_MASK, TMC5241_SILICON_RV_SHIFT, TMC5241_IOIN, false}) +#define TMC5241_VERSION_MASK 0xFF000000 +#define TMC5241_VERSION_SHIFT 24 +#define TMC5241_VERSION_FIELD ((RegisterField) {TMC5241_VERSION_MASK, TMC5241_VERSION_SHIFT, TMC5241_IOIN, false}) +#define TMC5241_X_COMPARE_MASK 0xFFFFFFFF +#define TMC5241_X_COMPARE_SHIFT 0 +#define TMC5241_X_COMPARE_FIELD ((RegisterField) {TMC5241_X_COMPARE_MASK, TMC5241_X_COMPARE_SHIFT, TMC5241_X_COMPARE, true}) +#define TMC5241_X_COMPARE_REPEAT_MASK 0x00FFFFFF +#define TMC5241_X_COMPARE_REPEAT_SHIFT 0 +#define TMC5241_X_COMPARE_REPEAT_FIELD ((RegisterField) {TMC5241_X_COMPARE_REPEAT_MASK, TMC5241_X_COMPARE_REPEAT_SHIFT, TMC5241_X_COMPARE_REPEAT, false}) +#define TMC5241_DIAG0_ERROR_MASK 0x00000001 +#define TMC5241_DIAG0_ERROR_SHIFT 0 +#define TMC5241_DIAG0_ERROR_FIELD ((RegisterField) {TMC5241_DIAG0_ERROR_MASK, TMC5241_DIAG0_ERROR_SHIFT, TMC5241_DIAG_GCONF, false}) +#define TMC5241_DIAG0_OTPW_MASK 0x00000002 +#define TMC5241_DIAG0_OTPW_SHIFT 1 +#define TMC5241_DIAG0_OTPW_FIELD ((RegisterField) {TMC5241_DIAG0_OTPW_MASK, TMC5241_DIAG0_OTPW_SHIFT, TMC5241_DIAG_GCONF, false}) +#define TMC5241_DIAG0_STALL_MASK 0x00000004 +#define TMC5241_DIAG0_STALL_SHIFT 2 +#define TMC5241_DIAG0_STALL_FIELD ((RegisterField) {TMC5241_DIAG0_STALL_MASK, TMC5241_DIAG0_STALL_SHIFT, TMC5241_DIAG_GCONF, false}) +#define TMC5241_DIAG0_INDEX_MASK 0x00000008 +#define TMC5241_DIAG0_INDEX_SHIFT 3 +#define TMC5241_DIAG0_INDEX_FIELD ((RegisterField) {TMC5241_DIAG0_INDEX_MASK, TMC5241_DIAG0_INDEX_SHIFT, TMC5241_DIAG_GCONF, false}) +#define TMC5241_DIAG0_STEP_MASK 0x00000010 +#define TMC5241_DIAG0_STEP_SHIFT 4 +#define TMC5241_DIAG0_STEP_FIELD ((RegisterField) {TMC5241_DIAG0_STEP_MASK, TMC5241_DIAG0_STEP_SHIFT, TMC5241_DIAG_GCONF, false}) +#define TMC5241_DIAG0_DIR_MASK 0x00000020 +#define TMC5241_DIAG0_DIR_SHIFT 5 +#define TMC5241_DIAG0_DIR_FIELD ((RegisterField) {TMC5241_DIAG0_DIR_MASK, TMC5241_DIAG0_DIR_SHIFT, TMC5241_DIAG_GCONF, false}) +#define TMC5241_DIAG0_XCOMP_MASK 0x00000040 +#define TMC5241_DIAG0_XCOMP_SHIFT 6 +#define TMC5241_DIAG0_XCOMP_FIELD ((RegisterField) {TMC5241_DIAG0_XCOMP_MASK, TMC5241_DIAG0_XCOMP_SHIFT, TMC5241_DIAG_GCONF, false}) +#define TMC5241_DIAG0_EV_STOP_REF_MASK 0x00000080 +#define TMC5241_DIAG0_EV_STOP_REF_SHIFT 7 +#define TMC5241_DIAG0_EV_STOP_REF_FIELD ((RegisterField) {TMC5241_DIAG0_EV_STOP_REF_MASK, TMC5241_DIAG0_EV_STOP_REF_SHIFT, TMC5241_DIAG_GCONF, false}) +#define TMC5241_DIAG0_EV_STOP_SG_MASK 0x00000100 +#define TMC5241_DIAG0_EV_STOP_SG_SHIFT 8 +#define TMC5241_DIAG0_EV_STOP_SG_FIELD ((RegisterField) {TMC5241_DIAG0_EV_STOP_SG_MASK, TMC5241_DIAG0_EV_STOP_SG_SHIFT, TMC5241_DIAG_GCONF, false}) +#define TMC5241_DIAG0_EV_POS_REACHED_MASK 0x00000200 +#define TMC5241_DIAG0_EV_POS_REACHED_SHIFT 9 +#define TMC5241_DIAG0_EV_POS_REACHED_FIELD ((RegisterField) {TMC5241_DIAG0_EV_POS_REACHED_MASK, TMC5241_DIAG0_EV_POS_REACHED_SHIFT, TMC5241_DIAG_GCONF, false}) +#define TMC5241_DIAG0_EV_N_DEVIATION_MASK 0x00000400 +#define TMC5241_DIAG0_EV_N_DEVIATION_SHIFT 10 +#define TMC5241_DIAG0_EV_N_DEVIATION_FIELD ((RegisterField) {TMC5241_DIAG0_EV_N_DEVIATION_MASK, TMC5241_DIAG0_EV_N_DEVIATION_SHIFT, TMC5241_DIAG_GCONF, false}) +#define TMC5241_DIAG0_OVERVOLTAGE_MASK 0x00000800 +#define TMC5241_DIAG0_OVERVOLTAGE_SHIFT 11 +#define TMC5241_DIAG0_OVERVOLTAGE_FIELD ((RegisterField) {TMC5241_DIAG0_OVERVOLTAGE_MASK, TMC5241_DIAG0_OVERVOLTAGE_SHIFT, TMC5241_DIAG_GCONF, false}) +#define TMC5241_DIAG1_ERROR_MASK 0x00010000 +#define TMC5241_DIAG1_ERROR_SHIFT 16 +#define TMC5241_DIAG1_ERROR_FIELD ((RegisterField) {TMC5241_DIAG1_ERROR_MASK, TMC5241_DIAG1_ERROR_SHIFT, TMC5241_DIAG_GCONF, false}) +#define TMC5241_DIAG1_OTPW_MASK 0x00020000 +#define TMC5241_DIAG1_OTPW_SHIFT 17 +#define TMC5241_DIAG1_OTPW_FIELD ((RegisterField) {TMC5241_DIAG1_OTPW_MASK, TMC5241_DIAG1_OTPW_SHIFT, TMC5241_DIAG_GCONF, false}) +#define TMC5241_DIAG1_STALL_MASK 0x00040000 +#define TMC5241_DIAG1_STALL_SHIFT 18 +#define TMC5241_DIAG1_STALL_FIELD ((RegisterField) {TMC5241_DIAG1_STALL_MASK, TMC5241_DIAG1_STALL_SHIFT, TMC5241_DIAG_GCONF, false}) +#define TMC5241_DIAG1_INDEX_MASK 0x00080000 +#define TMC5241_DIAG1_INDEX_SHIFT 19 +#define TMC5241_DIAG1_INDEX_FIELD ((RegisterField) {TMC5241_DIAG1_INDEX_MASK, TMC5241_DIAG1_INDEX_SHIFT, TMC5241_DIAG_GCONF, false}) +#define TMC5241_DIAG1_STEP_MASK 0x00100000 +#define TMC5241_DIAG1_STEP_SHIFT 20 +#define TMC5241_DIAG1_STEP_FIELD ((RegisterField) {TMC5241_DIAG1_STEP_MASK, TMC5241_DIAG1_STEP_SHIFT, TMC5241_DIAG_GCONF, false}) +#define TMC5241_DIAG1_DIR_MASK 0x00200000 +#define TMC5241_DIAG1_DIR_SHIFT 21 +#define TMC5241_DIAG1_DIR_FIELD ((RegisterField) {TMC5241_DIAG1_DIR_MASK, TMC5241_DIAG1_DIR_SHIFT, TMC5241_DIAG_GCONF, false}) +#define TMC5241_DIAG1_XCOMP_MASK 0x00400000 +#define TMC5241_DIAG1_XCOMP_SHIFT 22 +#define TMC5241_DIAG1_XCOMP_FIELD ((RegisterField) {TMC5241_DIAG1_XCOMP_MASK, TMC5241_DIAG1_XCOMP_SHIFT, TMC5241_DIAG_GCONF, false}) +#define TMC5241_DIAG1_EV_STOP_REF_MASK 0x00800000 +#define TMC5241_DIAG1_EV_STOP_REF_SHIFT 23 +#define TMC5241_DIAG1_EV_STOP_REF_FIELD ((RegisterField) {TMC5241_DIAG1_EV_STOP_REF_MASK, TMC5241_DIAG1_EV_STOP_REF_SHIFT, TMC5241_DIAG_GCONF, false}) +#define TMC5241_DIAG1_EV_STOP_SG_MASK 0x01000000 +#define TMC5241_DIAG1_EV_STOP_SG_SHIFT 24 +#define TMC5241_DIAG1_EV_STOP_SG_FIELD ((RegisterField) {TMC5241_DIAG1_EV_STOP_SG_MASK, TMC5241_DIAG1_EV_STOP_SG_SHIFT, TMC5241_DIAG_GCONF, false}) +#define TMC5241_DIAG1_EV_POS_REACHED_MASK 0x02000000 +#define TMC5241_DIAG1_EV_POS_REACHED_SHIFT 25 +#define TMC5241_DIAG1_EV_POS_REACHED_FIELD ((RegisterField) {TMC5241_DIAG1_EV_POS_REACHED_MASK, TMC5241_DIAG1_EV_POS_REACHED_SHIFT, TMC5241_DIAG_GCONF, false}) +#define TMC5241_DIAG1_EV_N_DEVIATION_MASK 0x04000000 +#define TMC5241_DIAG1_EV_N_DEVIATION_SHIFT 26 +#define TMC5241_DIAG1_EV_N_DEVIATION_FIELD ((RegisterField) {TMC5241_DIAG1_EV_N_DEVIATION_MASK, TMC5241_DIAG1_EV_N_DEVIATION_SHIFT, TMC5241_DIAG_GCONF, false}) +#define TMC5241_DIAG1_OVERVOLTAGE_MASK 0x08000000 +#define TMC5241_DIAG1_OVERVOLTAGE_SHIFT 27 +#define TMC5241_DIAG1_OVERVOLTAGE_FIELD ((RegisterField) {TMC5241_DIAG1_OVERVOLTAGE_MASK, TMC5241_DIAG1_OVERVOLTAGE_SHIFT, TMC5241_DIAG_GCONF, false}) +#define TMC5241_CURRENT_RANGE_MASK 0x00000003 +#define TMC5241_CURRENT_RANGE_SHIFT 0 +#define TMC5241_CURRENT_RANGE_FIELD ((RegisterField) {TMC5241_CURRENT_RANGE_MASK, TMC5241_CURRENT_RANGE_SHIFT, TMC5241_DRV_CONF, false}) +#define TMC5241_SLOPE_CONTROL_MASK 0x00000030 +#define TMC5241_SLOPE_CONTROL_SHIFT 4 +#define TMC5241_SLOPE_CONTROL_FIELD ((RegisterField) {TMC5241_SLOPE_CONTROL_MASK, TMC5241_SLOPE_CONTROL_SHIFT, TMC5241_DRV_CONF, false}) +#define TMC5241_GLOBAL_SCALER_MASK 0x000000FF +#define TMC5241_GLOBAL_SCALER_SHIFT 0 +#define TMC5241_GLOBAL_SCALER_FIELD ((RegisterField) {TMC5241_GLOBAL_SCALER_MASK, TMC5241_GLOBAL_SCALER_SHIFT, TMC5241_GLOBAL_SCALER, false}) +#define TMC5241_IHOLD_MASK 0x0000001F +#define TMC5241_IHOLD_SHIFT 0 +#define TMC5241_IHOLD_FIELD ((RegisterField) {TMC5241_IHOLD_MASK, TMC5241_IHOLD_SHIFT, TMC5241_IHOLD_IRUN, false}) +#define TMC5241_IRUN_MASK 0x00001F00 +#define TMC5241_IRUN_SHIFT 8 +#define TMC5241_IRUN_FIELD ((RegisterField) {TMC5241_IRUN_MASK, TMC5241_IRUN_SHIFT, TMC5241_IHOLD_IRUN, false}) +#define TMC5241_IHOLDDELAY_MASK 0x000F0000 +#define TMC5241_IHOLDDELAY_SHIFT 16 +#define TMC5241_IHOLDDELAY_FIELD ((RegisterField) {TMC5241_IHOLDDELAY_MASK, TMC5241_IHOLDDELAY_SHIFT, TMC5241_IHOLD_IRUN, false}) +#define TMC5241_IRUNDELAY_MASK 0x0F000000 +#define TMC5241_IRUNDELAY_SHIFT 24 +#define TMC5241_IRUNDELAY_FIELD ((RegisterField) {TMC5241_IRUNDELAY_MASK, TMC5241_IRUNDELAY_SHIFT, TMC5241_IHOLD_IRUN, false}) +#define TMC5241_TPOWERDOWN_MASK 0x000000FF +#define TMC5241_TPOWERDOWN_SHIFT 0 +#define TMC5241_TPOWERDOWN_FIELD ((RegisterField) {TMC5241_TPOWERDOWN_MASK, TMC5241_TPOWERDOWN_SHIFT, TMC5241_TPOWERDOWN, false}) +#define TMC5241_TSTEP_MASK 0x000FFFFF +#define TMC5241_TSTEP_SHIFT 0 +#define TMC5241_TSTEP_FIELD ((RegisterField) {TMC5241_TSTEP_MASK, TMC5241_TSTEP_SHIFT, TMC5241_TSTEP, false}) +#define TMC5241_TPWMTHRS_MASK 0x000FFFFF +#define TMC5241_TPWMTHRS_SHIFT 0 +#define TMC5241_TPWMTHRS_FIELD ((RegisterField) {TMC5241_TPWMTHRS_MASK, TMC5241_TPWMTHRS_SHIFT, TMC5241_TPWMTHRS, false}) +#define TMC5241_TCOOLTHRS_MASK 0x000FFFFF +#define TMC5241_TCOOLTHRS_SHIFT 0 +#define TMC5241_TCOOLTHRS_FIELD ((RegisterField) {TMC5241_TCOOLTHRS_MASK, TMC5241_TCOOLTHRS_SHIFT, TMC5241_TCOOLTHRS, false}) +#define TMC5241_THIGH_MASK 0x000FFFFF +#define TMC5241_THIGH_SHIFT 0 +#define TMC5241_THIGH_FIELD ((RegisterField) {TMC5241_THIGH_MASK, TMC5241_THIGH_SHIFT, TMC5241_THIGH, false}) +#define TMC5241_RAMPMODE_MASK 0x00000003 +#define TMC5241_RAMPMODE_SHIFT 0 +#define TMC5241_RAMPMODE_FIELD ((RegisterField) {TMC5241_RAMPMODE_MASK, TMC5241_RAMPMODE_SHIFT, TMC5241_RAMPMODE, false}) +#define TMC5241_XACTUAL_MASK 0xFFFFFFFF +#define TMC5241_XACTUAL_SHIFT 0 +#define TMC5241_XACTUAL_FIELD ((RegisterField) {TMC5241_XACTUAL_MASK, TMC5241_XACTUAL_SHIFT, TMC5241_XACTUAL, true}) +#define TMC5241_VACTUAL_MASK 0x00FFFFFF +#define TMC5241_VACTUAL_SHIFT 0 +#define TMC5241_VACTUAL_FIELD ((RegisterField) {TMC5241_VACTUAL_MASK, TMC5241_VACTUAL_SHIFT, TMC5241_VACTUAL, true}) +#define TMC5241_VSTART_MASK 0x0003FFFF +#define TMC5241_VSTART_SHIFT 0 +#define TMC5241_VSTART_FIELD ((RegisterField) {TMC5241_VSTART_MASK, TMC5241_VSTART_SHIFT, TMC5241_VSTART, false}) +#define TMC5241_A1_MASK 0x0003FFFF +#define TMC5241_A1_SHIFT 0 +#define TMC5241_A1_FIELD ((RegisterField) {TMC5241_A1_MASK, TMC5241_A1_SHIFT, TMC5241_A1, false}) +#define TMC5241_V1_MASK 0x000FFFFF +#define TMC5241_V1_SHIFT 0 +#define TMC5241_V1_FIELD ((RegisterField) {TMC5241_V1_MASK, TMC5241_V1_SHIFT, TMC5241_V1, false}) +#define TMC5241_AMAX_MASK 0x0003FFFF +#define TMC5241_AMAX_SHIFT 0 +#define TMC5241_AMAX_FIELD ((RegisterField) {TMC5241_AMAX_MASK, TMC5241_AMAX_SHIFT, TMC5241_AMAX, false}) +#define TMC5241_VMAX_MASK 0x007FFFFF +#define TMC5241_VMAX_SHIFT 0 +#define TMC5241_VMAX_FIELD ((RegisterField) {TMC5241_VMAX_MASK, TMC5241_VMAX_SHIFT, TMC5241_VMAX, false}) +#define TMC5241_DMAX_MASK 0x0003FFFF +#define TMC5241_DMAX_SHIFT 0 +#define TMC5241_DMAX_FIELD ((RegisterField) {TMC5241_DMAX_MASK, TMC5241_DMAX_SHIFT, TMC5241_DMAX, false}) +#define TMC5241_TVMAX_MASK 0x0000FFFF +#define TMC5241_TVMAX_SHIFT 0 +#define TMC5241_TVMAX_FIELD ((RegisterField) {TMC5241_TVMAX_MASK, TMC5241_TVMAX_SHIFT, TMC5241_TVMAX, false}) +#define TMC5241_D1_MASK 0x0003FFFF +#define TMC5241_D1_SHIFT 0 +#define TMC5241_D1_FIELD ((RegisterField) {TMC5241_D1_MASK, TMC5241_D1_SHIFT, TMC5241_D1, false}) +#define TMC5241_VSTOP_MASK 0x0003FFFF +#define TMC5241_VSTOP_SHIFT 0 +#define TMC5241_VSTOP_FIELD ((RegisterField) {TMC5241_VSTOP_MASK, TMC5241_VSTOP_SHIFT, TMC5241_VSTOP, false}) +#define TMC5241_TZEROWAIT_MASK 0x0000FFFF +#define TMC5241_TZEROWAIT_SHIFT 0 +#define TMC5241_TZEROWAIT_FIELD ((RegisterField) {TMC5241_TZEROWAIT_MASK, TMC5241_TZEROWAIT_SHIFT, TMC5241_TZEROWAIT, false}) +#define TMC5241_XTARGET_MASK 0xFFFFFFFF +#define TMC5241_XTARGET_SHIFT 0 +#define TMC5241_XTARGET_FIELD ((RegisterField) {TMC5241_XTARGET_MASK, TMC5241_XTARGET_SHIFT, TMC5241_XTARGET, true}) +#define TMC5241_V2_MASK 0x000FFFFF +#define TMC5241_V2_SHIFT 0 +#define TMC5241_V2_FIELD ((RegisterField) {TMC5241_V2_MASK, TMC5241_V2_SHIFT, TMC5241_V2, false}) +#define TMC5241_A2_MASK 0x0003FFFF +#define TMC5241_A2_SHIFT 0 +#define TMC5241_A2_FIELD ((RegisterField) {TMC5241_A2_MASK, TMC5241_A2_SHIFT, TMC5241_A2, false}) +#define TMC5241_D2_MASK 0x0003FFFF +#define TMC5241_D2_SHIFT 0 +#define TMC5241_D2_FIELD ((RegisterField) {TMC5241_D2_MASK, TMC5241_D2_SHIFT, TMC5241_D2, false}) +#define TMC5241_AACTUAL_MASK 0x00FFFFFF +#define TMC5241_AACTUAL_SHIFT 0 +#define TMC5241_AACTUAL_FIELD ((RegisterField) {TMC5241_AACTUAL_MASK, TMC5241_AACTUAL_SHIFT, TMC5241_AACTUAL, true}) +//#define TMC5241_RESERVED_MASK 0x000000FF +//#define TMC5241_RESERVED_SHIFT 0 +//#define TMC5241_RESERVED_FIELD ((RegisterField) {TMC5241_RESERVED_MASK, TMC5241_RESERVED_SHIFT, TMC5241_VDCMIN, false}) +#define TMC5241_VDCMIN_MASK 0x007FFF00 +#define TMC5241_VDCMIN_SHIFT 0 +#define TMC5241_VDCMIN_FIELD ((RegisterField) {TMC5241_VDCMIN_MASK, TMC5241_VDCMIN_SHIFT, TMC5241_VDCMIN, false}) +#define TMC5241_STOP_L_ENABLE_MASK 0x00000001 +#define TMC5241_STOP_L_ENABLE_SHIFT 0 +#define TMC5241_STOP_L_ENABLE_FIELD ((RegisterField) {TMC5241_STOP_L_ENABLE_MASK, TMC5241_STOP_L_ENABLE_SHIFT, TMC5241_SW_MODE, false}) +#define TMC5241_STOP_R_ENABLE_MASK 0x00000002 +#define TMC5241_STOP_R_ENABLE_SHIFT 1 +#define TMC5241_STOP_R_ENABLE_FIELD ((RegisterField) {TMC5241_STOP_R_ENABLE_MASK, TMC5241_STOP_R_ENABLE_SHIFT, TMC5241_SW_MODE, false}) +#define TMC5241_POL_STOP_L_MASK 0x00000004 +#define TMC5241_POL_STOP_L_SHIFT 2 +#define TMC5241_POL_STOP_L_FIELD ((RegisterField) {TMC5241_POL_STOP_L_MASK, TMC5241_POL_STOP_L_SHIFT, TMC5241_SW_MODE, false}) +#define TMC5241_POL_STOP_R_MASK 0x00000008 +#define TMC5241_POL_STOP_R_SHIFT 3 +#define TMC5241_POL_STOP_R_FIELD ((RegisterField) {TMC5241_POL_STOP_R_MASK, TMC5241_POL_STOP_R_SHIFT, TMC5241_SW_MODE, false}) +#define TMC5241_SWAP_LR_MASK 0x00000010 +#define TMC5241_SWAP_LR_SHIFT 4 +#define TMC5241_SWAP_LR_FIELD ((RegisterField) {TMC5241_SWAP_LR_MASK, TMC5241_SWAP_LR_SHIFT, TMC5241_SW_MODE, false}) +#define TMC5241_LATCH_L_ACTIVE_MASK 0x00000020 +#define TMC5241_LATCH_L_ACTIVE_SHIFT 5 +#define TMC5241_LATCH_L_ACTIVE_FIELD ((RegisterField) {TMC5241_LATCH_L_ACTIVE_MASK, TMC5241_LATCH_L_ACTIVE_SHIFT, TMC5241_SW_MODE, false}) +#define TMC5241_LATCH_L_INACTIVE_MASK 0x00000040 +#define TMC5241_LATCH_L_INACTIVE_SHIFT 6 +#define TMC5241_LATCH_L_INACTIVE_FIELD ((RegisterField) {TMC5241_LATCH_L_INACTIVE_MASK, TMC5241_LATCH_L_INACTIVE_SHIFT, TMC5241_SW_MODE, false}) +#define TMC5241_LATCH_R_ACTIVE_MASK 0x00000080 +#define TMC5241_LATCH_R_ACTIVE_SHIFT 7 +#define TMC5241_LATCH_R_ACTIVE_FIELD ((RegisterField) {TMC5241_LATCH_R_ACTIVE_MASK, TMC5241_LATCH_R_ACTIVE_SHIFT, TMC5241_SW_MODE, false}) +#define TMC5241_LATCH_R_INACTIVE_MASK 0x00000100 +#define TMC5241_LATCH_R_INACTIVE_SHIFT 8 +#define TMC5241_LATCH_R_INACTIVE_FIELD ((RegisterField) {TMC5241_LATCH_R_INACTIVE_MASK, TMC5241_LATCH_R_INACTIVE_SHIFT, TMC5241_SW_MODE, false}) +#define TMC5241_EN_LATCH_ENCODER_MASK 0x00000200 +#define TMC5241_EN_LATCH_ENCODER_SHIFT 9 +#define TMC5241_EN_LATCH_ENCODER_FIELD ((RegisterField) {TMC5241_EN_LATCH_ENCODER_MASK, TMC5241_EN_LATCH_ENCODER_SHIFT, TMC5241_SW_MODE, false}) +#define TMC5241_SG_STOP_MASK 0x00000400 +#define TMC5241_SG_STOP_SHIFT 10 +#define TMC5241_SG_STOP_FIELD ((RegisterField) {TMC5241_SG_STOP_MASK, TMC5241_SG_STOP_SHIFT, TMC5241_SW_MODE, false}) +#define TMC5241_EN_SOFTSTOP_MASK 0x00000800 +#define TMC5241_EN_SOFTSTOP_SHIFT 11 +#define TMC5241_EN_SOFTSTOP_FIELD ((RegisterField) {TMC5241_EN_SOFTSTOP_MASK, TMC5241_EN_SOFTSTOP_SHIFT, TMC5241_SW_MODE, false}) +#define TMC5241_EN_VIRTUAL_STOP_L_MASK 0x00001000 +#define TMC5241_EN_VIRTUAL_STOP_L_SHIFT 12 +#define TMC5241_EN_VIRTUAL_STOP_L_FIELD ((RegisterField) {TMC5241_EN_VIRTUAL_STOP_L_MASK, TMC5241_EN_VIRTUAL_STOP_L_SHIFT, TMC5241_SW_MODE, false}) +#define TMC5241_EN_VIRTUAL_STOP_R_MASK 0x00002000 +#define TMC5241_EN_VIRTUAL_STOP_R_SHIFT 13 +#define TMC5241_EN_VIRTUAL_STOP_R_FIELD ((RegisterField) {TMC5241_EN_VIRTUAL_STOP_R_MASK, TMC5241_EN_VIRTUAL_STOP_R_SHIFT, TMC5241_SW_MODE, false}) +#define TMC5241_VIRTUAL_STOP_ENC_MASK 0x00004000 +#define TMC5241_VIRTUAL_STOP_ENC_SHIFT 14 +#define TMC5241_VIRTUAL_STOP_ENC_FIELD ((RegisterField) {TMC5241_VIRTUAL_STOP_ENC_MASK, TMC5241_VIRTUAL_STOP_ENC_SHIFT, TMC5241_SW_MODE, false}) +#define TMC5241_STATUS_STOP_L_MASK 0x00000001 +#define TMC5241_STATUS_STOP_L_SHIFT 0 +#define TMC5241_STATUS_STOP_L_FIELD ((RegisterField) {TMC5241_STATUS_STOP_L_MASK, TMC5241_STATUS_STOP_L_SHIFT, TMC5241_RAMP_STAT, false}) +#define TMC5241_STATUS_STOP_R_MASK 0x00000002 +#define TMC5241_STATUS_STOP_R_SHIFT 1 +#define TMC5241_STATUS_STOP_R_FIELD ((RegisterField) {TMC5241_STATUS_STOP_R_MASK, TMC5241_STATUS_STOP_R_SHIFT, TMC5241_RAMP_STAT, false}) +#define TMC5241_STATUS_LATCH_L_MASK 0x00000004 +#define TMC5241_STATUS_LATCH_L_SHIFT 2 +#define TMC5241_STATUS_LATCH_L_FIELD ((RegisterField) {TMC5241_STATUS_LATCH_L_MASK, TMC5241_STATUS_LATCH_L_SHIFT, TMC5241_RAMP_STAT, false}) +#define TMC5241_STATUS_LATCH_R_MASK 0x00000008 +#define TMC5241_STATUS_LATCH_R_SHIFT 3 +#define TMC5241_STATUS_LATCH_R_FIELD ((RegisterField) {TMC5241_STATUS_LATCH_R_MASK, TMC5241_STATUS_LATCH_R_SHIFT, TMC5241_RAMP_STAT, false}) +#define TMC5241_EVENT_STOP_L_MASK 0x00000010 +#define TMC5241_EVENT_STOP_L_SHIFT 4 +#define TMC5241_EVENT_STOP_L_FIELD ((RegisterField) {TMC5241_EVENT_STOP_L_MASK, TMC5241_EVENT_STOP_L_SHIFT, TMC5241_RAMP_STAT, false}) +#define TMC5241_EVENT_STOP_R_MASK 0x00000020 +#define TMC5241_EVENT_STOP_R_SHIFT 5 +#define TMC5241_EVENT_STOP_R_FIELD ((RegisterField) {TMC5241_EVENT_STOP_R_MASK, TMC5241_EVENT_STOP_R_SHIFT, TMC5241_RAMP_STAT, false}) +#define TMC5241_EVENT_STOP_SG_MASK 0x00000040 +#define TMC5241_EVENT_STOP_SG_SHIFT 6 +#define TMC5241_EVENT_STOP_SG_FIELD ((RegisterField) {TMC5241_EVENT_STOP_SG_MASK, TMC5241_EVENT_STOP_SG_SHIFT, TMC5241_RAMP_STAT, false}) +#define TMC5241_EVENT_POS_REACHED_MASK 0x00000080 +#define TMC5241_EVENT_POS_REACHED_SHIFT 7 +#define TMC5241_EVENT_POS_REACHED_FIELD ((RegisterField) {TMC5241_EVENT_POS_REACHED_MASK, TMC5241_EVENT_POS_REACHED_SHIFT, TMC5241_RAMP_STAT, false}) +#define TMC5241_VELOCITY_REACHED_MASK 0x00000100 +#define TMC5241_VELOCITY_REACHED_SHIFT 8 +#define TMC5241_VELOCITY_REACHED_FIELD ((RegisterField) {TMC5241_VELOCITY_REACHED_MASK, TMC5241_VELOCITY_REACHED_SHIFT, TMC5241_RAMP_STAT, false}) +#define TMC5241_POSITION_REACHED_MASK 0x00000200 +#define TMC5241_POSITION_REACHED_SHIFT 9 +#define TMC5241_POSITION_REACHED_FIELD ((RegisterField) {TMC5241_POSITION_REACHED_MASK, TMC5241_POSITION_REACHED_SHIFT, TMC5241_RAMP_STAT, false}) +#define TMC5241_VZERO_MASK 0x00000400 +#define TMC5241_VZERO_SHIFT 10 +#define TMC5241_VZERO_FIELD ((RegisterField) {TMC5241_VZERO_MASK, TMC5241_VZERO_SHIFT, TMC5241_RAMP_STAT, false}) +#define TMC5241_T_ZEROWAIT_ACTIVE_MASK 0x00000800 +#define TMC5241_T_ZEROWAIT_ACTIVE_SHIFT 11 +#define TMC5241_T_ZEROWAIT_ACTIVE_FIELD ((RegisterField) {TMC5241_T_ZEROWAIT_ACTIVE_MASK, TMC5241_T_ZEROWAIT_ACTIVE_SHIFT, TMC5241_RAMP_STAT, false}) +#define TMC5241_SECOND_MOVE_MASK 0x00001000 +#define TMC5241_SECOND_MOVE_SHIFT 12 +#define TMC5241_SECOND_MOVE_FIELD ((RegisterField) {TMC5241_SECOND_MOVE_MASK, TMC5241_SECOND_MOVE_SHIFT, TMC5241_RAMP_STAT, false}) +#define TMC5241_STATUS_SG_MASK 0x00002000 +#define TMC5241_STATUS_SG_SHIFT 13 +#define TMC5241_STATUS_SG_FIELD ((RegisterField) {TMC5241_STATUS_SG_MASK, TMC5241_STATUS_SG_SHIFT, TMC5241_RAMP_STAT, false}) +#define TMC5241_STATUS_VIRTUAL_STOP_L_MASK 0x00004000 +#define TMC5241_STATUS_VIRTUAL_STOP_L_SHIFT 14 +#define TMC5241_STATUS_VIRTUAL_STOP_L_FIELD ((RegisterField) {TMC5241_STATUS_VIRTUAL_STOP_L_MASK, TMC5241_STATUS_VIRTUAL_STOP_L_SHIFT, TMC5241_RAMP_STAT, false}) +#define TMC5241_STATUS_VIRTUAL_STOP_R_MASK 0x00008000 +#define TMC5241_STATUS_VIRTUAL_STOP_R_SHIFT 15 +#define TMC5241_STATUS_VIRTUAL_STOP_R_FIELD ((RegisterField) {TMC5241_STATUS_VIRTUAL_STOP_R_MASK, TMC5241_STATUS_VIRTUAL_STOP_R_SHIFT, TMC5241_RAMP_STAT, false}) +#define TMC5241_XLATCH_MASK 0xFFFFFFFF +#define TMC5241_XLATCH_SHIFT 0 +#define TMC5241_XLATCH_FIELD ((RegisterField) {TMC5241_XLATCH_MASK, TMC5241_XLATCH_SHIFT, TMC5241_XLATCH, true}) +#define TMC5241_POL_A_MASK 0x00000001 +#define TMC5241_POL_A_SHIFT 0 +#define TMC5241_POL_A_FIELD ((RegisterField) {TMC5241_POL_A_MASK, TMC5241_POL_A_SHIFT, TMC5241_ENCMODE, false}) +#define TMC5241_POL_B_MASK 0x00000002 +#define TMC5241_POL_B_SHIFT 1 +#define TMC5241_POL_B_FIELD ((RegisterField) {TMC5241_POL_B_MASK, TMC5241_POL_B_SHIFT, TMC5241_ENCMODE, false}) +#define TMC5241_POL_N_MASK 0x00000004 +#define TMC5241_POL_N_SHIFT 2 +#define TMC5241_POL_N_FIELD ((RegisterField) {TMC5241_POL_N_MASK, TMC5241_POL_N_SHIFT, TMC5241_ENCMODE, false}) +#define TMC5241_IGNORE_AB_MASK 0x00000008 +#define TMC5241_IGNORE_AB_SHIFT 3 +#define TMC5241_IGNORE_AB_FIELD ((RegisterField) {TMC5241_IGNORE_AB_MASK, TMC5241_IGNORE_AB_SHIFT, TMC5241_ENCMODE, false}) +#define TMC5241_CLR_CONT_MASK 0x00000010 +#define TMC5241_CLR_CONT_SHIFT 4 +#define TMC5241_CLR_CONT_FIELD ((RegisterField) {TMC5241_CLR_CONT_MASK, TMC5241_CLR_CONT_SHIFT, TMC5241_ENCMODE, false}) +#define TMC5241_CLR_ONCE_MASK 0x00000020 +#define TMC5241_CLR_ONCE_SHIFT 5 +#define TMC5241_CLR_ONCE_FIELD ((RegisterField) {TMC5241_CLR_ONCE_MASK, TMC5241_CLR_ONCE_SHIFT, TMC5241_ENCMODE, false}) +#define TMC5241_POS_NEG_EDGE_MASK 0x000000C0 +#define TMC5241_POS_NEG_EDGE_SHIFT 6 +#define TMC5241_POS_NEG_EDGE_FIELD ((RegisterField) {TMC5241_POS_NEG_EDGE_MASK, TMC5241_POS_NEG_EDGE_SHIFT, TMC5241_ENCMODE, false}) +#define TMC5241_CLR_ENC_X_MASK 0x00000100 +#define TMC5241_CLR_ENC_X_SHIFT 8 +#define TMC5241_CLR_ENC_X_FIELD ((RegisterField) {TMC5241_CLR_ENC_X_MASK, TMC5241_CLR_ENC_X_SHIFT, TMC5241_ENCMODE, false}) +#define TMC5241_LATCH_X_ACT_MASK 0x00000200 +#define TMC5241_LATCH_X_ACT_SHIFT 9 +#define TMC5241_LATCH_X_ACT_FIELD ((RegisterField) {TMC5241_LATCH_X_ACT_MASK, TMC5241_LATCH_X_ACT_SHIFT, TMC5241_ENCMODE, false}) +#define TMC5241_ENC_SEL_DECIMAL_MASK 0x00000400 +#define TMC5241_ENC_SEL_DECIMAL_SHIFT 10 +#define TMC5241_ENC_SEL_DECIMAL_FIELD ((RegisterField) {TMC5241_ENC_SEL_DECIMAL_MASK, TMC5241_ENC_SEL_DECIMAL_SHIFT, TMC5241_ENCMODE, false}) +#define TMC5241_X_ENC_MASK 0xFFFFFFFF +#define TMC5241_X_ENC_SHIFT 0 +#define TMC5241_X_ENC_FIELD ((RegisterField) {TMC5241_X_ENC_MASK, TMC5241_X_ENC_SHIFT, TMC5241_X_ENC, true}) +#define TMC5241_ENC_CONST_MASK 0xFFFFFFFF +#define TMC5241_ENC_CONST_SHIFT 0 +#define TMC5241_ENC_CONST_FIELD ((RegisterField) {TMC5241_ENC_CONST_MASK, TMC5241_ENC_CONST_SHIFT, TMC5241_ENC_CONST, true}) +#define TMC5241_N_EVENT_MASK 0x00000001 +#define TMC5241_N_EVENT_SHIFT 0 +#define TMC5241_N_EVENT_FIELD ((RegisterField) {TMC5241_N_EVENT_MASK, TMC5241_N_EVENT_SHIFT, TMC5241_ENC_STATUS, false}) +#define TMC5241_DEVIATION_WARN_MASK 0x00000002 +#define TMC5241_DEVIATION_WARN_SHIFT 1 +#define TMC5241_DEVIATION_WARN_FIELD ((RegisterField) {TMC5241_DEVIATION_WARN_MASK, TMC5241_DEVIATION_WARN_SHIFT, TMC5241_ENC_STATUS, false}) +#define TMC5241_ENC_LATCH_MASK 0xFFFFFFFF +#define TMC5241_ENC_LATCH_SHIFT 0 +#define TMC5241_ENC_LATCH_FIELD ((RegisterField) {TMC5241_ENC_LATCH_MASK, TMC5241_ENC_LATCH_SHIFT, TMC5241_ENC_LATCH, false}) +#define TMC5241_ENC_DEVIATION_MASK 0x000FFFFF +#define TMC5241_ENC_DEVIATION_SHIFT 0 +#define TMC5241_ENC_DEVIATION_FIELD ((RegisterField) {TMC5241_ENC_DEVIATION_MASK, TMC5241_ENC_DEVIATION_SHIFT, TMC5241_ENC_DEVIATION, false}) +#define TMC5241_VIRTUAL_STOP_L_MASK 0xFFFFFFFF +#define TMC5241_VIRTUAL_STOP_L_SHIFT 0 +#define TMC5241_VIRTUAL_STOP_L_FIELD ((RegisterField) {TMC5241_VIRTUAL_STOP_L_MASK, TMC5241_VIRTUAL_STOP_L_SHIFT, TMC5241_VIRTUAL_STOP_L, true}) +#define TMC5241_VIRTUAL_STOP_R_MASK 0xFFFFFFFF +#define TMC5241_VIRTUAL_STOP_R_SHIFT 0 +#define TMC5241_VIRTUAL_STOP_R_FIELD ((RegisterField) {TMC5241_VIRTUAL_STOP_R_MASK, TMC5241_VIRTUAL_STOP_R_SHIFT, TMC5241_VIRTUAL_STOP_R, true}) +#define TMC5241_ADC_VSUPPLY_MASK 0x00001FFF +#define TMC5241_ADC_VSUPPLY_SHIFT 0 +#define TMC5241_ADC_VSUPPLY_FIELD ((RegisterField) {TMC5241_ADC_VSUPPLY_MASK, TMC5241_ADC_VSUPPLY_SHIFT, TMC5241_ADC_VSUPPLY_AIN, true}) +#define TMC5241_ADC_AIN_MASK 0x1FFF0000 +#define TMC5241_ADC_AIN_SHIFT 16 +#define TMC5241_ADC_AIN_FIELD ((RegisterField) {TMC5241_ADC_AIN_MASK, TMC5241_ADC_AIN_SHIFT, TMC5241_ADC_VSUPPLY_AIN, true}) +#define TMC5241_ADC_TEMP_MASK 0x00001FFF +#define TMC5241_ADC_TEMP_SHIFT 0 +#define TMC5241_ADC_TEMP_FIELD ((RegisterField) {TMC5241_ADC_TEMP_MASK, TMC5241_ADC_TEMP_SHIFT, TMC5241_ADC_TEMP, true}) +//#define TMC5241_RESERVED_MASK 0x1FFF0000 +//#define TMC5241_RESERVED_SHIFT 16 +//#define TMC5241_RESERVED_FIELD ((RegisterField) {TMC5241_RESERVED_MASK, TMC5241_RESERVED_SHIFT, TMC5241_ADC_TEMP, false}) +#define TMC5241_OVERVOLTAGE_VTH_MASK 0x00001FFF +#define TMC5241_OVERVOLTAGE_VTH_SHIFT 0 +#define TMC5241_OVERVOLTAGE_VTH_FIELD ((RegisterField) {TMC5241_OVERVOLTAGE_VTH_MASK, TMC5241_OVERVOLTAGE_VTH_SHIFT, TMC5241_OTW_OV_VTH, false}) +#define TMC5241_OVERTEMPPREWARNING_VTH_MASK 0x1FFF0000 +#define TMC5241_OVERTEMPPREWARNING_VTH_SHIFT 16 +#define TMC5241_OVERTEMPPREWARNING_VTH_FIELD ((RegisterField) {TMC5241_OVERTEMPPREWARNING_VTH_MASK, TMC5241_OVERTEMPPREWARNING_VTH_SHIFT, TMC5241_OTW_OV_VTH, false}) +#define TMC5241_MSLUT___MASK 0xFFFFFFFF +#define TMC5241_MSLUT___SHIFT 0 +#define TMC5241_MSLUT___FIELD ((RegisterField) {TMC5241_MSLUT___MASK, TMC5241_MSLUT___SHIFT, TMC5241_MSLUT[0], false}) +//#define TMC5241_MSLUT___MASK 0xFFFFFFFF +//#define TMC5241_MSLUT___SHIFT 0 +//#define TMC5241_MSLUT___FIELD ((RegisterField) {TMC5241_MSLUT___MASK, TMC5241_MSLUT___SHIFT, TMC5241_MSLUT[1], false}) +//#define TMC5241_MSLUT___MASK 0xFFFFFFFF +//#define TMC5241_MSLUT___SHIFT 0 +//#define TMC5241_MSLUT___FIELD ((RegisterField) {TMC5241_MSLUT___MASK, TMC5241_MSLUT___SHIFT, TMC5241_MSLUT[2], false}) +//#define TMC5241_MSLUT___MASK 0xFFFFFFFF +//#define TMC5241_MSLUT___SHIFT 0 +//#define TMC5241_MSLUT___FIELD ((RegisterField) {TMC5241_MSLUT___MASK, TMC5241_MSLUT___SHIFT, TMC5241_MSLUT[3], false}) +//#define TMC5241_MSLUT___MASK 0xFFFFFFFF +//#define TMC5241_MSLUT___SHIFT 0 +//#define TMC5241_MSLUT___FIELD ((RegisterField) {TMC5241_MSLUT___MASK, TMC5241_MSLUT___SHIFT, TMC5241_MSLUT[4], false}) +//#define TMC5241_MSLUT___MASK 0xFFFFFFFF +//#define TMC5241_MSLUT___SHIFT 0 +//#define TMC5241_MSLUT___FIELD ((RegisterField) {TMC5241_MSLUT___MASK, TMC5241_MSLUT___SHIFT, TMC5241_MSLUT[5], false}) +//#define TMC5241_MSLUT___MASK 0xFFFFFFFF +//#define TMC5241_MSLUT___SHIFT 0 +//#define TMC5241_MSLUT___FIELD ((RegisterField) {TMC5241_MSLUT___MASK, TMC5241_MSLUT___SHIFT, TMC5241_MSLUT[6], false}) +//#define TMC5241_MSLUT___MASK 0xFFFFFFFF +//#define TMC5241_MSLUT___SHIFT 0 +//#define TMC5241_MSLUT___FIELD ((RegisterField) {TMC5241_MSLUT___MASK, TMC5241_MSLUT___SHIFT, TMC5241_MSLUT[7], false}) +#define TMC5241_W0_MASK 0x00000003 +#define TMC5241_W0_SHIFT 0 +#define TMC5241_W0_FIELD ((RegisterField) {TMC5241_W0_MASK, TMC5241_W0_SHIFT, TMC5241_MSLUTSEL, false}) +#define TMC5241_W1_MASK 0x0000000C +#define TMC5241_W1_SHIFT 2 +#define TMC5241_W1_FIELD ((RegisterField) {TMC5241_W1_MASK, TMC5241_W1_SHIFT, TMC5241_MSLUTSEL, false}) +#define TMC5241_W2_MASK 0x00000030 +#define TMC5241_W2_SHIFT 4 +#define TMC5241_W2_FIELD ((RegisterField) {TMC5241_W2_MASK, TMC5241_W2_SHIFT, TMC5241_MSLUTSEL, false}) +#define TMC5241_W3_MASK 0x000000C0 +#define TMC5241_W3_SHIFT 6 +#define TMC5241_W3_FIELD ((RegisterField) {TMC5241_W3_MASK, TMC5241_W3_SHIFT, TMC5241_MSLUTSEL, false}) +#define TMC5241_X1_MASK 0x0000FF00 +#define TMC5241_X1_SHIFT 8 +#define TMC5241_X1_FIELD ((RegisterField) {TMC5241_X1_MASK, TMC5241_X1_SHIFT, TMC5241_MSLUTSEL, false}) +#define TMC5241_X2_MASK 0x00FF0000 +#define TMC5241_X2_SHIFT 16 +#define TMC5241_X2_FIELD ((RegisterField) {TMC5241_X2_MASK, TMC5241_X2_SHIFT, TMC5241_MSLUTSEL, false}) +#define TMC5241_X3_MASK 0xFF000000 +#define TMC5241_X3_SHIFT 24 +#define TMC5241_X3_FIELD ((RegisterField) {TMC5241_X3_MASK, TMC5241_X3_SHIFT, TMC5241_MSLUTSEL, false}) +#define TMC5241_START_SIN_MASK 0x000000FF +#define TMC5241_START_SIN_SHIFT 0 +#define TMC5241_START_SIN_FIELD ((RegisterField) {TMC5241_START_SIN_MASK, TMC5241_START_SIN_SHIFT, TMC5241_MSLUTSTART, false}) +#define TMC5241_START_SIN90_MASK 0x00FF0000 +#define TMC5241_START_SIN90_SHIFT 16 +#define TMC5241_START_SIN90_FIELD ((RegisterField) {TMC5241_START_SIN90_MASK, TMC5241_START_SIN90_SHIFT, TMC5241_MSLUTSTART, false}) +#define TMC5241_OFFSET_SIN90_MASK 0xFF000000 +#define TMC5241_OFFSET_SIN90_SHIFT 24 +#define TMC5241_OFFSET_SIN90_FIELD ((RegisterField) {TMC5241_OFFSET_SIN90_MASK, TMC5241_OFFSET_SIN90_SHIFT, TMC5241_MSLUTSTART, false}) +#define TMC5241_MSCNT_MASK 0x000003FF +#define TMC5241_MSCNT_SHIFT 0 +#define TMC5241_MSCNT_FIELD ((RegisterField) {TMC5241_MSCNT_MASK, TMC5241_MSCNT_SHIFT, TMC5241_MSCNT, false}) +#define TMC5241_CUR_B_MASK 0x000001FF +#define TMC5241_CUR_B_SHIFT 0 +#define TMC5241_CUR_B_FIELD ((RegisterField) {TMC5241_CUR_B_MASK, TMC5241_CUR_B_SHIFT, TMC5241_MSCURACT, true}) +#define TMC5241_CUR_A_MASK 0x01FF0000 +#define TMC5241_CUR_A_SHIFT 16 +#define TMC5241_CUR_A_FIELD ((RegisterField) {TMC5241_CUR_A_MASK, TMC5241_CUR_A_SHIFT, TMC5241_MSCURACT, true}) +#define TMC5241_TOFF_MASK 0x0000000F +#define TMC5241_TOFF_SHIFT 0 +#define TMC5241_TOFF_FIELD ((RegisterField) {TMC5241_TOFF_MASK, TMC5241_TOFF_SHIFT, TMC5241_CHOPCONF, false}) +#define TMC5241_HSTRT_TFD210_MASK 0x00000070 +#define TMC5241_HSTRT_TFD210_SHIFT 4 +#define TMC5241_HSTRT_TFD210_FIELD ((RegisterField) {TMC5241_HSTRT_TFD210_MASK, TMC5241_HSTRT_TFD210_SHIFT, TMC5241_CHOPCONF, false}) +#define TMC5241_HEND_OFFSET_MASK 0x00000780 +#define TMC5241_HEND_OFFSET_SHIFT 7 +#define TMC5241_HEND_OFFSET_FIELD ((RegisterField) {TMC5241_HEND_OFFSET_MASK, TMC5241_HEND_OFFSET_SHIFT, TMC5241_CHOPCONF, false}) +#define TMC5241_FD3_MASK 0x00000800 +#define TMC5241_FD3_SHIFT 11 +#define TMC5241_FD3_FIELD ((RegisterField) {TMC5241_FD3_MASK, TMC5241_FD3_SHIFT, TMC5241_CHOPCONF, false}) +#define TMC5241_DISFDCC_MASK 0x00001000 +#define TMC5241_DISFDCC_SHIFT 12 +#define TMC5241_DISFDCC_FIELD ((RegisterField) {TMC5241_DISFDCC_MASK, TMC5241_DISFDCC_SHIFT, TMC5241_CHOPCONF, false}) +#define TMC5241_CHM_MASK 0x00004000 +#define TMC5241_CHM_SHIFT 14 +#define TMC5241_CHM_FIELD ((RegisterField) {TMC5241_CHM_MASK, TMC5241_CHM_SHIFT, TMC5241_CHOPCONF, false}) +#define TMC5241_TBL_MASK 0x00018000 +#define TMC5241_TBL_SHIFT 15 +#define TMC5241_TBL_FIELD ((RegisterField) {TMC5241_TBL_MASK, TMC5241_TBL_SHIFT, TMC5241_CHOPCONF, false}) +#define TMC5241_VHIGHFS_MASK 0x00040000 +#define TMC5241_VHIGHFS_SHIFT 18 +#define TMC5241_VHIGHFS_FIELD ((RegisterField) {TMC5241_VHIGHFS_MASK, TMC5241_VHIGHFS_SHIFT, TMC5241_CHOPCONF, false}) +#define TMC5241_VHIGHCHM_MASK 0x00080000 +#define TMC5241_VHIGHCHM_SHIFT 19 +#define TMC5241_VHIGHCHM_FIELD ((RegisterField) {TMC5241_VHIGHCHM_MASK, TMC5241_VHIGHCHM_SHIFT, TMC5241_CHOPCONF, false}) +#define TMC5241_TPFD_MASK 0x00F00000 +#define TMC5241_TPFD_SHIFT 20 +#define TMC5241_TPFD_FIELD ((RegisterField) {TMC5241_TPFD_MASK, TMC5241_TPFD_SHIFT, TMC5241_CHOPCONF, false}) +#define TMC5241_MRES_MASK 0x0F000000 +#define TMC5241_MRES_SHIFT 24 +#define TMC5241_MRES_FIELD ((RegisterField) {TMC5241_MRES_MASK, TMC5241_MRES_SHIFT, TMC5241_CHOPCONF, false}) +#define TMC5241_INTPOL_MASK 0x10000000 +#define TMC5241_INTPOL_SHIFT 28 +#define TMC5241_INTPOL_FIELD ((RegisterField) {TMC5241_INTPOL_MASK, TMC5241_INTPOL_SHIFT, TMC5241_CHOPCONF, false}) +#define TMC5241_DEDGE_MASK 0x20000000 +#define TMC5241_DEDGE_SHIFT 29 +#define TMC5241_DEDGE_FIELD ((RegisterField) {TMC5241_DEDGE_MASK, TMC5241_DEDGE_SHIFT, TMC5241_CHOPCONF, false}) +#define TMC5241_DISS2G_MASK 0x40000000 +#define TMC5241_DISS2G_SHIFT 30 +#define TMC5241_DISS2G_FIELD ((RegisterField) {TMC5241_DISS2G_MASK, TMC5241_DISS2G_SHIFT, TMC5241_CHOPCONF, false}) +#define TMC5241_DISS2VS_MASK 0x80000000 +#define TMC5241_DISS2VS_SHIFT 31 +#define TMC5241_DISS2VS_FIELD ((RegisterField) {TMC5241_DISS2VS_MASK, TMC5241_DISS2VS_SHIFT, TMC5241_CHOPCONF, false}) +#define TMC5241_SEMIN_MASK 0x0000000F +#define TMC5241_SEMIN_SHIFT 0 +#define TMC5241_SEMIN_FIELD ((RegisterField) {TMC5241_SEMIN_MASK, TMC5241_SEMIN_SHIFT, TMC5241_COOLCONF, false}) +#define TMC5241_SEUP_MASK 0x00000060 +#define TMC5241_SEUP_SHIFT 5 +#define TMC5241_SEUP_FIELD ((RegisterField) {TMC5241_SEUP_MASK, TMC5241_SEUP_SHIFT, TMC5241_COOLCONF, false}) +#define TMC5241_SEMAX_MASK 0x00000F00 +#define TMC5241_SEMAX_SHIFT 8 +#define TMC5241_SEMAX_FIELD ((RegisterField) {TMC5241_SEMAX_MASK, TMC5241_SEMAX_SHIFT, TMC5241_COOLCONF, false}) +#define TMC5241_SEDN_MASK 0x00006000 +#define TMC5241_SEDN_SHIFT 13 +#define TMC5241_SEDN_FIELD ((RegisterField) {TMC5241_SEDN_MASK, TMC5241_SEDN_SHIFT, TMC5241_COOLCONF, false}) +#define TMC5241_SEIMIN_MASK 0x00008000 +#define TMC5241_SEIMIN_SHIFT 15 +#define TMC5241_SEIMIN_FIELD ((RegisterField) {TMC5241_SEIMIN_MASK, TMC5241_SEIMIN_SHIFT, TMC5241_COOLCONF, false}) +#define TMC5241_SGT_MASK 0x007F0000 +#define TMC5241_SGT_SHIFT 16 +#define TMC5241_SGT_FIELD ((RegisterField) {TMC5241_SGT_MASK, TMC5241_SGT_SHIFT, TMC5241_COOLCONF, true}) +#define TMC5241_SFILT_MASK 0x01000000 +#define TMC5241_SFILT_SHIFT 24 +#define TMC5241_SFILT_FIELD ((RegisterField) {TMC5241_SFILT_MASK, TMC5241_SFILT_SHIFT, TMC5241_COOLCONF, false}) +#define TMC5241_DC_TIME_MASK 0x000003FF +#define TMC5241_DC_TIME_SHIFT 0 +#define TMC5241_DC_TIME_FIELD ((RegisterField) {TMC5241_DC_TIME_MASK, TMC5241_DC_TIME_SHIFT, TMC5241_DCCTRL, false}) +#define TMC5241_DC_SG_MASK 0x00FF0000 +#define TMC5241_DC_SG_SHIFT 16 +#define TMC5241_DC_SG_FIELD ((RegisterField) {TMC5241_DC_SG_MASK, TMC5241_DC_SG_SHIFT, TMC5241_DCCTRL, false}) +#define TMC5241_SG_RESULT_MASK 0x000003FF +#define TMC5241_SG_RESULT_SHIFT 0 +#define TMC5241_SG_RESULT_FIELD ((RegisterField) {TMC5241_SG_RESULT_MASK, TMC5241_SG_RESULT_SHIFT, TMC5241_DRV_STATUS, false}) +#define TMC5241_S2VSA_MASK 0x00001000 +#define TMC5241_S2VSA_SHIFT 12 +#define TMC5241_S2VSA_FIELD ((RegisterField) {TMC5241_S2VSA_MASK, TMC5241_S2VSA_SHIFT, TMC5241_DRV_STATUS, false}) +#define TMC5241_S2VSB_MASK 0x00002000 +#define TMC5241_S2VSB_SHIFT 13 +#define TMC5241_S2VSB_FIELD ((RegisterField) {TMC5241_S2VSB_MASK, TMC5241_S2VSB_SHIFT, TMC5241_DRV_STATUS, false}) +#define TMC5241_STEALTH_MASK 0x00004000 +#define TMC5241_STEALTH_SHIFT 14 +#define TMC5241_STEALTH_FIELD ((RegisterField) {TMC5241_STEALTH_MASK, TMC5241_STEALTH_SHIFT, TMC5241_DRV_STATUS, false}) +#define TMC5241_FSACTIVE_MASK 0x00008000 +#define TMC5241_FSACTIVE_SHIFT 15 +#define TMC5241_FSACTIVE_FIELD ((RegisterField) {TMC5241_FSACTIVE_MASK, TMC5241_FSACTIVE_SHIFT, TMC5241_DRV_STATUS, false}) +#define TMC5241_CS_ACTUAL_MASK 0x001F0000 +#define TMC5241_CS_ACTUAL_SHIFT 16 +#define TMC5241_CS_ACTUAL_FIELD ((RegisterField) {TMC5241_CS_ACTUAL_MASK, TMC5241_CS_ACTUAL_SHIFT, TMC5241_DRV_STATUS, false}) +#define TMC5241_STALLGUARD_MASK 0x01000000 +#define TMC5241_STALLGUARD_SHIFT 24 +#define TMC5241_STALLGUARD_FIELD ((RegisterField) {TMC5241_STALLGUARD_MASK, TMC5241_STALLGUARD_SHIFT, TMC5241_DRV_STATUS, false}) +#define TMC5241_OT_MASK 0x02000000 +#define TMC5241_OT_SHIFT 25 +#define TMC5241_OT_FIELD ((RegisterField) {TMC5241_OT_MASK, TMC5241_OT_SHIFT, TMC5241_DRV_STATUS, false}) +#define TMC5241_OTPW_MASK 0x04000000 +#define TMC5241_OTPW_SHIFT 26 +#define TMC5241_OTPW_FIELD ((RegisterField) {TMC5241_OTPW_MASK, TMC5241_OTPW_SHIFT, TMC5241_DRV_STATUS, false}) +#define TMC5241_S2GA_MASK 0x08000000 +#define TMC5241_S2GA_SHIFT 27 +#define TMC5241_S2GA_FIELD ((RegisterField) {TMC5241_S2GA_MASK, TMC5241_S2GA_SHIFT, TMC5241_DRV_STATUS, false}) +#define TMC5241_S2GB_MASK 0x10000000 +#define TMC5241_S2GB_SHIFT 28 +#define TMC5241_S2GB_FIELD ((RegisterField) {TMC5241_S2GB_MASK, TMC5241_S2GB_SHIFT, TMC5241_DRV_STATUS, false}) +#define TMC5241_OLA_MASK 0x20000000 +#define TMC5241_OLA_SHIFT 29 +#define TMC5241_OLA_FIELD ((RegisterField) {TMC5241_OLA_MASK, TMC5241_OLA_SHIFT, TMC5241_DRV_STATUS, false}) +#define TMC5241_OLB_MASK 0x40000000 +#define TMC5241_OLB_SHIFT 30 +#define TMC5241_OLB_FIELD ((RegisterField) {TMC5241_OLB_MASK, TMC5241_OLB_SHIFT, TMC5241_DRV_STATUS, false}) +#define TMC5241_STST_MASK 0x80000000 +#define TMC5241_STST_SHIFT 31 +#define TMC5241_STST_FIELD ((RegisterField) {TMC5241_STST_MASK, TMC5241_STST_SHIFT, TMC5241_DRV_STATUS, false}) +#define TMC5241_PWM_OFS_MASK 0x000000FF +#define TMC5241_PWM_OFS_SHIFT 0 +#define TMC5241_PWM_OFS_FIELD ((RegisterField) {TMC5241_PWM_OFS_MASK, TMC5241_PWM_OFS_SHIFT, TMC5241_PWMCONF, false}) +#define TMC5241_PWM_GRAD_MASK 0x0000FF00 +#define TMC5241_PWM_GRAD_SHIFT 8 +#define TMC5241_PWM_GRAD_FIELD ((RegisterField) {TMC5241_PWM_GRAD_MASK, TMC5241_PWM_GRAD_SHIFT, TMC5241_PWMCONF, false}) +#define TMC5241_PWM_FREQ_MASK 0x00030000 +#define TMC5241_PWM_FREQ_SHIFT 16 +#define TMC5241_PWM_FREQ_FIELD ((RegisterField) {TMC5241_PWM_FREQ_MASK, TMC5241_PWM_FREQ_SHIFT, TMC5241_PWMCONF, false}) +#define TMC5241_PWM_AUTOSCALE_MASK 0x00040000 +#define TMC5241_PWM_AUTOSCALE_SHIFT 18 +#define TMC5241_PWM_AUTOSCALE_FIELD ((RegisterField) {TMC5241_PWM_AUTOSCALE_MASK, TMC5241_PWM_AUTOSCALE_SHIFT, TMC5241_PWMCONF, false}) +#define TMC5241_PWM_AUTOGRAD_MASK 0x00080000 +#define TMC5241_PWM_AUTOGRAD_SHIFT 19 +#define TMC5241_PWM_AUTOGRAD_FIELD ((RegisterField) {TMC5241_PWM_AUTOGRAD_MASK, TMC5241_PWM_AUTOGRAD_SHIFT, TMC5241_PWMCONF, false}) +#define TMC5241_FREEWHEEL_MASK 0x00300000 +#define TMC5241_FREEWHEEL_SHIFT 20 +#define TMC5241_FREEWHEEL_FIELD ((RegisterField) {TMC5241_FREEWHEEL_MASK, TMC5241_FREEWHEEL_SHIFT, TMC5241_PWMCONF, false}) +#define TMC5241_PWM_MEAS_SD_ENABLE_MASK 0x00400000 +#define TMC5241_PWM_MEAS_SD_ENABLE_SHIFT 22 +#define TMC5241_PWM_MEAS_SD_ENABLE_FIELD ((RegisterField) {TMC5241_PWM_MEAS_SD_ENABLE_MASK, TMC5241_PWM_MEAS_SD_ENABLE_SHIFT, TMC5241_PWMCONF, false}) +#define TMC5241_PWM_DIS_REG_STST_MASK 0x00800000 +#define TMC5241_PWM_DIS_REG_STST_SHIFT 23 +#define TMC5241_PWM_DIS_REG_STST_FIELD ((RegisterField) {TMC5241_PWM_DIS_REG_STST_MASK, TMC5241_PWM_DIS_REG_STST_SHIFT, TMC5241_PWMCONF, false}) +#define TMC5241_PWM_REG_MASK 0x0F000000 +#define TMC5241_PWM_REG_SHIFT 24 +#define TMC5241_PWM_REG_FIELD ((RegisterField) {TMC5241_PWM_REG_MASK, TMC5241_PWM_REG_SHIFT, TMC5241_PWMCONF, false}) +#define TMC5241_PWM_LIM_MASK 0xF0000000 +#define TMC5241_PWM_LIM_SHIFT 28 +#define TMC5241_PWM_LIM_FIELD ((RegisterField) {TMC5241_PWM_LIM_MASK, TMC5241_PWM_LIM_SHIFT, TMC5241_PWMCONF, false}) +#define TMC5241_PWM_SCALE_SUM_MASK 0x000003FF +#define TMC5241_PWM_SCALE_SUM_SHIFT 0 +#define TMC5241_PWM_SCALE_SUM_FIELD ((RegisterField) {TMC5241_PWM_SCALE_SUM_MASK, TMC5241_PWM_SCALE_SUM_SHIFT, TMC5241_PWM_SCALE, false}) +#define TMC5241_PWM_SCALE_AUTO_MASK 0x01FF0000 +#define TMC5241_PWM_SCALE_AUTO_SHIFT 16 +#define TMC5241_PWM_SCALE_AUTO_FIELD ((RegisterField) {TMC5241_PWM_SCALE_AUTO_MASK, TMC5241_PWM_SCALE_AUTO_SHIFT, TMC5241_PWM_SCALE, false}) +#define TMC5241_PWM_OFS_AUTO_MASK 0x000000FF +#define TMC5241_PWM_OFS_AUTO_SHIFT 0 +#define TMC5241_PWM_OFS_AUTO_FIELD ((RegisterField) {TMC5241_PWM_OFS_AUTO_MASK, TMC5241_PWM_OFS_AUTO_SHIFT, TMC5241_PWM_AUTO, false}) +#define TMC5241_PWM_GRAD_AUTO_MASK 0x00FF0000 +#define TMC5241_PWM_GRAD_AUTO_SHIFT 16 +#define TMC5241_PWM_GRAD_AUTO_FIELD ((RegisterField) {TMC5241_PWM_GRAD_AUTO_MASK, TMC5241_PWM_GRAD_AUTO_SHIFT, TMC5241_PWM_AUTO, false}) +#define TMC5241_SG4_THRS_MASK 0x000000FF +#define TMC5241_SG4_THRS_SHIFT 0 +#define TMC5241_SG4_THRS_FIELD ((RegisterField) {TMC5241_SG4_THRS_MASK, TMC5241_SG4_THRS_SHIFT, TMC5241_SG4_THRS, false}) +#define TMC5241_SG4_FILT_EN_MASK 0x00000100 +#define TMC5241_SG4_FILT_EN_SHIFT 8 +#define TMC5241_SG4_FILT_EN_FIELD ((RegisterField) {TMC5241_SG4_FILT_EN_MASK, TMC5241_SG4_FILT_EN_SHIFT, TMC5241_SG4_THRS, false}) +#define TMC5241_SG_ANGLE_OFFSET_MASK 0x00000200 +#define TMC5241_SG_ANGLE_OFFSET_SHIFT 9 +#define TMC5241_SG_ANGLE_OFFSET_FIELD ((RegisterField) {TMC5241_SG_ANGLE_OFFSET_MASK, TMC5241_SG_ANGLE_OFFSET_SHIFT, TMC5241_SG4_THRS, false}) +#define TMC5241_SG4_THRS_SHL_MASK 0x00000400 +#define TMC5241_SG4_THRS_SHL_SHIFT 10 +#define TMC5241_SG4_THRS_SHL_FIELD ((RegisterField) {TMC5241_SG4_THRS_SHL_MASK, TMC5241_SG4_THRS_SHL_SHIFT, TMC5241_SG4_THRS, false}) +#define TMC5241_SG4_RESULT_MASK 0x000003FF +#define TMC5241_SG4_RESULT_SHIFT 0 +#define TMC5241_SG4_RESULT_FIELD ((RegisterField) {TMC5241_SG4_RESULT_MASK, TMC5241_SG4_RESULT_SHIFT, TMC5241_SG4_RESULT, false}) +#define TMC5241_SG4_IND_0_MASK 0x000000FF +#define TMC5241_SG4_IND_0_SHIFT 0 +#define TMC5241_SG4_IND_0_FIELD ((RegisterField) {TMC5241_SG4_IND_0_MASK, TMC5241_SG4_IND_0_SHIFT, TMC5241_SG4_IND, false}) +#define TMC5241_SG4_IND_1_MASK 0x0000FF00 +#define TMC5241_SG4_IND_1_SHIFT 8 +#define TMC5241_SG4_IND_1_FIELD ((RegisterField) {TMC5241_SG4_IND_1_MASK, TMC5241_SG4_IND_1_SHIFT, TMC5241_SG4_IND, false}) +#define TMC5241_SG4_IND_2_MASK 0x00FF0000 +#define TMC5241_SG4_IND_2_SHIFT 16 +#define TMC5241_SG4_IND_2_FIELD ((RegisterField) {TMC5241_SG4_IND_2_MASK, TMC5241_SG4_IND_2_SHIFT, TMC5241_SG4_IND, false}) +#define TMC5241_SG4_IND_3_MASK 0xFF000000 +#define TMC5241_SG4_IND_3_SHIFT 24 +#define TMC5241_SG4_IND_3_FIELD ((RegisterField) {TMC5241_SG4_IND_3_MASK, TMC5241_SG4_IND_3_SHIFT, TMC5241_SG4_IND, false}) +#endif diff --git a/firmware/lib/tmc/ic/TMC5241/registercall_hierarchy_flowchart_SPI.svg b/firmware/lib/tmc/ic/TMC5241/registercall_hierarchy_flowchart_SPI.svg new file mode 100755 index 0000000..cbad58f --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5241/registercall_hierarchy_flowchart_SPI.svg @@ -0,0 +1,3 @@ + + +

HAL

HAL

APP (Eval)

APP (Eval)

API

API
Read a register
  •  Call tmcXXXX_readRegister function
Read a register...
Returns the register read value
Returns the register read value
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
tmcXXXX.c
tmcXXXX.c
SPI.c
SPI.c
tmcXXXX_eval.c
tmcXXXX_eval.c

 Implementation of SPI_readWrite
  • Sends and receives bytes on the SPI bus
Implementation of SPI_readWrite...
Returns the raw reply data
Returns the raw reply data

Implementation of tmcXXXX_readWriteSPI
  • Sets the CSN pin to LOW
  • Takes the array of data to write
  • Calls hardware function SPI_readWrite
  • Upon completion of data transfer,
    sets CSN to 
    HIGH
Implementation of tmcXXXX_readWriteSPI...
Passes on the raw reply data to the API
Passes on the raw reply data to the API
Implementation of readRegisterSPI
  • Constructs the datagram
  • Calls HAL wrapper function 
Implementation of readRegisterSPI...
tmcXXXX_readWriteSPI
tmcXXXX_readWriteSPI
Parses the reply and returns the register value
Parses the reply and returns the register value
Implementation of tmcXXXX_readRegister 
  • Check which bus is active SPI/UART. (e.g. SPI)
  • Calls bus-specific function (e.g. readRegisterSPI)
 
Implementation of tmcXXXX_readRegister...
Returns the register read value
Returns the register read value
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC5241/registercall_hierarchy_flowchart_UART.svg b/firmware/lib/tmc/ic/TMC5241/registercall_hierarchy_flowchart_UART.svg new file mode 100755 index 0000000..425f60a --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5241/registercall_hierarchy_flowchart_UART.svg @@ -0,0 +1,3 @@ + + +

HAL

HAL

APP (Eval)

APP (Eval)

API

API
Read a register
  •  Call tmcXXXX_readRegister function
Read a register...
Returns the register read value
Returns the register read value
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
tmcXXXX.c
tmcXXXX.c
UART.c
UART.c
tmcXXXX_eval.c
tmcXXXX_eval.c

 Implementation of UART_readWrite
  • Sends and receives bytes on the UART bus
Implementation of UART_readWrite...
Returns the raw reply data
Returns the raw reply data

Implementation of tmcXXXX_readWriteUART
  • Takes the array of data to write
  • Calls hardware function UART_readWrite
Implementation of tmcXXXX_readWriteUART...
Passes on the raw reply data to the API
Passes on the raw reply data to the API
Implementation of readRegisterUART
  • Constructs the datagram
  • Calls HAL wrapper function 
Implementation of readRegisterUART...
tmcXXXX_readWriteUART
tmcXXXX_readWriteUART
Parses the reply and returns the register value
Parses the reply and returns the register value
Implementation of tmcXXXX_readRegister 
  • Check which bus is active SPI/UART. (e.g. UART)
  • Calls bus-specific function (e.g. readRegisterUART)
 
Implementation of tmcXXXX_readRegister...
Returns the register read value
Returns the register read value
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC5241/uml-tmc-api.svg b/firmware/lib/tmc/ic/TMC5241/uml-tmc-api.svg new file mode 100755 index 0000000..5a5f8dd --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5241/uml-tmc-api.svg @@ -0,0 +1,3 @@ + + +

TMCXXXX_HW_Abstraction.h



TMCXXXX_HW_Abstraction.h...
// Constants
#define TMCXXXX_MOTORS              
                          
// Register definitions
#define TMCXXXX_GCONF        
                          ⋮
// Register fields definitions
#define TMCXXXX_GCONF_OTPW_FIELD
                     
// Constants...

TMCXXXX.h



TMCXXXX.h...
extern void tmcXXXX_readWriteSPI();
extern void tmcXXXX_readWriteUART();
extern TMCXXXXBusType tmcXXXX_getBusType();
extern uint8_t tmcXXXX_getNodeAddress();
                                  ⋮
tmcXXXX_readRegister();
tmcXXXX_writeRegister();
                                  ⋮
extern void tmcXXXX_readWriteSPI();...

TMCXXXX.c



TMCXXXX.c...
const uint8_t tmcCRCTable_Poly7Reflected[256] = {...};
int32_t tmcXXXX_readRegister(){
/* Call tmcXXXX_getBusType();
 * Based on bus type, call readRegisterSPI/UART() that
 * further calls tmcXXXX_readWriteSPI/UART();
 * For UART it also calls tmcXXXX_getNodeAddress();
                                           ⋮
}
                                           ⋮
const uint8_t tmcCRCTable_Poly7Reflected[256] = {.....
TMC-API
TMC-API

TMCXXXX_Simple_Rotation.h


TMCXXXX_Simple_Rotation.h...
void initAllMotors();
             ⋮
  
void initAllMotors()...

TMCXXXX_Simple_Rotation.c


TMCXXXX_Simple_Rotation.c...
void initAllMotors(){

// Configuring registers to enable motor drivers etc..
tmcXXXX_writeRegister();
                    ⋮
}
                    ⋮
void initAllMotors(){...
Examples
Examples
User Project
User Project

User_Project.h


User_Project.h

User_Project.c








User_Project.c...

void tmcXXXX_readWriteSPI(){
                           ⋮
}
void tmcXXXX_readWriteUART(){
                           ⋮
}
TMCXXXXBusType tmcXXXX_getBusType(){
                           ⋮
}
uint8_t tmcXXXX_getNodeAddress(){
                           ⋮
}

// User Code
                           ⋮
void tmcXXXX_readWriteSPI(){...
#include "TMCXXXX_HW_Abstraction.h"
#include "TMCXXXX.h"
#include "TMCXXXX_Simple_Rotation.h"
                                ⋮
TMCXXXXBusType bus = IC_BUS_SPI/UART;
uint8_t nodeAddress = <nodeAddress>;
                                ⋮
#include "TMCXXXX_HW_Abstraction.h"...
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC5262/README.md b/firmware/lib/tmc/ic/TMC5262/README.md new file mode 100755 index 0000000..6fc6c6b --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5262/README.md @@ -0,0 +1,43 @@ +# TMC5262 + + +## How to use + +To access the TMC5262's registers, the TMC-API offers two functions: **tmc5262_readRegister** and **tmc5262_writeRegister**. +Each of these functions takes in an **icID**, which is used to identify the IC when multiple ICs are connected. This identifier is passed down to the callback functions (see How to Integrate). + +## How to integrate: overview + +1. Include all the files of the TMC-API/ic/tmc/TMC5262 folder into the custom project. +2. Include the TMC5262.h file in the custom source code. +3. Implement the necessary callback functions (see below). +4. (optional): Take a look at the Examples subfolder for ready-made examples of the TMC-API usage. + +## Accessing the TMC5262 via SPI +The following diagram depicts how to access the TMC5262 via SPI using the TMC-API. + +![screenshot](registercall_hierarchy_flowchart_SPI.svg) + +The description of the functions, in the above flowchart, are as follows: +- The functions tmc5262_readRegister and tmc5262_writeRegister are used to read and write the registers respectively. These functions call the bus-specific function i.e readRegisterSPI or writeRegisterSPI. +- These bus specific functions constructs the datagram and further calls the bus specific callback 'tmcXXXX_readWriteSPI. +- This callback function further calls the hardware specific read/write function for SPI and needs to be implemented externally. + +### How to integrate: Callback functions +Implement the following callback functions to access the chip via SPI: + +1. **tmc5262_readWriteSPI()**, which is a HAL wrapper function that provides the necessary hardware access. This function should also set the chip select pin CSN to low before starting the data transfer and set to high upon completion. Please refer to the datasheet of the IC for further details. + +## Further info +### Dependency graph for the ICs with new register R/W mechanism +This graph illustrates the relationships between files within the TMC-API library, highlighting dependencies and identifying the files that are essential for integrating the library into the custom projects. + +![screenshot](uml-tmc-api.svg) + +### Example usage: TMC-Evalsystem +**For a reference usage of the TMC-API**, visit the [TMC-Evalsystem](https://github.com/analogdevicesinc/TMC-EvalSystem) + +## Migration status +The TMC5262 has been reworked to the access system described above. For more infos on the status of this and other ICs, check out the [migration page](https://github.com/analogdevicesinc/TMC-API/issues/53). + + diff --git a/firmware/lib/tmc/ic/TMC5262/TMC5262.c b/firmware/lib/tmc/ic/TMC5262/TMC5262.c new file mode 100755 index 0000000..b13793f --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5262/TMC5262.c @@ -0,0 +1,67 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#include "TMC5262.h" + + +static int32_t readRegisterSPI(uint16_t icID, uint8_t address); +static void writeRegisterSPI(uint16_t icID, uint8_t address, int32_t value); + + +int32_t tmc5262_readRegister(uint16_t icID, uint8_t address) +{ + return readRegisterSPI(icID, address); +} + +void tmc5262_writeRegister(uint16_t icID, uint8_t address, int32_t value) +{ + writeRegisterSPI(icID, address, value); +} + +int32_t readRegisterSPI(uint16_t icID, uint8_t address) +{ + uint8_t data[5] = { 0 }; + + // clear write bit + data[0] = address & TMC5262_ADDRESS_MASK; + + // Send the read request + tmc5262_readWriteSPI(icID, &data[0], sizeof(data)); + + // Rewrite address and clear write bit + data[0] = address & TMC5262_ADDRESS_MASK; + + // Send another request to receive the read reply + tmc5262_readWriteSPI(icID, &data[0], sizeof(data)); + + return ((int32_t)data[1] << 24) | ((int32_t) data[2] << 16) | ((int32_t) data[3] << 8) | ((int32_t) data[4]); +} + +void writeRegisterSPI(uint16_t icID, uint8_t address, int32_t value) +{ + uint8_t data[5] = { 0 }; + + data[0] = address | TMC5262_WRITE_BIT; + data[1] = 0xFF & (value>>24); + data[2] = 0xFF & (value>>16); + data[3] = 0xFF & (value>>8); + data[4] = 0xFF & (value>>0); + + // Send the write request + tmc5262_readWriteSPI(icID, &data[0], sizeof(data)); +} + +void tmc5262_rotateMotor(uint16_t icID, uint8_t motor, int32_t velocity) +{ + if(motor >= TMC5262_MOTORS) + return; + + tmc5262_writeRegister(icID, TMC5262_VMAX, (velocity < 0) ? -velocity : velocity); + tmc5262_fieldWrite(icID, TMC5262_RAMPMODE_FIELD, (velocity >= 0) ? TMC5262_MODE_VELPOS : TMC5262_MODE_VELNEG); +} diff --git a/firmware/lib/tmc/ic/TMC5262/TMC5262.h b/firmware/lib/tmc/ic/TMC5262/TMC5262.h new file mode 100755 index 0000000..b95fc85 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5262/TMC5262.h @@ -0,0 +1,74 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#ifndef TMC_IC_TMC5262_H_ +#define TMC_IC_TMC5262_H_ + +#include +#include +#include +#include "TMC5262_HW_Abstraction.h" + +// Default Register values +#define R0B 0x65FF // PLLs + +// => TMC-API wrapper +extern void tmc5262_readWriteSPI(uint16_t icID, uint8_t *data, size_t dataLength); +// => TMC-API wrapper + +int32_t tmc5262_readRegister(uint16_t icID, uint8_t address); +void tmc5262_writeRegister(uint16_t icID, uint8_t address, int32_t value); +void tmc5262_rotateMotor(uint16_t icID, uint8_t motor, int32_t velocity); +/// +typedef struct +{ + uint32_t mask; + uint8_t shift; + uint8_t address; + bool isSigned; +} RegisterField; + +static inline uint32_t tmc5262_fieldExtract(uint32_t data, RegisterField field) +{ + uint32_t value = (data & field.mask) >> field.shift; + + if (field.isSigned) + { + // Apply signedness conversion + uint32_t baseMask = field.mask >> field.shift; + uint32_t signMask = baseMask & (~baseMask >> 1); + value = (value ^ signMask) - signMask; + } + + return value; +} + +static inline uint32_t tmc5262_fieldRead(uint16_t icID, RegisterField field) +{ + uint32_t value = tmc5262_readRegister(icID, field.address); + + return tmc5262_fieldExtract(value, field); +} + +static inline uint32_t tmc5262_fieldUpdate(uint32_t data, RegisterField field, uint32_t value) +{ + return (data & (~field.mask)) | ((value << field.shift) & field.mask); +} + +static inline void tmc5262_fieldWrite(uint16_t icID, RegisterField field, uint32_t value) +{ + uint32_t regValue = tmc5262_readRegister(icID, field.address); + + regValue = tmc5262_fieldUpdate(regValue, field, value); + + tmc5262_writeRegister(icID, field.address, regValue); +} + + +#endif /* TMC_IC_TMC5262_H_ */ diff --git a/firmware/lib/tmc/ic/TMC5262/TMC5262_HW_Abstraction.h b/firmware/lib/tmc/ic/TMC5262/TMC5262_HW_Abstraction.h new file mode 100755 index 0000000..bd0171c --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5262/TMC5262_HW_Abstraction.h @@ -0,0 +1,1031 @@ +/******************************************************************************* +* Copyright © 2017 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + +#ifndef TMC5262_HW_ABSTRACTION +#define TMC5262_HW_ABSTRACTION + + +// Constants in TMC5262 + +#define TMC5262_REGISTER_COUNT 128 +#define TMC5262_MOTORS 1 +#define TMC5262_WRITE_BIT 0x80 +#define TMC5262_ADDRESS_MASK 0x7F +#define TMC5262_MAX_VELOCITY 8388096 +#define TMC5262_MAX_ACCELERATION 65535 + +// ramp modes (Register TMC5262_RAMPMODE) +#define TMC5262_MODE_POSITION 0 +#define TMC5262_MODE_VELPOS 1 +#define TMC5262_MODE_VELNEG 2 +#define TMC5262_MODE_HOLD 3 + +// limit switch mode bits (Register TMC5262_SWMODE) +#define TMC5262_SW_STOPL_ENABLE 0x0001 +#define TMC5262_SW_STOPR_ENABLE 0x0002 +#define TMC5262_SW_STOPL_POLARITY 0x0004 +#define TMC5262_SW_STOPR_POLARITY 0x0008 +#define TMC5262_SW_SWAP_LR 0x0010 +#define TMC5262_SW_LATCH_L_ACT 0x0020 +#define TMC5262_SW_LATCH_L_INACT 0x0040 +#define TMC5262_SW_LATCH_R_ACT 0x0080 +#define TMC5262_SW_LATCH_R_INACT 0x0100 +#define TMC5262_SW_LATCH_ENC 0x0200 +#define TMC5262_SW_SG_STOP 0x0400 +#define TMC5262_SW_SOFTSTOP 0x0800 + +// Status bits (Register TMC5262_RAMPSTAT) +#define TMC5262_RS_STOPL 0x0001 +#define TMC5262_RS_STOPR 0x0002 +#define TMC5262_RS_LATCHL 0x0004 +#define TMC5262_RS_LATCHR 0x0008 +#define TMC5262_RS_EV_STOPL 0x0010 +#define TMC5262_RS_EV_STOPR 0x0020 +#define TMC5262_RS_EV_STOP_SG 0x0040 +#define TMC5262_RS_EV_POSREACHED 0x0080 +#define TMC5262_RS_VELREACHED 0x0100 +#define TMC5262_RS_POSREACHED 0x0200 +#define TMC5262_RS_VZERO 0x0400 +#define TMC5262_RS_ZEROWAIT 0x0800 +#define TMC5262_RS_SECONDMOVE 0x1000 +#define TMC5262_RS_SG 0x2000 + +// Encoderbits (Register TMC5262_ENCMODE) +#define TMC5262_EM_DECIMAL 0x0400 +#define TMC5262_EM_LATCH_XACT 0x0200 +#define TMC5262_EM_CLR_XENC 0x0100 +#define TMC5262_EM_NEG_EDGE 0x0080 +#define TMC5262_EM_POS_EDGE 0x0040 +#define TMC5262_EM_CLR_ONCE 0x0020 +#define TMC5262_EM_CLR_CONT 0x0010 +#define TMC5262_EM_IGNORE_AB 0x0008 +#define TMC5262_EM_POL_N 0x0004 +#define TMC5262_EM_POL_B 0x0002 +#define TMC5262_EM_POL_A 0x0001 + + +// Registers in TMC5262 + +#define TMC5262_GCONF 0x00 +#define TMC5262_GSTAT 0x01 +#define TMC5262_DIAG_CONF 0x02 +#define TMC5262_DIAG_DAC_CONF 0x03 +#define TMC5262_IOIN 0x04 +#define TMC5262_X_COMPARE 0x05 +#define TMC5262_X_COMPARE_REPEAT 0x06 +#define TMC5262_DRV_CONF 0x0A +#define TMC5262_PLL 0x0B +#define TMC5262_IHOLD_IRUN 0x10 +#define TMC5262_TPOWERDOWN 0x11 +#define TMC5262_TSTEP 0x12 +#define TMC5262_TPWMTHRS 0x13 +#define TMC5262_TCOOLTHRS 0x14 +#define TMC5262_THIGH 0x15 +#define TMC5262_TSGP_LOW_VEL_THRS 0x16 +#define TMC5262_T_RCOIL_MEAS 0x17 +#define TMC5262_TUDCSTEP 0x18 +#define TMC5262_UDC_CONF 0x19 +#define TMC5262_STEPS_LOST 0x1A +#define TMC5262_RAMPMODE 0x20 +#define TMC5262_XACTUAL 0x21 +#define TMC5262_VACTUAL 0x22 +#define TMC5262_VSTART 0x23 +#define TMC5262_A1 0x24 +#define TMC5262_V1 0x25 +#define TMC5262_AMAX 0x26 +#define TMC5262_VMAX 0x27 +#define TMC5262_DMAX 0x28 +#define TMC5262_TVMAX 0x29 +#define TMC5262_D1 0x2A +#define TMC5262_VSTOP 0x2B +#define TMC5262_TZEROWAIT 0x2C +#define TMC5262_XTARGET 0x2D +#define TMC5262_V2 0x2E +#define TMC5262_A2 0x2F +#define TMC5262_D2 0x30 +#define TMC5262_AACTUAL 0x31 +#define TMC5262_SW_MODE 0x34 +#define TMC5262_RAMP_STAT 0x35 +#define TMC5262_XLATCH 0x36 +#define TMC5262_ENCMODE 0x38 +#define TMC5262_X_ENC 0x39 +#define TMC5262_ENC_CONST 0x3A +#define TMC5262_ENC_STATUS 0x3B +#define TMC5262_ENC_LATCH 0x3C +#define TMC5262_ENC_DEVIATION 0x3D +#define TMC5262_VIRTUAL_STOP_L 0x3E +#define TMC5262_VIRTUAL_STOP_R 0x3F +#define TMC5262_CURRENT_PI_REG 0x40 +#define TMC5262_ANGLE_PI_REG 0x41 +#define TMC5262_CUR_ANGLE_LIMIT 0x42 +#define TMC5262_ANGLE_LOWER_LIMIT 0x43 +#define TMC5262_CUR_ANGLE_MEAS 0x44 +#define TMC5262_PI_RESULTS 0x45 +#define TMC5262_COIL_INDUCT 0x46 +#define TMC5262_R_COIL 0x47 +#define TMC5262_R_COIL_USER 0x48 +#define TMC5262_SGP_CONF 0x49 +#define TMC5262_SGP_IND_2_3 0x4A +#define TMC5262_SGP_IND_0_1 0x4B +#define TMC5262_INDUCTANCE_VOLTAGE 0x4C +#define TMC5262_SGP_BEMF 0x4D +#define TMC5262_COOLSTEPPLUS_CONF 0x4E +#define TMC5262_COOLSTEPPLUS_PI_REG 0x4F +#define TMC5262_COOLSTEPPLUS_PI_DOWN 0x50 +#define TMC5262_COOLSTEPPLUS_RESERVE_CONF 0x51 +#define TMC5262_COOLSTEPPLUS_LOAD_RESERVE 0x52 +#define TMC5262_TSTEP_VELOCITY 0x53 +#define TMC5262_ADC_VSUPPLY_TEMP 0x58 +#define TMC5262_ADC_I 0x59 +#define TMC5262_OTW_OV_VTH 0x5A +#define TMC5262_MSLUT_0 0x60 +#define TMC5262_MSLUT_1 0x61 +#define TMC5262_MSLUT_2 0x62 +#define TMC5262_MSLUT_3 0x63 +#define TMC5262_MSLUT_4 0x64 +#define TMC5262_MSLUT_5 0x65 +#define TMC5262_MSLUT_6 0x66 +#define TMC5262_MSLUT_7 0x67 +#define TMC5262_MSLUTSEL 0x68 +#define TMC5262_MSLUTSTART 0x69 +#define TMC5262_MSCNT 0x6A +#define TMC5262_MSCURACT 0x6B +#define TMC5262_CHOPCONF 0x6C +#define TMC5262_COOLCONF 0x6D +#define TMC5262_DRV_STATUS 0x6F +#define TMC5262_PWMCONF 0x70 + + +// Fields in TMC5262 + +#define TMC5262_FAST_STANDSTILL_MASK 0x00000001 +#define TMC5262_FAST_STANDSTILL_SHIFT 0 +#define TMC5262_FAST_STANDSTILL_FIELD ((RegisterField) {TMC5262_FAST_STANDSTILL_MASK, TMC5262_FAST_STANDSTILL_SHIFT, TMC5262_GCONF, false}) +#define TMC5262_EN_STEALTHCHOP_MASK 0x00000002 +#define TMC5262_EN_STEALTHCHOP_SHIFT 1 +#define TMC5262_EN_STEALTHCHOP_FIELD ((RegisterField) {TMC5262_EN_STEALTHCHOP_MASK, TMC5262_EN_STEALTHCHOP_SHIFT, TMC5262_GCONF, false}) +#define TMC5262_MULTISTEP_FILT_MASK 0x00000004 +#define TMC5262_MULTISTEP_FILT_SHIFT 2 +#define TMC5262_MULTISTEP_FILT_FIELD ((RegisterField) {TMC5262_MULTISTEP_FILT_MASK, TMC5262_MULTISTEP_FILT_SHIFT, TMC5262_GCONF, false}) +#define TMC5262_SHAFT_MASK 0x00000008 +#define TMC5262_SHAFT_SHIFT 3 +#define TMC5262_SHAFT_FIELD ((RegisterField) {TMC5262_SHAFT_MASK, TMC5262_SHAFT_SHIFT, TMC5262_GCONF, false}) +#define TMC5262_SMALL_HYSTERESIS_MASK 0x00000010 +#define TMC5262_SMALL_HYSTERESIS_SHIFT 4 +#define TMC5262_SMALL_HYSTERESIS_FIELD ((RegisterField) {TMC5262_SMALL_HYSTERESIS_MASK, TMC5262_SMALL_HYSTERESIS_SHIFT, TMC5262_GCONF, false}) +#define TMC5262_STOP_ENABLE_MASK 0x00000020 +#define TMC5262_STOP_ENABLE_SHIFT 5 +#define TMC5262_STOP_ENABLE_FIELD ((RegisterField) {TMC5262_STOP_ENABLE_MASK, TMC5262_STOP_ENABLE_SHIFT, TMC5262_GCONF, false}) +#define TMC5262_DIRECT_MODE_MASK 0x00000040 +#define TMC5262_DIRECT_MODE_SHIFT 6 +#define TMC5262_DIRECT_MODE_FIELD ((RegisterField) {TMC5262_DIRECT_MODE_MASK, TMC5262_DIRECT_MODE_SHIFT, TMC5262_GCONF, false}) +#define TMC5262_LENGTH_STEPPULSE_MASK 0x00000F00 +#define TMC5262_LENGTH_STEPPULSE_SHIFT 8 +#define TMC5262_LENGTH_STEPPULSE_FIELD ((RegisterField) {TMC5262_LENGTH_STEPPULSE_MASK, TMC5262_LENGTH_STEPPULSE_SHIFT, TMC5262_GCONF, false}) +#define TMC5262_OV_NN_MASK 0x00001000 +#define TMC5262_OV_NN_SHIFT 12 +#define TMC5262_OV_NN_FIELD ((RegisterField) {TMC5262_OV_NN_MASK, TMC5262_OV_NN_SHIFT, TMC5262_GCONF, false}) +#define TMC5262_THREEPHASE_MCC_MASK 0x40000000 +#define TMC5262_THREEPHASE_MCC_SHIFT 30 +#define TMC5262_THREEPHASE_MCC_FIELD ((RegisterField) {TMC5262_THREEPHASE_MCC_MASK, TMC5262_THREEPHASE_MCC_SHIFT, TMC5262_GCONF, false}) +#define TMC5262_STEP_DIR_MASK 0x80000000 +#define TMC5262_STEP_DIR_SHIFT 31 +#define TMC5262_STEP_DIR_FIELD ((RegisterField) {TMC5262_STEP_DIR_MASK, TMC5262_STEP_DIR_SHIFT, TMC5262_GCONF, false}) +#define TMC5262_RESET_MASK 0x00000001 +#define TMC5262_RESET_SHIFT 0 +#define TMC5262_RESET_FIELD ((RegisterField) {TMC5262_RESET_MASK, TMC5262_RESET_SHIFT, TMC5262_GSTAT, false}) +#define TMC5262_DRV_ERR_MASK 0x00000002 +#define TMC5262_DRV_ERR_SHIFT 1 +#define TMC5262_DRV_ERR_FIELD ((RegisterField) {TMC5262_DRV_ERR_MASK, TMC5262_DRV_ERR_SHIFT, TMC5262_GSTAT, false}) +#define TMC5262_UV_CP_MASK 0x00000004 +#define TMC5262_UV_CP_SHIFT 2 +#define TMC5262_UV_CP_FIELD ((RegisterField) {TMC5262_UV_CP_MASK, TMC5262_UV_CP_SHIFT, TMC5262_GSTAT, false}) +#define TMC5262_REGISTER_RESET_MASK 0x00000008 +#define TMC5262_REGISTER_RESET_SHIFT 3 +#define TMC5262_REGISTER_RESET_FIELD ((RegisterField) {TMC5262_REGISTER_RESET_MASK, TMC5262_REGISTER_RESET_SHIFT, TMC5262_GSTAT, false}) +#define TMC5262_VM_UVLO_MASK 0x00000010 +#define TMC5262_VM_UVLO_SHIFT 4 +#define TMC5262_VM_UVLO_FIELD ((RegisterField) {TMC5262_VM_UVLO_MASK, TMC5262_VM_UVLO_SHIFT, TMC5262_GSTAT, false}) +#define TMC5262_VCCIO_UV_MASK 0x00000020 +#define TMC5262_VCCIO_UV_SHIFT 5 +#define TMC5262_VCCIO_UV_FIELD ((RegisterField) {TMC5262_VCCIO_UV_MASK, TMC5262_VCCIO_UV_SHIFT, TMC5262_GSTAT, false}) +#define TMC5262_DIAG0_ERROR_MASK 0x00000001 +#define TMC5262_DIAG0_ERROR_SHIFT 0 +#define TMC5262_DIAG0_ERROR_FIELD ((RegisterField) {TMC5262_DIAG0_ERROR_MASK, TMC5262_DIAG0_ERROR_SHIFT, TMC5262_DIAG_CONF, false}) +#define TMC5262_DIAG0_OTPW_MASK 0x00000002 +#define TMC5262_DIAG0_OTPW_SHIFT 1 +#define TMC5262_DIAG0_OTPW_FIELD ((RegisterField) {TMC5262_DIAG0_OTPW_MASK, TMC5262_DIAG0_OTPW_SHIFT, TMC5262_DIAG_CONF, false}) +#define TMC5262_DIAG0_STALL_MASK 0x00000004 +#define TMC5262_DIAG0_STALL_SHIFT 2 +#define TMC5262_DIAG0_STALL_FIELD ((RegisterField) {TMC5262_DIAG0_STALL_MASK, TMC5262_DIAG0_STALL_SHIFT, TMC5262_DIAG_CONF, false}) +#define TMC5262_DIAG0_INDEX_MASK 0x00000008 +#define TMC5262_DIAG0_INDEX_SHIFT 3 +#define TMC5262_DIAG0_INDEX_FIELD ((RegisterField) {TMC5262_DIAG0_INDEX_MASK, TMC5262_DIAG0_INDEX_SHIFT, TMC5262_DIAG_CONF, false}) +#define TMC5262_DIAG0_STEP_MASK 0x00000010 +#define TMC5262_DIAG0_STEP_SHIFT 4 +#define TMC5262_DIAG0_STEP_FIELD ((RegisterField) {TMC5262_DIAG0_STEP_MASK, TMC5262_DIAG0_STEP_SHIFT, TMC5262_DIAG_CONF, false}) +#define TMC5262_DIAG0_DIR_MASK 0x00000020 +#define TMC5262_DIAG0_DIR_SHIFT 5 +#define TMC5262_DIAG0_DIR_FIELD ((RegisterField) {TMC5262_DIAG0_DIR_MASK, TMC5262_DIAG0_DIR_SHIFT, TMC5262_DIAG_CONF, false}) +#define TMC5262_DIAG0_XCOMP_MASK 0x00000040 +#define TMC5262_DIAG0_XCOMP_SHIFT 6 +#define TMC5262_DIAG0_XCOMP_FIELD ((RegisterField) {TMC5262_DIAG0_XCOMP_MASK, TMC5262_DIAG0_XCOMP_SHIFT, TMC5262_DIAG_CONF, false}) +#define TMC5262_DIAG0_OV_MASK 0x00000080 +#define TMC5262_DIAG0_OV_SHIFT 7 +#define TMC5262_DIAG0_OV_FIELD ((RegisterField) {TMC5262_DIAG0_OV_MASK, TMC5262_DIAG0_OV_SHIFT, TMC5262_DIAG_CONF, false}) +#define TMC5262_DIAG0_DCUSTEP_MASK 0x00000100 +#define TMC5262_DIAG0_DCUSTEP_SHIFT 8 +#define TMC5262_DIAG0_DCUSTEP_FIELD ((RegisterField) {TMC5262_DIAG0_DCUSTEP_MASK, TMC5262_DIAG0_DCUSTEP_SHIFT, TMC5262_DIAG_CONF, false}) +#define TMC5262_DIAG0_EV_STOP_REF_MASK 0x00000200 +#define TMC5262_DIAG0_EV_STOP_REF_SHIFT 9 +#define TMC5262_DIAG0_EV_STOP_REF_FIELD ((RegisterField) {TMC5262_DIAG0_EV_STOP_REF_MASK, TMC5262_DIAG0_EV_STOP_REF_SHIFT, TMC5262_DIAG_CONF, false}) +#define TMC5262_DIAG0_EV_STOP_SG_MASK 0x00000400 +#define TMC5262_DIAG0_EV_STOP_SG_SHIFT 10 +#define TMC5262_DIAG0_EV_STOP_SG_FIELD ((RegisterField) {TMC5262_DIAG0_EV_STOP_SG_MASK, TMC5262_DIAG0_EV_STOP_SG_SHIFT, TMC5262_DIAG_CONF, false}) +#define TMC5262_DIAG0_EV_POS_REACHED_MASK 0x00000800 +#define TMC5262_DIAG0_EV_POS_REACHED_SHIFT 11 +#define TMC5262_DIAG0_EV_POS_REACHED_FIELD ((RegisterField) {TMC5262_DIAG0_EV_POS_REACHED_MASK, TMC5262_DIAG0_EV_POS_REACHED_SHIFT, TMC5262_DIAG_CONF, false}) +#define TMC5262_DIAG0_EV_N_DEVIATION_MASK 0x00001000 +#define TMC5262_DIAG0_EV_N_DEVIATION_SHIFT 12 +#define TMC5262_DIAG0_EV_N_DEVIATION_FIELD ((RegisterField) {TMC5262_DIAG0_EV_N_DEVIATION_MASK, TMC5262_DIAG0_EV_N_DEVIATION_SHIFT, TMC5262_DIAG_CONF, false}) +#define TMC5262_DIAG1_ERROR_MASK 0x00002000 +#define TMC5262_DIAG1_ERROR_SHIFT 13 +#define TMC5262_DIAG1_ERROR_FIELD ((RegisterField) {TMC5262_DIAG1_ERROR_MASK, TMC5262_DIAG1_ERROR_SHIFT, TMC5262_DIAG_CONF, false}) +#define TMC5262_DIAG1_OTPW_MASK 0x00004000 +#define TMC5262_DIAG1_OTPW_SHIFT 14 +#define TMC5262_DIAG1_OTPW_FIELD ((RegisterField) {TMC5262_DIAG1_OTPW_MASK, TMC5262_DIAG1_OTPW_SHIFT, TMC5262_DIAG_CONF, false}) +#define TMC5262_DIAG1_STALL_MASK 0x00008000 +#define TMC5262_DIAG1_STALL_SHIFT 15 +#define TMC5262_DIAG1_STALL_FIELD ((RegisterField) {TMC5262_DIAG1_STALL_MASK, TMC5262_DIAG1_STALL_SHIFT, TMC5262_DIAG_CONF, false}) +#define TMC5262_DIAG1_INDEX_MASK 0x00010000 +#define TMC5262_DIAG1_INDEX_SHIFT 16 +#define TMC5262_DIAG1_INDEX_FIELD ((RegisterField) {TMC5262_DIAG1_INDEX_MASK, TMC5262_DIAG1_INDEX_SHIFT, TMC5262_DIAG_CONF, false}) +#define TMC5262_DIAG1_STEP_MASK 0x00020000 +#define TMC5262_DIAG1_STEP_SHIFT 17 +#define TMC5262_DIAG1_STEP_FIELD ((RegisterField) {TMC5262_DIAG1_STEP_MASK, TMC5262_DIAG1_STEP_SHIFT, TMC5262_DIAG_CONF, false}) +#define TMC5262_DIAG1_DIR_MASK 0x00040000 +#define TMC5262_DIAG1_DIR_SHIFT 18 +#define TMC5262_DIAG1_DIR_FIELD ((RegisterField) {TMC5262_DIAG1_DIR_MASK, TMC5262_DIAG1_DIR_SHIFT, TMC5262_DIAG_CONF, false}) +#define TMC5262_DIAG1_XCOMP_MASK 0x00080000 +#define TMC5262_DIAG1_XCOMP_SHIFT 19 +#define TMC5262_DIAG1_XCOMP_FIELD ((RegisterField) {TMC5262_DIAG1_XCOMP_MASK, TMC5262_DIAG1_XCOMP_SHIFT, TMC5262_DIAG_CONF, false}) +#define TMC5262_DIAG1_OV_MASK 0x00100000 +#define TMC5262_DIAG1_OV_SHIFT 20 +#define TMC5262_DIAG1_OV_FIELD ((RegisterField) {TMC5262_DIAG1_OV_MASK, TMC5262_DIAG1_OV_SHIFT, TMC5262_DIAG_CONF, false}) +#define TMC5262_DIAG1_UDCSTEP_MASK 0x00200000 +#define TMC5262_DIAG1_UDCSTEP_SHIFT 21 +#define TMC5262_DIAG1_UDCSTEP_FIELD ((RegisterField) {TMC5262_DIAG1_UDCSTEP_MASK, TMC5262_DIAG1_UDCSTEP_SHIFT, TMC5262_DIAG_CONF, false}) +#define TMC5262_DIAG1_EV_STOP_REF_MASK 0x00400000 +#define TMC5262_DIAG1_EV_STOP_REF_SHIFT 22 +#define TMC5262_DIAG1_EV_STOP_REF_FIELD ((RegisterField) {TMC5262_DIAG1_EV_STOP_REF_MASK, TMC5262_DIAG1_EV_STOP_REF_SHIFT, TMC5262_DIAG_CONF, false}) +#define TMC5262_DIAG1_EV_STOP_SG_MASK 0x00800000 +#define TMC5262_DIAG1_EV_STOP_SG_SHIFT 23 +#define TMC5262_DIAG1_EV_STOP_SG_FIELD ((RegisterField) {TMC5262_DIAG1_EV_STOP_SG_MASK, TMC5262_DIAG1_EV_STOP_SG_SHIFT, TMC5262_DIAG_CONF, false}) +#define TMC5262_DIAG1_EV_POS_REACHED_MASK 0x01000000 +#define TMC5262_DIAG1_EV_POS_REACHED_SHIFT 24 +#define TMC5262_DIAG1_EV_POS_REACHED_FIELD ((RegisterField) {TMC5262_DIAG1_EV_POS_REACHED_MASK, TMC5262_DIAG1_EV_POS_REACHED_SHIFT, TMC5262_DIAG_CONF, false}) +#define TMC5262_DIAG1_EV_N_DEVIATION_MASK 0x02000000 +#define TMC5262_DIAG1_EV_N_DEVIATION_SHIFT 25 +#define TMC5262_DIAG1_EV_N_DEVIATION_FIELD ((RegisterField) {TMC5262_DIAG1_EV_N_DEVIATION_MASK, TMC5262_DIAG1_EV_N_DEVIATION_SHIFT, TMC5262_DIAG_CONF, false}) +#define TMC5262_DIAG0_NOD_PP_MASK 0x10000000 +#define TMC5262_DIAG0_NOD_PP_SHIFT 28 +#define TMC5262_DIAG0_NOD_PP_FIELD ((RegisterField) {TMC5262_DIAG0_NOD_PP_MASK, TMC5262_DIAG0_NOD_PP_SHIFT, TMC5262_DIAG_CONF, false}) +#define TMC5262_DIAG0_INVPP_MASK 0x20000000 +#define TMC5262_DIAG0_INVPP_SHIFT 29 +#define TMC5262_DIAG0_INVPP_FIELD ((RegisterField) {TMC5262_DIAG0_INVPP_MASK, TMC5262_DIAG0_INVPP_SHIFT, TMC5262_DIAG_CONF, false}) +#define TMC5262_DIAG1_NOD_PP_MASK 0x40000000 +#define TMC5262_DIAG1_NOD_PP_SHIFT 30 +#define TMC5262_DIAG1_NOD_PP_FIELD ((RegisterField) {TMC5262_DIAG1_NOD_PP_MASK, TMC5262_DIAG1_NOD_PP_SHIFT, TMC5262_DIAG_CONF, false}) +#define TMC5262_DIAG1_INVPP_MASK 0x80000000 +#define TMC5262_DIAG1_INVPP_SHIFT 31 +#define TMC5262_DIAG1_INVPP_FIELD ((RegisterField) {TMC5262_DIAG1_INVPP_MASK, TMC5262_DIAG1_INVPP_SHIFT, TMC5262_DIAG_CONF, false}) +#define TMC5262_DIAG0_DAC_EN_MASK 0x00000001 +#define TMC5262_DIAG0_DAC_EN_SHIFT 0 +#define TMC5262_DIAG0_DAC_EN_FIELD ((RegisterField) {TMC5262_DIAG0_DAC_EN_MASK, TMC5262_DIAG0_DAC_EN_SHIFT, TMC5262_DIAG_DAC_CONF, false}) +#define TMC5262_DIAG0_DAC_SEL_MASK 0x000001F0 +#define TMC5262_DIAG0_DAC_SEL_SHIFT 4 +#define TMC5262_DIAG0_DAC_SEL_FIELD ((RegisterField) {TMC5262_DIAG0_DAC_SEL_MASK, TMC5262_DIAG0_DAC_SEL_SHIFT, TMC5262_DIAG_DAC_CONF, false}) +#define TMC5262_DIAG1_DAC_EN_MASK 0x00001000 +#define TMC5262_DIAG1_DAC_EN_SHIFT 12 +#define TMC5262_DIAG1_DAC_EN_FIELD ((RegisterField) {TMC5262_DIAG1_DAC_EN_MASK, TMC5262_DIAG1_DAC_EN_SHIFT, TMC5262_DIAG_DAC_CONF, false}) +#define TMC5262_DIAG1_DAC_SEL_MASK 0x001F0000 +#define TMC5262_DIAG1_DAC_SEL_SHIFT 16 +#define TMC5262_DIAG1_DAC_SEL_FIELD ((RegisterField) {TMC5262_DIAG1_DAC_SEL_MASK, TMC5262_DIAG1_DAC_SEL_SHIFT, TMC5262_DIAG_DAC_CONF, false}) +#define TMC5262_REFL_MASK 0x00000001 +#define TMC5262_REFL_SHIFT 0 +#define TMC5262_REFL_FIELD ((RegisterField) {TMC5262_REFL_MASK, TMC5262_REFL_SHIFT, TMC5262_IOIN, false}) +#define TMC5262_REFR_MASK 0x00000002 +#define TMC5262_REFR_SHIFT 1 +#define TMC5262_REFR_FIELD ((RegisterField) {TMC5262_REFR_MASK, TMC5262_REFR_SHIFT, TMC5262_IOIN, false}) +#define TMC5262_ENCB_MASK 0x00000004 +#define TMC5262_ENCB_SHIFT 2 +#define TMC5262_ENCB_FIELD ((RegisterField) {TMC5262_ENCB_MASK, TMC5262_ENCB_SHIFT, TMC5262_IOIN, false}) +#define TMC5262_ENCA_MASK 0x00000008 +#define TMC5262_ENCA_SHIFT 3 +#define TMC5262_ENCA_FIELD ((RegisterField) {TMC5262_ENCA_MASK, TMC5262_ENCA_SHIFT, TMC5262_IOIN, false}) +#define TMC5262_DRV_ENN_MASK 0x00000010 +#define TMC5262_DRV_ENN_SHIFT 4 +#define TMC5262_DRV_ENN_FIELD ((RegisterField) {TMC5262_DRV_ENN_MASK, TMC5262_DRV_ENN_SHIFT, TMC5262_IOIN, false}) +#define TMC5262_ENCN_MASK 0x00000020 +#define TMC5262_ENCN_SHIFT 5 +#define TMC5262_ENCN_FIELD ((RegisterField) {TMC5262_ENCN_MASK, TMC5262_ENCN_SHIFT, TMC5262_IOIN, false}) +#define TMC5262_RESERVED_MASK 0x00000080 +#define TMC5262_RESERVED_SHIFT 7 +#define TMC5262_RESERVED_FIELD ((RegisterField) {TMC5262_RESERVED_MASK, TMC5262_RESERVED_SHIFT, TMC5262_IOIN, false}) +#define TMC5262_EXT_RES_DET_MASK 0x00002000 +#define TMC5262_EXT_RES_DET_SHIFT 13 +#define TMC5262_EXT_RES_DET_FIELD ((RegisterField) {TMC5262_EXT_RES_DET_MASK, TMC5262_EXT_RES_DET_SHIFT, TMC5262_IOIN, false}) +#define TMC5262_EXT_CLK_MASK 0x00004000 +#define TMC5262_EXT_CLK_SHIFT 14 +#define TMC5262_EXT_CLK_FIELD ((RegisterField) {TMC5262_EXT_CLK_MASK, TMC5262_EXT_CLK_SHIFT, TMC5262_IOIN, false}) +#define TMC5262_SILICON_RV_MASK 0x00070000 +#define TMC5262_SILICON_RV_SHIFT 16 +#define TMC5262_SILICON_RV_FIELD ((RegisterField) {TMC5262_SILICON_RV_MASK, TMC5262_SILICON_RV_SHIFT, TMC5262_IOIN, false}) +#define TMC5262_VERSION_MASK 0xFF000000 +#define TMC5262_VERSION_SHIFT 24 +#define TMC5262_VERSION_FIELD ((RegisterField) {TMC5262_VERSION_MASK, TMC5262_VERSION_SHIFT, TMC5262_IOIN, false}) +#define TMC5262_X_COMPARE_MASK 0xFFFFFFFF +#define TMC5262_X_COMPARE_SHIFT 0 +#define TMC5262_X_COMPARE_FIELD ((RegisterField) {TMC5262_X_COMPARE_MASK, TMC5262_X_COMPARE_SHIFT, TMC5262_X_COMPARE, true}) +#define TMC5262_X_COMPARE_REPEAT_MASK 0x00FFFFFF +#define TMC5262_X_COMPARE_REPEAT_SHIFT 0 +#define TMC5262_X_COMPARE_REPEAT_FIELD ((RegisterField) {TMC5262_X_COMPARE_REPEAT_MASK, TMC5262_X_COMPARE_REPEAT_SHIFT, TMC5262_X_COMPARE_REPEAT, false}) +#define TMC5262_CURRENT_RANGE_MASK 0x00000003 +#define TMC5262_CURRENT_RANGE_SHIFT 0 +#define TMC5262_CURRENT_RANGE_FIELD ((RegisterField) {TMC5262_CURRENT_RANGE_MASK, TMC5262_CURRENT_RANGE_SHIFT, TMC5262_DRV_CONF, false}) +#define TMC5262_CURRENT_RANGE_SCALE_MASK 0x0000000C +#define TMC5262_CURRENT_RANGE_SCALE_SHIFT 2 +#define TMC5262_CURRENT_RANGE_SCALE_FIELD ((RegisterField) {TMC5262_CURRENT_RANGE_SCALE_MASK, TMC5262_CURRENT_RANGE_SCALE_SHIFT, TMC5262_DRV_CONF, false}) +#define TMC5262_SLOPE_CONTROL_MASK 0x00000030 +#define TMC5262_SLOPE_CONTROL_SHIFT 4 +#define TMC5262_SLOPE_CONTROL_FIELD ((RegisterField) {TMC5262_SLOPE_CONTROL_MASK, TMC5262_SLOPE_CONTROL_SHIFT, TMC5262_DRV_CONF, false}) +#define TMC5262_COMMIT_MASK 0x00000001 +#define TMC5262_COMMIT_SHIFT 0 +#define TMC5262_COMMIT_FIELD ((RegisterField) {TMC5262_COMMIT_MASK, TMC5262_COMMIT_SHIFT, TMC5262_PLL, false}) +#define TMC5262_EXT_NOT_INT_MASK 0x00000002 +#define TMC5262_EXT_NOT_INT_SHIFT 1 +#define TMC5262_EXT_NOT_INT_FIELD ((RegisterField) {TMC5262_EXT_NOT_INT_MASK, TMC5262_EXT_NOT_INT_SHIFT, TMC5262_PLL, false}) +#define TMC5262_CLK_SYS_SEL_MASK 0x00000004 +#define TMC5262_CLK_SYS_SEL_SHIFT 2 +#define TMC5262_CLK_SYS_SEL_FIELD ((RegisterField) {TMC5262_CLK_SYS_SEL_MASK, TMC5262_CLK_SYS_SEL_SHIFT, TMC5262_PLL, false}) +#define TMC5262_ADC_CLK_ENA_MASK 0x00000008 +#define TMC5262_ADC_CLK_ENA_SHIFT 3 +#define TMC5262_ADC_CLK_ENA_FIELD ((RegisterField) {TMC5262_ADC_CLK_ENA_MASK, TMC5262_ADC_CLK_ENA_SHIFT, TMC5262_PLL, false}) +#define TMC5262_PWM_CLK_ENA_MASK 0x00000010 +#define TMC5262_PWM_CLK_ENA_SHIFT 4 +#define TMC5262_PWM_CLK_ENA_FIELD ((RegisterField) {TMC5262_PWM_CLK_ENA_MASK, TMC5262_PWM_CLK_ENA_SHIFT, TMC5262_PLL, false}) +#define TMC5262_CLOCK_DIVIDER_MASK 0x000003E0 +#define TMC5262_CLOCK_DIVIDER_SHIFT 5 +#define TMC5262_CLOCK_DIVIDER_FIELD ((RegisterField) {TMC5262_CLOCK_DIVIDER_MASK, TMC5262_CLOCK_DIVIDER_SHIFT, TMC5262_PLL, false}) +#define TMC5262_CLK_FSM_ENA_MASK 0x00000400 +#define TMC5262_CLK_FSM_ENA_SHIFT 10 +#define TMC5262_CLK_FSM_ENA_FIELD ((RegisterField) {TMC5262_CLK_FSM_ENA_MASK, TMC5262_CLK_FSM_ENA_SHIFT, TMC5262_PLL, false}) +#define TMC5262_CLK_1MO_TMO_MASK 0x00001000 +#define TMC5262_CLK_1MO_TMO_SHIFT 12 +#define TMC5262_CLK_1MO_TMO_FIELD ((RegisterField) {TMC5262_CLK_1MO_TMO_MASK, TMC5262_CLK_1MO_TMO_SHIFT, TMC5262_PLL, false}) +#define TMC5262_CLK_LOSS_MASK 0x00002000 +#define TMC5262_CLK_LOSS_SHIFT 13 +#define TMC5262_CLK_LOSS_FIELD ((RegisterField) {TMC5262_CLK_LOSS_MASK, TMC5262_CLK_LOSS_SHIFT, TMC5262_PLL, false}) +#define TMC5262_CLK_IS_STUCK_MASK 0x00004000 +#define TMC5262_CLK_IS_STUCK_SHIFT 14 +#define TMC5262_CLK_IS_STUCK_FIELD ((RegisterField) {TMC5262_CLK_IS_STUCK_MASK, TMC5262_CLK_IS_STUCK_SHIFT, TMC5262_PLL, false}) +#define TMC5262_PLL_LOCK_LOSS_MASK 0x00008000 +#define TMC5262_PLL_LOCK_LOSS_SHIFT 15 +#define TMC5262_PLL_LOCK_LOSS_FIELD ((RegisterField) {TMC5262_PLL_LOCK_LOSS_MASK, TMC5262_PLL_LOCK_LOSS_SHIFT, TMC5262_PLL, false}) +#define TMC5262_IHOLD_MASK 0x000000FF +#define TMC5262_IHOLD_SHIFT 0 +#define TMC5262_IHOLD_FIELD ((RegisterField) {TMC5262_IHOLD_MASK, TMC5262_IHOLD_SHIFT, TMC5262_IHOLD_IRUN, false}) +#define TMC5262_IRUN_MASK 0x0000FF00 +#define TMC5262_IRUN_SHIFT 8 +#define TMC5262_IRUN_FIELD ((RegisterField) {TMC5262_IRUN_MASK, TMC5262_IRUN_SHIFT, TMC5262_IHOLD_IRUN, false}) +#define TMC5262_IHOLDDELAY_MASK 0x00FF0000 +#define TMC5262_IHOLDDELAY_SHIFT 16 +#define TMC5262_IHOLDDELAY_FIELD ((RegisterField) {TMC5262_IHOLDDELAY_MASK, TMC5262_IHOLDDELAY_SHIFT, TMC5262_IHOLD_IRUN, false}) +#define TMC5262_IRUNDELAY_MASK 0x0F000000 +#define TMC5262_IRUNDELAY_SHIFT 24 +#define TMC5262_IRUNDELAY_FIELD ((RegisterField) {TMC5262_IRUNDELAY_MASK, TMC5262_IRUNDELAY_SHIFT, TMC5262_IHOLD_IRUN, false}) +#define TMC5262_TPOWERDOWN_MASK 0x000000FF +#define TMC5262_TPOWERDOWN_SHIFT 0 +#define TMC5262_TPOWERDOWN_FIELD ((RegisterField) {TMC5262_TPOWERDOWN_MASK, TMC5262_TPOWERDOWN_SHIFT, TMC5262_TPOWERDOWN, false}) +#define TMC5262_TSTEP_MASK 0x000FFFFF +#define TMC5262_TSTEP_SHIFT 0 +#define TMC5262_TSTEP_FIELD ((RegisterField) {TMC5262_TSTEP_MASK, TMC5262_TSTEP_SHIFT, TMC5262_TSTEP, false}) +#define TMC5262_TPWMTHRS_MASK 0x000FFFFF +#define TMC5262_TPWMTHRS_SHIFT 0 +#define TMC5262_TPWMTHRS_FIELD ((RegisterField) {TMC5262_TPWMTHRS_MASK, TMC5262_TPWMTHRS_SHIFT, TMC5262_TPWMTHRS, false}) +#define TMC5262_TCOOLTHRS_MASK 0x000FFFFF +#define TMC5262_TCOOLTHRS_SHIFT 0 +#define TMC5262_TCOOLTHRS_FIELD ((RegisterField) {TMC5262_TCOOLTHRS_MASK, TMC5262_TCOOLTHRS_SHIFT, TMC5262_TCOOLTHRS, false}) +#define TMC5262_THIGH_MASK 0x000FFFFF +#define TMC5262_THIGH_SHIFT 0 +#define TMC5262_THIGH_FIELD ((RegisterField) {TMC5262_THIGH_MASK, TMC5262_THIGH_SHIFT, TMC5262_THIGH, false}) +#define TMC5262_TSGP_LOW_VEL_THRS_MASK 0x000FFFFF +#define TMC5262_TSGP_LOW_VEL_THRS_SHIFT 0 +#define TMC5262_TSGP_LOW_VEL_THRS_FIELD ((RegisterField) {TMC5262_TSGP_LOW_VEL_THRS_MASK, TMC5262_TSGP_LOW_VEL_THRS_SHIFT, TMC5262_TSGP_LOW_VEL_THRS, false}) +#define TMC5262_T_RCOIL_MEAS_MASK 0x000FFFFF +#define TMC5262_T_RCOIL_MEAS_SHIFT 0 +#define TMC5262_T_RCOIL_MEAS_FIELD ((RegisterField) {TMC5262_T_RCOIL_MEAS_MASK, TMC5262_T_RCOIL_MEAS_SHIFT, TMC5262_T_RCOIL_MEAS, false}) +#define TMC5262_TUDCSTEP_MASK 0x000FFFFF +#define TMC5262_TUDCSTEP_SHIFT 0 +#define TMC5262_TUDCSTEP_FIELD ((RegisterField) {TMC5262_TUDCSTEP_MASK, TMC5262_TUDCSTEP_SHIFT, TMC5262_TUDCSTEP, false}) +#define TMC5262_DECEL_THRS_MASK 0x0000000F +#define TMC5262_DECEL_THRS_SHIFT 0 +#define TMC5262_DECEL_THRS_FIELD ((RegisterField) {TMC5262_DECEL_THRS_MASK, TMC5262_DECEL_THRS_SHIFT, TMC5262_UDC_CONF, false}) +#define TMC5262_ACCEL_THRS_MASK 0x000000F0 +#define TMC5262_ACCEL_THRS_SHIFT 4 +#define TMC5262_ACCEL_THRS_FIELD ((RegisterField) {TMC5262_ACCEL_THRS_MASK, TMC5262_ACCEL_THRS_SHIFT, TMC5262_UDC_CONF, false}) +#define TMC5262_UDC_ENABLE_MASK 0x00000100 +#define TMC5262_UDC_ENABLE_SHIFT 8 +#define TMC5262_UDC_ENABLE_FIELD ((RegisterField) {TMC5262_UDC_ENABLE_MASK, TMC5262_UDC_ENABLE_SHIFT, TMC5262_UDC_CONF, false}) +#define TMC5262_STEPS_LOST_MASK 0x000FFFFF +#define TMC5262_STEPS_LOST_SHIFT 0 +#define TMC5262_STEPS_LOST_FIELD ((RegisterField) {TMC5262_STEPS_LOST_MASK, TMC5262_STEPS_LOST_SHIFT, TMC5262_STEPS_LOST, true}) +#define TMC5262_RAMPMODE_MASK 0x00000003 +#define TMC5262_RAMPMODE_SHIFT 0 +#define TMC5262_RAMPMODE_FIELD ((RegisterField) {TMC5262_RAMPMODE_MASK, TMC5262_RAMPMODE_SHIFT, TMC5262_RAMPMODE, false}) +#define TMC5262_XACTUAL_MASK 0xFFFFFFFF +#define TMC5262_XACTUAL_SHIFT 0 +#define TMC5262_XACTUAL_FIELD ((RegisterField) {TMC5262_XACTUAL_MASK, TMC5262_XACTUAL_SHIFT, TMC5262_XACTUAL, true}) +#define TMC5262_VACTUAL_MASK 0x00FFFFFF +#define TMC5262_VACTUAL_SHIFT 0 +#define TMC5262_VACTUAL_FIELD ((RegisterField) {TMC5262_VACTUAL_MASK, TMC5262_VACTUAL_SHIFT, TMC5262_VACTUAL, true}) +#define TMC5262_VSTART_MASK 0x0003FFFF +#define TMC5262_VSTART_SHIFT 0 +#define TMC5262_VSTART_FIELD ((RegisterField) {TMC5262_VSTART_MASK, TMC5262_VSTART_SHIFT, TMC5262_VSTART, false}) +#define TMC5262_A1_MASK 0x0003FFFF +#define TMC5262_A1_SHIFT 0 +#define TMC5262_A1_FIELD ((RegisterField) {TMC5262_A1_MASK, TMC5262_A1_SHIFT, TMC5262_A1, false}) +#define TMC5262_V1_MASK 0x000FFFFF +#define TMC5262_V1_SHIFT 0 +#define TMC5262_V1_FIELD ((RegisterField) {TMC5262_V1_MASK, TMC5262_V1_SHIFT, TMC5262_V1, false}) +#define TMC5262_AMAX_MASK 0x0003FFFF +#define TMC5262_AMAX_SHIFT 0 +#define TMC5262_AMAX_FIELD ((RegisterField) {TMC5262_AMAX_MASK, TMC5262_AMAX_SHIFT, TMC5262_AMAX, false}) +#define TMC5262_VMAX_MASK 0x007FFFFF +#define TMC5262_VMAX_SHIFT 0 +#define TMC5262_VMAX_FIELD ((RegisterField) {TMC5262_VMAX_MASK, TMC5262_VMAX_SHIFT, TMC5262_VMAX, false}) +#define TMC5262_DMAX_MASK 0x0003FFFF +#define TMC5262_DMAX_SHIFT 0 +#define TMC5262_DMAX_FIELD ((RegisterField) {TMC5262_DMAX_MASK, TMC5262_DMAX_SHIFT, TMC5262_DMAX, false}) +#define TMC5262_TVMAX_MASK 0x0000FFFF +#define TMC5262_TVMAX_SHIFT 0 +#define TMC5262_TVMAX_FIELD ((RegisterField) {TMC5262_TVMAX_MASK, TMC5262_TVMAX_SHIFT, TMC5262_TVMAX, false}) +#define TMC5262_D1_MASK 0x0003FFFF +#define TMC5262_D1_SHIFT 0 +#define TMC5262_D1_FIELD ((RegisterField) {TMC5262_D1_MASK, TMC5262_D1_SHIFT, TMC5262_D1, false}) +#define TMC5262_VSTOP_MASK 0x0003FFFF +#define TMC5262_VSTOP_SHIFT 0 +#define TMC5262_VSTOP_FIELD ((RegisterField) {TMC5262_VSTOP_MASK, TMC5262_VSTOP_SHIFT, TMC5262_VSTOP, false}) +#define TMC5262_TZEROWAIT_MASK 0x0000FFFF +#define TMC5262_TZEROWAIT_SHIFT 0 +#define TMC5262_TZEROWAIT_FIELD ((RegisterField) {TMC5262_TZEROWAIT_MASK, TMC5262_TZEROWAIT_SHIFT, TMC5262_TZEROWAIT, false}) +#define TMC5262_XTARGET_MASK 0xFFFFFFFF +#define TMC5262_XTARGET_SHIFT 0 +#define TMC5262_XTARGET_FIELD ((RegisterField) {TMC5262_XTARGET_MASK, TMC5262_XTARGET_SHIFT, TMC5262_XTARGET, true}) +#define TMC5262_V2_MASK 0x000FFFFF +#define TMC5262_V2_SHIFT 0 +#define TMC5262_V2_FIELD ((RegisterField) {TMC5262_V2_MASK, TMC5262_V2_SHIFT, TMC5262_V2, false}) +#define TMC5262_A2_MASK 0x0003FFFF +#define TMC5262_A2_SHIFT 0 +#define TMC5262_A2_FIELD ((RegisterField) {TMC5262_A2_MASK, TMC5262_A2_SHIFT, TMC5262_A2, false}) +#define TMC5262_D2_MASK 0x0003FFFF +#define TMC5262_D2_SHIFT 0 +#define TMC5262_D2_FIELD ((RegisterField) {TMC5262_D2_MASK, TMC5262_D2_SHIFT, TMC5262_D2, false}) +#define TMC5262_AACTUAL_MASK 0x00FFFFFF +#define TMC5262_AACTUAL_SHIFT 0 +#define TMC5262_AACTUAL_FIELD ((RegisterField) {TMC5262_AACTUAL_MASK, TMC5262_AACTUAL_SHIFT, TMC5262_AACTUAL, true}) +#define TMC5262_STOP_L_ENABLE_MASK 0x00000001 +#define TMC5262_STOP_L_ENABLE_SHIFT 0 +#define TMC5262_STOP_L_ENABLE_FIELD ((RegisterField) {TMC5262_STOP_L_ENABLE_MASK, TMC5262_STOP_L_ENABLE_SHIFT, TMC5262_SW_MODE, false}) +#define TMC5262_STOP_R_ENABLE_MASK 0x00000002 +#define TMC5262_STOP_R_ENABLE_SHIFT 1 +#define TMC5262_STOP_R_ENABLE_FIELD ((RegisterField) {TMC5262_STOP_R_ENABLE_MASK, TMC5262_STOP_R_ENABLE_SHIFT, TMC5262_SW_MODE, false}) +#define TMC5262_POL_STOP_L_MASK 0x00000004 +#define TMC5262_POL_STOP_L_SHIFT 2 +#define TMC5262_POL_STOP_L_FIELD ((RegisterField) {TMC5262_POL_STOP_L_MASK, TMC5262_POL_STOP_L_SHIFT, TMC5262_SW_MODE, false}) +#define TMC5262_POL_STOP_R_MASK 0x00000008 +#define TMC5262_POL_STOP_R_SHIFT 3 +#define TMC5262_POL_STOP_R_FIELD ((RegisterField) {TMC5262_POL_STOP_R_MASK, TMC5262_POL_STOP_R_SHIFT, TMC5262_SW_MODE, false}) +#define TMC5262_SWAP_LR_MASK 0x00000010 +#define TMC5262_SWAP_LR_SHIFT 4 +#define TMC5262_SWAP_LR_FIELD ((RegisterField) {TMC5262_SWAP_LR_MASK, TMC5262_SWAP_LR_SHIFT, TMC5262_SW_MODE, false}) +#define TMC5262_LATCH_L_ACTIVE_MASK 0x00000020 +#define TMC5262_LATCH_L_ACTIVE_SHIFT 5 +#define TMC5262_LATCH_L_ACTIVE_FIELD ((RegisterField) {TMC5262_LATCH_L_ACTIVE_MASK, TMC5262_LATCH_L_ACTIVE_SHIFT, TMC5262_SW_MODE, false}) +#define TMC5262_LATCH_L_INACTIVE_MASK 0x00000040 +#define TMC5262_LATCH_L_INACTIVE_SHIFT 6 +#define TMC5262_LATCH_L_INACTIVE_FIELD ((RegisterField) {TMC5262_LATCH_L_INACTIVE_MASK, TMC5262_LATCH_L_INACTIVE_SHIFT, TMC5262_SW_MODE, false}) +#define TMC5262_LATCH_R_ACTIVE_MASK 0x00000080 +#define TMC5262_LATCH_R_ACTIVE_SHIFT 7 +#define TMC5262_LATCH_R_ACTIVE_FIELD ((RegisterField) {TMC5262_LATCH_R_ACTIVE_MASK, TMC5262_LATCH_R_ACTIVE_SHIFT, TMC5262_SW_MODE, false}) +#define TMC5262_LATCH_R_INACTIVE_MASK 0x00000100 +#define TMC5262_LATCH_R_INACTIVE_SHIFT 8 +#define TMC5262_LATCH_R_INACTIVE_FIELD ((RegisterField) {TMC5262_LATCH_R_INACTIVE_MASK, TMC5262_LATCH_R_INACTIVE_SHIFT, TMC5262_SW_MODE, false}) +#define TMC5262_EN_LATCH_ENCODER_MASK 0x00000200 +#define TMC5262_EN_LATCH_ENCODER_SHIFT 9 +#define TMC5262_EN_LATCH_ENCODER_FIELD ((RegisterField) {TMC5262_EN_LATCH_ENCODER_MASK, TMC5262_EN_LATCH_ENCODER_SHIFT, TMC5262_SW_MODE, false}) +#define TMC5262_SG_STOP_MASK 0x00000400 +#define TMC5262_SG_STOP_SHIFT 10 +#define TMC5262_SG_STOP_FIELD ((RegisterField) {TMC5262_SG_STOP_MASK, TMC5262_SG_STOP_SHIFT, TMC5262_SW_MODE, false}) +#define TMC5262_EN_SOFTSTOP_MASK 0x00000800 +#define TMC5262_EN_SOFTSTOP_SHIFT 11 +#define TMC5262_EN_SOFTSTOP_FIELD ((RegisterField) {TMC5262_EN_SOFTSTOP_MASK, TMC5262_EN_SOFTSTOP_SHIFT, TMC5262_SW_MODE, false}) +#define TMC5262_EN_VIRTUAL_STOP_L_MASK 0x00001000 +#define TMC5262_EN_VIRTUAL_STOP_L_SHIFT 12 +#define TMC5262_EN_VIRTUAL_STOP_L_FIELD ((RegisterField) {TMC5262_EN_VIRTUAL_STOP_L_MASK, TMC5262_EN_VIRTUAL_STOP_L_SHIFT, TMC5262_SW_MODE, false}) +#define TMC5262_EN_VIRTUAL_STOP_R_MASK 0x00002000 +#define TMC5262_EN_VIRTUAL_STOP_R_SHIFT 13 +#define TMC5262_EN_VIRTUAL_STOP_R_FIELD ((RegisterField) {TMC5262_EN_VIRTUAL_STOP_R_MASK, TMC5262_EN_VIRTUAL_STOP_R_SHIFT, TMC5262_SW_MODE, false}) +#define TMC5262_VIRTUAL_STOP_ENC_MASK 0x00004000 +#define TMC5262_VIRTUAL_STOP_ENC_SHIFT 14 +#define TMC5262_VIRTUAL_STOP_ENC_FIELD ((RegisterField) {TMC5262_VIRTUAL_STOP_ENC_MASK, TMC5262_VIRTUAL_STOP_ENC_SHIFT, TMC5262_SW_MODE, false}) +#define TMC5262_HARD_STOP_CLR_CUR_INT_MASK 0x00008000 +#define TMC5262_HARD_STOP_CLR_CUR_INT_SHIFT 15 +#define TMC5262_HARD_STOP_CLR_CUR_INT_FIELD ((RegisterField) {TMC5262_HARD_STOP_CLR_CUR_INT_MASK, TMC5262_HARD_STOP_CLR_CUR_INT_SHIFT, TMC5262_SW_MODE, false}) +#define TMC5262_STATUS_STOP_L_MASK 0x00000001 +#define TMC5262_STATUS_STOP_L_SHIFT 0 +#define TMC5262_STATUS_STOP_L_FIELD ((RegisterField) {TMC5262_STATUS_STOP_L_MASK, TMC5262_STATUS_STOP_L_SHIFT, TMC5262_RAMP_STAT, false}) +#define TMC5262_STATUS_STOP_R_MASK 0x00000002 +#define TMC5262_STATUS_STOP_R_SHIFT 1 +#define TMC5262_STATUS_STOP_R_FIELD ((RegisterField) {TMC5262_STATUS_STOP_R_MASK, TMC5262_STATUS_STOP_R_SHIFT, TMC5262_RAMP_STAT, false}) +#define TMC5262_STATUS_LATCH_L_MASK 0x00000004 +#define TMC5262_STATUS_LATCH_L_SHIFT 2 +#define TMC5262_STATUS_LATCH_L_FIELD ((RegisterField) {TMC5262_STATUS_LATCH_L_MASK, TMC5262_STATUS_LATCH_L_SHIFT, TMC5262_RAMP_STAT, false}) +#define TMC5262_STATUS_LATCH_R_MASK 0x00000008 +#define TMC5262_STATUS_LATCH_R_SHIFT 3 +#define TMC5262_STATUS_LATCH_R_FIELD ((RegisterField) {TMC5262_STATUS_LATCH_R_MASK, TMC5262_STATUS_LATCH_R_SHIFT, TMC5262_RAMP_STAT, false}) +#define TMC5262_EVENT_STOP_L_MASK 0x00000010 +#define TMC5262_EVENT_STOP_L_SHIFT 4 +#define TMC5262_EVENT_STOP_L_FIELD ((RegisterField) {TMC5262_EVENT_STOP_L_MASK, TMC5262_EVENT_STOP_L_SHIFT, TMC5262_RAMP_STAT, false}) +#define TMC5262_EVENT_STOP_R_MASK 0x00000020 +#define TMC5262_EVENT_STOP_R_SHIFT 5 +#define TMC5262_EVENT_STOP_R_FIELD ((RegisterField) {TMC5262_EVENT_STOP_R_MASK, TMC5262_EVENT_STOP_R_SHIFT, TMC5262_RAMP_STAT, false}) +#define TMC5262_EVENT_STOP_SG_MASK 0x00000040 +#define TMC5262_EVENT_STOP_SG_SHIFT 6 +#define TMC5262_EVENT_STOP_SG_FIELD ((RegisterField) {TMC5262_EVENT_STOP_SG_MASK, TMC5262_EVENT_STOP_SG_SHIFT, TMC5262_RAMP_STAT, false}) +#define TMC5262_EVENT_POS_REACHED_MASK 0x00000080 +#define TMC5262_EVENT_POS_REACHED_SHIFT 7 +#define TMC5262_EVENT_POS_REACHED_FIELD ((RegisterField) {TMC5262_EVENT_POS_REACHED_MASK, TMC5262_EVENT_POS_REACHED_SHIFT, TMC5262_RAMP_STAT, false}) +#define TMC5262_VELOCITY_REACHED_MASK 0x00000100 +#define TMC5262_VELOCITY_REACHED_SHIFT 8 +#define TMC5262_VELOCITY_REACHED_FIELD ((RegisterField) {TMC5262_VELOCITY_REACHED_MASK, TMC5262_VELOCITY_REACHED_SHIFT, TMC5262_RAMP_STAT, false}) +#define TMC5262_POSITION_REACHED_MASK 0x00000200 +#define TMC5262_POSITION_REACHED_SHIFT 9 +#define TMC5262_POSITION_REACHED_FIELD ((RegisterField) {TMC5262_POSITION_REACHED_MASK, TMC5262_POSITION_REACHED_SHIFT, TMC5262_RAMP_STAT, false}) +#define TMC5262_VZERO_MASK 0x00000400 +#define TMC5262_VZERO_SHIFT 10 +#define TMC5262_VZERO_FIELD ((RegisterField) {TMC5262_VZERO_MASK, TMC5262_VZERO_SHIFT, TMC5262_RAMP_STAT, false}) +#define TMC5262_T_ZEROWAIT_ACTIVE_MASK 0x00000800 +#define TMC5262_T_ZEROWAIT_ACTIVE_SHIFT 11 +#define TMC5262_T_ZEROWAIT_ACTIVE_FIELD ((RegisterField) {TMC5262_T_ZEROWAIT_ACTIVE_MASK, TMC5262_T_ZEROWAIT_ACTIVE_SHIFT, TMC5262_RAMP_STAT, false}) +#define TMC5262_SECOND_MOVE_MASK 0x00001000 +#define TMC5262_SECOND_MOVE_SHIFT 12 +#define TMC5262_SECOND_MOVE_FIELD ((RegisterField) {TMC5262_SECOND_MOVE_MASK, TMC5262_SECOND_MOVE_SHIFT, TMC5262_RAMP_STAT, false}) +#define TMC5262_STATUS_SG_MASK 0x00002000 +#define TMC5262_STATUS_SG_SHIFT 13 +#define TMC5262_STATUS_SG_FIELD ((RegisterField) {TMC5262_STATUS_SG_MASK, TMC5262_STATUS_SG_SHIFT, TMC5262_RAMP_STAT, false}) +#define TMC5262_STATUS_VIRTUAL_STOP_L_MASK 0x00004000 +#define TMC5262_STATUS_VIRTUAL_STOP_L_SHIFT 14 +#define TMC5262_STATUS_VIRTUAL_STOP_L_FIELD ((RegisterField) {TMC5262_STATUS_VIRTUAL_STOP_L_MASK, TMC5262_STATUS_VIRTUAL_STOP_L_SHIFT, TMC5262_RAMP_STAT, false}) +#define TMC5262_STATUS_VIRTUAL_STOP_R_MASK 0x00008000 +#define TMC5262_STATUS_VIRTUAL_STOP_R_SHIFT 15 +#define TMC5262_STATUS_VIRTUAL_STOP_R_FIELD ((RegisterField) {TMC5262_STATUS_VIRTUAL_STOP_R_MASK, TMC5262_STATUS_VIRTUAL_STOP_R_SHIFT, TMC5262_RAMP_STAT, false}) +#define TMC5262_XLATCH_MASK 0xFFFFFFFF +#define TMC5262_XLATCH_SHIFT 0 +#define TMC5262_XLATCH_FIELD ((RegisterField) {TMC5262_XLATCH_MASK, TMC5262_XLATCH_SHIFT, TMC5262_XLATCH, false}) +#define TMC5262_POL_A_MASK 0x00000001 +#define TMC5262_POL_A_SHIFT 0 +#define TMC5262_POL_A_FIELD ((RegisterField) {TMC5262_POL_A_MASK, TMC5262_POL_A_SHIFT, TMC5262_ENCMODE, false}) +#define TMC5262_POL_B_MASK 0x00000002 +#define TMC5262_POL_B_SHIFT 1 +#define TMC5262_POL_B_FIELD ((RegisterField) {TMC5262_POL_B_MASK, TMC5262_POL_B_SHIFT, TMC5262_ENCMODE, false}) +#define TMC5262_POL_N_MASK 0x00000004 +#define TMC5262_POL_N_SHIFT 2 +#define TMC5262_POL_N_FIELD ((RegisterField) {TMC5262_POL_N_MASK, TMC5262_POL_N_SHIFT, TMC5262_ENCMODE, false}) +#define TMC5262_IGNORE_AB_MASK 0x00000008 +#define TMC5262_IGNORE_AB_SHIFT 3 +#define TMC5262_IGNORE_AB_FIELD ((RegisterField) {TMC5262_IGNORE_AB_MASK, TMC5262_IGNORE_AB_SHIFT, TMC5262_ENCMODE, false}) +#define TMC5262_CLR_CONT_MASK 0x00000010 +#define TMC5262_CLR_CONT_SHIFT 4 +#define TMC5262_CLR_CONT_FIELD ((RegisterField) {TMC5262_CLR_CONT_MASK, TMC5262_CLR_CONT_SHIFT, TMC5262_ENCMODE, false}) +#define TMC5262_CLR_ONCE_MASK 0x00000020 +#define TMC5262_CLR_ONCE_SHIFT 5 +#define TMC5262_CLR_ONCE_FIELD ((RegisterField) {TMC5262_CLR_ONCE_MASK, TMC5262_CLR_ONCE_SHIFT, TMC5262_ENCMODE, false}) +#define TMC5262_POS_NEG_EDGE_MASK 0x000000C0 +#define TMC5262_POS_NEG_EDGE_SHIFT 6 +#define TMC5262_POS_NEG_EDGE_FIELD ((RegisterField) {TMC5262_POS_NEG_EDGE_MASK, TMC5262_POS_NEG_EDGE_SHIFT, TMC5262_ENCMODE, false}) +#define TMC5262_CLR_ENC_X_MASK 0x00000100 +#define TMC5262_CLR_ENC_X_SHIFT 8 +#define TMC5262_CLR_ENC_X_FIELD ((RegisterField) {TMC5262_CLR_ENC_X_MASK, TMC5262_CLR_ENC_X_SHIFT, TMC5262_ENCMODE, false}) +#define TMC5262_LATCH_X_ACT_MASK 0x00000200 +#define TMC5262_LATCH_X_ACT_SHIFT 9 +#define TMC5262_LATCH_X_ACT_FIELD ((RegisterField) {TMC5262_LATCH_X_ACT_MASK, TMC5262_LATCH_X_ACT_SHIFT, TMC5262_ENCMODE, false}) +#define TMC5262_ENC_SEL_DECIMAL_MASK 0x00000400 +#define TMC5262_ENC_SEL_DECIMAL_SHIFT 10 +#define TMC5262_ENC_SEL_DECIMAL_FIELD ((RegisterField) {TMC5262_ENC_SEL_DECIMAL_MASK, TMC5262_ENC_SEL_DECIMAL_SHIFT, TMC5262_ENCMODE, false}) +#define TMC5262_NBEMF_ABN_SEL_MASK 0x00000800 +#define TMC5262_NBEMF_ABN_SEL_SHIFT 11 +#define TMC5262_NBEMF_ABN_SEL_FIELD ((RegisterField) {TMC5262_NBEMF_ABN_SEL_MASK, TMC5262_NBEMF_ABN_SEL_SHIFT, TMC5262_ENCMODE, false}) +#define TMC5262_BEMF_HYST_MASK 0x00007000 +#define TMC5262_BEMF_HYST_SHIFT 12 +#define TMC5262_BEMF_HYST_FIELD ((RegisterField) {TMC5262_BEMF_HYST_MASK, TMC5262_BEMF_HYST_SHIFT, TMC5262_ENCMODE, false}) +#define TMC5262_BEMF_BLANK_TIME_MASK 0x00FF0000 +#define TMC5262_BEMF_BLANK_TIME_SHIFT 16 +#define TMC5262_BEMF_BLANK_TIME_FIELD ((RegisterField) {TMC5262_BEMF_BLANK_TIME_MASK, TMC5262_BEMF_BLANK_TIME_SHIFT, TMC5262_ENCMODE, false}) +#define TMC5262_BEMF_FILTER_SEL_MASK 0x30000000 +#define TMC5262_BEMF_FILTER_SEL_SHIFT 28 +#define TMC5262_BEMF_FILTER_SEL_FIELD ((RegisterField) {TMC5262_BEMF_FILTER_SEL_MASK, TMC5262_BEMF_FILTER_SEL_SHIFT, TMC5262_ENCMODE, false}) +#define TMC5262_X_ENC_MASK 0xFFFFFFFF +#define TMC5262_X_ENC_SHIFT 0 +#define TMC5262_X_ENC_FIELD ((RegisterField) {TMC5262_X_ENC_MASK, TMC5262_X_ENC_SHIFT, TMC5262_X_ENC, true}) +#define TMC5262_ENC_CONST_MASK 0xFFFFFFFF +#define TMC5262_ENC_CONST_SHIFT 0 +#define TMC5262_ENC_CONST_FIELD ((RegisterField) {TMC5262_ENC_CONST_MASK, TMC5262_ENC_CONST_SHIFT, TMC5262_ENC_CONST, true}) +#define TMC5262_N_EVENT_MASK 0x00000001 +#define TMC5262_N_EVENT_SHIFT 0 +#define TMC5262_N_EVENT_FIELD ((RegisterField) {TMC5262_N_EVENT_MASK, TMC5262_N_EVENT_SHIFT, TMC5262_ENC_STATUS, false}) +#define TMC5262_DEVIATION_WARN_MASK 0x00000002 +#define TMC5262_DEVIATION_WARN_SHIFT 1 +#define TMC5262_DEVIATION_WARN_FIELD ((RegisterField) {TMC5262_DEVIATION_WARN_MASK, TMC5262_DEVIATION_WARN_SHIFT, TMC5262_ENC_STATUS, false}) +#define TMC5262_ENC_LATCH_MASK 0xFFFFFFFF +#define TMC5262_ENC_LATCH_SHIFT 0 +#define TMC5262_ENC_LATCH_FIELD ((RegisterField) {TMC5262_ENC_LATCH_MASK, TMC5262_ENC_LATCH_SHIFT, TMC5262_ENC_LATCH, false}) +#define TMC5262_ENC_DEVIATION_MASK 0x000FFFFF +#define TMC5262_ENC_DEVIATION_SHIFT 0 +#define TMC5262_ENC_DEVIATION_FIELD ((RegisterField) {TMC5262_ENC_DEVIATION_MASK, TMC5262_ENC_DEVIATION_SHIFT, TMC5262_ENC_DEVIATION, false}) +#define TMC5262_VIRTUAL_STOP_L_MASK 0xFFFFFFFF +#define TMC5262_VIRTUAL_STOP_L_SHIFT 0 +#define TMC5262_VIRTUAL_STOP_L_FIELD ((RegisterField) {TMC5262_VIRTUAL_STOP_L_MASK, TMC5262_VIRTUAL_STOP_L_SHIFT, TMC5262_VIRTUAL_STOP_L, true}) +#define TMC5262_VIRTUAL_STOP_R_MASK 0xFFFFFFFF +#define TMC5262_VIRTUAL_STOP_R_SHIFT 0 +#define TMC5262_VIRTUAL_STOP_R_FIELD ((RegisterField) {TMC5262_VIRTUAL_STOP_R_MASK, TMC5262_VIRTUAL_STOP_R_SHIFT, TMC5262_VIRTUAL_STOP_R, true}) +#define TMC5262_CUR_P_MASK 0x00000FFF +#define TMC5262_CUR_P_SHIFT 0 +#define TMC5262_CUR_P_FIELD ((RegisterField) {TMC5262_CUR_P_MASK, TMC5262_CUR_P_SHIFT, TMC5262_CURRENT_PI_REG, false}) +#define TMC5262_CUR_I_MASK 0x03FF0000 +#define TMC5262_CUR_I_SHIFT 16 +#define TMC5262_CUR_I_FIELD ((RegisterField) {TMC5262_CUR_I_MASK, TMC5262_CUR_I_SHIFT, TMC5262_CURRENT_PI_REG, false}) +#define TMC5262_ANGLE_P_MASK 0x00000FFF +#define TMC5262_ANGLE_P_SHIFT 0 +#define TMC5262_ANGLE_P_FIELD ((RegisterField) {TMC5262_ANGLE_P_MASK, TMC5262_ANGLE_P_SHIFT, TMC5262_ANGLE_PI_REG, false}) +#define TMC5262_ANGLE_I_MASK 0x03FF0000 +#define TMC5262_ANGLE_I_SHIFT 16 +#define TMC5262_ANGLE_I_FIELD ((RegisterField) {TMC5262_ANGLE_I_MASK, TMC5262_ANGLE_I_SHIFT, TMC5262_ANGLE_PI_REG, false}) +#define TMC5262_ANGLE_PI_LIMIT_MASK 0x000003FF +#define TMC5262_ANGLE_PI_LIMIT_SHIFT 0 +#define TMC5262_ANGLE_PI_LIMIT_FIELD ((RegisterField) {TMC5262_ANGLE_PI_LIMIT_MASK, TMC5262_ANGLE_PI_LIMIT_SHIFT, TMC5262_CUR_ANGLE_LIMIT, false}) +#define TMC5262_ANGLE_PI_INT_POS_CLIP_MASK 0x00001000 +#define TMC5262_ANGLE_PI_INT_POS_CLIP_SHIFT 12 +#define TMC5262_ANGLE_PI_INT_POS_CLIP_FIELD ((RegisterField) {TMC5262_ANGLE_PI_INT_POS_CLIP_MASK, TMC5262_ANGLE_PI_INT_POS_CLIP_SHIFT, TMC5262_CUR_ANGLE_LIMIT, false}) +#define TMC5262_ANGLE_PI_INT_NEG_CLIP_MASK 0x00002000 +#define TMC5262_ANGLE_PI_INT_NEG_CLIP_SHIFT 13 +#define TMC5262_ANGLE_PI_INT_NEG_CLIP_FIELD ((RegisterField) {TMC5262_ANGLE_PI_INT_NEG_CLIP_MASK, TMC5262_ANGLE_PI_INT_NEG_CLIP_SHIFT, TMC5262_CUR_ANGLE_LIMIT, false}) +#define TMC5262_ANGLE_PI_POS_CLIP_MASK 0x00004000 +#define TMC5262_ANGLE_PI_POS_CLIP_SHIFT 14 +#define TMC5262_ANGLE_PI_POS_CLIP_FIELD ((RegisterField) {TMC5262_ANGLE_PI_POS_CLIP_MASK, TMC5262_ANGLE_PI_POS_CLIP_SHIFT, TMC5262_CUR_ANGLE_LIMIT, false}) +#define TMC5262_ANGLE_PI_NEG_CLIP_MASK 0x00008000 +#define TMC5262_ANGLE_PI_NEG_CLIP_SHIFT 15 +#define TMC5262_ANGLE_PI_NEG_CLIP_FIELD ((RegisterField) {TMC5262_ANGLE_PI_NEG_CLIP_MASK, TMC5262_ANGLE_PI_NEG_CLIP_SHIFT, TMC5262_CUR_ANGLE_LIMIT, false}) +#define TMC5262_CUR_PI_LIMIT_MASK 0x0FFF0000 +#define TMC5262_CUR_PI_LIMIT_SHIFT 16 +#define TMC5262_CUR_PI_LIMIT_FIELD ((RegisterField) {TMC5262_CUR_PI_LIMIT_MASK, TMC5262_CUR_PI_LIMIT_SHIFT, TMC5262_CUR_ANGLE_LIMIT, false}) +#define TMC5262_CUR_PI_INT_POS_CLIP_MASK 0x10000000 +#define TMC5262_CUR_PI_INT_POS_CLIP_SHIFT 28 +#define TMC5262_CUR_PI_INT_POS_CLIP_FIELD ((RegisterField) {TMC5262_CUR_PI_INT_POS_CLIP_MASK, TMC5262_CUR_PI_INT_POS_CLIP_SHIFT, TMC5262_CUR_ANGLE_LIMIT, false}) +#define TMC5262_CUR_PI_INT_NEG_CLIP_MASK 0x20000000 +#define TMC5262_CUR_PI_INT_NEG_CLIP_SHIFT 29 +#define TMC5262_CUR_PI_INT_NEG_CLIP_FIELD ((RegisterField) {TMC5262_CUR_PI_INT_NEG_CLIP_MASK, TMC5262_CUR_PI_INT_NEG_CLIP_SHIFT, TMC5262_CUR_ANGLE_LIMIT, false}) +#define TMC5262_CUR_PI_POS_CLIP_MASK 0x40000000 +#define TMC5262_CUR_PI_POS_CLIP_SHIFT 30 +#define TMC5262_CUR_PI_POS_CLIP_FIELD ((RegisterField) {TMC5262_CUR_PI_POS_CLIP_MASK, TMC5262_CUR_PI_POS_CLIP_SHIFT, TMC5262_CUR_ANGLE_LIMIT, false}) +#define TMC5262_CUR_PI_NEG_CLIP_MASK 0x80000000 +#define TMC5262_CUR_PI_NEG_CLIP_SHIFT 31 +#define TMC5262_CUR_PI_NEG_CLIP_FIELD ((RegisterField) {TMC5262_CUR_PI_NEG_CLIP_MASK, TMC5262_CUR_PI_NEG_CLIP_SHIFT, TMC5262_CUR_ANGLE_LIMIT, false}) +#define TMC5262_ANGLE_LOWER_I_LIMIT_MASK 0x000003FF +#define TMC5262_ANGLE_LOWER_I_LIMIT_SHIFT 0 +#define TMC5262_ANGLE_LOWER_I_LIMIT_FIELD ((RegisterField) {TMC5262_ANGLE_LOWER_I_LIMIT_MASK, TMC5262_ANGLE_LOWER_I_LIMIT_SHIFT, TMC5262_ANGLE_LOWER_LIMIT, false}) +#define TMC5262_ANGLE_ERROR_MASK 0x03FF0000 +#define TMC5262_ANGLE_ERROR_SHIFT 16 +#define TMC5262_ANGLE_ERROR_FIELD ((RegisterField) {TMC5262_ANGLE_ERROR_MASK, TMC5262_ANGLE_ERROR_SHIFT, TMC5262_ANGLE_LOWER_LIMIT, true}) +#define TMC5262_AMPL_MEAS_MASK 0x00000FFF +#define TMC5262_AMPL_MEAS_SHIFT 0 +#define TMC5262_AMPL_MEAS_FIELD ((RegisterField) {TMC5262_AMPL_MEAS_MASK, TMC5262_AMPL_MEAS_SHIFT, TMC5262_CUR_ANGLE_MEAS, false}) +#define TMC5262_ANGLE_MEAS_MASK 0x03FF0000 +#define TMC5262_ANGLE_MEAS_SHIFT 16 +#define TMC5262_ANGLE_MEAS_FIELD ((RegisterField) {TMC5262_ANGLE_MEAS_MASK, TMC5262_ANGLE_MEAS_SHIFT, TMC5262_CUR_ANGLE_MEAS, false}) +#define TMC5262_PWM_CALC_MASK 0x00001FFF +#define TMC5262_PWM_CALC_SHIFT 0 +#define TMC5262_PWM_CALC_FIELD ((RegisterField) {TMC5262_PWM_CALC_MASK, TMC5262_PWM_CALC_SHIFT, TMC5262_PI_RESULTS, true}) +#define TMC5262_ANGLE_CORR_CALC_MASK 0x03FF0000 +#define TMC5262_ANGLE_CORR_CALC_SHIFT 16 +#define TMC5262_ANGLE_CORR_CALC_FIELD ((RegisterField) {TMC5262_ANGLE_CORR_CALC_MASK, TMC5262_ANGLE_CORR_CALC_SHIFT, TMC5262_PI_RESULTS, true}) +#define TMC5262_COIL_INDUCT_MASK 0x00007FFF +#define TMC5262_COIL_INDUCT_SHIFT 0 +#define TMC5262_COIL_INDUCT_FIELD ((RegisterField) {TMC5262_COIL_INDUCT_MASK, TMC5262_COIL_INDUCT_SHIFT, TMC5262_COIL_INDUCT, false}) +#define TMC5262_RCOIL_MANUAL_MASK 0x00010000 +#define TMC5262_RCOIL_MANUAL_SHIFT 16 +#define TMC5262_RCOIL_MANUAL_FIELD ((RegisterField) {TMC5262_RCOIL_MANUAL_MASK, TMC5262_RCOIL_MANUAL_SHIFT, TMC5262_COIL_INDUCT, false}) +#define TMC5262_RCOIL_THERMAL_COUPLING_MASK 0x00020000 +#define TMC5262_RCOIL_THERMAL_COUPLING_SHIFT 17 +#define TMC5262_RCOIL_THERMAL_COUPLING_FIELD ((RegisterField) {TMC5262_RCOIL_THERMAL_COUPLING_MASK, TMC5262_RCOIL_THERMAL_COUPLING_SHIFT, TMC5262_COIL_INDUCT, false}) +#define TMC5262_R_COIL_AUTO_B_MASK 0x00000FFF +#define TMC5262_R_COIL_AUTO_B_SHIFT 0 +#define TMC5262_R_COIL_AUTO_B_FIELD ((RegisterField) {TMC5262_R_COIL_AUTO_B_MASK, TMC5262_R_COIL_AUTO_B_SHIFT, TMC5262_R_COIL, false}) +#define TMC5262_R_COIL_AUTO_A_MASK 0x0FFF0000 +#define TMC5262_R_COIL_AUTO_A_SHIFT 16 +#define TMC5262_R_COIL_AUTO_A_FIELD ((RegisterField) {TMC5262_R_COIL_AUTO_A_MASK, TMC5262_R_COIL_AUTO_A_SHIFT, TMC5262_R_COIL, false}) +#define TMC5262_R_COIL_USER_B_MASK 0x00000FFF +#define TMC5262_R_COIL_USER_B_SHIFT 0 +#define TMC5262_R_COIL_USER_B_FIELD ((RegisterField) {TMC5262_R_COIL_USER_B_MASK, TMC5262_R_COIL_USER_B_SHIFT, TMC5262_R_COIL_USER, false}) +#define TMC5262_R_COIL_USER_A_MASK 0x0FFF0000 +#define TMC5262_R_COIL_USER_A_SHIFT 16 +#define TMC5262_R_COIL_USER_A_FIELD ((RegisterField) {TMC5262_R_COIL_USER_A_MASK, TMC5262_R_COIL_USER_A_SHIFT, TMC5262_R_COIL_USER, false}) +#define TMC5262_SGP_THRS_MASK 0x000001FF +#define TMC5262_SGP_THRS_SHIFT 0 +#define TMC5262_SGP_THRS_FIELD ((RegisterField) {TMC5262_SGP_THRS_MASK, TMC5262_SGP_THRS_SHIFT, TMC5262_SGP_CONF, true}) +#define TMC5262_SGP_FILT_EN_MASK 0x00001000 +#define TMC5262_SGP_FILT_EN_SHIFT 12 +#define TMC5262_SGP_FILT_EN_FIELD ((RegisterField) {TMC5262_SGP_FILT_EN_MASK, TMC5262_SGP_FILT_EN_SHIFT, TMC5262_SGP_CONF, false}) +#define TMC5262_SGP_LOW_VEL_FREEZE_MASK 0x00002000 +#define TMC5262_SGP_LOW_VEL_FREEZE_SHIFT 13 +#define TMC5262_SGP_LOW_VEL_FREEZE_FIELD ((RegisterField) {TMC5262_SGP_LOW_VEL_FREEZE_MASK, TMC5262_SGP_LOW_VEL_FREEZE_SHIFT, TMC5262_SGP_CONF, false}) +#define TMC5262_SGP_CLEAR_CUR_PI_MASK 0x00004000 +#define TMC5262_SGP_CLEAR_CUR_PI_SHIFT 14 +#define TMC5262_SGP_CLEAR_CUR_PI_FIELD ((RegisterField) {TMC5262_SGP_CLEAR_CUR_PI_MASK, TMC5262_SGP_CLEAR_CUR_PI_SHIFT, TMC5262_SGP_CONF, false}) +#define TMC5262_SGP_LOW_VEL_SLOPE_MASK 0x00FF0000 +#define TMC5262_SGP_LOW_VEL_SLOPE_SHIFT 16 +#define TMC5262_SGP_LOW_VEL_SLOPE_FIELD ((RegisterField) {TMC5262_SGP_LOW_VEL_SLOPE_MASK, TMC5262_SGP_LOW_VEL_SLOPE_SHIFT, TMC5262_SGP_CONF, false}) +#define TMC5262_SGP_LOW_VEL_CNTS_MASK 0x30000000 +#define TMC5262_SGP_LOW_VEL_CNTS_SHIFT 28 +#define TMC5262_SGP_LOW_VEL_CNTS_FIELD ((RegisterField) {TMC5262_SGP_LOW_VEL_CNTS_MASK, TMC5262_SGP_LOW_VEL_CNTS_SHIFT, TMC5262_SGP_CONF, false}) +#define TMC5262_SGP_IND_2_MASK 0x000003FF +#define TMC5262_SGP_IND_2_SHIFT 0 +#define TMC5262_SGP_IND_2_FIELD ((RegisterField) {TMC5262_SGP_IND_2_MASK, TMC5262_SGP_IND_2_SHIFT, TMC5262_SGP_IND_2_3, true}) +#define TMC5262_SGP_IND_3_MASK 0x03FF0000 +#define TMC5262_SGP_IND_3_SHIFT 16 +#define TMC5262_SGP_IND_3_FIELD ((RegisterField) {TMC5262_SGP_IND_3_MASK, TMC5262_SGP_IND_3_SHIFT, TMC5262_SGP_IND_2_3, true}) +#define TMC5262_SGP_IND_0_MASK 0x000003FF +#define TMC5262_SGP_IND_0_SHIFT 0 +#define TMC5262_SGP_IND_0_FIELD ((RegisterField) {TMC5262_SGP_IND_0_MASK, TMC5262_SGP_IND_0_SHIFT, TMC5262_SGP_IND_0_1, true}) +#define TMC5262_SGP_IND_1_MASK 0x03FF0000 +#define TMC5262_SGP_IND_1_SHIFT 16 +#define TMC5262_SGP_IND_1_FIELD ((RegisterField) {TMC5262_SGP_IND_1_MASK, TMC5262_SGP_IND_1_SHIFT, TMC5262_SGP_IND_0_1, true}) +#define TMC5262_UL_B_MASK 0x00000FFF +#define TMC5262_UL_B_SHIFT 0 +#define TMC5262_UL_B_FIELD ((RegisterField) {TMC5262_UL_B_MASK, TMC5262_UL_B_SHIFT, TMC5262_INDUCTANCE_VOLTAGE, true}) +#define TMC5262_UL_A_MASK 0x0FFF0000 +#define TMC5262_UL_A_SHIFT 16 +#define TMC5262_UL_A_FIELD ((RegisterField) {TMC5262_UL_A_MASK, TMC5262_UL_A_SHIFT, TMC5262_INDUCTANCE_VOLTAGE, true}) +#define TMC5262_SGP_RAW_MASK 0x000003FF +#define TMC5262_SGP_RAW_SHIFT 0 +#define TMC5262_SGP_RAW_FIELD ((RegisterField) {TMC5262_SGP_RAW_MASK, TMC5262_SGP_RAW_SHIFT, TMC5262_SGP_BEMF, true}) +#define TMC5262_UBEMF_ABS_MASK 0x0FFF0000 +#define TMC5262_UBEMF_ABS_SHIFT 16 +#define TMC5262_UBEMF_ABS_FIELD ((RegisterField) {TMC5262_UBEMF_ABS_MASK, TMC5262_UBEMF_ABS_SHIFT, TMC5262_SGP_BEMF, false}) +#define TMC5262_COOL_CUR_DIV_MASK 0x0000000F +#define TMC5262_COOL_CUR_DIV_SHIFT 0 +#define TMC5262_COOL_CUR_DIV_FIELD ((RegisterField) {TMC5262_COOL_CUR_DIV_MASK, TMC5262_COOL_CUR_DIV_SHIFT, TMC5262_COOLSTEPPLUS_CONF, false}) +#define TMC5262_LOAD_FILT_EN_MASK 0x00000010 +#define TMC5262_LOAD_FILT_EN_SHIFT 4 +#define TMC5262_LOAD_FILT_EN_FIELD ((RegisterField) {TMC5262_LOAD_FILT_EN_MASK, TMC5262_LOAD_FILT_EN_SHIFT, TMC5262_COOLSTEPPLUS_CONF, false}) +#define TMC5262_COOLSTEP_P_MASK 0x00000FFF +#define TMC5262_COOLSTEP_P_SHIFT 0 +#define TMC5262_COOLSTEP_P_FIELD ((RegisterField) {TMC5262_COOLSTEP_P_MASK, TMC5262_COOLSTEP_P_SHIFT, TMC5262_COOLSTEPPLUS_PI_REG, false}) +#define TMC5262_COOLSTEP_I_MASK 0x03FF0000 +#define TMC5262_COOLSTEP_I_SHIFT 16 +#define TMC5262_COOLSTEP_I_FIELD ((RegisterField) {TMC5262_COOLSTEP_I_MASK, TMC5262_COOLSTEP_I_SHIFT, TMC5262_COOLSTEPPLUS_PI_REG, false}) +#define TMC5262_COOL_PI_DOWN_LIMIT_MASK 0x00000FFF +#define TMC5262_COOL_PI_DOWN_LIMIT_SHIFT 0 +#define TMC5262_COOL_PI_DOWN_LIMIT_FIELD ((RegisterField) {TMC5262_COOL_PI_DOWN_LIMIT_MASK, TMC5262_COOL_PI_DOWN_LIMIT_SHIFT, TMC5262_COOLSTEPPLUS_PI_DOWN, false}) +#define TMC5262_COOL_PI_OFF_SPEED_MASK 0x0FFF0000 +#define TMC5262_COOL_PI_OFF_SPEED_SHIFT 16 +#define TMC5262_COOL_PI_OFF_SPEED_FIELD ((RegisterField) {TMC5262_COOL_PI_OFF_SPEED_MASK, TMC5262_COOL_PI_OFF_SPEED_SHIFT, TMC5262_COOLSTEPPLUS_PI_DOWN, false}) +#define TMC5262_COOL_LOW_LOAD_RESERVE_MASK 0x000000FF +#define TMC5262_COOL_LOW_LOAD_RESERVE_SHIFT 0 +#define TMC5262_COOL_LOW_LOAD_RESERVE_FIELD ((RegisterField) {TMC5262_COOL_LOW_LOAD_RESERVE_MASK, TMC5262_COOL_LOW_LOAD_RESERVE_SHIFT, TMC5262_COOLSTEPPLUS_RESERVE_CONF, false}) +#define TMC5262_COOL_HI_LOAD_RESERVE_MASK 0x0000FF00 +#define TMC5262_COOL_HI_LOAD_RESERVE_SHIFT 8 +#define TMC5262_COOL_HI_LOAD_RESERVE_FIELD ((RegisterField) {TMC5262_COOL_HI_LOAD_RESERVE_MASK, TMC5262_COOL_HI_LOAD_RESERVE_SHIFT, TMC5262_COOLSTEPPLUS_RESERVE_CONF, false}) +#define TMC5262_COOL_LOW_GENERATORIC_RESERVE_MASK 0x00FF0000 +#define TMC5262_COOL_LOW_GENERATORIC_RESERVE_SHIFT 16 +#define TMC5262_COOL_LOW_GENERATORIC_RESERVE_FIELD ((RegisterField) {TMC5262_COOL_LOW_GENERATORIC_RESERVE_MASK, TMC5262_COOL_LOW_GENERATORIC_RESERVE_SHIFT, TMC5262_COOLSTEPPLUS_RESERVE_CONF, false}) +#define TMC5262_COOL_HI_GENERATORIC_RESERVE_MASK 0xFF000000 +#define TMC5262_COOL_HI_GENERATORIC_RESERVE_SHIFT 24 +#define TMC5262_COOL_HI_GENERATORIC_RESERVE_FIELD ((RegisterField) {TMC5262_COOL_HI_GENERATORIC_RESERVE_MASK, TMC5262_COOL_HI_GENERATORIC_RESERVE_SHIFT, TMC5262_COOLSTEPPLUS_RESERVE_CONF, false}) +#define TMC5262_SGP_RESULT_MASK 0x000003FF +#define TMC5262_SGP_RESULT_SHIFT 0 +#define TMC5262_SGP_RESULT_FIELD ((RegisterField) {TMC5262_SGP_RESULT_MASK, TMC5262_SGP_RESULT_SHIFT, TMC5262_COOLSTEPPLUS_LOAD_RESERVE, true}) +#define TMC5262_COOLSTEP_LOAD_RESERVE_MASK 0x01FF0000 +#define TMC5262_COOLSTEP_LOAD_RESERVE_SHIFT 16 +#define TMC5262_COOLSTEP_LOAD_RESERVE_FIELD ((RegisterField) {TMC5262_COOLSTEP_LOAD_RESERVE_MASK, TMC5262_COOLSTEP_LOAD_RESERVE_SHIFT, TMC5262_COOLSTEPPLUS_LOAD_RESERVE, false}) +#define TMC5262_TSTEP_VELOCITY_MASK 0x007FFFFF +#define TMC5262_TSTEP_VELOCITY_SHIFT 0 +#define TMC5262_TSTEP_VELOCITY_FIELD ((RegisterField) {TMC5262_TSTEP_VELOCITY_MASK, TMC5262_TSTEP_VELOCITY_SHIFT, TMC5262_TSTEP_VELOCITY, true}) +#define TMC5262_ADC_VSUPPLY_MASK 0x000001FF +#define TMC5262_ADC_VSUPPLY_SHIFT 0 +#define TMC5262_ADC_VSUPPLY_FIELD ((RegisterField) {TMC5262_ADC_VSUPPLY_MASK, TMC5262_ADC_VSUPPLY_SHIFT, TMC5262_ADC_VSUPPLY_TEMP, false}) +#define TMC5262_ADC_TEMP_MASK 0x01FF0000 +#define TMC5262_ADC_TEMP_SHIFT 16 +#define TMC5262_ADC_TEMP_FIELD ((RegisterField) {TMC5262_ADC_TEMP_MASK, TMC5262_ADC_TEMP_SHIFT, TMC5262_ADC_VSUPPLY_TEMP, false}) +#define TMC5262_ADC_I_A_MASK 0x00000FFF +#define TMC5262_ADC_I_A_SHIFT 0 +#define TMC5262_ADC_I_A_FIELD ((RegisterField) {TMC5262_ADC_I_A_MASK, TMC5262_ADC_I_A_SHIFT, TMC5262_ADC_I, true}) +#define TMC5262_ADC_I_B_MASK 0x0FFF0000 +#define TMC5262_ADC_I_B_SHIFT 16 +#define TMC5262_ADC_I_B_FIELD ((RegisterField) {TMC5262_ADC_I_B_MASK, TMC5262_ADC_I_B_SHIFT, TMC5262_ADC_I, true}) +#define TMC5262_OVERVOLTAGE_VTH_MASK 0x000001FF +#define TMC5262_OVERVOLTAGE_VTH_SHIFT 0 +#define TMC5262_OVERVOLTAGE_VTH_FIELD ((RegisterField) {TMC5262_OVERVOLTAGE_VTH_MASK, TMC5262_OVERVOLTAGE_VTH_SHIFT, TMC5262_OTW_OV_VTH, false}) +#define TMC5262_OVERTEMPPREWARNING_VTH_MASK 0x01FF0000 +#define TMC5262_OVERTEMPPREWARNING_VTH_SHIFT 16 +#define TMC5262_OVERTEMPPREWARNING_VTH_FIELD ((RegisterField) {TMC5262_OVERTEMPPREWARNING_VTH_MASK, TMC5262_OVERTEMPPREWARNING_VTH_SHIFT, TMC5262_OTW_OV_VTH, false}) +#define TMC5262_MSLUT_0_MASK 0xFFFFFFFF +#define TMC5262_MSLUT_0_SHIFT 0 +#define TMC5262_MSLUT_0_FIELD ((RegisterField) {TMC5262_MSLUT_0_MASK, TMC5262_MSLUT_0_SHIFT, TMC5262_MSLUT_0, false} +#define TMC5262_MSLUT_1_MASK 0xFFFFFFFF +#define TMC5262_MSLUT_1_SHIFT 0 +#define TMC5262_MSLUT_1_FIELD ((RegisterField) {TMC5262_MSLUT_1_MASK, TMC5262_MSLUT_1_SHIFT, TMC5262_MSLUT_1, false} +#define TMC5262_MSLUT_2_MASK 0xFFFFFFFF +#define TMC5262_MSLUT_2_SHIFT 0 +#define TMC5262_MSLUT_2_FIELD ((RegisterField) {TMC5262_MSLUT_2_MASK, TMC5262_MSLUT_2_SHIFT, TMC5262_MSLUT_2, false} +#define TMC5262_MSLUT_3_MASK 0xFFFFFFFF +#define TMC5262_MSLUT_3_SHIFT 0 +#define TMC5262_MSLUT_3_FIELD ((RegisterField) {TMC5262_MSLUT_3_MASK, TMC5262_MSLUT_3_SHIFT, TMC5262_MSLUT_3, false} +#define TMC5262_MSLUT_4_MASK 0xFFFFFFFF +#define TMC5262_MSLUT_4_SHIFT 0 +#define TMC5262_MSLUT_4_FIELD ((RegisterField) {TMC5262_MSLUT_4_MASK, TMC5262_MSLUT_4_SHIFT, TMC5262_MSLUT_4, false} +#define TMC5262_MSLUT_5_MASK 0xFFFFFFFF +#define TMC5262_MSLUT_5_SHIFT 0 +#define TMC5262_MSLUT_5_FIELD ((RegisterField) {TMC5262_MSLUT_5_MASK, TMC5262_MSLUT_5_SHIFT, TMC5262_MSLUT_5, false} +#define TMC5262_MSLUT_6_MASK 0xFFFFFFFF +#define TMC5262_MSLUT_6_SHIFT 0 +#define TMC5262_MSLUT_6_FIELD ((RegisterField) {TMC5262_MSLUT_6_MASK, TMC5262_MSLUT_6_SHIFT, TMC5262_MSLUT_6, false} +#define TMC5262_MSLUT_7_MASK 0xFFFFFFFF +#define TMC5262_MSLUT_7_SHIFT 0 +#define TMC5262_MSLUT_7_FIELD ((RegisterField) {TMC5262_MSLUT_7_MASK, TMC5262_MSLUT_7_SHIFT, TMC5262_MSLUT_7, false} +#define TMC5262_W0_MASK 0x00000003 +#define TMC5262_W0_SHIFT 0 +#define TMC5262_W0_FIELD ((RegisterField) {TMC5262_W0_MASK, TMC5262_W0_SHIFT, TMC5262_MSLUTSEL, false}) +#define TMC5262_W1_MASK 0x0000000C +#define TMC5262_W1_SHIFT 2 +#define TMC5262_W1_FIELD ((RegisterField) {TMC5262_W1_MASK, TMC5262_W1_SHIFT, TMC5262_MSLUTSEL, false}) +#define TMC5262_W2_MASK 0x00000030 +#define TMC5262_W2_SHIFT 4 +#define TMC5262_W2_FIELD ((RegisterField) {TMC5262_W2_MASK, TMC5262_W2_SHIFT, TMC5262_MSLUTSEL, false}) +#define TMC5262_W3_MASK 0x000000C0 +#define TMC5262_W3_SHIFT 6 +#define TMC5262_W3_FIELD ((RegisterField) {TMC5262_W3_MASK, TMC5262_W3_SHIFT, TMC5262_MSLUTSEL, false}) +#define TMC5262_X1_MASK 0x0000FF00 +#define TMC5262_X1_SHIFT 8 +#define TMC5262_X1_FIELD ((RegisterField) {TMC5262_X1_MASK, TMC5262_X1_SHIFT, TMC5262_MSLUTSEL, false}) +#define TMC5262_X2_MASK 0x00FF0000 +#define TMC5262_X2_SHIFT 16 +#define TMC5262_X2_FIELD ((RegisterField) {TMC5262_X2_MASK, TMC5262_X2_SHIFT, TMC5262_MSLUTSEL, false}) +#define TMC5262_X3_MASK 0xFF000000 +#define TMC5262_X3_SHIFT 24 +#define TMC5262_X3_FIELD ((RegisterField) {TMC5262_X3_MASK, TMC5262_X3_SHIFT, TMC5262_MSLUTSEL, false}) +#define TMC5262_START_SIN_MASK 0x000000FF +#define TMC5262_START_SIN_SHIFT 0 +#define TMC5262_START_SIN_FIELD ((RegisterField) {TMC5262_START_SIN_MASK, TMC5262_START_SIN_SHIFT, TMC5262_MSLUTSTART, false}) +#define TMC5262_START_SIN90_MASK 0x00FF0000 +#define TMC5262_START_SIN90_SHIFT 16 +#define TMC5262_START_SIN90_FIELD ((RegisterField) {TMC5262_START_SIN90_MASK, TMC5262_START_SIN90_SHIFT, TMC5262_MSLUTSTART, false}) +#define TMC5262_OFFSET_SIN90_MASK 0xFF000000 +#define TMC5262_OFFSET_SIN90_SHIFT 24 +#define TMC5262_OFFSET_SIN90_FIELD ((RegisterField) {TMC5262_OFFSET_SIN90_MASK, TMC5262_OFFSET_SIN90_SHIFT, TMC5262_MSLUTSTART, true}) +#define TMC5262_MSCNT_MASK 0x000003FF +#define TMC5262_MSCNT_SHIFT 0 +#define TMC5262_MSCNT_FIELD ((RegisterField) {TMC5262_MSCNT_MASK, TMC5262_MSCNT_SHIFT, TMC5262_MSCNT, false}) +#define TMC5262_CUR_B_MASK 0x000001FF +#define TMC5262_CUR_B_SHIFT 0 +#define TMC5262_CUR_B_FIELD ((RegisterField) {TMC5262_CUR_B_MASK, TMC5262_CUR_B_SHIFT, TMC5262_MSCURACT, true}) +#define TMC5262_CUR_A_MASK 0x01FF0000 +#define TMC5262_CUR_A_SHIFT 16 +#define TMC5262_CUR_A_FIELD ((RegisterField) {TMC5262_CUR_A_MASK, TMC5262_CUR_A_SHIFT, TMC5262_MSCURACT, true}) +#define TMC5262_TOFF_MASK 0x0000000F +#define TMC5262_TOFF_SHIFT 0 +#define TMC5262_TOFF_FIELD ((RegisterField) {TMC5262_TOFF_MASK, TMC5262_TOFF_SHIFT, TMC5262_CHOPCONF, false}) +#define TMC5262_HSTRT_TFD210_MASK 0x00000070 +#define TMC5262_HSTRT_TFD210_SHIFT 4 +#define TMC5262_HSTRT_TFD210_FIELD ((RegisterField) {TMC5262_HSTRT_TFD210_MASK, TMC5262_HSTRT_TFD210_SHIFT, TMC5262_CHOPCONF, false}) +#define TMC5262_HEND_OFFSET_MASK 0x00000780 +#define TMC5262_HEND_OFFSET_SHIFT 7 +#define TMC5262_HEND_OFFSET_FIELD ((RegisterField) {TMC5262_HEND_OFFSET_MASK, TMC5262_HEND_OFFSET_SHIFT, TMC5262_CHOPCONF, false}) +#define TMC5262_FD3_MASK 0x00000800 +#define TMC5262_FD3_SHIFT 11 +#define TMC5262_FD3_FIELD ((RegisterField) {TMC5262_FD3_MASK, TMC5262_FD3_SHIFT, TMC5262_CHOPCONF, false}) +#define TMC5262_DISFDCC_MASK 0x00001000 +#define TMC5262_DISFDCC_SHIFT 12 +#define TMC5262_DISFDCC_FIELD ((RegisterField) {TMC5262_DISFDCC_MASK, TMC5262_DISFDCC_SHIFT, TMC5262_CHOPCONF, false}) +#define TMC5262_CHM_MASK 0x00004000 +#define TMC5262_CHM_SHIFT 14 +#define TMC5262_CHM_FIELD ((RegisterField) {TMC5262_CHM_MASK, TMC5262_CHM_SHIFT, TMC5262_CHOPCONF, false}) +#define TMC5262_TBL_MASK 0x00018000 +#define TMC5262_TBL_SHIFT 15 +#define TMC5262_TBL_FIELD ((RegisterField) {TMC5262_TBL_MASK, TMC5262_TBL_SHIFT, TMC5262_CHOPCONF, false}) +#define TMC5262_TPFD_MASK 0x00F00000 +#define TMC5262_TPFD_SHIFT 20 +#define TMC5262_TPFD_FIELD ((RegisterField) {TMC5262_TPFD_MASK, TMC5262_TPFD_SHIFT, TMC5262_CHOPCONF, false}) +#define TMC5262_MRES_MASK 0x0F000000 +#define TMC5262_MRES_SHIFT 24 +#define TMC5262_MRES_FIELD ((RegisterField) {TMC5262_MRES_MASK, TMC5262_MRES_SHIFT, TMC5262_CHOPCONF, false}) +#define TMC5262_INTPOL_MASK 0x10000000 +#define TMC5262_INTPOL_SHIFT 28 +#define TMC5262_INTPOL_FIELD ((RegisterField) {TMC5262_INTPOL_MASK, TMC5262_INTPOL_SHIFT, TMC5262_CHOPCONF, false}) +#define TMC5262_DEDGE_MASK 0x20000000 +#define TMC5262_DEDGE_SHIFT 29 +#define TMC5262_DEDGE_FIELD ((RegisterField) {TMC5262_DEDGE_MASK, TMC5262_DEDGE_SHIFT, TMC5262_CHOPCONF, false}) +#define TMC5262_SEMIN_MASK 0x0000000F +#define TMC5262_SEMIN_SHIFT 0 +#define TMC5262_SEMIN_FIELD ((RegisterField) {TMC5262_SEMIN_MASK, TMC5262_SEMIN_SHIFT, TMC5262_COOLCONF, false}) +#define TMC5262_SEUP_MASK 0x00000060 +#define TMC5262_SEUP_SHIFT 5 +#define TMC5262_SEUP_FIELD ((RegisterField) {TMC5262_SEUP_MASK, TMC5262_SEUP_SHIFT, TMC5262_COOLCONF, false}) +#define TMC5262_SEMAX_MASK 0x00000F00 +#define TMC5262_SEMAX_SHIFT 8 +#define TMC5262_SEMAX_FIELD ((RegisterField) {TMC5262_SEMAX_MASK, TMC5262_SEMAX_SHIFT, TMC5262_COOLCONF, false}) +#define TMC5262_SEDN_MASK 0x00007000 +#define TMC5262_SEDN_SHIFT 12 +#define TMC5262_SEDN_FIELD ((RegisterField) {TMC5262_SEDN_MASK, TMC5262_SEDN_SHIFT, TMC5262_COOLCONF, false}) +#define TMC5262_SEIMIN_MASK 0x00008000 +#define TMC5262_SEIMIN_SHIFT 15 +#define TMC5262_SEIMIN_FIELD ((RegisterField) {TMC5262_SEIMIN_MASK, TMC5262_SEIMIN_SHIFT, TMC5262_COOLCONF, false}) +#define TMC5262_SGT_MASK 0x007F0000 +#define TMC5262_SGT_SHIFT 16 +#define TMC5262_SGT_FIELD ((RegisterField) {TMC5262_SGT_MASK, TMC5262_SGT_SHIFT, TMC5262_COOLCONF, true}) +#define TMC5262_THIGH_SG_OFF_MASK 0x00800000 +#define TMC5262_THIGH_SG_OFF_SHIFT 23 +#define TMC5262_THIGH_SG_OFF_FIELD ((RegisterField) {TMC5262_THIGH_SG_OFF_MASK, TMC5262_THIGH_SG_OFF_SHIFT, TMC5262_COOLCONF, false}) +#define TMC5262_SFILT_MASK 0x01000000 +#define TMC5262_SFILT_SHIFT 24 +#define TMC5262_SFILT_FIELD ((RegisterField) {TMC5262_SFILT_MASK, TMC5262_SFILT_SHIFT, TMC5262_COOLCONF, false}) +#define TMC5262_SG_RESULT_MASK 0x000003FF +#define TMC5262_SG_RESULT_SHIFT 0 +#define TMC5262_SG_RESULT_FIELD ((RegisterField) {TMC5262_SG_RESULT_MASK, TMC5262_SG_RESULT_SHIFT, TMC5262_DRV_STATUS, false}) +#define TMC5262_SEQ_STOPPED_MASK 0x00000400 +#define TMC5262_SEQ_STOPPED_SHIFT 10 +#define TMC5262_SEQ_STOPPED_FIELD ((RegisterField) {TMC5262_SEQ_STOPPED_MASK, TMC5262_SEQ_STOPPED_SHIFT, TMC5262_DRV_STATUS, false}) +#define TMC5262_OV_MASK 0x00000800 +#define TMC5262_OV_SHIFT 11 +#define TMC5262_OV_FIELD ((RegisterField) {TMC5262_OV_MASK, TMC5262_OV_SHIFT, TMC5262_DRV_STATUS, false}) +#define TMC5262_S2VSA_MASK 0x00001000 +#define TMC5262_S2VSA_SHIFT 12 +#define TMC5262_S2VSA_FIELD ((RegisterField) {TMC5262_S2VSA_MASK, TMC5262_S2VSA_SHIFT, TMC5262_DRV_STATUS, false}) +#define TMC5262_S2VSB_MASK 0x00002000 +#define TMC5262_S2VSB_SHIFT 13 +#define TMC5262_S2VSB_FIELD ((RegisterField) {TMC5262_S2VSB_MASK, TMC5262_S2VSB_SHIFT, TMC5262_DRV_STATUS, false}) +#define TMC5262_STEALTH_MASK 0x00004000 +#define TMC5262_STEALTH_SHIFT 14 +#define TMC5262_STEALTH_FIELD ((RegisterField) {TMC5262_STEALTH_MASK, TMC5262_STEALTH_SHIFT, TMC5262_DRV_STATUS, false}) +#define TMC5262_CS_ACTUAL_MASK 0x00FF0000 +#define TMC5262_CS_ACTUAL_SHIFT 16 +#define TMC5262_CS_ACTUAL_FIELD ((RegisterField) {TMC5262_CS_ACTUAL_MASK, TMC5262_CS_ACTUAL_SHIFT, TMC5262_DRV_STATUS, false}) +#define TMC5262_STALLGUARD_MASK 0x01000000 +#define TMC5262_STALLGUARD_SHIFT 24 +#define TMC5262_STALLGUARD_FIELD ((RegisterField) {TMC5262_STALLGUARD_MASK, TMC5262_STALLGUARD_SHIFT, TMC5262_DRV_STATUS, false}) +#define TMC5262_OT_MASK 0x02000000 +#define TMC5262_OT_SHIFT 25 +#define TMC5262_OT_FIELD ((RegisterField) {TMC5262_OT_MASK, TMC5262_OT_SHIFT, TMC5262_DRV_STATUS, false}) +#define TMC5262_OTPW_MASK 0x04000000 +#define TMC5262_OTPW_SHIFT 26 +#define TMC5262_OTPW_FIELD ((RegisterField) {TMC5262_OTPW_MASK, TMC5262_OTPW_SHIFT, TMC5262_DRV_STATUS, false}) +#define TMC5262_S2GA_MASK 0x08000000 +#define TMC5262_S2GA_SHIFT 27 +#define TMC5262_S2GA_FIELD ((RegisterField) {TMC5262_S2GA_MASK, TMC5262_S2GA_SHIFT, TMC5262_DRV_STATUS, false}) +#define TMC5262_S2GB_MASK 0x10000000 +#define TMC5262_S2GB_SHIFT 28 +#define TMC5262_S2GB_FIELD ((RegisterField) {TMC5262_S2GB_MASK, TMC5262_S2GB_SHIFT, TMC5262_DRV_STATUS, false}) +#define TMC5262_OLA_MASK 0x20000000 +#define TMC5262_OLA_SHIFT 29 +#define TMC5262_OLA_FIELD ((RegisterField) {TMC5262_OLA_MASK, TMC5262_OLA_SHIFT, TMC5262_DRV_STATUS, false}) +#define TMC5262_OLB_MASK 0x40000000 +#define TMC5262_OLB_SHIFT 30 +#define TMC5262_OLB_FIELD ((RegisterField) {TMC5262_OLB_MASK, TMC5262_OLB_SHIFT, TMC5262_DRV_STATUS, false}) +#define TMC5262_STST_MASK 0x80000000 +#define TMC5262_STST_SHIFT 31 +#define TMC5262_STST_FIELD ((RegisterField) {TMC5262_STST_MASK, TMC5262_STST_SHIFT, TMC5262_DRV_STATUS, false}) +#define TMC5262_PWM_FREQ_MASK 0x0000000F +#define TMC5262_PWM_FREQ_SHIFT 0 +#define TMC5262_PWM_FREQ_FIELD ((RegisterField) {TMC5262_PWM_FREQ_MASK, TMC5262_PWM_FREQ_SHIFT, TMC5262_PWMCONF, false}) +#define TMC5262_FREEWHEEL_MASK 0x00000030 +#define TMC5262_FREEWHEEL_SHIFT 4 +#define TMC5262_FREEWHEEL_FIELD ((RegisterField) {TMC5262_FREEWHEEL_MASK, TMC5262_FREEWHEEL_SHIFT, TMC5262_PWMCONF, false}) +#define TMC5262_OL_THRSH_MASK 0x000000C0 +#define TMC5262_OL_THRSH_SHIFT 6 +#define TMC5262_OL_THRSH_FIELD ((RegisterField) {TMC5262_OL_THRSH_MASK, TMC5262_OL_THRSH_SHIFT, TMC5262_PWMCONF, false}) +#define TMC5262_SD_ON_MEAS_LO_MASK 0x0000F000 +#define TMC5262_SD_ON_MEAS_LO_SHIFT 12 +#define TMC5262_SD_ON_MEAS_LO_FIELD ((RegisterField) {TMC5262_SD_ON_MEAS_LO_MASK, TMC5262_SD_ON_MEAS_LO_SHIFT, TMC5262_PWMCONF, false}) +#define TMC5262_SD_ON_MEAS_HI_MASK 0x000F0000 +#define TMC5262_SD_ON_MEAS_HI_SHIFT 16 +#define TMC5262_SD_ON_MEAS_HI_FIELD ((RegisterField) {TMC5262_SD_ON_MEAS_HI_MASK, TMC5262_SD_ON_MEAS_HI_SHIFT, TMC5262_PWMCONF, false}) +#define TMC5262_SD_ON_MEAS_MASK 0x000FF000 +#define TMC5262_SD_ON_MEAS_SHIFT 12 +#define TMC5262_SD_ON_MEAS_FIELD ((RegisterField) {TMC5262_SD_ON_MEAS_MASK, TMC5262_SD_ON_MEAS_SHIFT, TMC5262_PWMCONF, false}) + +#endif diff --git a/firmware/lib/tmc/ic/TMC5262/registercall_hierarchy_flowchart_SPI.svg b/firmware/lib/tmc/ic/TMC5262/registercall_hierarchy_flowchart_SPI.svg new file mode 100755 index 0000000..cbad58f --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5262/registercall_hierarchy_flowchart_SPI.svg @@ -0,0 +1,3 @@ + + +

HAL

HAL

APP (Eval)

APP (Eval)

API

API
Read a register
  •  Call tmcXXXX_readRegister function
Read a register...
Returns the register read value
Returns the register read value
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
tmcXXXX.c
tmcXXXX.c
SPI.c
SPI.c
tmcXXXX_eval.c
tmcXXXX_eval.c

 Implementation of SPI_readWrite
  • Sends and receives bytes on the SPI bus
Implementation of SPI_readWrite...
Returns the raw reply data
Returns the raw reply data

Implementation of tmcXXXX_readWriteSPI
  • Sets the CSN pin to LOW
  • Takes the array of data to write
  • Calls hardware function SPI_readWrite
  • Upon completion of data transfer,
    sets CSN to 
    HIGH
Implementation of tmcXXXX_readWriteSPI...
Passes on the raw reply data to the API
Passes on the raw reply data to the API
Implementation of readRegisterSPI
  • Constructs the datagram
  • Calls HAL wrapper function 
Implementation of readRegisterSPI...
tmcXXXX_readWriteSPI
tmcXXXX_readWriteSPI
Parses the reply and returns the register value
Parses the reply and returns the register value
Implementation of tmcXXXX_readRegister 
  • Check which bus is active SPI/UART. (e.g. SPI)
  • Calls bus-specific function (e.g. readRegisterSPI)
 
Implementation of tmcXXXX_readRegister...
Returns the register read value
Returns the register read value
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC5262/uml-tmc-api.svg b/firmware/lib/tmc/ic/TMC5262/uml-tmc-api.svg new file mode 100755 index 0000000..5a5f8dd --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5262/uml-tmc-api.svg @@ -0,0 +1,3 @@ + + +

TMCXXXX_HW_Abstraction.h



TMCXXXX_HW_Abstraction.h...
// Constants
#define TMCXXXX_MOTORS              
                          
// Register definitions
#define TMCXXXX_GCONF        
                          ⋮
// Register fields definitions
#define TMCXXXX_GCONF_OTPW_FIELD
                     
// Constants...

TMCXXXX.h



TMCXXXX.h...
extern void tmcXXXX_readWriteSPI();
extern void tmcXXXX_readWriteUART();
extern TMCXXXXBusType tmcXXXX_getBusType();
extern uint8_t tmcXXXX_getNodeAddress();
                                  ⋮
tmcXXXX_readRegister();
tmcXXXX_writeRegister();
                                  ⋮
extern void tmcXXXX_readWriteSPI();...

TMCXXXX.c



TMCXXXX.c...
const uint8_t tmcCRCTable_Poly7Reflected[256] = {...};
int32_t tmcXXXX_readRegister(){
/* Call tmcXXXX_getBusType();
 * Based on bus type, call readRegisterSPI/UART() that
 * further calls tmcXXXX_readWriteSPI/UART();
 * For UART it also calls tmcXXXX_getNodeAddress();
                                           ⋮
}
                                           ⋮
const uint8_t tmcCRCTable_Poly7Reflected[256] = {.....
TMC-API
TMC-API

TMCXXXX_Simple_Rotation.h


TMCXXXX_Simple_Rotation.h...
void initAllMotors();
             ⋮
  
void initAllMotors()...

TMCXXXX_Simple_Rotation.c


TMCXXXX_Simple_Rotation.c...
void initAllMotors(){

// Configuring registers to enable motor drivers etc..
tmcXXXX_writeRegister();
                    ⋮
}
                    ⋮
void initAllMotors(){...
Examples
Examples
User Project
User Project

User_Project.h


User_Project.h

User_Project.c








User_Project.c...

void tmcXXXX_readWriteSPI(){
                           ⋮
}
void tmcXXXX_readWriteUART(){
                           ⋮
}
TMCXXXXBusType tmcXXXX_getBusType(){
                           ⋮
}
uint8_t tmcXXXX_getNodeAddress(){
                           ⋮
}

// User Code
                           ⋮
void tmcXXXX_readWriteSPI(){...
#include "TMCXXXX_HW_Abstraction.h"
#include "TMCXXXX.h"
#include "TMCXXXX_Simple_Rotation.h"
                                ⋮
TMCXXXXBusType bus = IC_BUS_SPI/UART;
uint8_t nodeAddress = <nodeAddress>;
                                ⋮
#include "TMCXXXX_HW_Abstraction.h"...
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC5271/Examples/TMC5271_Simple_Rotation.c b/firmware/lib/tmc/ic/TMC5271/Examples/TMC5271_Simple_Rotation.c new file mode 100755 index 0000000..bc8e422 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5271/Examples/TMC5271_Simple_Rotation.c @@ -0,0 +1,31 @@ +/******************************************************************************* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#include "TMC5271_Simple_Rotation.h" + +/* + * Configures the registers with the right settings that are needed for rotating the motor. + * E.g Enabling driver, setting IRUN current etc. + */ +void initMotor(uint16_t icID) +{ + // Set IREF_R2 and IREF_R3 to High for setting the REF resistor to 10k. + // Run Current = 0.2A rms + // Hold Current = 0.14A rms + // Chopper Mode = SpreadCycle + + // Disable motor driver + tmc5271_writeRegister(icID, TMC5271_GCONF, 0x10024002); // writing value 0x10020002 = 268582914 = 0.0 to address 0 = 0x00(GCONF) + + tmc5271_writeRegister(icID, TMC5271_DRV_CONF, 0x0000000C); // writing value 0x0000000C = 12 = 0.0 to address 1 = 0x05(DRV_CONF) + tmc5271_writeRegister(icID, TMC5271_GLOBAL_SCALER, 0x0000FAFA); // writing value 0x0000FAFA = 64250 = 0.0 to address 2 = 0x06(GLOBAL_SCALER) + tmc5271_writeRegister(icID, TMC5271_IHOLD_IRUN, 0x04011F0A); // writing value 0x04011F0A = 67182346 = 0.0 to address 3 = 0x12(IHOLD_IRUN) + tmc5271_writeRegister(icID, TMC5271_CHOPCONF, 0x10410153); // writing value 0x10410153 = 272695635 = 0.0 to address 4 = 0x38(CHOPCONF) + tmc5271_writeRegister(icID, TMC5271_AMAX, 51200); // writing value to address 5 = 0x20(AMAX) + + // Enable motor driver + tmc5271_writeRegister(icID, TMC5271_GCONF, 0x10020002); // writing value 0x10020002 = 268566530 = 0.0 to address 0 = 0x00(GCONF) +} diff --git a/firmware/lib/tmc/ic/TMC5271/Examples/TMC5271_Simple_Rotation.h b/firmware/lib/tmc/ic/TMC5271/Examples/TMC5271_Simple_Rotation.h new file mode 100755 index 0000000..f75790b --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5271/Examples/TMC5271_Simple_Rotation.h @@ -0,0 +1,14 @@ +/******************************************************************************* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#ifndef TMC5271_SIMPLE_ROTATION_H_ +#define TMC5271_SIMPLE_ROTATION_H_ + +#include "TMC5271.h" + +void initMotor(uint16_t icID); + +#endif diff --git a/firmware/lib/tmc/ic/TMC5271/README.md b/firmware/lib/tmc/ic/TMC5271/README.md new file mode 100755 index 0000000..ace0a23 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5271/README.md @@ -0,0 +1,63 @@ +# TMC5271 + + +## How to use + +To access the TMC5271's registers, the TMC-API offers two functions: **tmc5271_readRegister** and **tmc5271_writeRegister**. +Each of these functions takes in an **icID**, which is used to identify the IC when multiple ICs are connected. This identifier is passed down to the callback functions (see How to Integrate). + +## How to integrate: overview + +1. Include all the files of the TMC-API/ic/tmc/TMC5271 folder into the custom project. +2. Include the TMC5271.h file in the custom source code. +3. Implement the necessary callback functions (see below). +4. (optional): Take a look at the Examples subfolder for ready-made examples of the TMC-API usage. + +## Accessing the TMC5271 via UART +The following diagram depicts how to access the TMC5271 via UART using the TMC-API. + +![screenshot](registercall_hierarchy_flowchart_UART.svg) + +The description of the functions, in the above flowchart, are as follows: +- The functions tmc5271_readRegister and tmc5271_writeRegister are used to read and write the registers respectively. These functions check the current active bus and calls the bus-specific function i.e readRegisterUART or writeRegisterUART. +- These bus specific functions constructs the datagram and further calls the bus specific callback 'tmcXXXX_readWriteUART. +- This callback function further calls the hardware specific read/write function for UART and needs to be implemented externally. + +### How to integrate: Callback functions +To communicate with TMC5271 IC, the TMC-API library needs to know which bus (UART, SPI) it shall use. For that, the callback function **'tmc5271_getBusType()'** needs to be implemented. +Additionally, implement the following callback functions to access the chip via UART: +1. **tmc5271_readWriteUART()**, which is a HAL wrapper function that provides the necessary hardware access. +2. **tmc5271_getNodeAddress()**, that returns the node/slave address. Node address could be set in NODECONF (0x3) register and the address could be incremented as defined by AD0, AD1 and AD2. (Node address + ADx) must be less than 255. For further details please consult the datasheet of TMC5271. + +### Sharing the CRC table with other TMC-API chips +The TMC5271 UART protocol uses an 8 bit CRC. For calculating this, a table-based algorithm is used. This table (tmcCRCTable_Poly7Reflected[256]) is 256 bytes big and identical across multiple different Trinamic chips (i.e. TMC2209). +If multiple Trinamic chips are being used in the same project, avoiding redundant copies of this table could save memory. It is possible to substitute this CRC table with another CRC table. + +## Accessing the TMC5271 via SPI +The following diagram depicts how to access the TMC5271 via SPI using the TMC-API. + +![screenshot](registercall_hierarchy_flowchart_SPI.svg) + +The description of the functions, in the above flowchart, are as follows: +- The functions tmc5271_readRegister and tmc5271_writeRegister are used to read and write the registers respectively. These functions check the current active bus and calls the bus-specific function i.e readRegisterSPI or writeRegisterSPI. +- These bus specific functions constructs the datagram and further calls the bus specific callback 'tmcXXXX_readWriteSPI. +- This callback function further calls the hardware specific read/write function for SPI and needs to be implemented externally. + +### How to integrate: Callback functions +To communicate with TMC5271 IC, the TMC-API library needs to know which bus (UART, SPI) it shall use. For that, the callback function **'tmc5271_getBusType()'** needs to be implemented. +Additionally, implement the following callback functions to access the chip via SPI: +1. **tmc5271_readWriteSPI()**, which is a HAL wrapper function that provides the necessary hardware access. This function should also set the chip select pin CSN to low before starting the data transfer and set to high upon completion. Please refer to the datasheet of the IC for further details. + +## Further info +### Dependency graph for the ICs with new register R/W mechanism +This graph illustrates the relationships between files within the TMC-API library, highlighting dependencies and identifying the files that are essential for integrating the library into the custom projects. + +![screenshot](uml-tmc-api.svg) + +### Example usage: TMC-Evalsystem +**For a reference usage of the TMC-API**, visit the [TMC-Evalsystem](https://github.com/analogdevicesinc/TMC-EvalSystem) + +## Migration status +The TMC5271 has been reworked to the access system described above. For more infos on the status of this and other ICs, check out the [migration page](https://github.com/analogdevicesinc/TMC-API/issues/53). + + diff --git a/firmware/lib/tmc/ic/TMC5271/TMC5271.c b/firmware/lib/tmc/ic/TMC5271/TMC5271.c new file mode 100755 index 0000000..598d52b --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5271/TMC5271.c @@ -0,0 +1,180 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#include + + +#ifdef TMC_API_EXTERNAL_CRC_TABLE +extern const uint8_t tmcCRCTable_Poly7Reflected[256]; +#else +const uint8_t tmcCRCTable_Poly7Reflected[256] = { + 0x00, 0x91, 0xE3, 0x72, 0x07, 0x96, 0xE4, 0x75, 0x0E, 0x9F, 0xED, 0x7C, 0x09, 0x98, 0xEA, 0x7B, + 0x1C, 0x8D, 0xFF, 0x6E, 0x1B, 0x8A, 0xF8, 0x69, 0x12, 0x83, 0xF1, 0x60, 0x15, 0x84, 0xF6, 0x67, + 0x38, 0xA9, 0xDB, 0x4A, 0x3F, 0xAE, 0xDC, 0x4D, 0x36, 0xA7, 0xD5, 0x44, 0x31, 0xA0, 0xD2, 0x43, + 0x24, 0xB5, 0xC7, 0x56, 0x23, 0xB2, 0xC0, 0x51, 0x2A, 0xBB, 0xC9, 0x58, 0x2D, 0xBC, 0xCE, 0x5F, + 0x70, 0xE1, 0x93, 0x02, 0x77, 0xE6, 0x94, 0x05, 0x7E, 0xEF, 0x9D, 0x0C, 0x79, 0xE8, 0x9A, 0x0B, + 0x6C, 0xFD, 0x8F, 0x1E, 0x6B, 0xFA, 0x88, 0x19, 0x62, 0xF3, 0x81, 0x10, 0x65, 0xF4, 0x86, 0x17, + 0x48, 0xD9, 0xAB, 0x3A, 0x4F, 0xDE, 0xAC, 0x3D, 0x46, 0xD7, 0xA5, 0x34, 0x41, 0xD0, 0xA2, 0x33, + 0x54, 0xC5, 0xB7, 0x26, 0x53, 0xC2, 0xB0, 0x21, 0x5A, 0xCB, 0xB9, 0x28, 0x5D, 0xCC, 0xBE, 0x2F, + 0xE0, 0x71, 0x03, 0x92, 0xE7, 0x76, 0x04, 0x95, 0xEE, 0x7F, 0x0D, 0x9C, 0xE9, 0x78, 0x0A, 0x9B, + 0xFC, 0x6D, 0x1F, 0x8E, 0xFB, 0x6A, 0x18, 0x89, 0xF2, 0x63, 0x11, 0x80, 0xF5, 0x64, 0x16, 0x87, + 0xD8, 0x49, 0x3B, 0xAA, 0xDF, 0x4E, 0x3C, 0xAD, 0xD6, 0x47, 0x35, 0xA4, 0xD1, 0x40, 0x32, 0xA3, + 0xC4, 0x55, 0x27, 0xB6, 0xC3, 0x52, 0x20, 0xB1, 0xCA, 0x5B, 0x29, 0xB8, 0xCD, 0x5C, 0x2E, 0xBF, + 0x90, 0x01, 0x73, 0xE2, 0x97, 0x06, 0x74, 0xE5, 0x9E, 0x0F, 0x7D, 0xEC, 0x99, 0x08, 0x7A, 0xEB, + 0x8C, 0x1D, 0x6F, 0xFE, 0x8B, 0x1A, 0x68, 0xF9, 0x82, 0x13, 0x61, 0xF0, 0x85, 0x14, 0x66, 0xF7, + 0xA8, 0x39, 0x4B, 0xDA, 0xAF, 0x3E, 0x4C, 0xDD, 0xA6, 0x37, 0x45, 0xD4, 0xA1, 0x30, 0x42, 0xD3, + 0xB4, 0x25, 0x57, 0xC6, 0xB3, 0x22, 0x50, 0xC1, 0xBA, 0x2B, 0x59, 0xC8, 0xBD, 0x2C, 0x5E, 0xCF, +}; +#endif + +static int32_t readRegisterSPI(uint16_t icID, uint8_t address); +static void writeRegisterSPI(uint16_t icID, uint8_t address, int32_t value); +static int32_t readRegisterUART(uint16_t icID, uint8_t registerAddress); +static void writeRegisterUART(uint16_t icID, uint8_t registerAddress, int32_t value); +static uint8_t CRC8(uint8_t *data, uint32_t bytes); + + +int32_t tmc5271_readRegister(uint16_t icID, uint8_t address) +{ + TMC5271BusType bus = tmc5271_getBusType(icID); + + if(bus == IC_BUS_SPI) + { + return readRegisterSPI(icID, address); + } + else if (bus == IC_BUS_UART) + { + return readRegisterUART(icID, address); + } + + //ToDo: Error handling + return -1; +} + +void tmc5271_writeRegister(uint16_t icID, uint8_t address, int32_t value) +{ + TMC5271BusType bus = tmc5271_getBusType(icID); + + if(bus == IC_BUS_SPI) + { + writeRegisterSPI(icID, address, value); + } + else if(bus == IC_BUS_UART) + { + writeRegisterUART(icID, address, value); + } +} + +int32_t readRegisterSPI(uint16_t icID, uint8_t address) +{ + uint8_t data[5] = { 0 }; + + // clear write bit + data[0] = address & TMC5271_ADDRESS_MASK; + + // Send the read request + tmc5271_readWriteSPI(icID, &data[0], sizeof(data)); + + // Rewrite address and clear write bit + data[0] = address & TMC5271_ADDRESS_MASK; + + // Send another request to receive the read reply + tmc5271_readWriteSPI(icID, &data[0], sizeof(data)); + + return ((int32_t)data[1] << 24) | ((int32_t) data[2] << 16) | ((int32_t) data[3] << 8) | ((int32_t) data[4]); +} + +void writeRegisterSPI(uint16_t icID, uint8_t address, int32_t value) +{ + uint8_t data[5] = { 0 }; + + data[0] = address | TMC5271_WRITE_BIT; + data[1] = 0xFF & (value>>24); + data[2] = 0xFF & (value>>16); + data[3] = 0xFF & (value>>8); + data[4] = 0xFF & (value>>0); + + // Send the write request + tmc5271_readWriteSPI(icID, &data[0], sizeof(data)); +} + +int32_t readRegisterUART(uint16_t icID, uint8_t registerAddress) +{ + uint8_t data[8] = { 0 }; + + registerAddress = registerAddress & TMC5271_ADDRESS_MASK; + + data[0] = 0x05; + data[1] = tmc5271_getNodeAddress(icID); //targetAddressUart; + data[2] = registerAddress; + data[3] = CRC8(data, 3); + + if (!tmc5271_readWriteUART(icID, &data[0], 4, 8)) + return 0; + + // Byte 0: Sync nibble correct? + if (data[0] != 0x05) + return 0; + + // Byte 1: Master address correct? + if (data[1] != 0xFF) + return 0; + + // Byte 2: Address correct? + if (data[2] != registerAddress) + return 0; + + // Byte 7: CRC correct? + if (data[7] != CRC8(data, 7)) + return 0; + + return ((uint32_t)data[3] << 24) | ((uint32_t)data[4] << 16) | ((uint32_t)data[5] << 8) | data[6]; +} + +void writeRegisterUART(uint16_t icID, uint8_t registerAddress, int32_t value) +{ + uint8_t data[8]; + + data[0] = 0x05; + data[1] = (uint8_t)tmc5271_getNodeAddress(icID); //targetAddressUart; + data[2] = registerAddress | TMC5271_WRITE_BIT; + data[3] = (value >> 24) & 0xFF; + data[4] = (value >> 16) & 0xFF; + data[5] = (value >> 8 ) & 0xFF; + data[6] = (value ) & 0xFF; + data[7] = CRC8(data, 7); + + tmc5271_readWriteUART(icID, &data[0], 8, 0); +} + +void tmc5271_rotateMotor(uint16_t icID, uint8_t motor, int32_t velocity) +{ + if(motor >= TMC5271_MOTORS) + return; + + tmc5271_writeRegister(icID, TMC5271_VMAX, (velocity < 0) ? -velocity : velocity); + tmc5271_fieldWrite(icID, TMC5271_RAMPMODE_FIELD, (velocity >= 0) ? TMC5271_MODE_VELPOS : TMC5271_MODE_VELNEG); +} + +static uint8_t CRC8(uint8_t *data, uint32_t bytes) +{ + uint8_t result = 0; + while(bytes--) + result = tmcCRCTable_Poly7Reflected[result ^ *data++]; + + // Flip the result around + // swap odd and even bits + result = ((result >> 1) & 0x55) | ((result & 0x55) << 1); + // swap consecutive pairs + result = ((result >> 2) & 0x33) | ((result & 0x33) << 2); + // swap nibbles ... + result = ((result >> 4) & 0x0F) | ((result & 0x0F) << 4); + + return result; +} diff --git a/firmware/lib/tmc/ic/TMC5271/TMC5271.h b/firmware/lib/tmc/ic/TMC5271/TMC5271.h new file mode 100755 index 0000000..b758dfa --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5271/TMC5271.h @@ -0,0 +1,120 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#ifndef TMC_IC_TMC5271_H_ +#define TMC_IC_TMC5271_H_ + +#include +#include +#include +#include "TMC5271_HW_Abstraction.h" + +/******************************************************************************* +* API Configuration Defines +* These control optional features of the TMC-API implementation. +* These can be commented in/out here or defined from the build system. +*******************************************************************************/ + +// Uncomment if you want to save space..... +// and put the table into your own .c file +//#define TMC_API_EXTERNAL_CRC_TABLE 1 +/******************************************************************************/ + +// Default Register values +#define R00 0x00000008 // GCONF +#define R0A 0x00000020 // DRVCONF +#define R10 0x00070A03 // IHOLD_IRUN +#define R11 0x0000000A // TPOWERDOWN +#define R2A 0x0000000A // D1 +#define R2B 0x0000000A // VSTOP +#define R30 0x0000000A // D2 + +#define R3A 0x00010000 // ENC_CONST + +#define R52 0x0B920F25 // OTW_OV_VTH +#define R60 0xAAAAB554 // MSLUT[0] +#define R61 0x4A9554AA // MSLUT[1] +#define R62 0x24492929 // MSLUT[2] +#define R63 0x10104222 // MSLUT[3] +#define R64 0xFBFFFFFF // MSLUT[4] +#define R65 0xB5BB777D // MSLUT[5] +#define R66 0x49295556 // MSLUT[6] +#define R67 0x00404222 // MSLUT[7] +#define R68 0xFFFF8056 // MSLUT[8] +#define R69 0x00F70000 // MSLUT[9] + +#define R6C 0x00410153 // CHOPCONF +#define R70 0xC44C001E // PWMCONF +#define R74 0x00000000 // PWMCONF + + +typedef enum { + IC_BUS_SPI, + IC_BUS_UART, + IC_BUS_WLAN, +} TMC5271BusType; + +typedef struct +{ + uint32_t mask; + uint8_t shift; + uint8_t address; + bool isSigned; +} RegisterField; + +// => TMC-API wrapper +extern void tmc5271_readWriteSPI(uint16_t icID, uint8_t *data, size_t dataLength); +extern bool tmc5271_readWriteUART(uint16_t icID, uint8_t *data, size_t writeLength, size_t readLength); +extern TMC5271BusType tmc5271_getBusType(uint16_t icID); +extern uint8_t tmc5271_getNodeAddress(uint16_t icID); +// => TMC-API wrapper + +int32_t tmc5271_readRegister(uint16_t icID, uint8_t address); +void tmc5271_writeRegister(uint16_t icID, uint8_t address, int32_t value); +void tmc5271_rotateMotor(uint16_t icID, uint8_t motor, int32_t velocity); + + +static inline uint32_t tmc5271_fieldExtract(uint32_t data, RegisterField field) +{ + uint32_t value = (data & field.mask) >> field.shift; + + if (field.isSigned) + { + // Apply signedness conversion + uint32_t baseMask = field.mask >> field.shift; + uint32_t signMask = baseMask & (~baseMask >> 1); + value = (value ^ signMask) - signMask; + } + + return value; +} + +static inline uint32_t tmc5271_fieldRead(uint16_t icID, RegisterField field) +{ + uint32_t value = tmc5271_readRegister(icID, field.address); + + return tmc5271_fieldExtract(value, field); +} + +static inline uint32_t field_update(uint32_t data, RegisterField field, uint32_t value) +{ + return (data & (~field.mask)) | ((value << field.shift) & field.mask); +} + +static inline void tmc5271_fieldWrite(uint16_t icID, RegisterField field, uint32_t value) +{ + uint32_t regValue = tmc5271_readRegister(icID, field.address); + + regValue = field_update(regValue, field, value); + + tmc5271_writeRegister(icID, field.address, regValue); +} + + +#endif /* TMC_IC_TMC5271_H_ */ diff --git a/firmware/lib/tmc/ic/TMC5271/TMC5271_HW_Abstraction.h b/firmware/lib/tmc/ic/TMC5271/TMC5271_HW_Abstraction.h new file mode 100755 index 0000000..d84bc2d --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5271/TMC5271_HW_Abstraction.h @@ -0,0 +1,683 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2023 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + +#ifndef TMC5271_HW_ABSTRACTION +#define TMC5271_HW_ABSTRACTION + + +// Constants + +#define TMC5271_REGISTER_COUNT 128 +#define TMC5271_MOTORS 1 +#define TMC5271_WRITE_BIT 0x80 +#define TMC5271_ADDRESS_MASK 0x7F +#define TMC5271_MAX_VELOCITY 8388096 +#define TMC5271_MAX_ACCELERATION 65535 + +// Ramp modes (Register TMC5271_RAMPMODE) + +#define TMC5271_MODE_POSITION 0 +#define TMC5271_MODE_VELPOS 1 +#define TMC5271_MODE_VELNEG 2 +#define TMC5271_MODE_HOLD 3 + +// Registers in TMC5271 + +#define TMC5271_GCONF 0x00 +#define TMC5271_GSTAT 0x01 +#define TMC5271_IFCNT 0x02 +#define TMC5271_SLAVECONF 0x03 +#define TMC5271_IOIN 0x04 +#define TMC5271_DRV_CONF 0x05 +#define TMC5271_GLOBAL_SCALER 0x06 +#define TMC5271_RAMPMODE 0x07 +#define TMC5271_MSLUT_ADDR 0x08 +#define TMC5271_MSLUT_DATA 0x09 +#define TMC5271_X_COMPARE 0x10 +#define TMC5271_X_COMPARE_REPEAT 0x11 +#define TMC5271_IHOLD_IRUN 0x12 +#define TMC5271_TPOWERDOWN 0x13 +#define TMC5271_TSTEP 0x14 +#define TMC5271_TPWMTHRS 0x15 +#define TMC5271_TCOOLTHRS 0x16 +#define TMC5271_THIGH 0x17 +#define TMC5271_XACTUAL 0x18 +#define TMC5271_VACTUAL 0x19 +#define TMC5271_AACTUAL 0x1A +#define TMC5271_VSTART 0x1B +#define TMC5271_A1 0x1C +#define TMC5271_V1 0x1D +#define TMC5271_A2 0x1E +#define TMC5271_V2 0x1F +#define TMC5271_AMAX 0x20 +#define TMC5271_VMAX 0x21 +#define TMC5271_DMAX 0x22 +#define TMC5271_D2 0x23 +#define TMC5271_D1 0x24 +#define TMC5271_VSTOP 0x25 +#define TMC5271_TVMAX 0x26 +#define TMC5271_TZEROWAIT 0x27 +#define TMC5271_XTARGET 0x28 +#define TMC5271_VDCMIN 0x29 +#define TMC5271_SW_MODE 0x2A +#define TMC5271_RAMP_STAT 0x2B +#define TMC5271_XLATCH 0x2C +#define TMC5271_POSITION_PI_CTRL 0x2D +#define TMC5271_X_ENC 0x2E +#define TMC5271_ENCMODE 0x2F +#define TMC5271_ENC_CONST 0x30 +#define TMC5271_ENC_STATUS 0x31 +#define TMC5271_ENC_LATCH 0x32 +#define TMC5271_ENC_DEVIATION 0x33 +#define TMC5271_VIRTUAL_STOP_L 0x34 +#define TMC5271_VIRTUAL_STOP_R 0x35 +#define TMC5271_MSCNT 0x36 +#define TMC5271_MSCURACT 0x37 +#define TMC5271_CHOPCONF 0x38 +#define TMC5271_COOLCONF 0x39 +#define TMC5271_DCCTRL 0x3A +#define TMC5271_DRV_STATUS 0x3B +#define TMC5271_PWMCONF 0x3C +#define TMC5271_PWM_SCALE 0x3D +#define TMC5271_PWM_AUTO 0x3E +#define TMC5271_SG4_THRS 0x3F +#define TMC5271_SG4_RESULT 0x40 +#define TMC5271_SG4_IND 0x41 + +// Register fields in TMC5271 + +#define TMC5271_EN_PWM_MODE_MASK 0x00000001 +#define TMC5271_EN_PWM_MODE_SHIFT 0 +#define TMC5271_EN_PWM_MODE_FIELD ((RegisterField) { TMC5271_EN_PWM_MODE_MASK, TMC5271_EN_PWM_MODE_SHIFT, TMC5271_GCONF, false }) +#define TMC5271_MULTISTEP_FILT_MASK 0x00000002 +#define TMC5271_MULTISTEP_FILT_SHIFT 1 +#define TMC5271_MULTISTEP_FILT_FIELD ((RegisterField) { TMC5271_MULTISTEP_FILT_MASK, TMC5271_MULTISTEP_FILT_SHIFT, TMC5271_GCONF, false }) +#define TMC5271_SHAFT_MASK 0x00000004 +#define TMC5271_SHAFT_SHIFT 2 +#define TMC5271_SHAFT_FIELD ((RegisterField) { TMC5271_SHAFT_MASK, TMC5271_SHAFT_SHIFT, TMC5271_GCONF, false }) +#define TMC5271_DIAG0_ERROR_MASK 0x00000008 +#define TMC5271_DIAG0_ERROR_SHIFT 3 +#define TMC5271_DIAG0_ERROR_FIELD ((RegisterField) { TMC5271_DIAG0_ERROR_MASK, TMC5271_DIAG0_ERROR_SHIFT, TMC5271_GCONF, false }) +#define TMC5271_DIAG0_OTPW_MASK 0x00000010 +#define TMC5271_DIAG0_OTPW_SHIFT 4 +#define TMC5271_DIAG0_OTPW_FIELD ((RegisterField) { TMC5271_DIAG0_OTPW_MASK, TMC5271_DIAG0_OTPW_SHIFT, TMC5271_GCONF, false }) +#define TMC5271_DIAG0_STALL_STEP_MASK 0x00000020 +#define TMC5271_DIAG0_STALL_STEP_SHIFT 5 +#define TMC5271_DIAG0_STALL_STEP_FIELD ((RegisterField) { TMC5271_DIAG0_STALL_STEP_MASK, TMC5271_DIAG0_STALL_STEP_SHIFT, TMC5271_GCONF, false }) +#define TMC5271_DIAG1_STALL_DIR_MASK 0x00000040 +#define TMC5271_DIAG1_STALL_DIR_SHIFT 6 +#define TMC5271_DIAG1_STALL_DIR_FIELD ((RegisterField) { TMC5271_DIAG1_STALL_DIR_MASK, TMC5271_DIAG1_STALL_DIR_SHIFT, TMC5271_GCONF, false }) +#define TMC5271_DIAG1_INDEX_MASK 0x00000080 +#define TMC5271_DIAG1_INDEX_SHIFT 7 +#define TMC5271_DIAG1_INDEX_FIELD ((RegisterField) { TMC5271_DIAG1_INDEX_MASK, TMC5271_DIAG1_INDEX_SHIFT, TMC5271_GCONF, false }) +#define TMC5271_DIAG0_INT_PUSHPULL_MASK 0x00000100 +#define TMC5271_DIAG0_INT_PUSHPULL_SHIFT 8 +#define TMC5271_DIAG0_INT_PUSHPULL_FIELD ((RegisterField) { TMC5271_DIAG0_INT_PUSHPULL_MASK, TMC5271_DIAG0_INT_PUSHPULL_SHIFT, TMC5271_GCONF, false }) +#define TMC5271_DIAG1_POSCOMP_PUSHPULL_MASK 0x00000200 +#define TMC5271_DIAG1_POSCOMP_PUSHPULL_SHIFT 9 +#define TMC5271_DIAG1_POSCOMP_PUSHPULL_FIELD ((RegisterField) { TMC5271_DIAG1_POSCOMP_PUSHPULL_MASK, TMC5271_DIAG1_POSCOMP_PUSHPULL_SHIFT, TMC5271_GCONF, false }) +#define TMC5271_SMALL_HYSTERESIS_MASK 0x00000400 +#define TMC5271_SMALL_HYSTERESIS_SHIFT 10 +#define TMC5271_SMALL_HYSTERESIS_FIELD ((RegisterField) { TMC5271_SMALL_HYSTERESIS_MASK, TMC5271_SMALL_HYSTERESIS_SHIFT, TMC5271_GCONF, false }) +#define TMC5271_STOP_ENABLE_MASK 0x00000800 +#define TMC5271_STOP_ENABLE_SHIFT 11 +#define TMC5271_STOP_ENABLE_FIELD ((RegisterField) { TMC5271_STOP_ENABLE_MASK, TMC5271_STOP_ENABLE_SHIFT, TMC5271_GCONF, false }) +#define TMC5271_DIRECT_MODE_MASK 0x00001000 +#define TMC5271_DIRECT_MODE_SHIFT 12 +#define TMC5271_DIRECT_MODE_FIELD ((RegisterField) { TMC5271_DIRECT_MODE_MASK, TMC5271_DIRECT_MODE_SHIFT, TMC5271_GCONF, false }) +#define TMC5271_SD_MASK 0x00002000 +#define TMC5271_SD_SHIFT 13 +#define TMC5271_SD_FIELD ((RegisterField) { TMC5271_SD_MASK, TMC5271_SD_SHIFT, TMC5271_GCONF, false }) +#define TMC5271_DRV_ENN_MASK 0x00004000 +#define TMC5271_DRV_ENN_SHIFT 14 +#define TMC5271_DRV_ENN_FIELD ((RegisterField) { TMC5271_DRV_ENN_MASK, TMC5271_DRV_ENN_SHIFT, TMC5271_GCONF, false }) +#define TMC5271_QSC_STS_ENA_MASK 0x00008000 +#define TMC5271_QSC_STS_ENA_SHIFT 15 +#define TMC5271_QSC_STS_ENA_FIELD ((RegisterField) { TMC5271_QSC_STS_ENA_MASK, TMC5271_QSC_STS_ENA_SHIFT, TMC5271_GCONF, false }) +#define TMC5271_DIAG0_SEL_NERROR_RAMP_MASK 0x20000000 +#define TMC5271_DIAG0_SEL_NERROR_RAMP_SHIFT 29 +#define TMC5271_DIAG0_SEL_NERROR_RAMP_FIELD ((RegisterField) { TMC5271_DIAG0_SEL_NERROR_RAMP_MASK, TMC5271_DIAG0_SEL_NERROR_RAMP_SHIFT, TMC5271_GCONF, false }) +#define TMC5271_DIAG1_SEL_NSTALLINDEX_XCOMP_MASK 0x40000000 +#define TMC5271_DIAG1_SEL_NSTALLINDEX_XCOMP_SHIFT 30 +#define TMC5271_DIAG1_SEL_NSTALLINDEX_XCOMP_FIELD ((RegisterField) { TMC5271_DIAG1_SEL_NSTALLINDEX_XCOMP_MASK, TMC5271_DIAG1_SEL_NSTALLINDEX_XCOMP_SHIFT, TMC5271_GCONF, false }) +#define TMC5271_RESET_MASK 0x00000001 +#define TMC5271_RESET_SHIFT 0 +#define TMC5271_RESET_FIELD ((RegisterField) { TMC5271_RESET_MASK, TMC5271_RESET_SHIFT, TMC5271_GSTAT, false }) +#define TMC5271_DRV_ERR_MASK 0x00000002 +#define TMC5271_DRV_ERR_SHIFT 1 +#define TMC5271_DRV_ERR_FIELD ((RegisterField) { TMC5271_DRV_ERR_MASK, TMC5271_DRV_ERR_SHIFT, TMC5271_GSTAT, false }) +#define TMC5271_UV_LDO_MASK 0x00000004 +#define TMC5271_UV_LDO_SHIFT 2 +#define TMC5271_UV_LDO_FIELD ((RegisterField) { TMC5271_UV_LDO_MASK, TMC5271_UV_LDO_SHIFT, TMC5271_GSTAT, false }) +#define TMC5271_REGISTER_RESET_MASK 0x00000008 +#define TMC5271_REGISTER_RESET_SHIFT 3 +#define TMC5271_REGISTER_RESET_FIELD ((RegisterField) { TMC5271_REGISTER_RESET_MASK, TMC5271_REGISTER_RESET_SHIFT, TMC5271_GSTAT, false }) +#define TMC5271_VM_UVLO_MASK 0x00000010 +#define TMC5271_VM_UVLO_SHIFT 4 +#define TMC5271_VM_UVLO_FIELD ((RegisterField) { TMC5271_VM_UVLO_MASK, TMC5271_VM_UVLO_SHIFT, TMC5271_GSTAT, false }) +#define TMC5271_IFCNT_MASK 0x000000FF +#define TMC5271_IFCNT_SHIFT 0 +#define TMC5271_IFCNT_FIELD ((RegisterField) { TMC5271_IFCNT_MASK, TMC5271_IFCNT_SHIFT, TMC5271_IFCNT, false }) +#define TMC5271_SLAVEADDR_MASK 0x000000FF +#define TMC5271_SLAVEADDR_SHIFT 0 +#define TMC5271_SLAVEADDR_FIELD ((RegisterField) { TMC5271_SLAVEADDR_MASK, TMC5271_SLAVEADDR_SHIFT, TMC5271_SLAVECONF, false }) +#define TMC5271_SENDDELAY_MASK 0x00000F00 +#define TMC5271_SENDDELAY_SHIFT 8 +#define TMC5271_SENDDELAY_FIELD ((RegisterField) { TMC5271_SENDDELAY_MASK, TMC5271_SENDDELAY_SHIFT, TMC5271_SLAVECONF, false }) +#define TMC5271_ADC_TEMPERATURE_MASK 0x000001FE +#define TMC5271_ADC_TEMPERATURE_SHIFT 1 +#define TMC5271_ADC_TEMPERATURE_FIELD ((RegisterField) { TMC5271_ADC_TEMPERATURE_MASK, TMC5271_ADC_TEMPERATURE_SHIFT, TMC5271_IOIN, false }) +#define TMC5271_ADC_EN_MASK 0x00000200 +#define TMC5271_ADC_EN_SHIFT 9 +#define TMC5271_ADC_EN_FIELD ((RegisterField) { TMC5271_ADC_EN_MASK, TMC5271_ADC_EN_SHIFT, TMC5271_IOIN, false }) +#define TMC5271_SEL_OSCILLATOR_MASK 0x00000800 +#define TMC5271_SEL_OSCILLATOR_SHIFT 11 +#define TMC5271_SEL_OSCILLATOR_FIELD ((RegisterField) { TMC5271_SEL_OSCILLATOR_MASK, TMC5271_SEL_OSCILLATOR_SHIFT, TMC5271_IOIN, false }) +#define TMC5271_EXT_RES_DET_MASK 0x00001000 +#define TMC5271_EXT_RES_DET_SHIFT 12 +#define TMC5271_EXT_RES_DET_FIELD ((RegisterField) { TMC5271_EXT_RES_DET_MASK, TMC5271_EXT_RES_DET_SHIFT, TMC5271_IOIN, false }) +#define TMC5271_OUTPUT_MASK 0x00002000 +#define TMC5271_OUTPUT_SHIFT 13 +#define TMC5271_OUTPUT_FIELD ((RegisterField) { TMC5271_OUTPUT_MASK, TMC5271_OUTPUT_SHIFT, TMC5271_IOIN, false }) +#define TMC5271_QSC_STATUS_MASK 0x00008000 +#define TMC5271_QSC_STATUS_SHIFT 15 +#define TMC5271_QSC_STATUS_FIELD ((RegisterField) { TMC5271_QSC_STATUS_MASK, TMC5271_QSC_STATUS_SHIFT, TMC5271_IOIN, false }) +#define TMC5271_SILICON_RV_MASK 0x00070000 +#define TMC5271_SILICON_RV_SHIFT 16 +#define TMC5271_SILICON_RV_FIELD ((RegisterField) { TMC5271_SILICON_RV_MASK, TMC5271_SILICON_RV_SHIFT, TMC5271_IOIN, false }) +#define TMC5271_VERSION_MASK 0xFF000000 +#define TMC5271_VERSION_SHIFT 24 +#define TMC5271_VERSION_FIELD ((RegisterField) { TMC5271_VERSION_MASK, TMC5271_VERSION_SHIFT, TMC5271_IOIN, false }) +#define TMC5271_FSR_MASK 0x00000003 +#define TMC5271_FSR_SHIFT 0 +#define TMC5271_FSR_FIELD ((RegisterField) { TMC5271_FSR_MASK, TMC5271_FSR_SHIFT, TMC5271_DRV_CONF, false }) +#define TMC5271_FSR_IREF_MASK 0x0000000C +#define TMC5271_FSR_IREF_SHIFT 2 +#define TMC5271_FSR_IREF_FIELD ((RegisterField) { TMC5271_FSR_IREF_MASK, TMC5271_FSR_IREF_SHIFT, TMC5271_DRV_CONF, false }) +#define TMC5271_EN_EMERGENCY_DISABLE_MASK 0x00000010 +#define TMC5271_EN_EMERGENCY_DISABLE_SHIFT 4 +#define TMC5271_EN_EMERGENCY_DISABLE_FIELD ((RegisterField) { TMC5271_EN_EMERGENCY_DISABLE_MASK, TMC5271_EN_EMERGENCY_DISABLE_SHIFT, TMC5271_DRV_CONF, false }) +#define TMC5271_STANDSTILL_TIME_MASK 0x00070000 +#define TMC5271_STANDSTILL_TIME_SHIFT 16 +#define TMC5271_STANDSTILL_TIME_FIELD ((RegisterField) { TMC5271_STANDSTILL_TIME_MASK, TMC5271_STANDSTILL_TIME_SHIFT, TMC5271_DRV_CONF, false }) +#define TMC5271_GLOBALSCALER_A_MASK 0x000000FF +#define TMC5271_GLOBALSCALER_A_SHIFT 0 +#define TMC5271_GLOBALSCALER_A_FIELD ((RegisterField) { TMC5271_GLOBALSCALER_A_MASK, TMC5271_GLOBALSCALER_A_SHIFT, TMC5271_GLOBAL_SCALER, false }) +#define TMC5271_GLOBALSCALER_B_MASK 0x0000FF00 +#define TMC5271_GLOBALSCALER_B_SHIFT 8 +#define TMC5271_GLOBALSCALER_B_FIELD ((RegisterField) { TMC5271_GLOBALSCALER_B_MASK, TMC5271_GLOBALSCALER_B_SHIFT, TMC5271_GLOBAL_SCALER, false }) +#define TMC5271_RAMPMODE_MASK 0x00000003 +#define TMC5271_RAMPMODE_SHIFT 0 +#define TMC5271_RAMPMODE_FIELD ((RegisterField) { TMC5271_RAMPMODE_MASK, TMC5271_RAMPMODE_SHIFT, TMC5271_RAMPMODE, false }) +#define TMC5271_MSLUT_ADDR_MASK 0x0000001F +#define TMC5271_MSLUT_ADDR_SHIFT 0 +#define TMC5271_MSLUT_ADDR_FIELD ((RegisterField) { TMC5271_MSLUT_ADDR_MASK, TMC5271_MSLUT_ADDR_SHIFT, TMC5271_MSLUT_ADDR, false }) +#define TMC5271_MSLUT_DATA_MASK 0xFFFFFFFF +#define TMC5271_MSLUT_DATA_SHIFT 0 +#define TMC5271_MSLUT_DATA_FIELD ((RegisterField) { TMC5271_MSLUT_DATA_MASK, TMC5271_MSLUT_DATA_SHIFT, TMC5271_MSLUT_DATA, false }) +#define TMC5271_MSLUT_DATA_START_SIN90_MASK 0xFF0000 +#define TMC5271_MSLUT_DATA_START_SIN90_SHIFT 16 +#define TMC5271_MSLUT_DATA_START_SIN90_FIELD ((RegisterField) { TMC5271_MSLUT_DATA_START_SIN90_MASK, TMC5271_MSLUT_DATA_START_SIN90_SHIFT, TMC5271_MSLUT_DATA, false }) +#define TMC5271_MSLUT_DATA_OFFSET_SIN90_MASK 0xFF0000 +#define TMC5271_MSLUT_DATA_OFFSET_SIN90_SHIFT 24 +#define TMC5271_MSLUT_DATA_OFFSET_SIN90_FIELD ((RegisterField) { TMC5271_MSLUT_DATA_OFFSET_SIN90_MASK, TMC5271_MSLUT_DATA_OFFSET_SIN90_SHIFT, TMC5271_MSLUT_DATA, false }) +#define TMC5271_X_COMPARE_MASK 0xFFFFFFFF +#define TMC5271_X_COMPARE_SHIFT 0 +#define TMC5271_X_COMPARE_FIELD ((RegisterField) { TMC5271_X_COMPARE_MASK, TMC5271_X_COMPARE_SHIFT, TMC5271_X_COMPARE, true }) +#define TMC5271_X_COMPARE_REPEAT_MASK 0x00FFFFFF +#define TMC5271_X_COMPARE_REPEAT_SHIFT 0 +#define TMC5271_X_COMPARE_REPEAT_FIELD ((RegisterField) { TMC5271_X_COMPARE_REPEAT_MASK, TMC5271_X_COMPARE_REPEAT_SHIFT, TMC5271_X_COMPARE_REPEAT, false }) +#define TMC5271_IHOLD_MASK 0x0000001F +#define TMC5271_IHOLD_SHIFT 0 +#define TMC5271_IHOLD_FIELD ((RegisterField) { TMC5271_IHOLD_MASK, TMC5271_IHOLD_SHIFT, TMC5271_IHOLD_IRUN, false }) +#define TMC5271_IRUN_MASK 0x00001F00 +#define TMC5271_IRUN_SHIFT 8 +#define TMC5271_IRUN_FIELD ((RegisterField) { TMC5271_IRUN_MASK, TMC5271_IRUN_SHIFT, TMC5271_IHOLD_IRUN, false }) +#define TMC5271_IHOLDDELAY_MASK 0x000F0000 +#define TMC5271_IHOLDDELAY_SHIFT 16 +#define TMC5271_IHOLDDELAY_FIELD ((RegisterField) { TMC5271_IHOLDDELAY_MASK, TMC5271_IHOLDDELAY_SHIFT, TMC5271_IHOLD_IRUN, false }) +#define TMC5271_IRUNDELAY_MASK 0x0F000000 +#define TMC5271_IRUNDELAY_SHIFT 24 +#define TMC5271_IRUNDELAY_FIELD ((RegisterField) { TMC5271_IRUNDELAY_MASK, TMC5271_IRUNDELAY_SHIFT, TMC5271_IHOLD_IRUN, false }) +#define TMC5271_TPOWERDOWN_MASK 0x000000FF +#define TMC5271_TPOWERDOWN_SHIFT 0 +#define TMC5271_TPOWERDOWN_FIELD ((RegisterField) { TMC5271_TPOWERDOWN_MASK, TMC5271_TPOWERDOWN_SHIFT, TMC5271_TPOWERDOWN, false }) +#define TMC5271_TSTEP_MASK 0x000FFFFF +#define TMC5271_TSTEP_SHIFT 0 +#define TMC5271_TSTEP_FIELD ((RegisterField) { TMC5271_TSTEP_MASK, TMC5271_TSTEP_SHIFT, TMC5271_TSTEP, false }) +#define TMC5271_TPWMTHRS_MASK 0x000FFFFF +#define TMC5271_TPWMTHRS_SHIFT 0 +#define TMC5271_TPWMTHRS_FIELD ((RegisterField) { TMC5271_TPWMTHRS_MASK, TMC5271_TPWMTHRS_SHIFT, TMC5271_TPWMTHRS, false }) +#define TMC5271_TCOOLTHRS_MASK 0x000FFFFF +#define TMC5271_TCOOLTHRS_SHIFT 0 +#define TMC5271_TCOOLTHRS_FIELD ((RegisterField) { TMC5271_TCOOLTHRS_MASK, TMC5271_TCOOLTHRS_SHIFT, TMC5271_TCOOLTHRS, false }) +#define TMC5271_THIGH_MASK 0x000FFFFF +#define TMC5271_THIGH_SHIFT 0 +#define TMC5271_THIGH_FIELD ((RegisterField) { TMC5271_THIGH_MASK, TMC5271_THIGH_SHIFT, TMC5271_THIGH, false }) +#define TMC5271_XACTUAL_MASK 0xFFFFFFFF +#define TMC5271_XACTUAL_SHIFT 0 +#define TMC5271_XACTUAL_FIELD ((RegisterField) { TMC5271_XACTUAL_MASK, TMC5271_XACTUAL_SHIFT, TMC5271_XACTUAL, true }) +#define TMC5271_VACTUAL_MASK 0x00FFFFFF +#define TMC5271_VACTUAL_SHIFT 0 +#define TMC5271_VACTUAL_FIELD ((RegisterField) { TMC5271_VACTUAL_MASK, TMC5271_VACTUAL_SHIFT, TMC5271_VACTUAL, true }) +#define TMC5271_AACTUAL_MASK 0x00FFFFFF +#define TMC5271_AACTUAL_SHIFT 0 +#define TMC5271_AACTUAL_FIELD ((RegisterField) { TMC5271_AACTUAL_MASK, TMC5271_AACTUAL_SHIFT, TMC5271_AACTUAL, true }) +#define TMC5271_VSTART_MASK 0x0003FFFF +#define TMC5271_VSTART_SHIFT 0 +#define TMC5271_VSTART_FIELD ((RegisterField) { TMC5271_VSTART_MASK, TMC5271_VSTART_SHIFT, TMC5271_VSTART, false }) +#define TMC5271_A1_MASK 0x0003FFFF +#define TMC5271_A1_SHIFT 0 +#define TMC5271_A1_FIELD ((RegisterField) { TMC5271_A1_MASK, TMC5271_A1_SHIFT, TMC5271_A1, false }) +#define TMC5271_V1_MASK 0x000FFFFF +#define TMC5271_V1_SHIFT 0 +#define TMC5271_V1_FIELD ((RegisterField) { TMC5271_V1_MASK, TMC5271_V1_SHIFT, TMC5271_V1, false }) +#define TMC5271_A2_MASK 0x0003FFFF +#define TMC5271_A2_SHIFT 0 +#define TMC5271_A2_FIELD ((RegisterField) { TMC5271_A2_MASK, TMC5271_A2_SHIFT, TMC5271_A2, false }) +#define TMC5271_V2_MASK 0x000FFFFF +#define TMC5271_V2_SHIFT 0 +#define TMC5271_V2_FIELD ((RegisterField) { TMC5271_V2_MASK, TMC5271_V2_SHIFT, TMC5271_V2, false }) +#define TMC5271_AMAX_MASK 0x0003FFFF +#define TMC5271_AMAX_SHIFT 0 +#define TMC5271_AMAX_FIELD ((RegisterField) { TMC5271_AMAX_MASK, TMC5271_AMAX_SHIFT, TMC5271_AMAX, false }) +#define TMC5271_VMAX_MASK 0x007FFFFF +#define TMC5271_VMAX_SHIFT 0 +#define TMC5271_VMAX_FIELD ((RegisterField) { TMC5271_VMAX_MASK, TMC5271_VMAX_SHIFT, TMC5271_VMAX, false }) +#define TMC5271_DMAX_MASK 0x0003FFFF +#define TMC5271_DMAX_SHIFT 0 +#define TMC5271_DMAX_FIELD ((RegisterField) { TMC5271_DMAX_MASK, TMC5271_DMAX_SHIFT, TMC5271_DMAX, false }) +#define TMC5271_D2_MASK 0x0003FFFF +#define TMC5271_D2_SHIFT 0 +#define TMC5271_D2_FIELD ((RegisterField) { TMC5271_D2_MASK, TMC5271_D2_SHIFT, TMC5271_D2, false }) +#define TMC5271_D1_MASK 0x0003FFFF +#define TMC5271_D1_SHIFT 0 +#define TMC5271_D1_FIELD ((RegisterField) { TMC5271_D1_MASK, TMC5271_D1_SHIFT, TMC5271_D1, false }) +#define TMC5271_VSTOP_MASK 0x0003FFFF +#define TMC5271_VSTOP_SHIFT 0 +#define TMC5271_VSTOP_FIELD ((RegisterField) { TMC5271_VSTOP_MASK, TMC5271_VSTOP_SHIFT, TMC5271_VSTOP, false }) +#define TMC5271_TVMAX_MASK 0x0000FFFF +#define TMC5271_TVMAX_SHIFT 0 +#define TMC5271_TVMAX_FIELD ((RegisterField) { TMC5271_TVMAX_MASK, TMC5271_TVMAX_SHIFT, TMC5271_TVMAX, false }) +#define TMC5271_TZEROWAIT_MASK 0x0000FFFF +#define TMC5271_TZEROWAIT_SHIFT 0 +#define TMC5271_TZEROWAIT_FIELD ((RegisterField) { TMC5271_TZEROWAIT_MASK, TMC5271_TZEROWAIT_SHIFT, TMC5271_TZEROWAIT, false }) +#define TMC5271_XTARGET_MASK 0xFFFFFFFF +#define TMC5271_XTARGET_SHIFT 0 +#define TMC5271_XTARGET_FIELD ((RegisterField) { TMC5271_XTARGET_MASK, TMC5271_XTARGET_SHIFT, TMC5271_XTARGET, true }) +#define TMC5271_VDCMIN_RESERVED_MASK 0x000000FF +#define TMC5271_VDCMIN_RESERVED_SHIFT 0 +#define TMC5271_VDCMIN_RESERVED_FIELD ((RegisterField) { TMC5271_VDCMIN_RESERVED_MASK, TMC5271_VDCMIN_RESERVED_SHIFT, TMC5271_VDCMIN, false }) +#define TMC5271_VDCMIN_VDCMIN_MASK 0x007FFF00 +#define TMC5271_VDCMIN_VDCMIN_SHIFT 8 +#define TMC5271_VDCMIN_VDCMIN_FIELD ((RegisterField) { TMC5271_VDCMIN_VDCMIN_MASK, TMC5271_VDCMIN_VDCMIN_SHIFT, TMC5271_VDCMIN, false }) +#define TMC5271_SW_MODE_STOP_L_ENABLE_MASK 0x00000001 +#define TMC5271_SW_MODE_STOP_L_ENABLE_SHIFT 0 +#define TMC5271_SW_MODE_STOP_L_ENABLE_FIELD ((RegisterField) { TMC5271_SW_MODE_STOP_L_ENABLE_MASK, TMC5271_SW_MODE_STOP_L_ENABLE_SHIFT, TMC5271_SW_MODE, false }) +#define TMC5271_SW_MODE_STOP_R_ENABLE_MASK 0x00000002 +#define TMC5271_SW_MODE_STOP_R_ENABLE_SHIFT 1 +#define TMC5271_SW_MODE_STOP_R_ENABLE_FIELD ((RegisterField) { TMC5271_SW_MODE_STOP_R_ENABLE_MASK, TMC5271_SW_MODE_STOP_R_ENABLE_SHIFT, TMC5271_SW_MODE, false }) +#define TMC5271_SW_MODE_POL_STOP_L_MASK 0x00000004 +#define TMC5271_SW_MODE_POL_STOP_L_SHIFT 2 +#define TMC5271_SW_MODE_POL_STOP_L_FIELD ((RegisterField) { TMC5271_SW_MODE_POL_STOP_L_MASK, TMC5271_SW_MODE_POL_STOP_L_SHIFT, TMC5271_SW_MODE, false }) +#define TMC5271_SW_MODE_POL_STOP_R_MASK 0x00000008 +#define TMC5271_SW_MODE_POL_STOP_R_SHIFT 3 +#define TMC5271_SW_MODE_POL_STOP_R_FIELD ((RegisterField) { TMC5271_SW_MODE_POL_STOP_R_MASK, TMC5271_SW_MODE_POL_STOP_R_SHIFT, TMC5271_SW_MODE, false }) +#define TMC5271_SW_MODE_SWAP_LR_MASK 0x00000010 +#define TMC5271_SW_MODE_SWAP_LR_SHIFT 4 +#define TMC5271_SW_MODE_SWAP_LR_FIELD ((RegisterField) { TMC5271_SW_MODE_SWAP_LR_MASK, TMC5271_SW_MODE_SWAP_LR_SHIFT, TMC5271_SW_MODE, false }) +#define TMC5271_SW_MODE_LATCH_L_ACTIVE_MASK 0x00000020 +#define TMC5271_SW_MODE_LATCH_L_ACTIVE_SHIFT 5 +#define TMC5271_SW_MODE_LATCH_L_ACTIVE_FIELD ((RegisterField) { TMC5271_SW_MODE_LATCH_L_ACTIVE_MASK, TMC5271_SW_MODE_LATCH_L_ACTIVE_SHIFT, TMC5271_SW_MODE, false }) +#define TMC5271_SW_MODE_LATCH_L_INACTIVE_MASK 0x00000040 +#define TMC5271_SW_MODE_LATCH_L_INACTIVE_SHIFT 6 +#define TMC5271_SW_MODE_LATCH_L_INACTIVE_FIELD ((RegisterField) { TMC5271_SW_MODE_LATCH_L_INACTIVE_MASK, TMC5271_SW_MODE_LATCH_L_INACTIVE_SHIFT, TMC5271_SW_MODE, false }) +#define TMC5271_SW_MODE_LATCH_R_ACTIVE_MASK 0x00000080 +#define TMC5271_SW_MODE_LATCH_R_ACTIVE_SHIFT 7 +#define TMC5271_SW_MODE_LATCH_R_ACTIVE_FIELD ((RegisterField) { TMC5271_SW_MODE_LATCH_R_ACTIVE_MASK, TMC5271_SW_MODE_LATCH_R_ACTIVE_SHIFT, TMC5271_SW_MODE, false }) +#define TMC5271_SW_MODE_LATCH_R_INACTIVE_MASK 0x00000100 +#define TMC5271_SW_MODE_LATCH_R_INACTIVE_SHIFT 8 +#define TMC5271_SW_MODE_LATCH_R_INACTIVE_FIELD ((RegisterField) { TMC5271_SW_MODE_LATCH_R_INACTIVE_MASK, TMC5271_SW_MODE_LATCH_R_INACTIVE_SHIFT, TMC5271_SW_MODE, false }) +#define TMC5271_SW_MODE_EN_LATCH_ENCODER_MASK 0x00000200 +#define TMC5271_SW_MODE_EN_LATCH_ENCODER_SHIFT 9 +#define TMC5271_SW_MODE_EN_LATCH_ENCODER_FIELD ((RegisterField) { TMC5271_SW_MODE_EN_LATCH_ENCODER_MASK, TMC5271_SW_MODE_EN_LATCH_ENCODER_SHIFT, TMC5271_SW_MODE, false }) +#define TMC5271_SW_MODE_SG_STOP_MASK 0x00000400 +#define TMC5271_SW_MODE_SG_STOP_SHIFT 10 +#define TMC5271_SW_MODE_SG_STOP_FIELD ((RegisterField) { TMC5271_SW_MODE_SG_STOP_MASK, TMC5271_SW_MODE_SG_STOP_SHIFT, TMC5271_SW_MODE, false }) +#define TMC5271_SW_MODE_EN_SOFTSTOP_MASK 0x00000800 +#define TMC5271_SW_MODE_EN_SOFTSTOP_SHIFT 11 +#define TMC5271_SW_MODE_EN_SOFTSTOP_FIELD ((RegisterField) { TMC5271_SW_MODE_EN_SOFTSTOP_MASK, TMC5271_SW_MODE_EN_SOFTSTOP_SHIFT, TMC5271_SW_MODE, false }) +#define TMC5271_SW_MODE_EN_VIRTUAL_STOP_L_MASK 0x00001000 +#define TMC5271_SW_MODE_EN_VIRTUAL_STOP_L_SHIFT 12 +#define TMC5271_SW_MODE_EN_VIRTUAL_STOP_L_FIELD ((RegisterField) { TMC5271_SW_MODE_EN_VIRTUAL_STOP_L_MASK, TMC5271_SW_MODE_EN_VIRTUAL_STOP_L_SHIFT, TMC5271_SW_MODE, false }) +#define TMC5271_SW_MODE_EN_VIRTUAL_STOP_R_MASK 0x00002000 +#define TMC5271_SW_MODE_EN_VIRTUAL_STOP_R_SHIFT 13 +#define TMC5271_SW_MODE_EN_VIRTUAL_STOP_R_FIELD ((RegisterField) { TMC5271_SW_MODE_EN_VIRTUAL_STOP_R_MASK, TMC5271_SW_MODE_EN_VIRTUAL_STOP_R_SHIFT, TMC5271_SW_MODE, false }) +#define TMC5271_SW_MODE_VIRTUAL_STEP_ENC_MASK 0x00004000 +#define TMC5271_SW_MODE_VIRTUAL_STEP_ENC_SHIFT 14 +#define TMC5271_SW_MODE_VIRTUAL_STEP_ENC_FIELD ((RegisterField) { TMC5271_SW_MODE_VIRTUAL_STEP_ENC_MASK, TMC5271_SW_MODE_VIRTUAL_STEP_ENC_SHIFT, TMC5271_SW_MODE, false }) +#define TMC5271_STATUS_STOP_L_MASK 0x00000001 +#define TMC5271_STATUS_STOP_L_SHIFT 0 +#define TMC5271_STATUS_STOP_L_FIELD ((RegisterField) { TMC5271_STATUS_STOP_L_MASK, TMC5271_STATUS_STOP_L_SHIFT, TMC5271_RAMP_STAT, false }) +#define TMC5271_STATUS_STOP_R_MASK 0x00000002 +#define TMC5271_STATUS_STOP_R_SHIFT 1 +#define TMC5271_STATUS_STOP_R_FIELD ((RegisterField) { TMC5271_STATUS_STOP_R_MASK, TMC5271_STATUS_STOP_R_SHIFT, TMC5271_RAMP_STAT, false }) +#define TMC5271_STATUS_LATCH_L_MASK 0x00000004 +#define TMC5271_STATUS_LATCH_L_SHIFT 2 +#define TMC5271_STATUS_LATCH_L_FIELD ((RegisterField) { TMC5271_STATUS_LATCH_L_MASK, TMC5271_STATUS_LATCH_L_SHIFT, TMC5271_RAMP_STAT, false }) +#define TMC5271_STATUS_LATCH_R_MASK 0x00000008 +#define TMC5271_STATUS_LATCH_R_SHIFT 3 +#define TMC5271_STATUS_LATCH_R_FIELD ((RegisterField) { TMC5271_STATUS_LATCH_R_MASK, TMC5271_STATUS_LATCH_R_SHIFT, TMC5271_RAMP_STAT, false }) +#define TMC5271_EVENT_STOP_L_MASK 0x00000010 +#define TMC5271_EVENT_STOP_L_SHIFT 4 +#define TMC5271_EVENT_STOP_L_FIELD ((RegisterField) { TMC5271_EVENT_STOP_L_MASK, TMC5271_EVENT_STOP_L_SHIFT, TMC5271_RAMP_STAT, false }) +#define TMC5271_EVENT_STOP_R_MASK 0x00000020 +#define TMC5271_EVENT_STOP_R_SHIFT 5 +#define TMC5271_EVENT_STOP_R_FIELD ((RegisterField) { TMC5271_EVENT_STOP_R_MASK, TMC5271_EVENT_STOP_R_SHIFT, TMC5271_RAMP_STAT, false }) +#define TMC5271_EVENT_STOP_SG_MASK 0x00000040 +#define TMC5271_EVENT_STOP_SG_SHIFT 6 +#define TMC5271_EVENT_STOP_SG_FIELD ((RegisterField) { TMC5271_EVENT_STOP_SG_MASK, TMC5271_EVENT_STOP_SG_SHIFT, TMC5271_RAMP_STAT, false }) +#define TMC5271_EVENT_POS_REACHED_MASK 0x00000080 +#define TMC5271_EVENT_POS_REACHED_SHIFT 7 +#define TMC5271_EVENT_POS_REACHED_FIELD ((RegisterField) { TMC5271_EVENT_POS_REACHED_MASK, TMC5271_EVENT_POS_REACHED_SHIFT, TMC5271_RAMP_STAT, false }) +#define TMC5271_VELOCITY_REACHED_MASK 0x00000100 +#define TMC5271_VELOCITY_REACHED_SHIFT 8 +#define TMC5271_VELOCITY_REACHED_FIELD ((RegisterField) { TMC5271_VELOCITY_REACHED_MASK, TMC5271_VELOCITY_REACHED_SHIFT, TMC5271_RAMP_STAT, false }) +#define TMC5271_POSITION_REACHED_MASK 0x00000200 +#define TMC5271_POSITION_REACHED_SHIFT 9 +#define TMC5271_POSITION_REACHED_FIELD ((RegisterField) { TMC5271_POSITION_REACHED_MASK, TMC5271_POSITION_REACHED_SHIFT, TMC5271_RAMP_STAT, false }) +#define TMC5271_VZERO_MASK 0x00000400 +#define TMC5271_VZERO_SHIFT 10 +#define TMC5271_VZERO_FIELD ((RegisterField) { TMC5271_VZERO_MASK, TMC5271_VZERO_SHIFT, TMC5271_RAMP_STAT, false }) +#define TMC5271_T_ZEROWAIT_ACTIVE_MASK 0x00000800 +#define TMC5271_T_ZEROWAIT_ACTIVE_SHIFT 11 +#define TMC5271_T_ZEROWAIT_ACTIVE_FIELD ((RegisterField) { TMC5271_T_ZEROWAIT_ACTIVE_MASK, TMC5271_T_ZEROWAIT_ACTIVE_SHIFT, TMC5271_RAMP_STAT, false }) +#define TMC5271_SECOND_MOVE_MASK 0x00001000 +#define TMC5271_SECOND_MOVE_SHIFT 12 +#define TMC5271_SECOND_MOVE_FIELD ((RegisterField) { TMC5271_SECOND_MOVE_MASK, TMC5271_SECOND_MOVE_SHIFT, TMC5271_RAMP_STAT, false }) +#define TMC5271_STATUS_SG_MASK 0x00002000 +#define TMC5271_STATUS_SG_SHIFT 13 +#define TMC5271_STATUS_SG_FIELD ((RegisterField) { TMC5271_STATUS_SG_MASK, TMC5271_STATUS_SG_SHIFT, TMC5271_RAMP_STAT, false }) +#define TMC5271_STATUS_VIRTUAL_STOP_L_MASK 0x00004000 +#define TMC5271_STATUS_VIRTUAL_STOP_L_SHIFT 14 +#define TMC5271_STATUS_VIRTUAL_STOP_L_FIELD ((RegisterField) { TMC5271_STATUS_VIRTUAL_STOP_L_MASK, TMC5271_STATUS_VIRTUAL_STOP_L_SHIFT, TMC5271_RAMP_STAT, false }) +#define TMC5271_STATUS_VIRTUAL_STOP_R_MASK 0x00008000 +#define TMC5271_STATUS_VIRTUAL_STOP_R_SHIFT 15 +#define TMC5271_STATUS_VIRTUAL_STOP_R_FIELD ((RegisterField) { TMC5271_STATUS_VIRTUAL_STOP_R_MASK, TMC5271_STATUS_VIRTUAL_STOP_R_SHIFT, TMC5271_RAMP_STAT, false }) +#define TMC5271_XLATCH_MASK 0xFFFFFFFF +#define TMC5271_XLATCH_SHIFT 0 +#define TMC5271_XLATCH_FIELD ((RegisterField) { TMC5271_XLATCH_MASK, TMC5271_XLATCH_SHIFT, TMC5271_XLATCH, true }) +#define TMC5271_P_POSITION_MASK 0x000003FF +#define TMC5271_P_POSITION_SHIFT 0 +#define TMC5271_P_POSITION_FIELD ((RegisterField) { TMC5271_P_POSITION_MASK, TMC5271_P_POSITION_SHIFT, TMC5271_POSITION_PI_CTRL, false }) +#define TMC5271_TOLERANCE_MASK 0x00FF0000 +#define TMC5271_TOLERANCE_SHIFT 16 +#define TMC5271_TOLERANCE_FIELD ((RegisterField) { TMC5271_TOLERANCE_MASK, TMC5271_TOLERANCE_SHIFT, TMC5271_POSITION_PI_CTRL, false }) +#define TMC5271_TOL_ON_POS_REACHED_MASK 0x10000000 +#define TMC5271_TOL_ON_POS_REACHED_SHIFT 28 +#define TMC5271_TOL_ON_POS_REACHED_FIELD ((RegisterField) { TMC5271_TOL_ON_POS_REACHED_MASK, TMC5271_TOL_ON_POS_REACHED_SHIFT, TMC5271_POSITION_PI_CTRL, false }) +#define TMC5271_X_ENC_MASK 0xFFFFFFFF +#define TMC5271_X_ENC_SHIFT 0 +#define TMC5271_X_ENC_FIELD ((RegisterField) { TMC5271_X_ENC_MASK, TMC5271_X_ENC_SHIFT, TMC5271_X_ENC, true }) +#define TMC5271_POL_A_MASK 0x00000001 +#define TMC5271_POL_A_SHIFT 0 +#define TMC5271_POL_A_FIELD ((RegisterField) { TMC5271_POL_A_MASK, TMC5271_POL_A_SHIFT, TMC5271_ENCMODE, false }) +#define TMC5271_POL_B_MASK 0x00000002 +#define TMC5271_POL_B_SHIFT 1 +#define TMC5271_POL_B_FIELD ((RegisterField) { TMC5271_POL_B_MASK, TMC5271_POL_B_SHIFT, TMC5271_ENCMODE, false }) +#define TMC5271_POL_N_MASK 0x00000004 +#define TMC5271_POL_N_SHIFT 2 +#define TMC5271_POL_N_FIELD ((RegisterField) { TMC5271_POL_N_MASK, TMC5271_POL_N_SHIFT, TMC5271_ENCMODE, false }) +#define TMC5271_IGNORE_AB_MASK 0x00000008 +#define TMC5271_IGNORE_AB_SHIFT 3 +#define TMC5271_IGNORE_AB_FIELD ((RegisterField) { TMC5271_IGNORE_AB_MASK, TMC5271_IGNORE_AB_SHIFT, TMC5271_ENCMODE, false }) +#define TMC5271_CLR_CONT_MASK 0x00000010 +#define TMC5271_CLR_CONT_SHIFT 4 +#define TMC5271_CLR_CONT_FIELD ((RegisterField) { TMC5271_CLR_CONT_MASK, TMC5271_CLR_CONT_SHIFT, TMC5271_ENCMODE, false }) +#define TMC5271_CLR_ONCE_MASK 0x00000020 +#define TMC5271_CLR_ONCE_SHIFT 5 +#define TMC5271_CLR_ONCE_FIELD ((RegisterField) { TMC5271_CLR_ONCE_MASK, TMC5271_CLR_ONCE_SHIFT, TMC5271_ENCMODE, false }) +#define TMC5271_POS_NEG_EDGE_MASK 0x000000C0 +#define TMC5271_POS_NEG_EDGE_SHIFT 6 +#define TMC5271_POS_NEG_EDGE_FIELD ((RegisterField) { TMC5271_POS_NEG_EDGE_MASK, TMC5271_POS_NEG_EDGE_SHIFT, TMC5271_ENCMODE, false }) +#define TMC5271_CLR_ENC_X_MASK 0x00000100 +#define TMC5271_CLR_ENC_X_SHIFT 8 +#define TMC5271_CLR_ENC_X_FIELD ((RegisterField) { TMC5271_CLR_ENC_X_MASK, TMC5271_CLR_ENC_X_SHIFT, TMC5271_ENCMODE, false }) +#define TMC5271_LATCH_X_ACT_MASK 0x00000200 +#define TMC5271_LATCH_X_ACT_SHIFT 9 +#define TMC5271_LATCH_X_ACT_FIELD ((RegisterField) { TMC5271_LATCH_X_ACT_MASK, TMC5271_LATCH_X_ACT_SHIFT, TMC5271_ENCMODE, false }) +#define TMC5271_ENC_SEL_DECIMAL_MASK 0x00000400 +#define TMC5271_ENC_SEL_DECIMAL_SHIFT 10 +#define TMC5271_ENC_SEL_DECIMAL_FIELD ((RegisterField) { TMC5271_ENC_SEL_DECIMAL_MASK, TMC5271_ENC_SEL_DECIMAL_SHIFT, TMC5271_ENCMODE, false }) +#define TMC5271_NBEMF_ABN_SEL_MASK 0x00000800 +#define TMC5271_NBEMF_ABN_SEL_SHIFT 11 +#define TMC5271_NBEMF_ABN_SEL_FIELD ((RegisterField) { TMC5271_NBEMF_ABN_SEL_MASK, TMC5271_NBEMF_ABN_SEL_SHIFT, TMC5271_ENCMODE, false }) +#define TMC5271_BEMF_HYST_MASK 0x00007000 +#define TMC5271_BEMF_HYST_SHIFT 12 +#define TMC5271_BEMF_HYST_FIELD ((RegisterField) { TMC5271_BEMF_HYST_MASK, TMC5271_BEMF_HYST_SHIFT, TMC5271_ENCMODE, false }) +#define TMC5271_QSC_ENC_EN_MASK 0x00008000 +#define TMC5271_QSC_ENC_EN_SHIFT 15 +#define TMC5271_QSC_ENC_EN_FIELD ((RegisterField) { TMC5271_QSC_ENC_EN_MASK, TMC5271_QSC_ENC_EN_SHIFT, TMC5271_ENCMODE, false }) +#define TMC5271_BEMF_BLANK_TIME_MASK 0x00FF0000 +#define TMC5271_BEMF_BLANK_TIME_SHIFT 16 +#define TMC5271_BEMF_BLANK_TIME_FIELD ((RegisterField) { TMC5271_BEMF_BLANK_TIME_MASK, TMC5271_BEMF_BLANK_TIME_SHIFT, TMC5271_ENCMODE, false }) +#define TMC5271_BEMF_FILTER_SEL_MASK 0x30000000 +#define TMC5271_BEMF_FILTER_SEL_SHIFT 28 +#define TMC5271_BEMF_FILTER_SEL_FIELD ((RegisterField) { TMC5271_BEMF_FILTER_SEL_MASK, TMC5271_BEMF_FILTER_SEL_SHIFT, TMC5271_ENCMODE, false }) +#define TMC5271_ENC_CONST_MASK 0xFFFFFFFF +#define TMC5271_ENC_CONST_SHIFT 0 +#define TMC5271_ENC_CONST_FIELD ((RegisterField) { TMC5271_ENC_CONST_MASK, TMC5271_ENC_CONST_SHIFT, TMC5271_ENC_CONST, true }) +#define TMC5271_N_EVENT_MASK 0x00000001 +#define TMC5271_N_EVENT_SHIFT 0 +#define TMC5271_N_EVENT_FIELD ((RegisterField) { TMC5271_N_EVENT_MASK, TMC5271_N_EVENT_SHIFT, TMC5271_ENC_STATUS, false }) +#define TMC5271_DEVIATION_WARN_MASK 0x00000002 +#define TMC5271_DEVIATION_WARN_SHIFT 1 +#define TMC5271_DEVIATION_WARN_FIELD ((RegisterField) { TMC5271_DEVIATION_WARN_MASK, TMC5271_DEVIATION_WARN_SHIFT, TMC5271_ENC_STATUS, false }) +#define TMC5271_ENC_LATCH_MASK 0xFFFFFFFF +#define TMC5271_ENC_LATCH_SHIFT 0 +#define TMC5271_ENC_LATCH_FIELD ((RegisterField) { TMC5271_ENC_LATCH_MASK, TMC5271_ENC_LATCH_SHIFT, TMC5271_ENC_LATCH, true }) +#define TMC5271_ENC_DEVIATION_MASK 0x000FFFFF +#define TMC5271_ENC_DEVIATION_SHIFT 0 +#define TMC5271_ENC_DEVIATION_FIELD ((RegisterField) { TMC5271_ENC_DEVIATION_MASK, TMC5271_ENC_DEVIATION_SHIFT, TMC5271_ENC_DEVIATION, false }) +#define TMC5271_VIRTUAL_STOP_L_MASK 0xFFFFFFFF +#define TMC5271_VIRTUAL_STOP_L_SHIFT 0 +#define TMC5271_VIRTUAL_STOP_L_FIELD ((RegisterField) { TMC5271_VIRTUAL_STOP_L_MASK, TMC5271_VIRTUAL_STOP_L_SHIFT, TMC5271_VIRTUAL_STOP_L, true }) +#define TMC5271_VIRTUAL_STOP_R_MASK 0xFFFFFFFF +#define TMC5271_VIRTUAL_STOP_R_SHIFT 0 +#define TMC5271_VIRTUAL_STOP_R_FIELD ((RegisterField) { TMC5271_VIRTUAL_STOP_R_MASK, TMC5271_VIRTUAL_STOP_R_SHIFT, TMC5271_VIRTUAL_STOP_R, true }) +#define TMC5271_MSCNT_MASK 0x000003FF +#define TMC5271_MSCNT_SHIFT 0 +#define TMC5271_MSCNT_FIELD ((RegisterField) { TMC5271_MSCNT_MASK, TMC5271_MSCNT_SHIFT, TMC5271_MSCNT, false }) +#define TMC5271_CUR_A_MASK 0x000001FF +#define TMC5271_CUR_A_SHIFT 0 +#define TMC5271_CUR_A_FIELD ((RegisterField) { TMC5271_CUR_A_MASK, TMC5271_CUR_A_SHIFT, TMC5271_MSCURACT, false }) +#define TMC5271_CUR_B_MASK 0x01FF0000 +#define TMC5271_CUR_B_SHIFT 16 +#define TMC5271_CUR_B_FIELD ((RegisterField) { TMC5271_CUR_B_MASK, TMC5271_CUR_B_SHIFT, TMC5271_MSCURACT, false }) +#define TMC5271_TOFF_MASK 0x0000000F +#define TMC5271_TOFF_SHIFT 0 +#define TMC5271_TOFF_FIELD ((RegisterField) { TMC5271_TOFF_MASK, TMC5271_TOFF_SHIFT, TMC5271_CHOPCONF, false }) +#define TMC5271_HSTRT_TFD210_MASK 0x00000070 +#define TMC5271_HSTRT_TFD210_SHIFT 4 +#define TMC5271_HSTRT_TFD210_FIELD ((RegisterField) { TMC5271_HSTRT_TFD210_MASK, TMC5271_HSTRT_TFD210_SHIFT, TMC5271_CHOPCONF, false }) +#define TMC5271_HEND_OFFSET_MASK 0x00000780 +#define TMC5271_HEND_OFFSET_SHIFT 7 +#define TMC5271_HEND_OFFSET_FIELD ((RegisterField) { TMC5271_HEND_OFFSET_MASK, TMC5271_HEND_OFFSET_SHIFT, TMC5271_CHOPCONF, false }) +#define TMC5271_FD3_MASK 0x00000800 +#define TMC5271_FD3_SHIFT 11 +#define TMC5271_FD3_FIELD ((RegisterField) { TMC5271_FD3_MASK, TMC5271_FD3_SHIFT, TMC5271_CHOPCONF, false }) +#define TMC5271_DISFDCC_MASK 0x00001000 +#define TMC5271_DISFDCC_SHIFT 12 +#define TMC5271_DISFDCC_FIELD ((RegisterField) { TMC5271_DISFDCC_MASK, TMC5271_DISFDCC_SHIFT, TMC5271_CHOPCONF, false }) +#define TMC5271_CHM_MASK 0x00004000 +#define TMC5271_CHM_SHIFT 14 +#define TMC5271_CHM_FIELD ((RegisterField) { TMC5271_CHM_MASK, TMC5271_CHM_SHIFT, TMC5271_CHOPCONF, false }) +#define TMC5271_TBL_MASK 0x00018000 +#define TMC5271_TBL_SHIFT 15 +#define TMC5271_TBL_FIELD ((RegisterField) { TMC5271_TBL_MASK, TMC5271_TBL_SHIFT, TMC5271_CHOPCONF, false }) +#define TMC5271_VHIGHFS_MASK 0x00040000 +#define TMC5271_VHIGHFS_SHIFT 18 +#define TMC5271_VHIGHFS_FIELD ((RegisterField) { TMC5271_VHIGHFS_MASK, TMC5271_VHIGHFS_SHIFT, TMC5271_CHOPCONF, false }) +#define TMC5271_VHIGHCHM_MASK 0x00080000 +#define TMC5271_VHIGHCHM_SHIFT 19 +#define TMC5271_VHIGHCHM_FIELD ((RegisterField) { TMC5271_VHIGHCHM_MASK, TMC5271_VHIGHCHM_SHIFT, TMC5271_CHOPCONF, false }) +#define TMC5271_TPFD_MASK 0x00F00000 +#define TMC5271_TPFD_SHIFT 20 +#define TMC5271_TPFD_FIELD ((RegisterField) { TMC5271_TPFD_MASK, TMC5271_TPFD_SHIFT, TMC5271_CHOPCONF, false }) +#define TMC5271_MRES_MASK 0x0F000000 +#define TMC5271_MRES_SHIFT 24 +#define TMC5271_MRES_FIELD ((RegisterField) { TMC5271_MRES_MASK, TMC5271_MRES_SHIFT, TMC5271_CHOPCONF, false }) +#define TMC5271_INTPOL_MASK 0x10000000 +#define TMC5271_INTPOL_SHIFT 28 +#define TMC5271_INTPOL_FIELD ((RegisterField) { TMC5271_INTPOL_MASK, TMC5271_INTPOL_SHIFT, TMC5271_CHOPCONF, false }) +#define TMC5271_DEDGE_MASK 0x20000000 +#define TMC5271_DEDGE_SHIFT 29 +#define TMC5271_DEDGE_FIELD ((RegisterField) { TMC5271_DEDGE_MASK, TMC5271_DEDGE_SHIFT, TMC5271_CHOPCONF, false }) +#define TMC5271_DISS2G_MASK 0x40000000 +#define TMC5271_DISS2G_SHIFT 30 +#define TMC5271_DISS2G_FIELD ((RegisterField) { TMC5271_DISS2G_MASK, TMC5271_DISS2G_SHIFT, TMC5271_CHOPCONF, false }) +#define TMC5271_DISS2VS_MASK 0x80000000 +#define TMC5271_DISS2VS_SHIFT 31 +#define TMC5271_DISS2VS_FIELD ((RegisterField) { TMC5271_DISS2VS_MASK, TMC5271_DISS2VS_SHIFT, TMC5271_CHOPCONF, false }) +#define TMC5271_SEMIN_MASK 0x0000000F +#define TMC5271_SEMIN_SHIFT 0 +#define TMC5271_SEMIN_FIELD ((RegisterField) { TMC5271_SEMIN_MASK, TMC5271_SEMIN_SHIFT, TMC5271_COOLCONF, false }) +#define TMC5271_SEUP_MASK 0x00000060 +#define TMC5271_SEUP_SHIFT 5 +#define TMC5271_SEUP_FIELD ((RegisterField) { TMC5271_SEUP_MASK, TMC5271_SEUP_SHIFT, TMC5271_COOLCONF, false }) +#define TMC5271_SEMAX_MASK 0x00000F00 +#define TMC5271_SEMAX_SHIFT 8 +#define TMC5271_SEMAX_FIELD ((RegisterField) { TMC5271_SEMAX_MASK, TMC5271_SEMAX_SHIFT, TMC5271_COOLCONF, false }) +#define TMC5271_SEDN_MASK 0x00006000 +#define TMC5271_SEDN_SHIFT 13 +#define TMC5271_SEDN_FIELD ((RegisterField) { TMC5271_SEDN_MASK, TMC5271_SEDN_SHIFT, TMC5271_COOLCONF, false }) +#define TMC5271_SEIMIN_MASK 0x00008000 +#define TMC5271_SEIMIN_SHIFT 15 +#define TMC5271_SEIMIN_FIELD ((RegisterField) { TMC5271_SEIMIN_MASK, TMC5271_SEIMIN_SHIFT, TMC5271_COOLCONF, false }) +#define TMC5271_SGT_MASK 0x007F0000 +#define TMC5271_SGT_SHIFT 16 +#define TMC5271_SGT_FIELD ((RegisterField) { TMC5271_SGT_MASK, TMC5271_SGT_SHIFT, TMC5271_COOLCONF, false }) +#define TMC5271_SFILT_MASK 0x01000000 +#define TMC5271_SFILT_SHIFT 24 +#define TMC5271_SFILT_FIELD ((RegisterField) { TMC5271_SFILT_MASK, TMC5271_SFILT_SHIFT, TMC5271_COOLCONF, false }) +#define TMC5271_DC_TIME_MASK 0x000003FF +#define TMC5271_DC_TIME_SHIFT 0 +#define TMC5271_DC_TIME_FIELD ((RegisterField) { TMC5271_DC_TIME_MASK, TMC5271_DC_TIME_SHIFT, TMC5271_DCCTRL, false }) +#define TMC5271_DC_SG_MASK 0x00FF0000 +#define TMC5271_DC_SG_SHIFT 16 +#define TMC5271_DC_SG_FIELD ((RegisterField) { TMC5271_DC_SG_MASK, TMC5271_DC_SG_SHIFT, TMC5271_DCCTRL, false }) +#define TMC5271_SG_RESULT_MASK 0x000003FF +#define TMC5271_SG_RESULT_SHIFT 0 +#define TMC5271_SG_RESULT_FIELD ((RegisterField) { TMC5271_SG_RESULT_MASK, TMC5271_SG_RESULT_SHIFT, TMC5271_DRV_STATUS, false }) +#define TMC5271_S2VSA_MASK 0x00001000 +#define TMC5271_S2VSA_SHIFT 12 +#define TMC5271_S2VSA_FIELD ((RegisterField) { TMC5271_S2VSA_MASK, TMC5271_S2VSA_SHIFT, TMC5271_DRV_STATUS, false }) +#define TMC5271_S2VSB_MASK 0x00002000 +#define TMC5271_S2VSB_SHIFT 13 +#define TMC5271_S2VSB_FIELD ((RegisterField) { TMC5271_S2VSB_MASK, TMC5271_S2VSB_SHIFT, TMC5271_DRV_STATUS, false }) +#define TMC5271_STEALTH_MASK 0x00004000 +#define TMC5271_STEALTH_SHIFT 14 +#define TMC5271_STEALTH_FIELD ((RegisterField) { TMC5271_STEALTH_MASK, TMC5271_STEALTH_SHIFT, TMC5271_DRV_STATUS, false }) +#define TMC5271_FSACTIVE_MASK 0x00008000 +#define TMC5271_FSACTIVE_SHIFT 15 +#define TMC5271_FSACTIVE_FIELD ((RegisterField) { TMC5271_FSACTIVE_MASK, TMC5271_FSACTIVE_SHIFT, TMC5271_DRV_STATUS, false }) +#define TMC5271_CS_ACTUAL_MASK 0x001F0000 +#define TMC5271_CS_ACTUAL_SHIFT 16 +#define TMC5271_CS_ACTUAL_FIELD ((RegisterField) { TMC5271_CS_ACTUAL_MASK, TMC5271_CS_ACTUAL_SHIFT, TMC5271_DRV_STATUS, false }) +#define TMC5271_STALLGUARD_MASK 0x01000000 +#define TMC5271_STALLGUARD_SHIFT 24 +#define TMC5271_STALLGUARD_FIELD ((RegisterField) { TMC5271_STALLGUARD_MASK, TMC5271_STALLGUARD_SHIFT, TMC5271_DRV_STATUS, false }) +#define TMC5271_OT_MASK 0x02000000 +#define TMC5271_OT_SHIFT 25 +#define TMC5271_OT_FIELD ((RegisterField) { TMC5271_OT_MASK, TMC5271_OT_SHIFT, TMC5271_DRV_STATUS, false }) +#define TMC5271_OTPW_MASK 0x04000000 +#define TMC5271_OTPW_SHIFT 26 +#define TMC5271_OTPW_FIELD ((RegisterField) { TMC5271_OTPW_MASK, TMC5271_OTPW_SHIFT, TMC5271_DRV_STATUS, false }) +#define TMC5271_S2GA_MASK 0x08000000 +#define TMC5271_S2GA_SHIFT 27 +#define TMC5271_S2GA_FIELD ((RegisterField) { TMC5271_S2GA_MASK, TMC5271_S2GA_SHIFT, TMC5271_DRV_STATUS, false }) +#define TMC5271_S2GB_MASK 0x10000000 +#define TMC5271_S2GB_SHIFT 28 +#define TMC5271_S2GB_FIELD ((RegisterField) { TMC5271_S2GB_MASK, TMC5271_S2GB_SHIFT, TMC5271_DRV_STATUS, false }) +#define TMC5271_OLA_MASK 0x20000000 +#define TMC5271_OLA_SHIFT 29 +#define TMC5271_OLA_FIELD ((RegisterField) { TMC5271_OLA_MASK, TMC5271_OLA_SHIFT, TMC5271_DRV_STATUS, false }) +#define TMC5271_OLB_MASK 0x40000000 +#define TMC5271_OLB_SHIFT 30 +#define TMC5271_OLB_FIELD ((RegisterField) { TMC5271_OLB_MASK, TMC5271_OLB_SHIFT, TMC5271_DRV_STATUS, false }) +#define TMC5271_STST_MASK 0x80000000 +#define TMC5271_STST_SHIFT 31 +#define TMC5271_STST_FIELD ((RegisterField) { TMC5271_STST_MASK, TMC5271_STST_SHIFT, TMC5271_DRV_STATUS, false }) +#define TMC5271_PWM_OFS_MASK 0x000000FF +#define TMC5271_PWM_OFS_SHIFT 0 +#define TMC5271_PWM_OFS_FIELD ((RegisterField) { TMC5271_PWM_OFS_MASK, TMC5271_PWM_OFS_SHIFT, TMC5271_PWMCONF, false }) +#define TMC5271_PWM_GRAD_MASK 0x0000FF00 +#define TMC5271_PWM_GRAD_SHIFT 8 +#define TMC5271_PWM_GRAD_FIELD ((RegisterField) { TMC5271_PWM_GRAD_MASK, TMC5271_PWM_GRAD_SHIFT, TMC5271_PWMCONF, false }) +#define TMC5271_PWM_FREQ_MASK 0x00030000 +#define TMC5271_PWM_FREQ_SHIFT 16 +#define TMC5271_PWM_FREQ_FIELD ((RegisterField) { TMC5271_PWM_FREQ_MASK, TMC5271_PWM_FREQ_SHIFT, TMC5271_PWMCONF, false }) +#define TMC5271_PWM_AUTOSCALE_MASK 0x00040000 +#define TMC5271_PWM_AUTOSCALE_SHIFT 18 +#define TMC5271_PWM_AUTOSCALE_FIELD ((RegisterField) { TMC5271_PWM_AUTOSCALE_MASK, TMC5271_PWM_AUTOSCALE_SHIFT, TMC5271_PWMCONF, false }) +#define TMC5271_PWM_AUTOGRAD_MASK 0x00080000 +#define TMC5271_PWM_AUTOGRAD_SHIFT 19 +#define TMC5271_PWM_AUTOGRAD_FIELD ((RegisterField) { TMC5271_PWM_AUTOGRAD_MASK, TMC5271_PWM_AUTOGRAD_SHIFT, TMC5271_PWMCONF, false }) +#define TMC5271_FREEWHEEL_MASK 0x00300000 +#define TMC5271_FREEWHEEL_SHIFT 20 +#define TMC5271_FREEWHEEL_FIELD ((RegisterField) { TMC5271_FREEWHEEL_MASK, TMC5271_FREEWHEEL_SHIFT, TMC5271_PWMCONF, false }) +#define TMC5271_PWM_MEAS_SD_ENABLE_MASK 0x00400000 +#define TMC5271_PWM_MEAS_SD_ENABLE_SHIFT 22 +#define TMC5271_PWM_MEAS_SD_ENABLE_FIELD ((RegisterField) { TMC5271_PWM_MEAS_SD_ENABLE_MASK, TMC5271_PWM_MEAS_SD_ENABLE_SHIFT, TMC5271_PWMCONF, false }) +#define TMC5271_PWM_DIS_REG_STST_MASK 0x00800000 +#define TMC5271_PWM_DIS_REG_STST_SHIFT 23 +#define TMC5271_PWM_DIS_REG_STST_FIELD ((RegisterField) { TMC5271_PWM_DIS_REG_STST_MASK, TMC5271_PWM_DIS_REG_STST_SHIFT, TMC5271_PWMCONF, false }) +#define TMC5271_PWM_REG_MASK 0x0F000000 +#define TMC5271_PWM_REG_SHIFT 24 +#define TMC5271_PWM_REG_FIELD ((RegisterField) { TMC5271_PWM_REG_MASK, TMC5271_PWM_REG_SHIFT, TMC5271_PWMCONF, false }) +#define TMC5271_PWM_LIM_MASK 0xF0000000 +#define TMC5271_PWM_LIM_SHIFT 28 +#define TMC5271_PWM_LIM_FIELD ((RegisterField) { TMC5271_PWM_LIM_MASK, TMC5271_PWM_LIM_SHIFT, TMC5271_PWMCONF, false }) +#define TMC5271_PWM_SCALE_SUM_MASK 0x000003FF +#define TMC5271_PWM_SCALE_SUM_SHIFT 0 +#define TMC5271_PWM_SCALE_SUM_FIELD ((RegisterField) { TMC5271_PWM_SCALE_SUM_MASK, TMC5271_PWM_SCALE_SUM_SHIFT, TMC5271_PWM_SCALE, false }) +#define TMC5271_PWM_SCALE_AUTO_MASK 0x01FF0000 +#define TMC5271_PWM_SCALE_AUTO_SHIFT 16 +#define TMC5271_PWM_SCALE_AUTO_FIELD ((RegisterField) { TMC5271_PWM_SCALE_AUTO_MASK, TMC5271_PWM_SCALE_AUTO_SHIFT, TMC5271_PWM_SCALE, false }) +#define TMC5271_PWM_OFS_AUTO_MASK 0x000000FF +#define TMC5271_PWM_OFS_AUTO_SHIFT 0 +#define TMC5271_PWM_OFS_AUTO_FIELD ((RegisterField) { TMC5271_PWM_OFS_AUTO_MASK, TMC5271_PWM_OFS_AUTO_SHIFT, TMC5271_PWM_AUTO, false }) +#define TMC5271_PWM_GRAD_AUTO_MASK 0x00FF0000 +#define TMC5271_PWM_GRAD_AUTO_SHIFT 16 +#define TMC5271_PWM_GRAD_AUTO_FIELD ((RegisterField) { TMC5271_PWM_GRAD_AUTO_MASK, TMC5271_PWM_GRAD_AUTO_SHIFT, TMC5271_PWM_AUTO, false }) +#define TMC5271_SG4_THRS_MASK 0x000000FF +#define TMC5271_SG4_THRS_SHIFT 0 +#define TMC5271_SG4_THRS_FIELD ((RegisterField) { TMC5271_SG4_THRS_MASK, TMC5271_SG4_THRS_SHIFT, TMC5271_SG4_THRS, false }) +#define TMC5271_SG4_FILT_EN_MASK 0x00000100 +#define TMC5271_SG4_FILT_EN_SHIFT 8 +#define TMC5271_SG4_FILT_EN_FIELD ((RegisterField) { TMC5271_SG4_FILT_EN_MASK, TMC5271_SG4_FILT_EN_SHIFT, TMC5271_SG4_THRS, false }) +#define TMC5271_SG_ANGLE_OFFSET_MASK 0x00000200 +#define TMC5271_SG_ANGLE_OFFSET_SHIFT 9 +#define TMC5271_SG_ANGLE_OFFSET_FIELD ((RegisterField) { TMC5271_SG_ANGLE_OFFSET_MASK, TMC5271_SG_ANGLE_OFFSET_SHIFT, TMC5271_SG4_THRS, false }) +#define TMC5271_SG4_RESULT_SG_RESULT_MASK 0x000003FF +#define TMC5271_SG4_RESULT_SG_RESULT_SHIFT 0 +#define TMC5271_SG4_RESULT_SG_RESULT_FIELD ((RegisterField) { TMC5271_SG4_RESULT_SG_RESULT_MASK, TMC5271_SG4_RESULT_SG_RESULT_SHIFT, TMC5271_SG4_RESULT, false }) +#define TMC5271_IND_0_MASK 0x000000FF +#define TMC5271_IND_0_SHIFT 0 +#define TMC5271_IND_0_FIELD ((RegisterField) { TMC5271_IND_0_MASK, TMC5271_IND_0_SHIFT, TMC5271_SG4_IND, false }) +#define TMC5271_IND_1_MASK 0x0000FF00 +#define TMC5271_IND_1_SHIFT 8 +#define TMC5271_IND_1_FIELD ((RegisterField) { TMC5271_IND_1_MASK, TMC5271_IND_1_SHIFT, TMC5271_SG4_IND, false }) +#define TMC5271_IND_2_MASK 0x00FF0000 +#define TMC5271_IND_2_SHIFT 16 +#define TMC5271_IND_2_FIELD ((RegisterField) { TMC5271_IND_2_MASK, TMC5271_IND_2_SHIFT, TMC5271_SG4_IND, false }) +#define TMC5271_IND_3_MASK 0xFF000000 +#define TMC5271_IND_3_SHIFT 24 +#define TMC5271_IND_3_FIELD ((RegisterField) { TMC5271_IND_3_MASK, TMC5271_IND_3_SHIFT, TMC5271_SG4_IND, false }) + +#endif diff --git a/firmware/lib/tmc/ic/TMC5271/registercall_hierarchy_flowchart_SPI.svg b/firmware/lib/tmc/ic/TMC5271/registercall_hierarchy_flowchart_SPI.svg new file mode 100755 index 0000000..cbad58f --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5271/registercall_hierarchy_flowchart_SPI.svg @@ -0,0 +1,3 @@ + + +

HAL

HAL

APP (Eval)

APP (Eval)

API

API
Read a register
  •  Call tmcXXXX_readRegister function
Read a register...
Returns the register read value
Returns the register read value
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
tmcXXXX.c
tmcXXXX.c
SPI.c
SPI.c
tmcXXXX_eval.c
tmcXXXX_eval.c

 Implementation of SPI_readWrite
  • Sends and receives bytes on the SPI bus
Implementation of SPI_readWrite...
Returns the raw reply data
Returns the raw reply data

Implementation of tmcXXXX_readWriteSPI
  • Sets the CSN pin to LOW
  • Takes the array of data to write
  • Calls hardware function SPI_readWrite
  • Upon completion of data transfer,
    sets CSN to 
    HIGH
Implementation of tmcXXXX_readWriteSPI...
Passes on the raw reply data to the API
Passes on the raw reply data to the API
Implementation of readRegisterSPI
  • Constructs the datagram
  • Calls HAL wrapper function 
Implementation of readRegisterSPI...
tmcXXXX_readWriteSPI
tmcXXXX_readWriteSPI
Parses the reply and returns the register value
Parses the reply and returns the register value
Implementation of tmcXXXX_readRegister 
  • Check which bus is active SPI/UART. (e.g. SPI)
  • Calls bus-specific function (e.g. readRegisterSPI)
 
Implementation of tmcXXXX_readRegister...
Returns the register read value
Returns the register read value
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC5271/registercall_hierarchy_flowchart_UART.svg b/firmware/lib/tmc/ic/TMC5271/registercall_hierarchy_flowchart_UART.svg new file mode 100755 index 0000000..425f60a --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5271/registercall_hierarchy_flowchart_UART.svg @@ -0,0 +1,3 @@ + + +

HAL

HAL

APP (Eval)

APP (Eval)

API

API
Read a register
  •  Call tmcXXXX_readRegister function
Read a register...
Returns the register read value
Returns the register read value
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
tmcXXXX.c
tmcXXXX.c
UART.c
UART.c
tmcXXXX_eval.c
tmcXXXX_eval.c

 Implementation of UART_readWrite
  • Sends and receives bytes on the UART bus
Implementation of UART_readWrite...
Returns the raw reply data
Returns the raw reply data

Implementation of tmcXXXX_readWriteUART
  • Takes the array of data to write
  • Calls hardware function UART_readWrite
Implementation of tmcXXXX_readWriteUART...
Passes on the raw reply data to the API
Passes on the raw reply data to the API
Implementation of readRegisterUART
  • Constructs the datagram
  • Calls HAL wrapper function 
Implementation of readRegisterUART...
tmcXXXX_readWriteUART
tmcXXXX_readWriteUART
Parses the reply and returns the register value
Parses the reply and returns the register value
Implementation of tmcXXXX_readRegister 
  • Check which bus is active SPI/UART. (e.g. UART)
  • Calls bus-specific function (e.g. readRegisterUART)
 
Implementation of tmcXXXX_readRegister...
Returns the register read value
Returns the register read value
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC5271/uml-tmc-api.svg b/firmware/lib/tmc/ic/TMC5271/uml-tmc-api.svg new file mode 100755 index 0000000..5a5f8dd --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5271/uml-tmc-api.svg @@ -0,0 +1,3 @@ + + +

TMCXXXX_HW_Abstraction.h



TMCXXXX_HW_Abstraction.h...
// Constants
#define TMCXXXX_MOTORS              
                          
// Register definitions
#define TMCXXXX_GCONF        
                          ⋮
// Register fields definitions
#define TMCXXXX_GCONF_OTPW_FIELD
                     
// Constants...

TMCXXXX.h



TMCXXXX.h...
extern void tmcXXXX_readWriteSPI();
extern void tmcXXXX_readWriteUART();
extern TMCXXXXBusType tmcXXXX_getBusType();
extern uint8_t tmcXXXX_getNodeAddress();
                                  ⋮
tmcXXXX_readRegister();
tmcXXXX_writeRegister();
                                  ⋮
extern void tmcXXXX_readWriteSPI();...

TMCXXXX.c



TMCXXXX.c...
const uint8_t tmcCRCTable_Poly7Reflected[256] = {...};
int32_t tmcXXXX_readRegister(){
/* Call tmcXXXX_getBusType();
 * Based on bus type, call readRegisterSPI/UART() that
 * further calls tmcXXXX_readWriteSPI/UART();
 * For UART it also calls tmcXXXX_getNodeAddress();
                                           ⋮
}
                                           ⋮
const uint8_t tmcCRCTable_Poly7Reflected[256] = {.....
TMC-API
TMC-API

TMCXXXX_Simple_Rotation.h


TMCXXXX_Simple_Rotation.h...
void initAllMotors();
             ⋮
  
void initAllMotors()...

TMCXXXX_Simple_Rotation.c


TMCXXXX_Simple_Rotation.c...
void initAllMotors(){

// Configuring registers to enable motor drivers etc..
tmcXXXX_writeRegister();
                    ⋮
}
                    ⋮
void initAllMotors(){...
Examples
Examples
User Project
User Project

User_Project.h


User_Project.h

User_Project.c








User_Project.c...

void tmcXXXX_readWriteSPI(){
                           ⋮
}
void tmcXXXX_readWriteUART(){
                           ⋮
}
TMCXXXXBusType tmcXXXX_getBusType(){
                           ⋮
}
uint8_t tmcXXXX_getNodeAddress(){
                           ⋮
}

// User Code
                           ⋮
void tmcXXXX_readWriteSPI(){...
#include "TMCXXXX_HW_Abstraction.h"
#include "TMCXXXX.h"
#include "TMCXXXX_Simple_Rotation.h"
                                ⋮
TMCXXXXBusType bus = IC_BUS_SPI/UART;
uint8_t nodeAddress = <nodeAddress>;
                                ⋮
#include "TMCXXXX_HW_Abstraction.h"...
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC5272/Examples/TMC5272_Simple_Rotation.c b/firmware/lib/tmc/ic/TMC5272/Examples/TMC5272_Simple_Rotation.c new file mode 100755 index 0000000..e3dca89 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5272/Examples/TMC5272_Simple_Rotation.c @@ -0,0 +1,37 @@ +/******************************************************************************* +* Copyright © 2023 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#include "TMC5272_Simple_Rotation.h" + +/* + * Configures the registers with the right settings that are needed for rotating both motors. + * E.g Enabling drivers, setting IRUN current etc. + */ +void initAllMotors(uint16_t icID) +{ + // Set IREF_R2 and IREF_R3 to High for setting the REF resistor to 10k. + // Run Current = 0.2A rms + // Hold Current = 0.14A rms + // Chopper Mode = SpreadCycle + + // For Motor 0 & 1 + tmc5272_writeRegister(icID, TMC5272_GCONF, 0x10024002); // writing value 0x10024002 = 268582914 = 0.0 to address 0 = 0x00(GCONF) + tmc5272_writeRegister(icID, TMC5272_DRV_CONF, 0x0000034D); // writing value 0x0000034D = 845 = 0.0 to address 3 = 0x05(DRV_CONF) + tmc5272_writeRegister(icID, TMC5272_GLOBAL_SCALER, 0xFBFBFBFB); // writing value 0xFBFBFBFB = 0 = 0.0 to address 4 = 0x06(GLOBAL_SCALER) + + // For Motor 0 + tmc5272_writeRegister(icID, TMC5272_IHOLD_IRUN(0), 0x04010F0A); // writing value 0x04011F0A = 67182346 = 0.0 to address 10 = 0x12(M0_IHOLD_IRUN) + tmc5272_writeRegister(icID, TMC5272_CHOPCONF(0), 0x10410153); // writing value 0x10410153 = 272695635 = 0.0 to address 39 = 0x38(M0_CHOPCONF) + tmc5272_writeRegister(icID, TMC5272_AMAX(0), 51200); // writing value to address 21 = 0x20(M0_AMAX) + + // For Motor 1 + tmc5272_writeRegister(icID, TMC5272_IHOLD_IRUN(1), 0x04010F0A); // writing value 0x04011F0A = 67182346 = 0.0 to address 10 = 0x12(M0_IHOLD_IRUN) + tmc5272_writeRegister(icID, TMC5272_CHOPCONF(1), 0x10410153); // writing value 0x10410153 = 272695635 = 0.0 to address 39 = 0x38(M0_CHOPCONF) + tmc5272_writeRegister(icID, TMC5272_AMAX(1), 51200); // writing value to address 21 = 0x20(M0_AMAX) + + // Enable Motor 0 & 1 + tmc5272_writeRegister(icID, TMC5272_GCONF, 0x00020002); // writing value 0x00020002 = 131074 = 0.0 to address 0 = 0x00(GCONF) +} diff --git a/firmware/lib/tmc/ic/TMC5272/Examples/TMC5272_Simple_Rotation.h b/firmware/lib/tmc/ic/TMC5272/Examples/TMC5272_Simple_Rotation.h new file mode 100755 index 0000000..ac942c2 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5272/Examples/TMC5272_Simple_Rotation.h @@ -0,0 +1,14 @@ +/******************************************************************************* +* Copyright © 2023 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#ifndef TMC5272_SIMPLE_ROTATION_H_ +#define TMC5272_SIMPLE_ROTATION_H_ + +#include "TMC5272.h" + +void initAllMotors(uint16_t icID); + +#endif diff --git a/firmware/lib/tmc/ic/TMC5272/README.md b/firmware/lib/tmc/ic/TMC5272/README.md new file mode 100755 index 0000000..f0b76bf --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5272/README.md @@ -0,0 +1,63 @@ +# TMC5272 + + +## How to use + +To access the TMC5272's registers, the TMC-API offers two functions: **tmc5272_readRegister** and **tmc5272_writeRegister**. +Each of these functions takes in an **icID**, which is used to identify the IC when multiple ICs are connected. This identifier is passed down to the callback functions (see How to Integrate). + +## How to integrate: overview + +1. Include all the files of the TMC-API/ic/tmc/TMC5272 folder into the custom project. +2. Include the TMC5272.h file in the custom source code. +3. Implement the necessary callback functions (see below). +4. (optional): Take a look at the Examples subfolder for ready-made examples of the TMC-API usage. + +## Accessing the TMC5272 via UART +The following diagram depicts how to access the TMC5272 via UART using the TMC-API. + +![screenshot](registercall_hierarchy_flowchart_UART.svg) + +The description of the functions, in the above flowchart, are as follows: +- The functions tmc5272_readRegister and tmc5272_writeRegister are used to read and write the registers respectively. These functions check the current active bus and calls the bus-specific function i.e readRegisterUART or writeRegisterUART. +- These bus specific functions constructs the datagram and further calls the bus specific callback 'tmcXXXX_readWriteUART. +- This callback function further calls the hardware specific read/write function for UART and needs to be implemented externally. + +### How to integrate: Callback functions +To communicate with TMC5272 IC, the TMC-API library needs to know which bus (UART, SPI) it shall use. For that, the callback function **'tmc5272_getBusType()'** needs to be implemented. +Additionally, implement the following callback functions to access the chip via UART: +1. **tmc5272_readWriteUART()**, which is a HAL wrapper function that provides the necessary hardware access. +2. **tmc5272_getNodeAddress()**, that returns the node/slave address. Node address could be set in NODECONF (0x3) register and the address could be incremented as defined by AD0, AD1 and AD2. (Node address + ADx) must be less than 255. For further details please consult the datasheet of TMC5272. + +### Sharing the CRC table with other TMC-API chips +The TMC5272 UART protocol uses an 8 bit CRC. For calculating this, a table-based algorithm is used. This table (tmcCRCTable_Poly7Reflected[256]) is 256 bytes big and identical across multiple different Trinamic chips (i.e. TMC2209). +If multiple Trinamic chips are being used in the same project, avoiding redundant copies of this table could save memory. It is possible to substitute this CRC table with another CRC table. + +## Accessing the TMC5272 via SPI +The following diagram depicts how to access the TMC5272 via SPI using the TMC-API. + +![screenshot](registercall_hierarchy_flowchart_SPI.svg) + +The description of the functions, in the above flowchart, are as follows: +- The functions tmc5272_readRegister and tmc5272_writeRegister are used to read and write the registers respectively. These functions check the current active bus and calls the bus-specific function i.e readRegisterSPI or writeRegisterSPI. +- These bus specific functions constructs the datagram and further calls the bus specific callback 'tmcXXXX_readWriteSPI. +- This callback function further calls the hardware specific read/write function for SPI and needs to be implemented externally. + +### How to integrate: Callback functions +To communicate with TMC5272 IC, the TMC-API library needs to know which bus (UART, SPI) it shall use. For that, the callback function **'tmc5272_getBusType()'** needs to be implemented. +Additionally, implement the following callback functions to access the chip via SPI: +1. **tmc5272_readWriteSPI()**, which is a HAL wrapper function that provides the necessary hardware access. This function should also set the chip select pin CSN to low before starting the data transfer and set to high upon completion. Please refer to the datasheet of the IC for further details. + +## Further info +### Dependency graph for the ICs with new register R/W mechanism +This graph illustrates the relationships between files within the TMC-API library, highlighting dependencies and identifying the files that are essential for integrating the library into the custom projects. + +![screenshot](uml-tmc-api.svg) + +### Example usage: TMC-Evalsystem +**For a reference usage of the TMC-API**, visit the [TMC-Evalsystem](https://github.com/analogdevicesinc/TMC-EvalSystem) + +## Migration status +The TMC5272 has been reworked to the access system described above. For more infos on the status of this and other ICs, check out the [migration page](https://github.com/analogdevicesinc/TMC-API/issues/53). + + diff --git a/firmware/lib/tmc/ic/TMC5272/TMC5272.c b/firmware/lib/tmc/ic/TMC5272/TMC5272.c new file mode 100755 index 0000000..fd24524 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5272/TMC5272.c @@ -0,0 +1,179 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#include "TMC5272.h" + + +#ifdef TMC_API_EXTERNAL_CRC_TABLE +extern const uint8_t tmcCRCTable_Poly7Reflected[256]; +#else +const uint8_t tmcCRCTable_Poly7Reflected[256] = { + 0x00, 0x91, 0xE3, 0x72, 0x07, 0x96, 0xE4, 0x75, 0x0E, 0x9F, 0xED, 0x7C, 0x09, 0x98, 0xEA, 0x7B, + 0x1C, 0x8D, 0xFF, 0x6E, 0x1B, 0x8A, 0xF8, 0x69, 0x12, 0x83, 0xF1, 0x60, 0x15, 0x84, 0xF6, 0x67, + 0x38, 0xA9, 0xDB, 0x4A, 0x3F, 0xAE, 0xDC, 0x4D, 0x36, 0xA7, 0xD5, 0x44, 0x31, 0xA0, 0xD2, 0x43, + 0x24, 0xB5, 0xC7, 0x56, 0x23, 0xB2, 0xC0, 0x51, 0x2A, 0xBB, 0xC9, 0x58, 0x2D, 0xBC, 0xCE, 0x5F, + 0x70, 0xE1, 0x93, 0x02, 0x77, 0xE6, 0x94, 0x05, 0x7E, 0xEF, 0x9D, 0x0C, 0x79, 0xE8, 0x9A, 0x0B, + 0x6C, 0xFD, 0x8F, 0x1E, 0x6B, 0xFA, 0x88, 0x19, 0x62, 0xF3, 0x81, 0x10, 0x65, 0xF4, 0x86, 0x17, + 0x48, 0xD9, 0xAB, 0x3A, 0x4F, 0xDE, 0xAC, 0x3D, 0x46, 0xD7, 0xA5, 0x34, 0x41, 0xD0, 0xA2, 0x33, + 0x54, 0xC5, 0xB7, 0x26, 0x53, 0xC2, 0xB0, 0x21, 0x5A, 0xCB, 0xB9, 0x28, 0x5D, 0xCC, 0xBE, 0x2F, + 0xE0, 0x71, 0x03, 0x92, 0xE7, 0x76, 0x04, 0x95, 0xEE, 0x7F, 0x0D, 0x9C, 0xE9, 0x78, 0x0A, 0x9B, + 0xFC, 0x6D, 0x1F, 0x8E, 0xFB, 0x6A, 0x18, 0x89, 0xF2, 0x63, 0x11, 0x80, 0xF5, 0x64, 0x16, 0x87, + 0xD8, 0x49, 0x3B, 0xAA, 0xDF, 0x4E, 0x3C, 0xAD, 0xD6, 0x47, 0x35, 0xA4, 0xD1, 0x40, 0x32, 0xA3, + 0xC4, 0x55, 0x27, 0xB6, 0xC3, 0x52, 0x20, 0xB1, 0xCA, 0x5B, 0x29, 0xB8, 0xCD, 0x5C, 0x2E, 0xBF, + 0x90, 0x01, 0x73, 0xE2, 0x97, 0x06, 0x74, 0xE5, 0x9E, 0x0F, 0x7D, 0xEC, 0x99, 0x08, 0x7A, 0xEB, + 0x8C, 0x1D, 0x6F, 0xFE, 0x8B, 0x1A, 0x68, 0xF9, 0x82, 0x13, 0x61, 0xF0, 0x85, 0x14, 0x66, 0xF7, + 0xA8, 0x39, 0x4B, 0xDA, 0xAF, 0x3E, 0x4C, 0xDD, 0xA6, 0x37, 0x45, 0xD4, 0xA1, 0x30, 0x42, 0xD3, + 0xB4, 0x25, 0x57, 0xC6, 0xB3, 0x22, 0x50, 0xC1, 0xBA, 0x2B, 0x59, 0xC8, 0xBD, 0x2C, 0x5E, 0xCF, +}; +#endif + +static int32_t readRegisterSPI(uint16_t icID, uint8_t address); +static void writeRegisterSPI(uint16_t icID, uint8_t address, int32_t value); +static int32_t readRegisterUART(uint16_t icID, uint8_t registerAddress); +static void writeRegisterUART(uint16_t icID, uint8_t registerAddress, int32_t value); +static uint8_t CRC8(uint8_t *data, uint32_t bytes); + + +int32_t tmc5272_readRegister(uint16_t icID, uint8_t address) +{ + TMC5272BusType bus = tmc5272_getBusType(icID); + + if(bus == IC_BUS_SPI) + { + return readRegisterSPI(icID, address); + } + else if (bus == IC_BUS_UART) + { + return readRegisterUART(icID, address); + } + + // ToDo: Error handling + return -1; +} +void tmc5272_writeRegister(uint16_t icID, uint8_t address, int32_t value) +{ + TMC5272BusType bus = tmc5272_getBusType(icID); + + if(bus == IC_BUS_SPI) + { + writeRegisterSPI(icID, address, value); + } + else if(bus == IC_BUS_UART) + { + writeRegisterUART(icID, address, value); + } +} + +int32_t readRegisterSPI(uint16_t icID, uint8_t address) +{ + uint8_t data[5] = { 0 }; + + // clear write bit + data[0] = address & TMC5272_ADDRESS_MASK; + + // Send the read request + tmc5272_readWriteSPI(icID, &data[0], sizeof(data)); + + // Rewrite address and clear write bit + data[0] = address & TMC5272_ADDRESS_MASK; + + // Send another request to receive the read reply + tmc5272_readWriteSPI(icID, &data[0], sizeof(data)); + + return ((int32_t)data[1] << 24) | ((int32_t) data[2] << 16) | ((int32_t) data[3] << 8) | ((int32_t) data[4]); +} + +void writeRegisterSPI(uint16_t icID, uint8_t address, int32_t value) +{ + uint8_t data[5] = { 0 }; + + data[0] = address | TMC5272_WRITE_BIT; + data[1] = 0xFF & (value>>24); + data[2] = 0xFF & (value>>16); + data[3] = 0xFF & (value>>8); + data[4] = 0xFF & (value>>0); + + // Send the write request + tmc5272_readWriteSPI(icID, &data[0], sizeof(data)); +} + +int32_t readRegisterUART(uint16_t icID, uint8_t registerAddress) +{ + uint8_t data[8] = { 0 }; + + registerAddress = registerAddress & TMC5272_ADDRESS_MASK; + + data[0] = 0x05; + data[1] = tmc5272_getNodeAddress(icID); + data[2] = registerAddress; + data[3] = CRC8(data, 3); + + if (!tmc5272_readWriteUART(icID, &data[0], 4, 8)) + return 0; + + // Byte 0: Sync nibble correct? + if (data[0] != 0x05) + return 0; + + // Byte 1: Master address correct? + if (data[1] != 0xFF) + return 0; + + // Byte 2: Address correct? + if (data[2] != registerAddress) + return 0; + + // Byte 7: CRC correct? + if (data[7] != CRC8(data, 7)) + return 0; + + return ((uint32_t)data[3] << 24) | ((uint32_t)data[4] << 16) | (data[5] << 8) | data[6]; +} + +void writeRegisterUART(uint16_t icID, uint8_t registerAddress, int32_t value) +{ + uint8_t data[8]; + + data[0] = 0x05; + data[1] = tmc5272_getNodeAddress(icID); + data[2] = registerAddress | TMC5272_WRITE_BIT; + data[3] = (value >> 24) & 0xFF; + data[4] = (value >> 16) & 0xFF; + data[5] = (value >> 8 ) & 0xFF; + data[6] = (value ) & 0xFF; + data[7] = CRC8(data, 7); + + tmc5272_readWriteUART(icID, &data[0], 8, 0); +} + +void tmc5272_rotateMotor(uint16_t icID, uint8_t motor, int32_t velocity) +{ + if(motor >= TMC5272_MOTORS) + return; + + tmc5272_writeRegister(icID, TMC5272_VMAX(motor), (velocity >= 0)? velocity : -velocity); + tmc5272_fieldWrite(icID, TMC5272_RAMPMODE_FIELD(motor), (velocity >= 0) ? TMC5272_MODE_VELPOS : TMC5272_MODE_VELNEG); +} + +static uint8_t CRC8(uint8_t *data, uint32_t bytes) +{ + uint8_t result = 0; + while(bytes--) + result = tmcCRCTable_Poly7Reflected[result ^ *data++]; + + // Flip the result around + // swap odd and even bits + result = ((result >> 1) & 0x55) | ((result & 0x55) << 1); + // swap consecutive pairs + result = ((result >> 2) & 0x33) | ((result & 0x33) << 2); + // swap nibbles ... + result = ((result >> 4) & 0x0F) | ((result & 0x0F) << 4); + + return result; +} diff --git a/firmware/lib/tmc/ic/TMC5272/TMC5272.h b/firmware/lib/tmc/ic/TMC5272/TMC5272.h new file mode 100755 index 0000000..cc934ca --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5272/TMC5272.h @@ -0,0 +1,115 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#ifndef TMC_IC_TMC5272_H_ +#define TMC_IC_TMC5272_H_ + +#include +#include +#include +#include "TMC5272_HW_Abstraction.h" + +/******************************************************************************* +* API Configuration Defines +* These control optional features of the TMC-API implementation. +* These can be commented in/out here or defined from the build system. +*******************************************************************************/ + +// Uncomment if you want to save space..... +// and put the table into your own .c file +//#define TMC_API_EXTERNAL_CRC_TABLE 1 + +// Default Register values +#define R00 0x00000008 // GCONF +#define R0A 0x00000020 // DRVCONF +#define R10 0x00070A03 // IHOLD_IRUN +#define R11 0x0000000A // TPOWERDOWN +#define R2A 0x0000000A // D1 +#define R2B 0x0000000A // VSTOP +#define R30 0x0000000A // D2 + +#define R3A 0x00010000 // ENC_CONST + +#define R52 0x0B920F25 // OTW_OV_VTH +#define R60 0xAAAAB554 // MSLUT[0] +#define R61 0x4A9554AA // MSLUT[1] +#define R62 0x24492929 // MSLUT[2] +#define R63 0x10104222 // MSLUT[3] +#define R64 0xFBFFFFFF // MSLUT[4] +#define R65 0xB5BB777D // MSLUT[5] +#define R66 0x49295556 // MSLUT[6] +#define R67 0x00404222 // MSLUT[7] +#define R68 0xFFFF8056 // MSLUT[8] +#define R69 0x00F70000 // MSLUT[9] + +#define R6C 0x00410153 // CHOPCONF +#define R70 0xC44C001E // PWMCONF +#define R74 0x00000000 // PWMCONF + +typedef enum { + IC_BUS_SPI, + IC_BUS_UART, +} TMC5272BusType; + +// => TMC-API wrapper +extern void tmc5272_readWriteSPI(uint16_t icID, uint8_t *data, size_t dataLength); +extern bool tmc5272_readWriteUART(uint16_t icID, uint8_t *data, size_t writeLength, size_t readLength); +extern TMC5272BusType tmc5272_getBusType(uint16_t icID); +extern uint8_t tmc5272_getNodeAddress(uint16_t icID); +// => TMC-API wrapper + +int32_t tmc5272_readRegister(uint16_t icID, uint8_t address); +void tmc5272_writeRegister(uint16_t icID, uint8_t address, int32_t value); +void tmc5272_rotateMotor(uint16_t icID, uint8_t motor, int32_t velocity); + +typedef struct +{ + uint32_t mask; + uint8_t shift; + uint8_t address; + bool isSigned; +} RegisterField; + +static inline uint32_t tmc5272_fieldExtract(uint32_t data, RegisterField field) +{ + uint32_t value = (data & field.mask) >> field.shift; + + if (field.isSigned) + { + // Apply signedness conversion + uint32_t baseMask = field.mask >> field.shift; + uint32_t signMask = baseMask & (~baseMask >> 1); + value = (value ^ signMask) - signMask; + } + + return value; +} + +static inline uint32_t tmc5272_fieldRead(uint16_t icID, RegisterField field) +{ + uint32_t value = tmc5272_readRegister(icID, field.address); + + return tmc5272_fieldExtract(value, field); +} + +static inline uint32_t tmc5272_fieldUpdate(uint32_t data, RegisterField field, uint32_t value) +{ + return (data & (~field.mask)) | ((value << field.shift) & field.mask); +} + +static inline void tmc5272_fieldWrite(uint16_t icID, RegisterField field, uint32_t value) +{ + uint32_t regValue = tmc5272_readRegister(icID, field.address); + + regValue = tmc5272_fieldUpdate(regValue, field, value); + + tmc5272_writeRegister(icID, field.address, regValue); +} + +#endif /* TMC_IC_TMC5272_H_ */ diff --git a/firmware/lib/tmc/ic/TMC5272/TMC5272_HW_Abstraction.h b/firmware/lib/tmc/ic/TMC5272/TMC5272_HW_Abstraction.h new file mode 100755 index 0000000..60ebafa --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5272/TMC5272_HW_Abstraction.h @@ -0,0 +1,735 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + +#ifndef TMC5272_HW_ABSTRACTION +#define TMC5272_HW_ABSTRACTION + +// Constants +#define TMC5272_REGISTER_COUNT 128 +#define TMC5272_MOTORS 2 +#define TMC5272_WRITE_BIT 0x80 +#define TMC5272_ADDRESS_MASK 0x7F +#define TMC5272_MAX_VELOCITY 8388096 +#define TMC5272_MAX_ACCELERATION UINTN_MAX + +// Ramp modes (Register TMC5272_RAMPMODE) +#define TMC5272_MODE_POSITION 0 +#define TMC5272_MODE_VELPOS 1 +#define TMC5272_MODE_VELNEG 2 +#define TMC5272_MODE_HOLD 3 + +// Registers in TMC5272 + +#define MOTOR_ADDR(m) (0x35 * m) + +#define TMC5272_GCONF 0x00 +#define TMC5272_GSTAT 0x01 +#define TMC5272_IFCNT 0x02 +#define TMC5272_SLAVECONF 0x03 +#define TMC5272_IOIN 0x04 +#define TMC5272_DRV_CONF 0x05 +#define TMC5272_GLOBAL_SCALER 0x06 +#define TMC5272_RAMPMODE 0x07 +#define TMC5272_MSLUT_ADDR 0x08 +#define TMC5272_MSLUT_DATA 0x09 + + // motor = 0 motor = 1 +#define TMC5272_X_COMPARE(motor) (0x10 + MOTOR_ADDR(motor)) // 0x10 0x45 +#define TMC5272_X_COMPARE_REPEAT(motor) (0x11 + MOTOR_ADDR(motor)) // 0x11 0x46 +#define TMC5272_IHOLD_IRUN(motor) (0x12 + MOTOR_ADDR(motor)) // 0x12 0x47 +#define TMC5272_TPOWERDOWN(motor) (0x13 + MOTOR_ADDR(motor)) // 0x13 0x48 +#define TMC5272_TSTEP(motor) (0x14 + MOTOR_ADDR(motor)) // 0x14 0x49 +#define TMC5272_TPWMTHRS(motor) (0x15 + MOTOR_ADDR(motor)) // 0x15 0x4A +#define TMC5272_TCOOLTHRS(motor) (0x16 + MOTOR_ADDR(motor)) // 0x16 0x4B +#define TMC5272_THIGH(motor) (0x17 + MOTOR_ADDR(motor)) // 0x17 0x4C +#define TMC5272_XACTUAL(motor) (0x18 + MOTOR_ADDR(motor)) // 0x18 0x4D +#define TMC5272_VACTUAL(motor) (0x19 + MOTOR_ADDR(motor)) // 0x19 0x4E +#define TMC5272_AACTUAL(motor) (0x1A + MOTOR_ADDR(motor)) // 0x1A 0x4F +#define TMC5272_VSTART(motor) (0x1B + MOTOR_ADDR(motor)) // 0x1B 0x50 +#define TMC5272_A1(motor) (0x1C + MOTOR_ADDR(motor)) // 0x1C 0x51 +#define TMC5272_V1(motor) (0x1D + MOTOR_ADDR(motor)) // 0x1D 0x52 +#define TMC5272_A2(motor) (0x1E + MOTOR_ADDR(motor)) // 0x1E 0x53 +#define TMC5272_V2(motor) (0x1F + MOTOR_ADDR(motor)) // 0x1F 0x54 +#define TMC5272_AMAX(motor) (0x20 + MOTOR_ADDR(motor)) // 0x20 0x55 +#define TMC5272_VMAX(motor) (0x21 + MOTOR_ADDR(motor)) // 0x21 0x56 +#define TMC5272_DMAX(motor) (0x22 + MOTOR_ADDR(motor)) // 0x22 0x57 +#define TMC5272_D2(motor) (0x23 + MOTOR_ADDR(motor)) // 0x23 0x58 +#define TMC5272_D1(motor) (0x24 + MOTOR_ADDR(motor)) // 0x24 0x59 +#define TMC5272_VSTOP(motor) (0x25 + MOTOR_ADDR(motor)) // 0x25 0x5A +#define TMC5272_TVMAX(motor) (0x26 + MOTOR_ADDR(motor)) // 0x26 0x5B +#define TMC5272_TZEROWAIT(motor) (0x27 + MOTOR_ADDR(motor)) // 0x27 0x5C +#define TMC5272_XTARGET(motor) (0x28 + MOTOR_ADDR(motor)) // 0x28 0x5D +#define TMC5272_VDCMIN(motor) (0x29 + MOTOR_ADDR(motor)) // 0x29 0x5E +#define TMC5272_SW_MODE(motor) (0x2A + MOTOR_ADDR(motor)) // 0x2A 0x5F +#define TMC5272_RAMP_STAT(motor) (0x2B + MOTOR_ADDR(motor)) // 0x2B 0x60 +#define TMC5272_XLATCH(motor) (0x2C + MOTOR_ADDR(motor)) // 0x2C 0x61 +#define TMC5272_POSITION_PI_CTRL(motor) (0x2D + MOTOR_ADDR(motor)) // 0x2D 0x62 +#define TMC5272_X_ENC(motor) (0x2E + MOTOR_ADDR(motor)) // 0x2E 0x63 +#define TMC5272_ENCMODE(motor) (0x2F + MOTOR_ADDR(motor)) // 0x2F 0x64 +#define TMC5272_ENC_CONST(motor) (0x30 + MOTOR_ADDR(motor)) // 0x30 0x65 +#define TMC5272_ENC_STATUS(motor) (0x31 + MOTOR_ADDR(motor)) // 0x31 0x66 +#define TMC5272_ENC_LATCH(motor) (0x32 + MOTOR_ADDR(motor)) // 0x32 0x67 +#define TMC5272_ENC_DEVIATION(motor) (0x33 + MOTOR_ADDR(motor)) // 0x33 0x68 +#define TMC5272_VIRTUAL_STOP_L(motor) (0x34 + MOTOR_ADDR(motor)) // 0x34 0x69 +#define TMC5272_VIRTUAL_STOP_R(motor) (0x35 + MOTOR_ADDR(motor)) // 0x35 0x6A +#define TMC5272_MSCNT(motor) (0x36 + MOTOR_ADDR(motor)) // 0x36 0x6B +#define TMC5272_MSCURACT(motor) (0x37 + MOTOR_ADDR(motor)) // 0x37 0x6C +#define TMC5272_CHOPCONF(motor) (0x38 + MOTOR_ADDR(motor)) // 0x38 0x6D +#define TMC5272_COOLCONF(motor) (0x39 + MOTOR_ADDR(motor)) // 0x39 0x6E +#define TMC5272_DCCTRL(motor) (0x3A + MOTOR_ADDR(motor)) // 0x3A 0x6F +#define TMC5272_DRV_STATUS(motor) (0x3B + MOTOR_ADDR(motor)) // 0x3B 0x70 +#define TMC5272_PWMCONF(motor) (0x3C + MOTOR_ADDR(motor)) // 0x3C 0x71 +#define TMC5272_PWM_SCALE(motor) (0x3D + MOTOR_ADDR(motor)) // 0x3D 0x72 +#define TMC5272_PWM_AUTO(motor) (0x3E + MOTOR_ADDR(motor)) // 0x3E 0x73 +#define TMC5272_SG4_THRS(motor) (0x3F + MOTOR_ADDR(motor)) // 0x3F 0x74 +#define TMC5272_SG4_RESULT(motor) (0x40 + MOTOR_ADDR(motor)) // 0x40 0x75 +#define TMC5272_SG4_IND(motor) (0x41 + MOTOR_ADDR(motor)) // 0x41 0x76 + +// Register fields in TMC5272 + +#define TMC5272_GCONF_M0_EN_PWM_MODE_MASK 0x00000001 +#define TMC5272_GCONF_M0_EN_PWM_MODE_SHIFT 0 +#define TMC5272_GCONF_M0_EN_PWM_MODE_FIELD ((RegisterField) { TMC5272_GCONF_M0_EN_PWM_MODE_MASK, TMC5272_GCONF_M0_EN_PWM_MODE_SHIFT, TMC5272_GCONF, false }) +#define TMC5272_GCONF_M0_MULTISTEP_FILT_MASK 0x00000002 +#define TMC5272_GCONF_M0_MULTISTEP_FILT_SHIFT 1 +#define TMC5272_GCONF_M0_MULTISTEP_FILT_FIELD ((RegisterField) { TMC5272_GCONF_M0_MULTISTEP_FILT_MASK, TMC5272_GCONF_M0_MULTISTEP_FILT_SHIFT, TMC5272_GCONF, false }) +#define TMC5272_GCONF_M0_SHAFT_MASK 0x00000004 +#define TMC5272_GCONF_M0_SHAFT_SHIFT 2 +#define TMC5272_GCONF_M0_SHAFT_FIELD(motor) ((RegisterField) { TMC5272_GCONF_M0_SHAFT_MASK, TMC5272_GCONF_M0_SHAFT_SHIFT, TMC5272_GCONF, false }) +#define TMC5272_GCONF_M0_DIAG0_ERROR_MASK 0x00000008 +#define TMC5272_GCONF_M0_DIAG0_ERROR_SHIFT 3 +#define TMC5272_GCONF_M0_DIAG0_ERROR_FIELD ((RegisterField) { TMC5272_GCONF_M0_DIAG0_ERROR_MASK, TMC5272_GCONF_M0_DIAG0_ERROR_SHIFT, TMC5272_GCONF, false }) +#define TMC5272_GCONF_DIAG0_OTPW_MASK 0x00000010 +#define TMC5272_GCONF_DIAG0_OTPW_SHIFT 4 +#define TMC5272_GCONF_DIAG0_OTPW_FIELD ((RegisterField) { TMC5272_GCONF_DIAG0_OTPW_MASK, TMC5272_GCONF_DIAG0_OTPW_SHIFT, TMC5272_GCONF, false }) +#define TMC5272_GCONF_DIAG0_STALL_STEP_MASK 0x00000020 +#define TMC5272_GCONF_DIAG0_STALL_STEP_SHIFT 5 +#define TMC5272_GCONF_DIAG0_STALL_STEP_SHIF ((RegisterField) { TMC5272_GCONF_DIAG0_OTPW_MASK, TMC5272_GCONF_DIAG0_OTPW_SHIFT, TMC5272_GCONF, false }) +#define TMC5272_GCONF_DIAG1_STALL_DIR_MASK 0x00000040 +#define TMC5272_GCONF_DIAG1_STALL_DIR_SHIFT 6 +#define TMC5272_GCONF_DIAG1_STALL_DIR_FIELD ((RegisterField) { TMC5272_GCONF_DIAG1_STALL_DIR_MASK, TMC5272_GCONF_DIAG1_STALL_DIR_SHIFT, TMC5272_GCONF, false }) +#define TMC5272_GCONF_M0_DIAG1_INDEX_MASK 0x00000080 +#define TMC5272_GCONF_M0_DIAG1_INDEX_SHIFT 7 +#define TMC5272_GCONF_M0_DIAG1_INDEX_FIELD ((RegisterField) { TMC5272_GCONF_M0_DIAG1_INDEX_MASK, TMC5272_GCONF_M0_DIAG1_INDEX_SHIFT, TMC5272_GCONF, false }) +#define TMC5272_GCONF_DIAG0_INT_PUSHPULL_MASK 0x00000100 +#define TMC5272_GCONF_DIAG0_INT_PUSHPULL_SHIFT 8 +#define TMC5272_GCONF_DIAG0_INT_PUSHPULL_FIELD ((RegisterField) { TMC5272_GCONF_M0_DIAG1_INDEX_MASK, TMC5272_GCONF_M0_DIAG1_INDEX_SHIFT, TMC5272_GCONF, false }) +#define TMC5272_GCONF_DIAG1_POSCOMP_PUSHPULL_MASK 0x00000200 +#define TMC5272_GCONF_DIAG1_POSCOMP_PUSHPULL_SHIFT 9 +#define TMC5272_GCONF_DIAG1_POSCOMP_PUSHPULL_FIELD ((RegisterField) { TMC5272_GCONF_DIAG1_POSCOMP_PUSHPULL_MASK, TMC5272_GCONF_DIAG1_POSCOMP_PUSHPULL_SHIFT, TMC5272_GCONF, false }) +#define TMC5272_GCONF_M0_SMALL_HYSTERESIS_MASK 0x00000400 +#define TMC5272_GCONF_M0_SMALL_HYSTERESIS_SHIFT 10 +#define TMC5272_GCONF_M0_SMALL_HYSTERESIS_FIELD ((RegisterField) { TMC5272_GCONF_M0_SMALL_HYSTERESIS_MASK, TMC5272_GCONF_M0_SMALL_HYSTERESIS_SHIFT, TMC5272_GCONF, false }) +#define TMC5272_GCONF_M0_STOP_ENABLE_MASK 0x00000800 +#define TMC5272_GCONF_M0_STOP_ENABLE_SHIFT 11 +#define TMC5272_GCONF_M0_STOP_ENABLE_FIELD ((RegisterField) { TMC5272_GCONF_M0_STOP_ENABLE_MASK, TMC5272_GCONF_M0_STOP_ENABLE_SHIFT, TMC5272_GCONF, false }) +#define TMC5272_GCONF_M0_DIRECT_MODE_MASK 0x00001000 +#define TMC5272_GCONF_M0_DIRECT_MODE_SHIFT 12 +#define TMC5272_GCONF_M0_DIRECT_MODE_FIELD ((RegisterField) { TMC5272_GCONF_M0_DIRECT_MODE_MASK, TMC5272_GCONF_M0_DIRECT_MODE_SHIFT, TMC5272_GCONF, false }) +#define TMC5272_GCONF_M0_SD_MASK 0x00002000 +#define TMC5272_GCONF_M0_SD_SHIFT 13 +#define TMC5272_GCONF_M0_SD_FIELD ((RegisterField) { TMC5272_GCONF_M0_SD_MASK, TMC5272_GCONF_M0_SD_SHIFT, TMC5272_GCONF, false }) +#define TMC5272_GCONF_M0_DRV_ENN_MASK 0x00004000 +#define TMC5272_GCONF_M0_DRV_ENN_SHIFT 14 +#define TMC5272_GCONF_M0_DRV_ENN_FIELD ((RegisterField) { TMC5272_GCONF_M0_DRV_ENN_MASK, TMC5272_GCONF_M0_DRV_ENN_SHIFT, TMC5272_GCONF, false }) +#define TMC5272_GCONF_M1_EN_PWM_MODE_MASK 0x00010000 +#define TMC5272_GCONF_M1_EN_PWM_MODE_SHIFT 16 +#define TMC5272_GCONF_M1_EN_PWM_MODE_FIELD ((RegisterField) { TMC5272_GCONF_M1_EN_PWM_MODE_MASK, TMC5272_GCONF_M1_EN_PWM_MODE_SHIFT, TMC5272_GCONF, false }) +#define TMC5272_GCONF_M1_MULTISTEP_FILT_MASK 0x00020000 +#define TMC5272_GCONF_M1_MULTISTEP_FILT_SHIFT 17 +#define TMC5272_GCONF_M1_MULTISTEP_FILT_FIELD ((RegisterField) { TMC5272_GCONF_M1_MULTISTEP_FILT_MASK, TMC5272_GCONF_M1_MULTISTEP_FILT_SHIFT, TMC5272_GCONF, false }) +#define TMC5272_GCONF_M1_SHAFT_MASK 0x00040000 +#define TMC5272_GCONF_M1_SHAFT_SHIFT 18 +#define TMC5272_GCONF_M1_SHAFT_FIELD ((RegisterField) { TMC5272_GCONF_M1_SHAFT_MASK, TMC5272_GCONF_M1_SHAFT_SHIFT, TMC5272_GCONF, false }) +#define TMC5272_GCONF_DIAG0_INTOUT_SEL_MASK 0x00180000 +#define TMC5272_GCONF_DIAG0_INTOUT_SEL_SHIFT 19 +#define TMC5272_GCONF_DIAG0_INTOUT_SEL_FIELD ((RegisterField) { TMC5272_GCONF_DIAG0_INTOUT_SEL_MASK, TMC5272_GCONF_DIAG0_INTOUT_SEL_SHIFT, TMC5272_GCONF, false }) +#define TMC5272_GCONF_DIAG1_X_COMP_SEL_MASK 0x00600000 +#define TMC5272_GCONF_DIAG1_X_COMP_SEL_SHIFT 21 +#define TMC5272_GCONF_DIAG1_X_COMP_SEL_FIELD ((RegisterField) { TMC5272_GCONF_DIAG1_X_COMP_SEL_MASK, TMC5272_GCONF_DIAG1_X_COMP_SEL_SHIFT, TMC5272_GCONF, false }) +#define TMC5272_GCONF_M1_DIAG1_INDEX_MASK 0x00800000 +#define TMC5272_GCONF_M1_DIAG1_INDEX_SHIFT 23 +#define TMC5272_GCONF_M1_DIAG1_INDEX_FIELD ((RegisterField) { TMC5272_GCONF_M1_DIAG1_INDEX_MASK, TMC5272_GCONF_M1_DIAG1_INDEX_SHIFT, TMC5272_GCONF, false }) +#define TMC5272_GCONF_M1_SMALL_HYSTERESIS_MASK 0x01000000 +#define TMC5272_GCONF_M1_SMALL_HYSTERESIS_SHIFT 24 +#define TMC5272_GCONF_M1_SMALL_HYSTERESIS_FIELD ((RegisterField) { TMC5272_GCONF_M1_DIAG1_INDEX_MASK, TMC5272_GCONF_M1_DIAG1_INDEX_SHIFT, TMC5272_GCONF, false }) +#define TMC5272_GCONF_M1_STOP_ENABLE_MASK 0x02000000 +#define TMC5272_GCONF_M1_STOP_ENABLE_SHIFT 25 +#define TMC5272_GCONF_M1_STOP_ENABLE_FIELD ((RegisterField) { TMC5272_GCONF_M1_STOP_ENABLE_MASK, TMC5272_GCONF_M1_STOP_ENABLE_SHIFT, TMC5272_GCONF, false }) +#define TMC5272_GCONF_M1_DIRECT_MODE_MASK 0x04000000 +#define TMC5272_GCONF_M1_DIRECT_MODE_SHIFT 26 +#define TMC5272_GCONF_M1_DIRECT_MODE_FIELD ((RegisterField) { TMC5272_GCONF_M1_DIRECT_MODE_MASK, TMC5272_GCONF_M1_DIRECT_MODE_SHIFT, TMC5272_GCONF, false }) +#define TMC5272_GCONF_M1_SD_MASK 0x08000000 +#define TMC5272_GCONF_M1_SD_SHIFT 27 +#define TMC5272_GCONF_M1_SD_FIELD ((RegisterField) { TMC5272_GCONF_M1_SD_MASK, TMC5272_GCONF_M1_SD_SHIFT, TMC5272_GCONF, false }) +#define TMC5272_GCONF_M1_DRV_ENN_MASK 0x10000000 +#define TMC5272_GCONF_M1_DRV_ENN_SHIFT 28 +#define TMC5272_GCONF_M1_DRV_ENN_FIELD ((RegisterField) { TMC5272_GCONF_M1_DRV_ENN_MASK, TMC5272_GCONF_M1_DRV_ENN_SHIFT, TMC5272_GCONF, false }) +#define TMC5272_GSTAT_RESET_MASK 0x00000001 +#define TMC5272_GSTAT_RESET_SHIFT 0 +#define TMC5272_GSTAT_RESET_FIELD ((RegisterField) { TMC5272_GSTAT_RESET_MASK, TMC5272_GSTAT_RESET_SHIFT, TMC5272_GSTAT, false }) +#define TMC5272_GSTAT_M0_DRV_ERR_MASK 0x00000002 +#define TMC5272_GSTAT_M0_DRV_ERR_SHIFT 1 +#define TMC5272_GSTAT_M0_DRV_ERR_FIELD ((RegisterField) { TMC5272_GSTAT_M0_DRV_ERR_MASK, TMC5272_GSTAT_M0_DRV_ERR_SHIFT, TMC5272_GSTAT, false }) +#define TMC5272_GSTAT_UV_CP_MASK 0x00000004 +#define TMC5272_GSTAT_UV_CP_SHIFT 2 +#define TMC5272_GSTAT_UV_CP_FIELD ((RegisterField) { TMC5272_GSTAT_UV_CP_MASK, TMC5272_GSTAT_UV_CP_SHIFT, TMC5272_GSTAT, false }) +#define TMC5272_GSTAT_REGISTER_RESET_MASK 0x00000008 +#define TMC5272_GSTAT_REGISTER_RESET_SHIFT 3 +#define TMC5272_GSTAT_REGISTER_RESET_FIELD ((RegisterField) { TMC5272_GSTAT_REGISTER_RESET_MASK, TMC5272_GSTAT_REGISTER_RESET_SHIFT, TMC5272_GSTAT, false }) +#define TMC5272_GSTAT_VM_UVLO_MASK 0x00000010 +#define TMC5272_GSTAT_VM_UVLO_SHIFT 4 +#define TMC5272_GSTAT_VM_UVLO_FIELD ((RegisterField) { TMC5272_GSTAT_VM_UVLO_MASK, TMC5272_GSTAT_VM_UVLO_SHIFT, TMC5272_GSTAT, false }) +#define TMC5272_GSTAT_M1_DRV_ERR_MASK 0x00000020 +#define TMC5272_GSTAT_M1_DRV_ERR_SHIFT 5 +#define TMC5272_GSTAT_M1_DRV_ERR_FIELD ((RegisterField) { TMC5272_GSTAT_M1_DRV_ERR_MASK, TMC5272_GSTAT_M1_DRV_ERR_SHIFT, TMC5272_GSTAT, false }) +#define TMC5272_IFCNT_MASK 0x000000FF +#define TMC5272_IFCNT_SHIFT 0 +#define TMC5272_IFCNT_FIELD ((RegisterField) { TMC5272_IFCNT_MASK, TMC5272_IFCNT_SHIFT, TMC5272_IFCNT, false }) +#define TMC5272_SLAVECONF_SLAVEADDR_MASK 0x000000FF +#define TMC5272_SLAVECONF_SLAVEADDR_SHIFT 0 +#define TMC5272_SLAVECONF_SLAVEADDR_FIELD ((RegisterField) { TMC5272_SLAVECONF_SLAVEADDR_MASK, TMC5272_SLAVECONF_SLAVEADDR_SHIFT, TMC5272_SLAVECONF, false }) +#define TMC5272_SLAVECONF_SENDDELAY_MASK 0x00000F00 +#define TMC5272_SLAVECONF_SENDDELAY_SHIFT 8 +#define TMC5272_SLAVECONF_SENDDELAY_FIELD ((RegisterField) { TMC5272_SLAVECONF_SENDDELAY_MASK, TMC5272_SLAVECONF_SENDDELAY_SHIFT, TMC5272_SLAVECONF, false }) +#define TMC5272_IOIN_ADC_TEMPERATURE_MASK 0x000001FE +#define TMC5272_IOIN_ADC_TEMPERATURE_SHIFT 1 +#define TMC5272_IOIN_ADC_TEMPERATURE_FIELD ((RegisterField) { TMC5272_IOIN_ADC_TEMPERATURE_MASK, TMC5272_IOIN_ADC_TEMPERATURE_SHIFT, TMC5272_IOIN, false }) +#define TMC5272_IOIN_ADC_EN_MASK 0x00000200 +#define TMC5272_IOIN_ADC_EN_SHIFT 9 +#define TMC5272_IOIN_ADC_EN_FIELD ((RegisterField) { TMC5272_IOIN_ADC_EN_MASK, TMC5272_IOIN_ADC_EN_SHIFT, TMC5272_IOIN, false }) +#define TMC5272_IOIN_SEL_OSCILLATOR_MASK 0x00000800 +#define TMC5272_IOIN_SEL_OSCILLATOR_SHIFT 11 +#define TMC5272_IOIN_SEL_OSCILLATOR_FIELD ((RegisterField) { TMC5272_IOIN_SEL_OSCILLATOR_MASK, TMC5272_IOIN_SEL_OSCILLATOR_SHIFT, TMC5272_IOIN, false }) +#define TMC5272_IOIN_EXT_RES_DET_MASK 0x00001000 +#define TMC5272_IOIN_EXT_RES_DET_SHIFT 12 +#define TMC5272_IOIN_EXT_RES_DET_FIELD ((RegisterField) { TMC5272_IOIN_EXT_RES_DET_MASK, TMC5272_IOIN_EXT_RES_DET_SHIFT, TMC5272_IOIN, false }) +#define TMC5272_IOIN_OUTPUT_MASK 0x00002000 +#define TMC5272_IOIN_OUTPUT_SHIFT 13 +#define TMC5272_IOIN_OUTPUT_FIELD ((RegisterField) { TMC5272_IOIN_EXT_RES_DET_MASK, TMC5272_IOIN_EXT_RES_DET_SHIFT, TMC5272_IOIN, false }) +#define TMC5272_IOIN_QSC_STATUS_MASK 0x00008000 +#define TMC5272_IOIN_QSC_STATUS_SHIFT 15 +#define TMC5272_IOIN_QSC_STATUS_FIELD ((RegisterField) { TMC5272_IOIN_QSC_STATUS_MASK, TMC5272_IOIN_QSC_STATUS_SHIFT, TMC5272_IOIN, false }) +#define TMC5272_IOIN_SILICON_RV_MASK 0x00070000 +#define TMC5272_IOIN_SILICON_RV_SHIFT 16 +#define TMC5272_IOIN_SILICON_RV_FIELD ((RegisterField) { TMC5272_IOIN_SILICON_RV_MASK, TMC5272_IOIN_SILICON_RV_SHIFT, TMC5272_IOIN, false }) +#define TMC5272_IOIN_VERSION_MASK 0xFF000000 +#define TMC5272_IOIN_VERSION_SHIFT 24 +#define TMC5272_IOIN_VERSION_FIELD ((RegisterField) { TMC5272_IOIN_VERSION_MASK, TMC5272_IOIN_VERSION_SHIFT, TMC5272_IOIN, false }) +#define TMC5272_DRV_CONF_FSR_M0_MASK 0x00000003 +#define TMC5272_DRV_CONF_FSR_M0_SHIFT 0 +#define TMC5272_DRV_CONF_FSR_M0_FIELD ((RegisterField) { TMC5272_DRV_CONF_FSR_M0_MASK, TMC5272_DRV_CONF_FSR_M0_SHIFT, TMC5272_DRV_CONF, false }) +#define TMC5272_DRV_CONF_FSR_IREF_M0_MASK 0x0000000C +#define TMC5272_DRV_CONF_FSR_IREF_M0_SHIFT 2 +#define TMC5272_DRV_CONF_FSR_IREF_M0_FIELD ((RegisterField) { TMC5272_DRV_CONF_FSR_IREF_M0_MASK, TMC5272_DRV_CONF_FSR_IREF_M0_SHIFT, TMC5272_DRV_CONF, false }) +#define TMC5272_DRV_CONF_M0_EN_EMERGENCY_DISABLE_MASK 0x00000010 +#define TMC5272_DRV_CONF_M0_EN_EMERGENCY_DISABLE_SHIFT 4 +#define TMC5272_DRV_CONF_M0_EN_EMERGENCY_DISABLE_FIELD ((RegisterField) { TMC5272_DRV_CONF_M0_EN_EMERGENCY_DISABLE_MASK, TMC5272_DRV_CONF_M0_EN_EMERGENCY_DISABLE_SHIFT, TMC5272_DRV_CONF, false }) +#define TMC5272_DRV_CONF_M0_SEL_EM_STOP_SRC_MASK 0x00000020 +#define TMC5272_DRV_CONF_M0_SEL_EM_STOP_SRC_SHIFT 5 +#define TMC5272_DRV_CONF_M0_SEL_EM_STOP_SRC_FIELD ((RegisterField) { TMC5272_DRV_CONF_M0_SEL_EM_STOP_SRC_MASK, TMC5272_DRV_CONF_M0_SEL_EM_STOP_SRC_SHIFT, TMC5272_DRV_CONF, false }) +#define TMC5272_DRV_CONF_FSR_M1_MASK 0x000000C0 +#define TMC5272_DRV_CONF_FSR_M1_SHIFT 6 +#define TMC5272_DRV_CONF_FSR_M1_FIELD ((RegisterField) { TMC5272_DRV_CONF_FSR_M1_MASK, TMC5272_DRV_CONF_FSR_M1_SHIFT, TMC5272_DRV_CONF, false }) +#define TMC5272_DRV_CONF_FSR_IREF_M1_MASK 0x00000300 +#define TMC5272_DRV_CONF_FSR_IREF_M1_SHIFT 8 +#define TMC5272_DRV_CONF_FSR_IREF_M1_FIELD ((RegisterField) { TMC5272_DRV_CONF_FSR_IREF_M1_MASK, TMC5272_DRV_CONF_FSR_IREF_M1_SHIFT, TMC5272_DRV_CONF, false }) +#define TMC5272_DRV_CONF_M1_EN_EMERGENCY_DISABLE_MASK 0x00000400 +#define TMC5272_DRV_CONF_M1_EN_EMERGENCY_DISABLE_SHIFT 10 +#define TMC5272_DRV_CONF_M1_EN_EMERGENCY_DISABLE1_FIELD ((RegisterField) { TMC5272_DRV_CONF_M1_EN_EMERGENCY_DISABLE_MASK, TMC5272_DRV_CONF_M1_EN_EMERGENCY_DISABLE_SHIFT, TMC5272_DRV_CONF, false }) +#define TMC5272_DRV_CONF_M1_SEL_EM_STOP_SRC_MASK 0x00000800 +#define TMC5272_DRV_CONF_M1_SEL_EM_STOP_SRC_SHIFT 11 +#define TMC5272_DRV_CONF_M1_SEL_EM_STOP_SRC_FIELD ((RegisterField) { TMC5272_DRV_CONF_M1_SEL_EM_STOP_SRC_MASK, TMC5272_DRV_CONF_M1_SEL_EM_STOP_SRC_SHIFT, TMC5272_DRV_CONF, false }) +#define TMC5272_DRV_CONF_M0_STANDSTILL_TIME_MASK 0x00070000 +#define TMC5272_DRV_CONF_M0_STANDSTILL_TIME_SHIFT 16 +#define TMC5272_DRV_CONF_M0_STANDSTILL_TIME_FIELD ((RegisterField) { TMC5272_DRV_CONF_M0_STANDSTILL_TIME_MASK, TMC5272_DRV_CONF_M0_STANDSTILL_TIME_SHIFT, TMC5272_DRV_CONF, false }) +#define TMC5272_DRV_CONF_M1_STANDSTILL_TIME_MASK 0x00700000 +#define TMC5272_DRV_CONF_M1_STANDSTILL_TIME_SHIFT 20 +#define TMC5272_DRV_CONF_M1_STANDSTILL_TIME_FIELD ((RegisterField) { TMC5272_DRV_CONF_M1_STANDSTILL_TIME_MASK, TMC5272_DRV_CONF_M1_STANDSTILL_TIME_SHIFT, TMC5272_DRV_CONF, false }) +#define TMC5272_GLOBAL_SCALER_GLOBALSCALER_M0_A_MASK 0x000000FF +#define TMC5272_GLOBAL_SCALER_GLOBALSCALER_M0_A_SHIFT 0 +#define TMC5272_GLOBAL_SCALER_GLOBALSCALER_M0_A_FIELD ((RegisterField) { TMC5272_GLOBAL_SCALER_GLOBALSCALER_M0_A_MASK, TMC5272_GLOBAL_SCALER_GLOBALSCALER_M0_A_SHIFT, TMC5272_GLOBAL_SCALER, false }) +#define TMC5272_GLOBAL_SCALER_GLOBALSCALER_M0_B_MASK 0x0000FF00 +#define TMC5272_GLOBAL_SCALER_GLOBALSCALER_M0_B_SHIFT 8 +#define TMC5272_GLOBAL_SCALER_GLOBALSCALER_M0_B_FIELD ((RegisterField) { TMC5272_GLOBAL_SCALER_GLOBALSCALER_M0_B_MASK, TMC5272_GLOBAL_SCALER_GLOBALSCALER_M0_B_SHIFT, TMC5272_GLOBAL_SCALER, false }) +#define TMC5272_GLOBAL_SCALER_GLOBALSCALER_M1_A_MASK 0x00FF0000 +#define TMC5272_GLOBAL_SCALER_GLOBALSCALER_M1_A_SHIFT 16 +#define TMC5272_GLOBAL_SCALER_GLOBALSCALER_M1_A_FIELD ((RegisterField) { TMC5272_GLOBAL_SCALER_GLOBALSCALER_M1_A_MASK, TMC5272_GLOBAL_SCALER_GLOBALSCALER_M1_A_SHIFT, TMC5272_GLOBAL_SCALER, false }) +#define TMC5272_GLOBAL_SCALER_GLOBALSCALER_M1_B_MASK 0xFF000000 +#define TMC5272_GLOBAL_SCALER_GLOBALSCALER_M1_B_SHIFT 24 +#define TMC5272_GLOBAL_SCALER_GLOBALSCALER_M1_B_FIELD ((RegisterField) { TMC5272_GLOBAL_SCALER_GLOBALSCALER_M1_B_MASK, TMC5272_GLOBAL_SCALER_GLOBALSCALER_M1_B_SHIFT, TMC5272_GLOBAL_SCALER, false }) +#define TMC5272_RAMPMODE_M0_RAMPMODE_MASK 0x00000003 +#define TMC5272_RAMPMODE_M0_RAMPMODE_SHIFT 0 +#define TMC5272_RAMPMODE_M0_RAMPMODE_FIELD ((RegisterField) { TMC5272_RAMPMODE_M0_RAMPMODE_MASK, TMC5272_RAMPMODE_M0_RAMPMODE_SHIFT, TMC5272_RAMPMODE, false }) +#define TMC5272_RAMPMODE_M1_RAMPMODE_MASK 0x0000000C +#define TMC5272_RAMPMODE_M1_RAMPMODE_SHIFT 2 +#define TMC5272_RAMPMODE_M1_RAMPMODE_FIELD ((RegisterField) { TMC5272_RAMPMODE_M1_RAMPMODE_MASK, TMC5272_RAMPMODE_M1_RAMPMODE_SHIFT, TMC5272_RAMPMODE, false }) +#define TMC5272_RAMPMODE_SHIFT(motor) (2 * (motor)) +#define TMC5272_RAMPMODE_MASK(motor) (TMC5272_RAMPMODE_M0_RAMPMODE_MASK << TMC5272_RAMPMODE_SHIFT(motor)) +#define TMC5272_RAMPMODE_FIELD(motor) ((RegisterField) { TMC5272_RAMPMODE_MASK(motor), TMC5272_RAMPMODE_SHIFT(motor), TMC5272_RAMPMODE, false }) +#define TMC5272_RAMPMODE_RAMP_SYN_POS_UPDATE_MASK 0x00000100 +#define TMC5272_RAMPMODE_RAMP_SYN_POS_UPDATE_SHIFT 8 +#define TMC5272_RAMPMODE_RAMP_SYN_POS_UPDATE_FIELD ((RegisterField) { TMC5272_RAMPMODE_RAMP_SYN_POS_UPDATE_MASK, TMC5272_RAMPMODE_RAMP_SYN_POS_UPDATE_SHIFT, TMC5272_RAMPMODE, false }) +#define TMC5272_RAMPMODE_AXIS_INTERPOLATION_MASK 0x00000200 +#define TMC5272_RAMPMODE_AXIS_INTERPOLATION_SHIFT 9 +#define TMC5272_RAMPMODE_AXIS_INTERPOLATION_FIELD ((RegisterField) { TMC5272_RAMPMODE_AXIS_INTERPOLATION_MASK, TMC5272_RAMPMODE_AXIS_INTERPOLATION_SHIFT, TMC5272_RAMPMODE, false }) +#define TMC5272_MSLUT_ADDR_MASK 0x0000001F +#define TMC5272_MSLUT_ADDR_SHIFT 0 +#define TMC5272_MSLUT_ADDR_FIELD ((RegisterField) { TMC5272_MSLUT_ADDR_MASK, TMC5272_MSLUT_ADDR_SHIFT, TMC5272_MSLUT_ADDR, false }) +#define TMC5272_MSLUT_START_START_SIN_MASK 0xFF +#define TMC5272_MSLUT_START_START_SIN_SHIFT 0 +#define TMC5272_MSLUT_START_START_SIN_FIELD ((RegisterField) { TMC5272_MSLUT_START_START_SIN_MASK, TMC5272_MSLUT_START_START_SIN_SHIFT, TMC5272_MSLUT_DATA, false }) +#define TMC5272_MSLUT_START_START_SIN90_MASK 0xFF0000 +#define TMC5272_MSLUT_START_START_SIN90_SHIFT 16 +#define TMC5272_MSLUT_START_START_SIN90_FIELD ((RegisterField) { TMC5272_MSLUT_START_START_SIN90_MASK, TMC5272_MSLUT_START_START_SIN90_SHIFT, TMC5272_MSLUT_DATA, false }) +#define TMC5272_MSLUT_START_OFFSET_SIN90_MASK 0xFF000000 +#define TMC5272_MSLUT_START_OFFSET_SIN90_SHIFT 24 +#define TMC5272_MSLUT_START_OFFSET_SIN90_FIELD ((RegisterField) { TMC5272_MSLUT_START_OFFSET_SIN90_MASK, TMC5272_MSLUT_START_OFFSET_SIN90_SHIFT, TMC5272_MSLUT_DATA, true }) +#define TMC5272_X_COMPARE_MASK 0xFFFFFFFF +#define TMC5272_X_COMPARE_SHIFT 0 +#define TMC5272_X_COMPARE_FIELD(motor) ((RegisterField) { TMC5272_X_COMPARE_MASK, TMC5272_X_COMPARE_SHIFT, TMC5272_X_COMPARE(motor), true }) +#define TMC5272_X_COMPARE_REPEAT_MASK 0x00FFFFFF +#define TMC5272_X_COMPARE_REPEAT_SHIFT 0 +#define TMC5272_X_COMPARE_REPEAT_FIELD(motor) ((RegisterField) { TMC5272_X_COMPARE_REPEAT_MASK, TMC5272_X_COMPARE_REPEAT_SHIFT, TMC5272_X_COMPARE_REPEAT(motor), false }) +#define TMC5272_IHOLD_IRUN_IHOLD_MASK 0x0000001F +#define TMC5272_IHOLD_IRUN_IHOLD_SHIFT 0 +#define TMC5272_IHOLD_IRUN_IHOLD_FIELD(motor) ((RegisterField) { TMC5272_IHOLD_IRUN_IHOLD_MASK, TMC5272_IHOLD_IRUN_IHOLD_SHIFT, TMC5272_IHOLD_IRUN(motor), false }) +#define TMC5272_IHOLD_IRUN_IRUN_MASK 0x00001F00 +#define TMC5272_IHOLD_IRUN_IRUN_SHIFT 8 +#define TMC5272_IHOLD_IRUN_IRUN_FIELD(motor) ((RegisterField) { TMC5272_IHOLD_IRUN_IRUN_MASK, TMC5272_IHOLD_IRUN_IRUN_SHIFT, TMC5272_IHOLD_IRUN(motor), false }) +#define TMC5272_IHOLD_IRUN_IHOLDDELAY_MASK 0x000F0000 +#define TMC5272_IHOLD_IRUN_IHOLDDELAY_SHIFT 16 +#define TMC5272_IHOLD_IRUN_IHOLDDELAY_FIELD(motor) ((RegisterField) { TMC5272_IHOLD_IRUN_IHOLDDELAY_MASK, TMC5272_IHOLD_IRUN_IHOLDDELAY_SHIFT, TMC5272_IHOLD_IRUN(motor), false }) +#define TMC5272_IHOLD_IRUN_IRUNDELAY_MASK 0x0F000000 +#define TMC5272_IHOLD_IRUN_IRUNDELAY_SHIFT 24 +#define TMC5272_IHOLD_IRUN_IRUNDELAY_FIELD(motor) ((RegisterField) { TMC5272_IHOLD_IRUN_IRUNDELAY_MASK, TMC5272_IHOLD_IRUN_IRUNDELAY_SHIFT, TMC5272_IHOLD_IRUN(motor), false }) +#define TMC5272_TPOWERDOWN_MASK 0x000000FF +#define TMC5272_TPOWERDOWN_SHIFT 0 +#define TMC5272_TPOWERDOWN_FIELD(motor) ((RegisterField) { TMC5272_TPOWERDOWN_MASK, TMC5272_TPOWERDOWN_SHIFT, TMC5272_TPOWERDOWN(motor), false }) +#define TMC5272_TSTEP_MASK 0x000FFFFF +#define TMC5272_TSTEP_SHIFT 0 +#define TMC5272_TSTEP_FIELD(motor) ((RegisterField) { TMC5272_TSTEP_MASK, TMC5272_TSTEP_SHIFT, TMC5272_TSTEP(motor), false }) +#define TMC5272_TPWMTHRS_MASK 0x000FFFFF +#define TMC5272_TPWMTHRS_SHIFT 0 +#define TMC5272_TPWMTHRS_FIELD(motor) ((RegisterField) { TMC5272_TPWMTHRS_MASK, TMC5272_TPWMTHRS_SHIFT, TMC5272_TPWMTHRS(motor), false }) +#define TMC5272_TCOOLTHRS_MASK 0x000FFFFF +#define TMC5272_TCOOLTHRS_SHIFT 0 +#define TMC5272_TCOOLTHRS_FIELD(motor) ((RegisterField) { TMC5272_TCOOLTHRS_MASK, TMC5272_TCOOLTHRS_SHIFT, TMC5272_TCOOLTHRS(motor), false }) +#define TMC5272_THIGH_MASK 0x000FFFFF +#define TMC5272_THIGH_SHIFT 0 +#define TMC5272_THIGH_FIELD(motor) ((RegisterField) { TMC5272_THIGH_MASK, TMC5272_THIGH_SHIFT, TMC5272_THIGH(motor), false }) +#define TMC5272_XACTUAL_MASK 0xFFFFFFFF +#define TMC5272_XACTUAL_SHIFT 0 +#define TMC5272_XACTUAL_FIELD(motor) ((RegisterField) { TMC5272_XACTUAL_MASK, TMC5272_XACTUAL_SHIFT, TMC5272_XACTUAL(motor), true }) +#define TMC5272_VACTUAL_MASK 0x00FFFFFF +#define TMC5272_VACTUAL_SHIFT 0 +#define TMC5272_VACTUAL_FIELD(motor) ((RegisterField) { TMC5272_VACTUAL_MASK, TMC5272_VACTUAL_SHIFT, TMC5272_VACTUAL(motor), true }) +#define TMC5272_AACTUAL_MASK 0x00FFFFFF +#define TMC5272_AACTUAL_SHIFT 0 +#define TMC5272_AACTUAL_FIELD(motor) ((RegisterField) { TMC5272_AACTUAL_MASK, TMC5272_AACTUAL_SHIFT, TMC5272_AACTUAL(motor), true }) +#define TMC5272_VSTART_MASK 0x0003FFFF +#define TMC5272_VSTART_SHIFT 0 +#define TMC5272_VSTART_FIELD(motor) ((RegisterField) { TMC5272_VSTART_MASK, TMC5272_VSTART_SHIFT, TMC5272_VSTART(motor), false }) +#define TMC5272_A1_MASK 0x0003FFFF +#define TMC5272_A1_SHIFT 0 +#define TMC5272_A1_FIELD(motor) ((RegisterField) { TMC5272_A1_MASK, TMC5272_A1_SHIFT, TMC5272_A1(motor), false }) +#define TMC5272_V1_MASK 0x000FFFFF +#define TMC5272_V1_SHIFT 0 +#define TMC5272_V1_FIELD(motor) ((RegisterField) { TMC5272_V1_MASK, TMC5272_V1_SHIFT, TMC5272_V1(motor), false }) +#define TMC5272_A2_MASK 0x0003FFFF +#define TMC5272_A2_SHIFT 0 +#define TMC5272_A2_FIELD(motor) ((RegisterField) { TMC5272_A2_MASK, TMC5272_A2_SHIFT, TMC5272_A2(motor), false }) +#define TMC5272_V2_MASK 0x000FFFFF +#define TMC5272_V2_SHIFT 0 +#define TMC5272_V2_FIELD(motor) ((RegisterField) { TMC5272_V2_MASK, TMC5272_V2_SHIFT, TMC5272_V2(motor), false }) +#define TMC5272_AMAX_MASK 0x0003FFFF +#define TMC5272_AMAX_SHIFT 0 +#define TMC5272_AMAX_FIELD(motor) ((RegisterField) { TMC5272_AMAX_MASK, TMC5272_AMAX_SHIFT, TMC5272_AMAX(motor), false }) +#define TMC5272_VMAX_MASK 0x007FFFFF +#define TMC5272_VMAX_SHIFT 0 +#define TMC5272_VMAX_FIELD(motor) ((RegisterField) { TMC5272_VMAX_MASK, TMC5272_VMAX_SHIFT, TMC5272_VMAX(motor), false }) +#define TMC5272_DMAX_MASK 0x0003FFFF +#define TMC5272_DMAX_SHIFT 0 +#define TMC5272_DMAX_FIELD(motor) ((RegisterField) { TMC5272_DMAX_MASK, TMC5272_DMAX_SHIFT, TMC5272_DMAX(motor), false }) +#define TMC5272_D2_MASK 0x0003FFFF +#define TMC5272_D2_SHIFT 0 +#define TMC5272_D2_FIELD(motor) ((RegisterField) { TMC5272_D2_MASK, TMC5272_D2_SHIFT, TMC5272_D2(motor), false }) +#define TMC5272_D1_MASK 0x0003FFFF +#define TMC5272_D1_SHIFT 0 +#define TMC5272_D1_FIELD(motor) ((RegisterField) { TMC5272_D1_MASK, TMC5272_D1_SHIFT, TMC5272_D1(motor), false }) +#define TMC5272_VSTOP_MASK 0x0003FFFF +#define TMC5272_VSTOP_SHIFT 0 +#define TMC5272_VSTOP_FIELD(motor) ((RegisterField) { TMC5272_VSTOP_MASK, TMC5272_VSTOP_SHIFT, TMC5272_VSTOP(motor), false }) +#define TMC5272_TVMAX_MASK 0x0000FFFF +#define TMC5272_TVMAX_SHIFT 0 +#define TMC5272_TVMAX_FIELD(motor) ((RegisterField) { TMC5272_TVMAX_MASK, TMC5272_TVMAX_SHIFT, TMC5272_TVMAX(motor), false }) +#define TMC5272_TZEROWAIT_MASK 0x0000FFFF +#define TMC5272_TZEROWAIT_SHIFT 0 +#define TMC5272_TZEROWAIT_FIELD(motor) ((RegisterField) { TMC5272_TZEROWAIT_MASK, TMC5272_TZEROWAIT_SHIFT, TMC5272_TZEROWAIT(motor), false }) +#define TMC5272_XTARGET_MASK 0xFFFFFFFF +#define TMC5272_XTARGET_SHIFT 0 +#define TMC5272_XTARGET_FIELD(motor) ((RegisterField) { TMC5272_XTARGET_MASK, TMC5272_XTARGET_SHIFT, TMC5272_XTARGET(motor), true }) +#define TMC5272_VDCMIN_RESERVED_MASK 0x000000FF +#define TMC5272_VDCMIN_RESERVED_SHIFT 0 +#define TMC5272_VDCMIN_RESERVED_FIELD(motor) ((RegisterField) { TMC5272_VDCMIN_RESERVED_MASK, TMC5272_VDCMIN_RESERVED_SHIFT, TMC5272_VDCMIN(motor), false }) +#define TMC5272_VDCMIN_VDCMIN_MASK 0x007FFF00 +#define TMC5272_VDCMIN_VDCMIN_SHIFT 8 +#define TMC5272_VDCMIN_VDCMIN_FIELD(motor) ((RegisterField) { TMC5272_VDCMIN_VDCMIN_MASK, TMC5272_VDCMIN_VDCMIN_SHIFT, TMC5272_VDCMIN(motor), false }) +#define TMC5272_SW_MODE_STOP_L_ENABLE_MASK 0x00000001 +#define TMC5272_SW_MODE_STOP_L_ENABLE_SHIFT 0 +#define TMC5272_SW_MODE_STOP_L_ENABLE_FIELD(motor) ((RegisterField) { TMC5272_SW_MODE_STOP_L_ENABLE_MASK, TMC5272_SW_MODE_STOP_L_ENABLE_SHIFT, TMC5272_SW_MODE(motor), false }) +#define TMC5272_SW_MODE_STOP_R_ENABLE_MASK 0x00000002 +#define TMC5272_SW_MODE_STOP_R_ENABLE_SHIFT 1 +#define TMC5272_SW_MODE_STOP_R_ENABLE_FIELD(motor) ((RegisterField) { TMC5272_SW_MODE_STOP_R_ENABLE_MASK, TMC5272_SW_MODE_STOP_R_ENABLE_SHIFT, TMC5272_SW_MODE(motor), false }) +#define TMC5272_SW_MODE_POL_STOP_L_MASK 0x00000004 +#define TMC5272_SW_MODE_POL_STOP_L_SHIFT 2 +#define TMC5272_SW_MODE_POL_STOP_L_FIELD(motor) ((RegisterField) { TMC5272_SW_MODE_POL_STOP_L_MASK, TMC5272_SW_MODE_POL_STOP_L_SHIFT, TMC5272_SW_MODE(motor), false }) +#define TMC5272_SW_MODE_POL_STOP_R_MASK 0x00000008 +#define TMC5272_SW_MODE_POL_STOP_R_SHIFT 3 +#define TMC5272_SW_MODE_POL_STOP_R_FIELD(motor) ((RegisterField) { TMC5272_SW_MODE_POL_STOP_R_MASK, TMC5272_SW_MODE_POL_STOP_R_SHIFT, TMC5272_SW_MODE(motor), false }) +#define TMC5272_SW_MODE_SWAP_LR_MASK 0x00000010 +#define TMC5272_SW_MODE_SWAP_LR_SHIFT 4 +#define TMC5272_SW_MODE_SWAP_LR_FIELD(motor) ((RegisterField) { TMC5272_SW_MODE_SWAP_LR_MASK, TMC5272_SW_MODE_SWAP_LR_SHIFT, TMC5272_SW_MODE(motor), false }) +#define TMC5272_SW_MODE_LATCH_L_ACTIVE_MASK 0x00000020 +#define TMC5272_SW_MODE_LATCH_L_ACTIVE_SHIFT 5 +#define TMC5272_SW_MODE_LATCH_L_ACTIVE_FIELD(motor) ((RegisterField) { TMC5272_SW_MODE_LATCH_L_ACTIVE_MASK, TMC5272_SW_MODE_LATCH_L_ACTIVE_SHIFT, TMC5272_SW_MODE(motor), false }) +#define TMC5272_SW_MODE_LATCH_L_INACTIVE_MASK 0x00000040 +#define TMC5272_SW_MODE_LATCH_L_INACTIVE_SHIFT 6 +#define TMC5272_SW_MODE_LATCH_L_INACTIVE_FIELD(motor) ((RegisterField) { TMC5272_SW_MODE_LATCH_L_INACTIVE_MASK, TMC5272_SW_MODE_LATCH_L_ACTIVE_SHIFT, TMC5272_SW_MODE(motor), false }) +#define TMC5272_SW_MODE_LATCH_R_ACTIVE_MASK 0x00000080 +#define TMC5272_SW_MODE_LATCH_R_ACTIVE_SHIFT 7 +#define TMC5272_SW_MODE_LATCH_R_ACTIVE_FIELD(motor) ((RegisterField) { TMC5272_SW_MODE_LATCH_R_ACTIVE_MASK, TMC5272_SW_MODE_LATCH_R_ACTIVE_SHIFT, TMC5272_SW_MODE(motor), false }) +#define TMC5272_SW_MODE_LATCH_R_INACTIVE_MASK 0x00000100 +#define TMC5272_SW_MODE_LATCH_R_INACTIVE_SHIFT 8 +#define TMC5272_SW_MODE_LATCH_R_INACTIVE_FIELD(motor) ((RegisterField) { TMC5272_SW_MODE_LATCH_R_INACTIVE_MASK, TMC5272_SW_MODE_LATCH_R_INACTIVE_SHIFT, TMC5272_SW_MODE(motor), false }) +#define TMC5272_SW_MODE_EN_LATCH_ENCODER_MASK 0x00000200 +#define TMC5272_SW_MODE_EN_LATCH_ENCODER_SHIFT 9 +#define TMC5272_SW_MODE_EN_LATCH_ENCODER_FIELD(motor) ((RegisterField) { TMC5272_SW_MODE_EN_LATCH_ENCODER_MASK, TMC5272_SW_MODE_EN_LATCH_ENCODER_SHIFT, TMC5272_SW_MODE(motor), false }) +#define TMC5272_SW_MODE_SG_STOP_MASK 0x00000400 +#define TMC5272_SW_MODE_SG_STOP_SHIFT 10 +#define TMC5272_SW_MODE_SG_STOP_FIELD(motor) ((RegisterField) { TMC5272_SW_MODE_SG_STOP_MASK, TMC5272_SW_MODE_SG_STOP_SHIFT, TMC5272_SW_MODE(motor), false }) +#define TMC5272_SW_MODE_EN_SOFTSTOP_MASK 0x00000800 +#define TMC5272_SW_MODE_EN_SOFTSTOP_SHIFT 11 +#define TMC5272_SW_MODE_EN_SOFTSTOP_FIELD(motor) ((RegisterField) { TMC5272_SW_MODE_EN_SOFTSTOP_MASK, TMC5272_SW_MODE_EN_SOFTSTOP_SHIFT, TMC5272_SW_MODE(motor), false }) +#define TMC5272_SW_MODE_EN_VIRTUAL_STOP_L_MASK 0x00001000 +#define TMC5272_SW_MODE_EN_VIRTUAL_STOP_L_SHIFT 12 +#define TMC5272_SW_MODE_EN_VIRTUAL_STOP_L_FIELD(motor) ((RegisterField) { TMC5272_SW_MODE_EN_SOFTSTOP_MASK, TMC5272_SW_MODE_EN_SOFTSTOP_SHIFT, TMC5272_SW_MODE(motor), false }) +#define TMC5272_SW_MODE_EN_VIRTUAL_STOP_R_MASK 0x00002000 +#define TMC5272_SW_MODE_EN_VIRTUAL_STOP_R_SHIFT 13 +#define TMC5272_SW_MODE_EN_VIRTUAL_STOP_R_FIELD(motor) ((RegisterField) { TMC5272_SW_MODE_EN_VIRTUAL_STOP_R_MASK, TMC5272_SW_MODE_EN_VIRTUAL_STOP_R_SHIFT, TMC5272_SW_MODE(motor), false }) +#define TMC5272_SW_MODE_VIRTUAL_STEP_ENC_MASK 0x00004000 +#define TMC5272_SW_MODE_VIRTUAL_STEP_ENC_SHIFT 14 +#define TMC5272_SW_MODE_VIRTUAL_STEP_ENC_FIELD(motor) ((RegisterField) { TMC5272_SW_MODE_VIRTUAL_STEP_ENC_MASK, TMC5272_SW_MODE_VIRTUAL_STEP_ENC_SHIFT, TMC5272_SW_MODE(motor), false }) +#define TMC5272_RAMP_STAT_STATUS_STOP_L_MASK 0x00000001 +#define TMC5272_RAMP_STAT_STATUS_STOP_L_SHIFT 0 +#define TMC5272_RAMP_STAT_STATUS_STOP_L_FIELD(motor) ((RegisterField) { TMC5272_RAMP_STAT_STATUS_STOP_L_MASK, TMC5272_RAMP_STAT_STATUS_STOP_L_SHIFT, TMC5272_RAMP_STAT(motor), false }) +#define TMC5272_RAMP_STAT_STATUS_STOP_R_MASK 0x00000002 +#define TMC5272_RAMP_STAT_STATUS_STOP_R_SHIFT 1 +#define TMC5272_RAMP_STAT_STATUS_STOP_R_FIELD(motor) ((RegisterField) { TMC5272_RAMP_STAT_STATUS_STOP_R_MASK, TMC5272_RAMP_STAT_STATUS_STOP_R_SHIFT, TMC5272_RAMP_STAT(motor), false }) +#define TMC5272_RAMP_STAT_STATUS_LATCH_L_MASK 0x00000004 +#define TMC5272_RAMP_STAT_STATUS_LATCH_L_SHIFT 2 +#define TMC5272_RAMP_STAT_STATUS_LATCH_L_FIELD(motor) ((RegisterField) { TMC5272_RAMP_STAT_STATUS_LATCH_L_MASK, TMC5272_RAMP_STAT_STATUS_LATCH_L_SHIFT, TMC5272_RAMP_STAT(motor), false }) +#define TMC5272_RAMP_STAT_STATUS_LATCH_R_MASK 0x00000008 +#define TMC5272_RAMP_STAT_STATUS_LATCH_R_SHIFT 3 +#define TMC5272_RAMP_STAT_STATUS_LATCH_R_FIELD(motor) ((RegisterField) { TMC5272_RAMP_STAT_STATUS_LATCH_R_MASK, TMC5272_RAMP_STAT_STATUS_LATCH_R_SHIFT, TMC5272_RAMP_STAT(motor), false }) +#define TMC5272_RAMP_STAT_EVENT_STOP_L_MASK 0x00000010 +#define TMC5272_RAMP_STAT_EVENT_STOP_L_SHIFT 4 +#define TMC5272_RAMP_STAT_EVENT_STOP_L_FIELD(motor) ((RegisterField) { TMC5272_RAMP_STAT_EVENT_STOP_L_MASK, TMC5272_RAMP_STAT_EVENT_STOP_L_SHIFT, TMC5272_RAMP_STAT(motor), false }) +#define TMC5272_RAMP_STAT_EVENT_STOP_R_MASK 0x00000020 +#define TMC5272_RAMP_STAT_EVENT_STOP_R_SHIFT 5 +#define TMC5272_RAMP_STAT_EVENT_STOP_R_FIELD(motor) ((RegisterField) { TMC5272_RAMP_STAT_EVENT_STOP_R_MASK, TMC5272_RAMP_STAT_EVENT_STOP_R_SHIFT, TMC5272_RAMP_STAT(motor), false }) +#define TMC5272_RAMP_STAT_EVENT_STOP_SG_MASK 0x00000040 +#define TMC5272_RAMP_STAT_EVENT_STOP_SG_SHIFT 6 +#define TMC5272_RAMP_STAT_EVENT_STOP_SG_FIELD(motor) ((RegisterField) { TMC5272_RAMP_STAT_EVENT_STOP_SG_MASK, TMC5272_RAMP_STAT_EVENT_STOP_SG_SHIFT, TMC5272_RAMP_STAT(motor), false }) +#define TMC5272_RAMP_STAT_EVENT_POS_REACHED_MASK 0x00000080 +#define TMC5272_RAMP_STAT_EVENT_POS_REACHED_SHIFT 7 +#define TMC5272_RAMP_STAT_EVENT_POS_REACHED_FIELD(motor) ((RegisterField) { TMC5272_RAMP_STAT_EVENT_POS_REACHED_MASK, TMC5272_RAMP_STAT_EVENT_POS_REACHED_SHIFT, TMC5272_RAMP_STAT(motor), false }) +#define TMC5272_RAMP_STAT_VELOCITY_REACHED_MASK 0x00000100 +#define TMC5272_RAMP_STAT_VELOCITY_REACHED_SHIFT 8 +#define TMC5272_RAMP_STAT_VELOCITY_REACHED_FIELD(motor) ((RegisterField) { TMC5272_RAMP_STAT_VELOCITY_REACHED_MASK, TMC5272_RAMP_STAT_VELOCITY_REACHED_SHIFT, TMC5272_RAMP_STAT(motor), false }) +#define TMC5272_RAMP_STAT_POSITION_REACHED_MASK 0x00000200 +#define TMC5272_RAMP_STAT_POSITION_REACHED_SHIFT 9 +#define TMC5272_RAMP_STAT_POSITION_REACHED_FIELD(motor) ((RegisterField) { TMC5272_RAMP_STAT_POSITION_REACHED_MASK, TMC5272_RAMP_STAT_POSITION_REACHED_SHIFT, TMC5272_RAMP_STAT(motor), false }) +#define TMC5272_RAMP_STAT_VZERO_MASK 0x00000400 +#define TMC5272_RAMP_STAT_VZERO_SHIFT 10 +#define TMC5272_RAMP_STAT_VZERO_FIELD(motor) ((RegisterField) { TMC5272_RAMP_STAT_VZERO_MASK, TMC5272_RAMP_STAT_VZERO_SHIFT, TMC5272_RAMP_STAT(motor), false }) +#define TMC5272_RAMP_STAT_T_ZEROWAIT_ACTIVE_MASK 0x00000800 +#define TMC5272_RAMP_STAT_T_ZEROWAIT_ACTIVE_SHIFT 11 +#define TMC5272_RAMP_STAT_T_ZEROWAIT_ACTIVE_FIELD(motor) ((RegisterField) { TMC5272_RAMP_STAT_T_ZEROWAIT_ACTIVE_MASK, TMC5272_RAMP_STAT_T_ZEROWAIT_ACTIVE_SHIFT, TMC5272_RAMP_STAT(motor), false }) +#define TMC5272_RAMP_STAT_SECOND_MOVE_MASK 0x00001000 +#define TMC5272_RAMP_STAT_SECOND_MOVE_SHIFT 12 +#define TMC5272_RAMP_STAT_SECOND_MOVE_FIELD(motor) ((RegisterField) { TMC5272_RAMP_STAT_SECOND_MOVE_MASK, TMC5272_RAMP_STAT_SECOND_MOVE_SHIFT, TMC5272_RAMP_STAT(motor), false }) +#define TMC5272_RAMP_STAT_STATUS_SG_MASK 0x00002000 +#define TMC5272_RAMP_STAT_STATUS_SG_SHIFT 13 +#define TMC5272_RAMP_STAT_STATUS_SG_FIELD(motor) ((RegisterField) { TMC5272_RAMP_STAT_STATUS_SG_MASK, TMC5272_RAMP_STAT_STATUS_SG_SHIFT, TMC5272_RAMP_STAT(motor), false }) +#define TMC5272_RAMP_STAT_STATUS_VIRTUAL_STOP_L_MASK 0x00004000 +#define TMC5272_RAMP_STAT_STATUS_VIRTUAL_STOP_L_SHIFT 14 +#define TMC5272_RAMP_STAT_STATUS_VIRTUAL_STOP_L_FIELD(motor) ((RegisterField) { TMC5272_RAMP_STAT_STATUS_VIRTUAL_STOP_L_MASK, TMC5272_RAMP_STAT_STATUS_VIRTUAL_STOP_L_SHIFT, TMC5272_RAMP_STAT(motor), false }) +#define TMC5272_RAMP_STAT_STATUS_VIRTUAL_STOP_R_MASK 0x00008000 +#define TMC5272_RAMP_STAT_STATUS_VIRTUAL_STOP_R_SHIFT 15 +#define TMC5272_RAMP_STAT_STATUS_VIRTUAL_STOP_R_FIELD(motor) ((RegisterField) { TMC5272_RAMP_STAT_STATUS_VIRTUAL_STOP_R_MASK, TMC5272_RAMP_STAT_STATUS_VIRTUAL_STOP_R_SHIFT, TMC5272_RAMP_STAT(motor), false }) +#define TMC5272_XLATCH_MASK 0xFFFFFFFF +#define TMC5272_XLATCH_SHIFT 0 +#define TMC5272_XLATCH_FIELD(motor) ((RegisterField) { TMC5272_XLATCH_MASK, TMC5272_XLATCH_SHIFT, TMC5272_XLATCH(motor), true }) +#define TMC5272_POSITION_PI_CTRL_POSITION_PI_CTRL_REGS_MASK 0xFFFFFFFF +#define TMC5272_POSITION_PI_CTRL_POSITION_PI_CTRL_REGS_SHIFT 0 +#define TMC5272_POSITION_PI_CTRL_POSITION_PI_CTRL_REGS_FIELD(motor) ((RegisterField) { TMC5272_POSITION_PI_CTRL_POSITION_PI_CTRL_REGS_MASK, TMC5272_POSITION_PI_CTRL_POSITION_PI_CTRL_REGS_SHIFT, TMC5272_POSITION_PI_CTRL(motor), false }) +#define TMC5272_X_ENC_MASK 0xFFFFFFFF +#define TMC5272_X_ENC_SHIFT 0 +#define TMC5272_X_ENC_FIELD(motor) ((RegisterField) { TMC5272_X_ENC_MASK, TMC5272_X_ENC_SHIFT, TMC5272_X_ENC(motor), true }) +#define TMC5272_ENCMODE_POL_A_MASK 0x00000001 +#define TMC5272_ENCMODE_POL_A_SHIFT 0 +#define TMC5272_ENCMODE_POL_A_FIELD(motor) ((RegisterField) { TMC5272_ENCMODE_POL_A_MASK, TMC5272_ENCMODE_POL_A_SHIFT, TMC5272_ENCMODE(motor), false }) +#define TMC5272_ENCMODE_POL_B_MASK 0x00000002 +#define TMC5272_ENCMODE_POL_B_SHIFT 1 +#define TMC5272_ENCMODE_POL_B_FIELD(motor) ((RegisterField) { TMC5272_ENCMODE_POL_B_MASK, TMC5272_ENCMODE_POL_B_SHIFT, TMC5272_ENCMODE(motor), false }) +#define TMC5272_ENCMODE_POL_N_MASK 0x00000004 +#define TMC5272_ENCMODE_POL_N_SHIFT 2 +#define TMC5272_ENCMODE_POL_N_FIELD(motor) ((RegisterField) { TMC5272_ENCMODE_POL_N_MASK, TMC5272_ENCMODE_POL_N_SHIFT, TMC5272_ENCMODE(motor), false }) +#define TMC5272_ENCMODE_IGNORE_AB_MASK 0x00000008 +#define TMC5272_ENCMODE_IGNORE_AB_SHIFT 3 +#define TMC5272_ENCMODE_IGNORE_AB_FIELD(motor) ((RegisterField) { TMC5272_ENCMODE_IGNORE_AB_MASK, TMC5272_ENCMODE_IGNORE_AB_SHIFT, TMC5272_ENCMODE(motor), false }) +#define TMC5272_ENCMODE_CLR_CONT_MASK 0x00000010 +#define TMC5272_ENCMODE_CLR_CONT_SHIFT 4 +#define TMC5272_ENCMODE_CLR_CONT_FIELD(motor) ((RegisterField) { TMC5272_ENCMODE_CLR_CONT_MASK, TMC5272_ENCMODE_CLR_CONT_SHIFT, TMC5272_ENCMODE(motor), false }) +#define TMC5272_ENCMODE_CLR_ONCE_MASK 0x00000020 +#define TMC5272_ENCMODE_CLR_ONCE_SHIFT 5 +#define TMC5272_ENCMODE_CLR_ONCE_FIELD(motor) ((RegisterField) { TMC5272_ENCMODE_CLR_ONCE_MASK, TMC5272_ENCMODE_CLR_ONCE_SHIFT, TMC5272_ENCMODE(motor), false }) +#define TMC5272_ENCMODE_POS_NEG_EDGE_MASK 0x000000C0 +#define TMC5272_ENCMODE_POS_NEG_EDGE_SHIFT 6 +#define TMC5272_ENCMODE_POS_NEG_EDGE_FIELD(motor) ((RegisterField) { TMC5272_ENCMODE_POS_NEG_EDGE_MASK, TMC5272_ENCMODE_POS_NEG_EDGE_SHIFT, TMC5272_ENCMODE(motor), false }) +#define TMC5272_ENCMODE_CLR_ENC_X_MASK 0x00000100 +#define TMC5272_ENCMODE_CLR_ENC_X_SHIFT 8 +#define TMC5272_ENCMODE_CLR_ENC_X_FIELD(motor) ((RegisterField) { TMC5272_ENCMODE_CLR_ENC_X_MASK, TMC5272_ENCMODE_CLR_ENC_X_SHIFT, TMC5272_ENCMODE(motor), false }) +#define TMC5272_ENCMODE_LATCH_X_ACT_MASK 0x00000200 +#define TMC5272_ENCMODE_LATCH_X_ACT_SHIFT 9 +#define TMC5272_ENCMODE_LATCH_X_ACT_FIELD(motor) ((RegisterField) { TMC5272_ENCMODE_LATCH_X_ACT_MASK, TMC5272_ENCMODE_LATCH_X_ACT_SHIFT, TMC5272_ENCMODE(motor), false }) +#define TMC5272_ENCMODE_ENC_SEL_DECIMAL_MASK 0x00000400 +#define TMC5272_ENCMODE_ENC_SEL_DECIMAL_SHIFT 10 +#define TMC5272_ENCMODE_ENC_SEL_DECIMAL_FIELD(motor) ((RegisterField) { TMC5272_ENCMODE_ENC_SEL_DECIMAL_MASK, TMC5272_ENCMODE_ENC_SEL_DECIMAL_SHIFT, TMC5272_ENCMODE(motor), false }) +#define TMC5272_ENCMODE_NBEMF_ABN_SEL_MASK 0x00000800 +#define TMC5272_ENCMODE_NBEMF_ABN_SEL_SHIFT 11 +#define TMC5272_ENCMODE_NBEMF_ABN_SEL_FIELD(motor) ((RegisterField) { TMC5272_ENCMODE_NBEMF_ABN_SEL_MASK, TMC5272_ENCMODE_NBEMF_ABN_SEL_SHIFT, TMC5272_ENCMODE(motor), false }) +#define TMC5272_ENCMODE_BEMF_HYST_MASK 0x00007000 +#define TMC5272_ENCMODE_BEMF_HYST_SHIFT 12 +#define TMC5272_ENCMODE_BEMF_HYST_FIELD(motor) ((RegisterField) { TMC5272_ENCMODE_BEMF_HYST_MASK, TMC5272_ENCMODE_BEMF_HYST_SHIFT, TMC5272_ENCMODE(motor), false }) +#define TMC5272_ENCMODE_BEMF_BLANK_TIME_MASK 0x00FF0000 +#define TMC5272_ENCMODE_BEMF_BLANK_TIME_SHIFT 16 +#define TMC5272_ENCMODE_BEMF_BLANK_TIME_FIELD(motor) ((RegisterField) { TMC5272_ENCMODE_BEMF_BLANK_TIME_MASK, TMC5272_ENCMODE_BEMF_BLANK_TIME_SHIFT, TMC5272_ENCMODE(motor), false }) +#define TMC5272_ENC_CONST_MASK 0xFFFFFFFF +#define TMC5272_ENC_CONST_SHIFT 0 +#define TMC5272_ENC_CONST_FIELD(motor) ((RegisterField) { TMC5272_ENC_CONST_MASK, TMC5272_ENC_CONST_SHIFT, TMC5272_ENC_CONST(motor), true }) +#define TMC5272_ENC_STATUS_N_EVENT_MASK 0x00000001 +#define TMC5272_ENC_STATUS_N_EVENT_SHIFT 0 +#define TMC5272_ENC_STATUS_N_EVENT_FIELD(motor) ((RegisterField) { TMC5272_ENC_STATUS_N_EVENT_MASK, TMC5272_ENC_STATUS_N_EVENT_SHIFT, TMC5272_ENC_STATUS(motor), false }) +#define TMC5272_ENC_STATUS_DEVIATION_WARN_MASK 0x00000002 +#define TMC5272_ENC_STATUS_DEVIATION_WARN_SHIFT 1 +#define TMC5272_ENC_STATUS_DEVIATION_WARN_FIELD(motor) ((RegisterField) { TMC5272_ENC_STATUS_DEVIATION_WARN_MASK, TMC5272_ENC_STATUS_DEVIATION_WARN_SHIFT, TMC5272_ENC_STATUS(motor), false }) +#define TMC5272_ENC_LATCH_MASK 0xFFFFFFFF +#define TMC5272_ENC_LATCH_SHIFT 0 +#define TMC5272_ENC_LATCH_FIELD(motor) ((RegisterField) { TMC5272_ENC_LATCH_MASK, TMC5272_ENC_LATCH_SHIFT, TMC5272_ENC_LATCH(motor), true }) +#define TMC5272_ENC_DEVIATION_MASK 0x000FFFFF +#define TMC5272_ENC_DEVIATION_SHIFT 0 +#define TMC5272_ENC_DEVIATION_FIELD(motor) ((RegisterField) { TMC5272_ENC_DEVIATION_MASK, TMC5272_ENC_DEVIATION_SHIFT, TMC5272_ENC_DEVIATION(motor), false }) +#define TMC5272_VIRTUAL_STOP_L_MASK 0xFFFFFFFF +#define TMC5272_VIRTUAL_STOP_L_SHIFT 0 +#define TMC5272_VIRTUAL_STOP_L_FIELD(motor) ((RegisterField) { TMC5272_VIRTUAL_STOP_L_MASK, TMC5272_VIRTUAL_STOP_L_SHIFT, TMC5272_VIRTUAL_STOP_L(motor), true }) +#define TMC5272_VIRTUAL_STOP_R_MASK 0xFFFFFFFF +#define TMC5272_VIRTUAL_STOP_R_SHIFT 0 +#define TMC5272_VIRTUAL_STOP_R_FIELD(motor) ((RegisterField) { TMC5272_VIRTUAL_STOP_R_MASK, TMC5272_VIRTUAL_STOP_R_SHIFT, TMC5272_VIRTUAL_STOP_R(motor), true }) +#define TMC5272_MSCNT_MASK 0x000003FF +#define TMC5272_MSCNT_SHIFT 0 +#define TMC5272_MSCNT_FIELD(motor) ((RegisterField) { TMC5272_MSCNT_MASK, TMC5272_MSCNT_SHIFT, TMC5272_MSCNT(motor), false }) +#define TMC5272_MSCURACT_CUR_A_MASK 0x000001FF +#define TMC5272_MSCURACT_CUR_A_SHIFT 0 +#define TMC5272_MSCURACT_CUR_A_FIELD(motor) ((RegisterField) { TMC5272_MSCURACT_CUR_A_MASK, TMC5272_MSCURACT_CUR_A_SHIFT, TMC5272_MSCURACT(motor), false }) +#define TMC5272_MSCURACT_CUR_B_MASK 0x01FF0000 +#define TMC5272_MSCURACT_CUR_B_SHIFT 16 +#define TMC5272_MSCURACT_CUR_B_FIELD(motor) ((RegisterField) { TMC5272_MSCURACT_CUR_B_MASK, TMC5272_MSCURACT_CUR_B_SHIFT, TMC5272_MSCURACT(motor), false }) +#define TMC5272_CHOPCONF_TOFF_MASK 0x0000000F +#define TMC5272_CHOPCONF_TOFF_SHIFT 0 +#define TMC5272_CHOPCONF_TOFF_FIELD(motor) ((RegisterField) { TMC5272_CHOPCONF_TOFF_MASK, TMC5272_CHOPCONF_TOFF_SHIFT, TMC5272_CHOPCONF(motor), false }) +#define TMC5272_CHOPCONF_HSTRT_TFD210_MASK 0x00000070 +#define TMC5272_CHOPCONF_HSTRT_TFD210_SHIFT 4 +#define TMC5272_CHOPCONF_HSTRT_TFD210_FIELD(motor) ((RegisterField) { TMC5272_CHOPCONF_HSTRT_TFD210_MASK, TMC5272_CHOPCONF_HSTRT_TFD210_SHIFT, TMC5272_CHOPCONF(motor), false }) +#define TMC5272_CHOPCONF_HEND_OFFSET_MASK 0x00000780 +#define TMC5272_CHOPCONF_HEND_OFFSET_SHIFT 7 +#define TMC5272_CHOPCONF_HEND_OFFSET_FIELD(motor) ((RegisterField) { TMC5272_CHOPCONF_HEND_OFFSET_MASK, TMC5272_CHOPCONF_HEND_OFFSET_SHIFT, TMC5272_CHOPCONF(motor), false }) +#define TMC5272_CHOPCONF_FD3_MASK 0x00000800 +#define TMC5272_CHOPCONF_FD3_SHIFT 11 +#define TMC5272_CHOPCONF_FD3_FIELD(motor) ((RegisterField) { TMC5272_CHOPCONF_FD3_MASK, TMC5272_CHOPCONF_FD3_SHIFT, TMC5272_CHOPCONF(motor), false }) +#define TMC5272_CHOPCONF_DISFDCC_MASK 0x00001000 +#define TMC5272_CHOPCONF_DISFDCC_SHIFT 12 +#define TMC5272_CHOPCONF_DISFDCC_FIELD(motor) ((RegisterField) { TMC5272_CHOPCONF_DISFDCC_MASK, TMC5272_CHOPCONF_DISFDCC_SHIFT, TMC5272_CHOPCONF(motor), false }) +#define TMC5272_CHOPCONF_CHM_MASK 0x00004000 +#define TMC5272_CHOPCONF_CHM_SHIFT 14 +#define TMC5272_CHOPCONF_CHM_FIELD(motor) ((RegisterField) { TMC5272_CHOPCONF_CHM_MASK, TMC5272_CHOPCONF_CHM_SHIFT, TMC5272_CHOPCONF(motor), false }) +#define TMC5272_CHOPCONF_TBL_MASK 0x00018000 +#define TMC5272_CHOPCONF_TBL_SHIFT 15 +#define TMC5272_CHOPCONF_TBL_FIELD(motor) ((RegisterField) { TMC5272_CHOPCONF_TBL_MASK, TMC5272_CHOPCONF_TBL_SHIFT, TMC5272_CHOPCONF(motor), false }) +#define TMC5272_CHOPCONF_VHIGHFS_MASK 0x00040000 +#define TMC5272_CHOPCONF_VHIGHFS_SHIFT 18 +#define TMC5272_CHOPCONF_VHIGHFS_FIELD(motor) ((RegisterField) { TMC5272_CHOPCONF_VHIGHFS_MASK, TMC5272_CHOPCONF_VHIGHFS_SHIFT, TMC5272_CHOPCONF(motor), false }) +#define TMC5272_CHOPCONF_VHIGHCHM_MASK 0x00080000 +#define TMC5272_CHOPCONF_VHIGHCHM_SHIFT 19 +#define TMC5272_CHOPCONF_VHIGHCHM_FIELD(motor) ((RegisterField) { TMC5272_CHOPCONF_VHIGHCHM_MASK, TMC5272_CHOPCONF_VHIGHCHM_SHIFT, TMC5272_CHOPCONF(motor), false }) +#define TMC5272_CHOPCONF_TPFD_MASK 0x00F00000 +#define TMC5272_CHOPCONF_TPFD_SHIFT 20 +#define TMC5272_CHOPCONF_TPFD_FIELD(motor) ((RegisterField) { TMC5272_CHOPCONF_TPFD_MASK, TMC5272_CHOPCONF_TPFD_SHIFT, TMC5272_CHOPCONF(motor), false }) +#define TMC5272_CHOPCONF_MRES_MASK 0x0F000000 +#define TMC5272_CHOPCONF_MRES_SHIFT 24 +#define TMC5272_CHOPCONF_MRES_FIELD(motor) ((RegisterField) { TMC5272_CHOPCONF_MRES_MASK, TMC5272_CHOPCONF_MRES_SHIFT, TMC5272_CHOPCONF(motor), false }) +#define TMC5272_CHOPCONF_INTPOL_MASK 0x10000000 +#define TMC5272_CHOPCONF_INTPOL_SHIFT 28 +#define TMC5272_CHOPCONF_INTPOL_FIELD(motor) ((RegisterField) { TMC5272_CHOPCONF_INTPOL_MASK, TMC5272_CHOPCONF_INTPOL_SHIFT, TMC5272_CHOPCONF(motor), false }) +#define TMC5272_CHOPCONF_DEDGE_MASK 0x20000000 +#define TMC5272_CHOPCONF_DEDGE_SHIFT 29 +#define TMC5272_CHOPCONF_DEDGE_FIELD(motor) ((RegisterField) { TMC5272_CHOPCONF_DEDGE_MASK, TMC5272_CHOPCONF_DEDGE_SHIFT, TMC5272_CHOPCONF(motor), false }) +#define TMC5272_CHOPCONF_DISS2G_MASK 0x40000000 +#define TMC5272_CHOPCONF_DISS2G_SHIFT 30 +#define TMC5272_CHOPCONF_DISS2G_FIELD(motor) ((RegisterField) { TMC5272_CHOPCONF_DISS2G_MASK, TMC5272_CHOPCONF_DISS2G_SHIFT, TMC5272_CHOPCONF(motor), false }) +#define TMC5272_CHOPCONF_DISS2VS_MASK 0x80000000 +#define TMC5272_CHOPCONF_DISS2VS_SHIFT 31 +#define TMC5272_CHOPCONF_DISS2VS_FIELD(motor) ((RegisterField) { TMC5272_CHOPCONF_DISS2VS_MASK, TMC5272_CHOPCONF_DISS2VS_SHIFT, TMC5272_CHOPCONF(motor), false }) +#define TMC5272_COOLCONF_SEMIN_MASK 0x0000000F +#define TMC5272_COOLCONF_SEMIN_SHIFT 0 +#define TMC5272_COOLCONF_SEMIN_FIELD(motor) ((RegisterField) { TMC5272_COOLCONF_SEMIN_MASK, TMC5272_COOLCONF_SEMIN_SHIFT, TMC5272_COOLCONF(motor), false }) +#define TMC5272_COOLCONF_SEUP_MASK 0x00000060 +#define TMC5272_COOLCONF_SEUP_SHIFT 5 +#define TMC5272_COOLCONF_SEUP_FIELD(motor) ((RegisterField) { TMC5272_COOLCONF_SEUP_MASK, TMC5272_COOLCONF_SEUP_SHIFT, TMC5272_COOLCONF(motor), false }) +#define TMC5272_COOLCONF_SEMAX_MASK 0x00000F00 +#define TMC5272_COOLCONF_SEMAX_SHIFT 8 +#define TMC5272_COOLCONF_SEMAX_FIELD(motor) ((RegisterField) { TMC5272_COOLCONF_SEMAX_MASK, TMC5272_COOLCONF_SEMAX_SHIFT, TMC5272_COOLCONF(motor), false }) +#define TMC5272_COOLCONF_SEDN_MASK 0x00006000 +#define TMC5272_COOLCONF_SEDN_SHIFT 13 +#define TMC5272_COOLCONF_SEDN_FIELD(motor) ((RegisterField) { TMC5272_COOLCONF_SEDN_MASK, TMC5272_COOLCONF_SEDN_SHIFT, TMC5272_COOLCONF(motor), false }) +#define TMC5272_COOLCONF_SEIMIN_MASK 0x00008000 +#define TMC5272_COOLCONF_SEIMIN_SHIFT 15 +#define TMC5272_COOLCONF_SEIMIN_FIELD(motor) ((RegisterField) { TMC5272_COOLCONF_SEIMIN_MASK, TMC5272_COOLCONF_SEIMIN_SHIFT, TMC5272_COOLCONF(motor), false }) +#define TMC5272_COOLCONF_SGT_MASK 0x007F0000 +#define TMC5272_COOLCONF_SGT_SHIFT 16 +#define TMC5272_COOLCONF_SGT_FIELD(motor) ((RegisterField) { TMC5272_COOLCONF_SGT_MASK, TMC5272_COOLCONF_SGT_SHIFT, TMC5272_COOLCONF(motor), true }) +#define TMC5272_COOLCONF_SFILT_MASK 0x01000000 +#define TMC5272_COOLCONF_SFILT_SHIFT 24 +#define TMC5272_COOLCONF_SFILT_FIELD(motor) ((RegisterField) { TMC5272_COOLCONF_SFILT_MASK, TMC5272_COOLCONF_SFILT_SHIFT, TMC5272_COOLCONF(motor), false }) +#define TMC5272_DCCTRL_DC_TIME_MASK 0x000003FF +#define TMC5272_DCCTRL_DC_TIME_SHIFT 0 +#define TMC5272_DCCTRL_DC_TIME_FIELD(motor) ((RegisterField) { TMC5272_DCCTRL_DC_TIME_MASK, TMC5272_DCCTRL_DC_TIME_SHIFT, TMC5272_DCCTRL(motor), false }) +#define TMC5272_DCCTRL_DC_SG_MASK 0x00FFFC00 +#define TMC5272_DCCTRL_DC_SG_SHIFT 10 +#define TMC5272_DCCTRL_DC_SG_FIELD(motor) ((RegisterField) { TMC5272_DCCTRL_DC_SG_MASK, TMC5272_DCCTRL_DC_SG_SHIFT, TMC5272_DCCTRL(motor), false }) +#define TMC5272_DRV_STATUS_SG_RESULT_MASK 0x000003FF +#define TMC5272_DRV_STATUS_SG_RESULT_SHIFT 0 +#define TMC5272_DRV_STATUS_SG_RESULT_FIELD(motor) ((RegisterField) { TMC5272_DRV_STATUS_SG_RESULT_MASK, TMC5272_DRV_STATUS_SG_RESULT_SHIFT, TMC5272_DRV_STATUS(motor), false }) +#define TMC5272_DRV_STATUS_S2VSA_MASK 0x00001000 +#define TMC5272_DRV_STATUS_S2VSA_SHIFT 12 +#define TMC5272_DRV_STATUS_S2VSA_FIELD(motor) ((RegisterField) { TMC5272_DRV_STATUS_S2VSA_MASK, TMC5272_DRV_STATUS_S2VSA_SHIFT, TMC5272_DRV_STATUS(motor), false }) +#define TMC5272_DRV_STATUS_S2VSB_MASK 0x00002000 +#define TMC5272_DRV_STATUS_S2VSB_SHIFT 13 +#define TMC5272_DRV_STATUS_S2VSB_FIELD(motor) ((RegisterField) { TMC5272_DRV_STATUS_S2VSB_MASK, TMC5272_DRV_STATUS_S2VSB_SHIFT, TMC5272_DRV_STATUS(motor), false }) +#define TMC5272_DRV_STATUS_STEALTH_MASK 0x00004000 +#define TMC5272_DRV_STATUS_STEALTH_SHIFT 14 +#define TMC5272_DRV_STATUS_STEALTH_FIELD(motor) ((RegisterField) { TMC5272_DRV_STATUS_STEALTH_MASK, TMC5272_DRV_STATUS_STEALTH_SHIFT, TMC5272_DRV_STATUS(motor), false }) +#define TMC5272_DRV_STATUS_FSACTIVE_MASK 0x00008000 +#define TMC5272_DRV_STATUS_FSACTIVE_SHIFT 15 +#define TMC5272_DRV_STATUS_FSACTIVE_FIELD(motor) ((RegisterField) { TMC5272_DRV_STATUS_FSACTIVE_MASK, TMC5272_DRV_STATUS_FSACTIVE_SHIFT, TMC5272_DRV_STATUS(motor), false }) +#define TMC5272_DRV_STATUS_CS_ACTUAL_MASK 0x001F0000 +#define TMC5272_DRV_STATUS_CS_ACTUAL_SHIFT 16 +#define TMC5272_DRV_STATUS_CS_ACTUAL_FIELD(motor) ((RegisterField) { TMC5272_DRV_STATUS_CS_ACTUAL_MASK, TMC5272_DRV_STATUS_CS_ACTUAL_SHIFT, TMC5272_DRV_STATUS(motor), false }) +#define TMC5272_DRV_STATUS_STALLGUARD_MASK 0x01000000 +#define TMC5272_DRV_STATUS_STALLGUARD_SHIFT 24 +#define TMC5272_DRV_STATUS_STALLGUARD_FIELD(motor) ((RegisterField) { TMC5272_DRV_STATUS_STALLGUARD_MASK, TMC5272_DRV_STATUS_STALLGUARD_SHIFT, TMC5272_DRV_STATUS(motor), false }) +#define TMC5272_DRV_STATUS_OT_MASK 0x02000000 +#define TMC5272_DRV_STATUS_OT_SHIFT 25 +#define TMC5272_DRV_STATUS_OT_FIELD(motor) ((RegisterField) { TMC5272_DRV_STATUS_OT_MASK, TMC5272_DRV_STATUS_OT_SHIFT, TMC5272_DRV_STATUS(motor), false }) +#define TMC5272_DRV_STATUS_OTPW_MASK 0x04000000 +#define TMC5272_DRV_STATUS_OTPW_SHIFT 26 +#define TMC5272_DRV_STATUS_OTPW_FIELD(motor) ((RegisterField) { TMC5272_DRV_STATUS_OTPW_MASK, TMC5272_DRV_STATUS_OTPW_SHIFT, TMC5272_DRV_STATUS(motor), false }) +#define TMC5272_DRV_STATUS_S2GA_MASK 0x08000000 +#define TMC5272_DRV_STATUS_S2GA_SHIFT 27 +#define TMC5272_DRV_STATUS_S2GA_FIELD(motor) ((RegisterField) { TMC5272_DRV_STATUS_S2GA_MASK, TMC5272_DRV_STATUS_S2GA_SHIFT, TMC5272_DRV_STATUS(motor), false }) +#define TMC5272_DRV_STATUS_S2GB_MASK 0x10000000 +#define TMC5272_DRV_STATUS_S2GB_SHIFT 28 +#define TMC5272_DRV_STATUS_S2GB_FIELD(motor) ((RegisterField) { TMC5272_DRV_STATUS_S2GB_MASK, TMC5272_DRV_STATUS_S2GB_SHIFT, TMC5272_DRV_STATUS(motor), false }) +#define TMC5272_DRV_STATUS_OLA_MASK 0x20000000 +#define TMC5272_DRV_STATUS_OLA_SHIFT 29 +#define TMC5272_DRV_STATUS_OLA_FIELD(motor) ((RegisterField) { TMC5272_DRV_STATUS_OLA_MASK, TMC5272_DRV_STATUS_OLA_SHIFT, TMC5272_DRV_STATUS(motor), false }) +#define TMC5272_DRV_STATUS_OLB_MASK 0x40000000 +#define TMC5272_DRV_STATUS_OLB_SHIFT 30 +#define TMC5272_DRV_STATUS_OLB_FIELD(motor) ((RegisterField) { TMC5272_DRV_STATUS_OLB_MASK, TMC5272_DRV_STATUS_OLB_SHIFT, TMC5272_DRV_STATUS(motor), false }) +#define TMC5272_DRV_STATUS_STST_MASK 0x80000000 +#define TMC5272_DRV_STATUS_STST_SHIFT 31 +#define TMC5272_DRV_STATUS_STST_FIELD(motor) ((RegisterField) { TMC5272_DRV_STATUS_STST_MASK, TMC5272_DRV_STATUS_STST_SHIFT, TMC5272_DRV_STATUS(motor), false }) +#define TMC5272_PWMCONF_PWM_OFS_MASK 0x000000FF +#define TMC5272_PWMCONF_PWM_OFS_SHIFT 0 +#define TMC5272_PWMCONF_PWM_OFS_FIELD(motor) ((RegisterField) { TMC5272_PWMCONF_PWM_OFS_MASK, TMC5272_PWMCONF_PWM_OFS_SHIFT, TMC5272_PWMCONF(motor), false }) +#define TMC5272_PWMCONF_PWM_GRAD_MASK 0x0000FF00 +#define TMC5272_PWMCONF_PWM_GRAD_SHIFT 8 +#define TMC5272_PWMCONF_PWM_GRAD_FIELD(motor) ((RegisterField) { TMC5272_PWMCONF_PWM_GRAD_MASK, TMC5272_PWMCONF_PWM_GRAD_SHIFT, TMC5272_PWMCONF(motor), false }) +#define TMC5272_PWMCONF_PWM_FREQ_MASK 0x00030000 +#define TMC5272_PWMCONF_PWM_FREQ_SHIFT 16 +#define TMC5272_PWMCONF_PWM_FREQ_FIELD(motor) ((RegisterField) { TMC5272_PWMCONF_PWM_FREQ_MASK, TMC5272_PWMCONF_PWM_FREQ_SHIFT, TMC5272_PWMCONF(motor), false }) +#define TMC5272_PWMCONF_PWM_AUTOSCALE_MASK 0x00040000 +#define TMC5272_PWMCONF_PWM_AUTOSCALE_SHIFT 18 +#define TMC5272_PWMCONF_PWM_AUTOSCALE_FIELD(motor) ((RegisterField) { TMC5272_PWMCONF_PWM_AUTOSCALE_MASK, TMC5272_PWMCONF_PWM_AUTOSCALE_SHIFT, TMC5272_PWMCONF(motor), false }) +#define TMC5272_PWMCONF_PWM_AUTOGRAD_MASK 0x00080000 +#define TMC5272_PWMCONF_PWM_AUTOGRAD_SHIFT 19 +#define TMC5272_PWMCONF_PWM_AUTOGRAD_FIELD(motor) ((RegisterField) { TMC5272_PWMCONF_PWM_AUTOGRAD_MASK, TMC5272_PWMCONF_PWM_AUTOGRAD_SHIFT, TMC5272_PWMCONF(motor), false }) +#define TMC5272_PWMCONF_FREEWHEEL_MASK 0x00300000 +#define TMC5272_PWMCONF_FREEWHEEL_SHIFT 20 +#define TMC5272_PWMCONF_FREEWHEEL_FIELD(motor) ((RegisterField) { TMC5272_PWMCONF_FREEWHEEL_MASK, TMC5272_PWMCONF_FREEWHEEL_SHIFT, TMC5272_PWMCONF(motor), false }) +#define TMC5272_PWMCONF_PWM_MEAS_SD_ENABLE_MASK 0x00400000 +#define TMC5272_PWMCONF_PWM_MEAS_SD_ENABLE_SHIFT 22 +#define TMC5272_PWMCONF_PWM_MEAS_SD_ENABLE_FIELD(motor) ((RegisterField) { TMC5272_PWMCONF_PWM_MEAS_SD_ENABLE_MASK, TMC5272_PWMCONF_PWM_MEAS_SD_ENABLE_SHIFT, TMC5272_PWMCONF(motor), false }) +#define TMC5272_PWMCONF_PWM_DIS_REG_STST_MASK 0x00800000 +#define TMC5272_PWMCONF_PWM_DIS_REG_STST_SHIFT 23 +#define TMC5272_PWMCONF_PWM_DIS_REG_STST_FIELD(motor) ((RegisterField) { TMC5272_PWMCONF_PWM_DIS_REG_STST_MASK, TMC5272_PWMCONF_PWM_DIS_REG_STST_SHIFT, TMC5272_PWMCONF(motor), false }) +#define TMC5272_PWMCONF_PWM_REG_MASK 0x0F000000 +#define TMC5272_PWMCONF_PWM_REG_SHIFT 24 +#define TMC5272_PWMCONF_PWM_REG_FIELD(motor) ((RegisterField) { TMC5272_PWMCONF_PWM_REG_MASK, TMC5272_PWMCONF_PWM_REG_SHIFT, TMC5272_PWMCONF(motor), false }) +#define TMC5272_PWMCONF_PWM_LIM_MASK 0xF0000000 +#define TMC5272_PWMCONF_PWM_LIM_SHIFT 28 +#define TMC5272_PWMCONF_PWM_LIM_FIELD(motor) ((RegisterField) { TMC5272_PWMCONF_PWM_LIM_MASK, TMC5272_PWMCONF_PWM_LIM_SHIFT, TMC5272_PWMCONF(motor), false }) +#define TMC5272_PWM_SCALE_PWM_SCALE_SUM_MASK 0x000003FF +#define TMC5272_PWM_SCALE_PWM_SCALE_SUM_SHIFT 0 +#define TMC5272_PWM_SCALE_PWM_SCALE_SUM_FIELD(motor) ((RegisterField) { TMC5272_PWM_SCALE_PWM_SCALE_SUM_MASK, TMC5272_PWM_SCALE_PWM_SCALE_SUM_SHIFT, TMC5272_PWM_SCALE(motor), false }) +#define TMC5272_PWM_SCALE_PWM_SCALE_AUTO_MASK 0x01FF0000 +#define TMC5272_PWM_SCALE_PWM_SCALE_AUTO_SHIFT 16 +#define TMC5272_PWM_SCALE_PWM_SCALE_AUTO_FIELD(motor) ((RegisterField) { TMC5272_PWM_SCALE_PWM_SCALE_AUTO_MASK, TMC5272_PWM_SCALE_PWM_SCALE_AUTO_SHIFT, TMC5272_PWM_SCALE(motor), false }) +#define TMC5272_PWM_AUTO_PWM_OFS_AUTO_MASK 0x000000FF +#define TMC5272_PWM_AUTO_PWM_OFS_AUTO_SHIFT 0 +#define TMC5272_PWM_AUTO_PWM_OFS_AUTO_FIELD(motor) ((RegisterField) { TMC5272_PWM_AUTO_PWM_OFS_AUTO_MASK, TMC5272_PWM_AUTO_PWM_OFS_AUTO_SHIFT, TMC5272_PWM_AUTO(motor), false }) +#define TMC5272_PWM_AUTO_PWM_GRAD_AUTO_MASK 0x00FF0000 +#define TMC5272_PWM_AUTO_PWM_GRAD_AUTO_SHIFT 16 +#define TMC5272_PWM_AUTO_PWM_GRAD_AUTO_FIELD(motor) ((RegisterField) { TMC5272_PWM_AUTO_PWM_GRAD_AUTO_MASK, TMC5272_PWM_AUTO_PWM_GRAD_AUTO_SHIFT, TMC5272_PWM_AUTO(motor), false }) +#define TMC5272_SG4_THRS_SG4_THRS_MASK 0x000000FF +#define TMC5272_SG4_THRS_SG4_THRS_SHIFT 0 +#define TMC5272_SG4_THRS_SG4_THRS_FIELD(motor) ((RegisterField) { TMC5272_SG4_THRS_SG4_THRS_MASK, TMC5272_SG4_THRS_SG4_THRS_SHIFT, TMC5272_SG4_THRS(motor), false }) +#define TMC5272_SG4_THRS_SG4_FILT_EN_MASK 0x00000100 +#define TMC5272_SG4_THRS_SG4_FILT_EN_SHIFT 8 +#define TMC5272_SG4_THRS_SG4_FILT_EN_FIELD(motor) ((RegisterField) { TMC5272_SG4_THRS_SG4_FILT_EN_MASK, TMC5272_SG4_THRS_SG4_FILT_EN_SHIFT, TMC5272_SG4_THRS(motor), false }) +#define TMC5272_SG4_THRS_SG_ANGLE_OFFSET_MASK 0x00000200 +#define TMC5272_SG4_THRS_SG_ANGLE_OFFSET_SHIFT 9 +#define TMC5272_SG4_THRS_SG_ANGLE_OFFSET_FIELD(motor) ((RegisterField) { TMC5272_SG4_THRS_SG_ANGLE_OFFSET_MASK, TMC5272_SG4_THRS_SG_ANGLE_OFFSET_SHIFT, TMC5272_SG4_THRS(motor), false }) +#define TMC5272_SG4_RESULT_SG_RESULT_MASK 0x000003FF +#define TMC5272_SG4_RESULT_SG_RESULT_SHIFT 0 +#define TMC5272_SG4_RESULT_SG_RESULT_FIELD(motor) ((RegisterField) { TMC5272_SG4_RESULT_SG_RESULT_MASK, TMC5272_SG4_RESULT_SG_RESULT_SHIFT, TMC5272_SG4_RESULT(motor), false }) +#define TMC5272_SG4_IND_SG4_IND_0_MASK 0x000000FF +#define TMC5272_SG4_IND_SG4_IND_0_SHIFT 0 +#define TMC5272_SG4_IND_SG4_IND_0_FIELD(motor) ((RegisterField) { TMC5272_SG4_IND_SG4_IND_0_MASK, TMC5272_SG4_IND_SG4_IND_0_SHIFT, TMC5272_SG4_IND(motor), false }) +#define TMC5272_SG4_IND_SG4_IND_1_MASK 0x0000FF00 +#define TMC5272_SG4_IND_SG4_IND_1_SHIFT 8 +#define TMC5272_SG4_IND_SG4_IND_1_FIELD(motor) ((RegisterField) { TMC5272_SG4_IND_SG4_IND_1_MASK, TMC5272_SG4_IND_SG4_IND_1_SHIFT, TMC5272_SG4_IND(motor), false }) +#define TMC5272_SG4_IND_SG4_IND_2_MASK 0x00FF0000 +#define TMC5272_SG4_IND_SG4_IND_2_SHIFT 16 +#define TMC5272_SG4_IND_SG4_IND_2_FIELD(motor) ((RegisterField) { TMC5272_SG4_IND_SG4_IND_2_MASK, TMC5272_SG4_IND_SG4_IND_2_SHIFT, TMC5272_SG4_IND(motor), false }) +#define TMC5272_SG4_IND_SG4_IND_3_MASK 0xFF000000 +#define TMC5272_SG4_IND_SG4_IND_3_SHIFT 24 +#define TMC5272_SG4_IND_SG4_IND_3_FIELD(motor) ((RegisterField) { TMC5272_SG4_IND_SG4_IND_3_MASK, TMC5272_SG4_IND_SG4_IND_3_SHIFT, TMC5272_SG4_IND(motor), false }) + +#endif diff --git a/firmware/lib/tmc/ic/TMC5272/registercall_hierarchy_flowchart_SPI.svg b/firmware/lib/tmc/ic/TMC5272/registercall_hierarchy_flowchart_SPI.svg new file mode 100755 index 0000000..cbad58f --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5272/registercall_hierarchy_flowchart_SPI.svg @@ -0,0 +1,3 @@ + + +

HAL

HAL

APP (Eval)

APP (Eval)

API

API
Read a register
  •  Call tmcXXXX_readRegister function
Read a register...
Returns the register read value
Returns the register read value
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
tmcXXXX.c
tmcXXXX.c
SPI.c
SPI.c
tmcXXXX_eval.c
tmcXXXX_eval.c

 Implementation of SPI_readWrite
  • Sends and receives bytes on the SPI bus
Implementation of SPI_readWrite...
Returns the raw reply data
Returns the raw reply data

Implementation of tmcXXXX_readWriteSPI
  • Sets the CSN pin to LOW
  • Takes the array of data to write
  • Calls hardware function SPI_readWrite
  • Upon completion of data transfer,
    sets CSN to 
    HIGH
Implementation of tmcXXXX_readWriteSPI...
Passes on the raw reply data to the API
Passes on the raw reply data to the API
Implementation of readRegisterSPI
  • Constructs the datagram
  • Calls HAL wrapper function 
Implementation of readRegisterSPI...
tmcXXXX_readWriteSPI
tmcXXXX_readWriteSPI
Parses the reply and returns the register value
Parses the reply and returns the register value
Implementation of tmcXXXX_readRegister 
  • Check which bus is active SPI/UART. (e.g. SPI)
  • Calls bus-specific function (e.g. readRegisterSPI)
 
Implementation of tmcXXXX_readRegister...
Returns the register read value
Returns the register read value
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC5272/registercall_hierarchy_flowchart_UART.svg b/firmware/lib/tmc/ic/TMC5272/registercall_hierarchy_flowchart_UART.svg new file mode 100755 index 0000000..425f60a --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5272/registercall_hierarchy_flowchart_UART.svg @@ -0,0 +1,3 @@ + + +

HAL

HAL

APP (Eval)

APP (Eval)

API

API
Read a register
  •  Call tmcXXXX_readRegister function
Read a register...
Returns the register read value
Returns the register read value
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
tmcXXXX.c
tmcXXXX.c
UART.c
UART.c
tmcXXXX_eval.c
tmcXXXX_eval.c

 Implementation of UART_readWrite
  • Sends and receives bytes on the UART bus
Implementation of UART_readWrite...
Returns the raw reply data
Returns the raw reply data

Implementation of tmcXXXX_readWriteUART
  • Takes the array of data to write
  • Calls hardware function UART_readWrite
Implementation of tmcXXXX_readWriteUART...
Passes on the raw reply data to the API
Passes on the raw reply data to the API
Implementation of readRegisterUART
  • Constructs the datagram
  • Calls HAL wrapper function 
Implementation of readRegisterUART...
tmcXXXX_readWriteUART
tmcXXXX_readWriteUART
Parses the reply and returns the register value
Parses the reply and returns the register value
Implementation of tmcXXXX_readRegister 
  • Check which bus is active SPI/UART. (e.g. UART)
  • Calls bus-specific function (e.g. readRegisterUART)
 
Implementation of tmcXXXX_readRegister...
Returns the register read value
Returns the register read value
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC5272/uml-tmc-api.svg b/firmware/lib/tmc/ic/TMC5272/uml-tmc-api.svg new file mode 100755 index 0000000..5a5f8dd --- /dev/null +++ b/firmware/lib/tmc/ic/TMC5272/uml-tmc-api.svg @@ -0,0 +1,3 @@ + + +

TMCXXXX_HW_Abstraction.h



TMCXXXX_HW_Abstraction.h...
// Constants
#define TMCXXXX_MOTORS              
                          
// Register definitions
#define TMCXXXX_GCONF        
                          ⋮
// Register fields definitions
#define TMCXXXX_GCONF_OTPW_FIELD
                     
// Constants...

TMCXXXX.h



TMCXXXX.h...
extern void tmcXXXX_readWriteSPI();
extern void tmcXXXX_readWriteUART();
extern TMCXXXXBusType tmcXXXX_getBusType();
extern uint8_t tmcXXXX_getNodeAddress();
                                  ⋮
tmcXXXX_readRegister();
tmcXXXX_writeRegister();
                                  ⋮
extern void tmcXXXX_readWriteSPI();...

TMCXXXX.c



TMCXXXX.c...
const uint8_t tmcCRCTable_Poly7Reflected[256] = {...};
int32_t tmcXXXX_readRegister(){
/* Call tmcXXXX_getBusType();
 * Based on bus type, call readRegisterSPI/UART() that
 * further calls tmcXXXX_readWriteSPI/UART();
 * For UART it also calls tmcXXXX_getNodeAddress();
                                           ⋮
}
                                           ⋮
const uint8_t tmcCRCTable_Poly7Reflected[256] = {.....
TMC-API
TMC-API

TMCXXXX_Simple_Rotation.h


TMCXXXX_Simple_Rotation.h...
void initAllMotors();
             ⋮
  
void initAllMotors()...

TMCXXXX_Simple_Rotation.c


TMCXXXX_Simple_Rotation.c...
void initAllMotors(){

// Configuring registers to enable motor drivers etc..
tmcXXXX_writeRegister();
                    ⋮
}
                    ⋮
void initAllMotors(){...
Examples
Examples
User Project
User Project

User_Project.h


User_Project.h

User_Project.c








User_Project.c...

void tmcXXXX_readWriteSPI(){
                           ⋮
}
void tmcXXXX_readWriteUART(){
                           ⋮
}
TMCXXXXBusType tmcXXXX_getBusType(){
                           ⋮
}
uint8_t tmcXXXX_getNodeAddress(){
                           ⋮
}

// User Code
                           ⋮
void tmcXXXX_readWriteSPI(){...
#include "TMCXXXX_HW_Abstraction.h"
#include "TMCXXXX.h"
#include "TMCXXXX_Simple_Rotation.h"
                                ⋮
TMCXXXXBusType bus = IC_BUS_SPI/UART;
uint8_t nodeAddress = <nodeAddress>;
                                ⋮
#include "TMCXXXX_HW_Abstraction.h"...
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC6100/README.md b/firmware/lib/tmc/ic/TMC6100/README.md new file mode 100755 index 0000000..e6315c6 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC6100/README.md @@ -0,0 +1,43 @@ +# TMC6100 + + +## How to use + +To access the TMC6100's registers, the TMC-API offers two functions: **tmc6100_readRegister** and **tmc6100_writeRegister**. +Each of these functions takes in an **icID**, which is used to identify the IC when multiple ICs are connected. This identifier is passed down to the callback functions (see How to Integrate). + +## How to integrate: overview + +1. Include all the files of the TMC-API/ic/tmc/TMC6100 folder into the custom project. +2. Include the TMC6100.h file in the custom source code. +3. Implement the necessary callback functions (see below). +4. (optional): Take a look at the Examples subfolder for ready-made examples of the TMC-API usage. + +## Accessing the TMC6100 via SPI +The following diagram depicts how to access the TMC6100 via SPI using the TMC-API. + +![screenshot](registercall_hierarchy_flowchart_SPI.svg) + +The description of the functions, in the above flowchart, are as follows: +- The functions tmc6100_readRegister and tmc6100_writeRegister are used to read and write the registers respectively. These functions check the current active bus and calls the bus-specific function i.e readRegisterSPI or writeRegisterSPI. +- These bus specific functions constructs the datagram and further calls the bus specific callback 'tmcXXXX_readWriteSPI. +- This callback function further calls the hardware specific read/write function for SPI and needs to be implemented externally. + +### How to integrate: Callback functions +To communicate with TMC6100 IC, the TMC-API library needs to know which bus (UART, SPI) it shall use. For that, the callback function **'tmc6100_getBusType()'** needs to be implemented. +Additionally, implement the following callback functions to access the chip via SPI: +1. **tmc6100_readWriteSPI()**, which is a HAL wrapper function that provides the necessary hardware access. This function should also set the chip select pin CSN to low before starting the data transfer and set to high upon completion. Please refer to the datasheet of the IC for further details. + +## Further info +### Dependency graph for the ICs with new register R/W mechanism +This graph illustrates the relationships between files within the TMC-API library, highlighting dependencies and identifying the files that are essential for integrating the library into the custom projects. + +![screenshot](uml-tmc-api.svg) + +### Example usage: TMC-Evalsystem +**For a reference usage of the TMC-API**, visit the [TMC-Evalsystem](https://github.com/analogdevicesinc/TMC-EvalSystem) + +## Migration status +The TMC6100 has been reworked to the access system described above. For more infos on the status of this and other ICs, check out the [migration page](https://github.com/analogdevicesinc/TMC-API/issues/53). + + diff --git a/firmware/lib/tmc/ic/TMC6100/TMC6100.c b/firmware/lib/tmc/ic/TMC6100/TMC6100.c new file mode 100755 index 0000000..0717296 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC6100/TMC6100.c @@ -0,0 +1,55 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#include "TMC6100.h" + +static int32_t readRegisterSPI(uint16_t icID, uint8_t address); +static void writeRegisterSPI(uint16_t icID, uint8_t address, int32_t value); + +int32_t tmc6100_readRegister(uint16_t icID, uint8_t address) +{ + return readRegisterSPI(icID, address); +} +void tmc6100_writeRegister(uint16_t icID, uint8_t address, int32_t value) +{ + writeRegisterSPI(icID, address, value); +} + +int32_t readRegisterSPI(uint16_t icID, uint8_t address) +{ + uint8_t data[5] = { 0 }; + + // clear write bit + data[0] = address & TMC6100_ADDRESS_MASK; + + // Send the read request + tmc6100_readWriteSPI(icID, &data[0], sizeof(data)); + + // Rewrite address and clear write bit + data[0] = address & TMC6100_ADDRESS_MASK; + + // Send another request to receive the read reply + tmc6100_readWriteSPI(icID, &data[0], sizeof(data)); + + return ((int32_t)data[1] << 24) | ((int32_t) data[2] << 16) | ((int32_t) data[3] << 8) | ((int32_t) data[4]); +} + +void writeRegisterSPI(uint16_t icID, uint8_t address, int32_t value) +{ + uint8_t data[5] = { 0 }; + + data[0] = address | TMC6100_WRITE_BIT; + data[1] = 0xFF & (value>>24); + data[2] = 0xFF & (value>>16); + data[3] = 0xFF & (value>>8); + data[4] = 0xFF & (value>>0); + + // Send the write request + tmc6100_readWriteSPI(icID, &data[0], sizeof(data)); +} diff --git a/firmware/lib/tmc/ic/TMC6100/TMC6100.h b/firmware/lib/tmc/ic/TMC6100/TMC6100.h new file mode 100755 index 0000000..89abdf6 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC6100/TMC6100.h @@ -0,0 +1,69 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#ifndef TMC_IC_TMC6100_H_ +#define TMC_IC_TMC6100_H_ + +#include +#include +#include +#include "TMC6100_HW_Abstraction.h" + +// => TMC-API wrapper +extern void tmc6100_readWriteSPI(uint16_t icID, uint8_t *data, size_t dataLength); +// => TMC-API wrapper + +int32_t tmc6100_readRegister(uint16_t icID, uint8_t address); +void tmc6100_writeRegister(uint16_t icID, uint8_t address, int32_t value); + +typedef struct +{ + uint32_t mask; + uint8_t shift; + uint8_t address; + bool isSigned; +} RegisterField; + +static inline uint32_t tmc6100_fieldExtract(uint32_t data, RegisterField field) +{ + uint32_t value = (data & field.mask) >> field.shift; + + if (field.isSigned) + { + // Apply signedness conversion + uint32_t baseMask = field.mask >> field.shift; + uint32_t signMask = baseMask & (~baseMask >> 1); + value = (value ^ signMask) - signMask; + } + + return value; +} + +static inline uint32_t tmc6100_fieldRead(uint16_t icID, RegisterField field) +{ + uint32_t value = tmc6100_readRegister(icID, field.address); + + return tmc6100_fieldExtract(value, field); +} + +static inline uint32_t tmc6100_fieldUpdate(uint32_t data, RegisterField field, uint32_t value) +{ + return (data & (~field.mask)) | ((value << field.shift) & field.mask); +} + +static inline void tmc6100_fieldWrite(uint16_t icID, RegisterField field, uint32_t value) +{ + uint32_t regValue = tmc6100_readRegister(icID, field.address); + + regValue = tmc6100_fieldUpdate(regValue, field, value); + + tmc6100_writeRegister(icID, field.address, regValue); +} + +#endif /* TMC_IC_TMC6630_H_ */ diff --git a/firmware/lib/tmc/ic/TMC6100/TMC6100_HW_Abstraction.h b/firmware/lib/tmc/ic/TMC6100/TMC6100_HW_Abstraction.h new file mode 100755 index 0000000..a38a6e8 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC6100/TMC6100_HW_Abstraction.h @@ -0,0 +1,182 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + +#ifndef TMC6100_HW_ABSTRACTION +#define TMC6100_HW_ABSTRACTION + + +// Constants +#define TMC6100_MOTORS 1 +#define TMC6100_WRITE_BIT 0x80 +#define TMC6100_ADDRESS_MASK 0x7F +#define TMC6100_MAX_VELOCITY 8388096 +#define TMC6100_MAX_ACCELERATION (uint16_t) 65535 + + +// Registers +#define TMC6100_GCONF 0x00 +#define TMC6100_GSTAT 0x01 +#define TMC6100_IOIN_OUTPUT 0x04 +#define TMC6100_OTP_PROG 0x06 +#define TMC6100_OTP_READ 0x07 +#define TMC6100_FACTORY_CONF 0x08 +#define TMC6100_SHORT_CONF 0x09 +#define TMC6100_DRV_CONF 0x0A + + +// Register fields + +#define TMC6100_DISABLE_MASK 0x00000001 +#define TMC6100_DISABLE_SHIFT 0 +#define TMC6100_DISABLE_FIELD ((RegisterField) {TMC6100_DISABLE_MASK, TMC6100_DISABLE_SHIFT, TMC6100_GCONF, false}) +#define TMC6100_SINGLELINE_MASK 0x00000002 +#define TMC6100_SINGLELINE_SHIFT 1 +#define TMC6100_SINGLELINE_FIELD ((RegisterField) {TMC6100_SINGLELINE_MASK, TMC6100_SINGLELINE_SHIFT, TMC6100_GCONF, false}) +#define TMC6100_FAULTDIRECT_MASK 0x00000004 +#define TMC6100_FAULTDIRECT_SHIFT 2 +#define TMC6100_FAULTDIRECT_FIELD ((RegisterField) {TMC6100_FAULTDIRECT_MASK, TMC6100_FAULTDIRECT_SHIFT, TMC6100_GCONF, false}) +#define TMC6100_UNUSED_MASK 0x00000008 +#define TMC6100_UNUSED_SHIFT 3 +#define TMC6100_UNUSED_FIELD ((RegisterField) {TMC6100_UNUSED_MASK, TMC6100_UNUSED_SHIFT, TMC6100_GCONF, false}) +#define TMC6100_RESERVED_MASK 0x00000040 +#define TMC6100_RESERVED_SHIFT 6 +#define TMC6100_RESERVED_FIELD ((RegisterField) {TMC6100_RESERVED_MASK, TMC6100_RESERVED_SHIFT, TMC6100_GCONF, false}) +#define TMC6100_TEST_MODE_MASK 0x00000080 +#define TMC6100_TEST_MODE_SHIFT 7 +#define TMC6100_TEST_MODE_FIELD ((RegisterField) {TMC6100_TEST_MODE_MASK, TMC6100_TEST_MODE_SHIFT, TMC6100_GCONF, false}) +#define TMC6100_RESET_MASK 0x00000001 +#define TMC6100_RESET_SHIFT 0 +#define TMC6100_RESET_FIELD ((RegisterField) {TMC6100_RESET_MASK, TMC6100_RESET_SHIFT, TMC6100_GSTAT, false}) +#define TMC6100_DRV_OTPW_MASK 0x00000002 +#define TMC6100_DRV_OTPW_SHIFT 1 +#define TMC6100_DRV_OTPW_FIELD ((RegisterField) {TMC6100_DRV_OTPW_MASK, TMC6100_DRV_OTPW_SHIFT, TMC6100_GSTAT, false}) +#define TMC6100_DRV_OT_MASK 0x00000004 +#define TMC6100_DRV_OT_SHIFT 2 +#define TMC6100_DRV_OT_FIELD ((RegisterField) {TMC6100_DRV_OT_MASK, TMC6100_DRV_OT_SHIFT, TMC6100_GSTAT, false}) +#define TMC6100_UV_CP_MASK 0x00000008 +#define TMC6100_UV_CP_SHIFT 3 +#define TMC6100_UV_CP_FIELD ((RegisterField) {TMC6100_UV_CP_MASK, TMC6100_UV_CP_SHIFT, TMC6100_GSTAT, false}) +#define TMC6100_SHORTDET_U_MASK 0x00000010 +#define TMC6100_SHORTDET_U_SHIFT 4 +#define TMC6100_SHORTDET_U_FIELD ((RegisterField) {TMC6100_SHORTDET_U_MASK, TMC6100_SHORTDET_U_SHIFT, TMC6100_GSTAT, false}) +#define TMC6100_S2GU_MASK 0x00000020 +#define TMC6100_S2GU_SHIFT 5 +#define TMC6100_S2GU_FIELD ((RegisterField) {TMC6100_S2GU_MASK, TMC6100_S2GU_SHIFT, TMC6100_GSTAT, false}) +#define TMC6100_S2VSU_MASK 0x00000040 +#define TMC6100_S2VSU_SHIFT 6 +#define TMC6100_S2VSU_FIELD ((RegisterField) {TMC6100_S2VSU_MASK, TMC6100_S2VSU_SHIFT, TMC6100_GSTAT, false}) +#define TMC6100_SHORTDET_V_MASK 0x00000100 +#define TMC6100_SHORTDET_V_SHIFT 8 +#define TMC6100_SHORTDET_V_FIELD ((RegisterField) {TMC6100_SHORTDET_V_MASK, TMC6100_SHORTDET_V_SHIFT, TMC6100_GSTAT, false}) +#define TMC6100_S2GV_MASK 0x00000200 +#define TMC6100_S2GV_SHIFT 9 +#define TMC6100_S2GV_FIELD ((RegisterField) {TMC6100_S2GV_MASK, TMC6100_S2GV_SHIFT, TMC6100_GSTAT, false}) +#define TMC6100_S2VSV_MASK 0x00000400 +#define TMC6100_S2VSV_SHIFT 10 +#define TMC6100_S2VSV_FIELD ((RegisterField) {TMC6100_S2VSV_MASK, TMC6100_S2VSV_SHIFT, TMC6100_GSTAT, false}) +#define TMC6100_SHORTDET_W_MASK 0x00001000 +#define TMC6100_SHORTDET_W_SHIFT 12 +#define TMC6100_SHORTDET_W_FIELD ((RegisterField) {TMC6100_SHORTDET_W_MASK, TMC6100_SHORTDET_W_SHIFT, TMC6100_GSTAT, false}) +#define TMC6100_S2GW_MASK 0x00002000 +#define TMC6100_S2GW_SHIFT 13 +#define TMC6100_S2GW_FIELD ((RegisterField) {TMC6100_S2GW_MASK, TMC6100_S2GW_SHIFT, TMC6100_GSTAT, false}) +#define TMC6100_S2VSW_MASK 0x00004000 +#define TMC6100_S2VSW_SHIFT 14 +#define TMC6100_S2VSW_FIELD ((RegisterField) {TMC6100_S2VSW_MASK, TMC6100_S2VSW_SHIFT, TMC6100_GSTAT, false}) +#define TMC6100_UL_MASK 0x00000001 +#define TMC6100_UL_SHIFT 0 +#define TMC6100_UL_FIELD ((RegisterField) {TMC6100_UL_MASK, TMC6100_UL_SHIFT, TMC6100_IOIN_OUTPUT, false}) +#define TMC6100_UH_MASK 0x00000002 +#define TMC6100_UH_SHIFT 1 +#define TMC6100_UH_FIELD ((RegisterField) {TMC6100_UH_MASK, TMC6100_UH_SHIFT, TMC6100_IOIN_OUTPUT, false}) +#define TMC6100_VL_MASK 0x00000004 +#define TMC6100_VL_SHIFT 2 +#define TMC6100_VL_FIELD ((RegisterField) {TMC6100_VL_MASK, TMC6100_VL_SHIFT, TMC6100_IOIN_OUTPUT, false}) +#define TMC6100_VH_MASK 0x00000008 +#define TMC6100_VH_SHIFT 3 +#define TMC6100_VH_FIELD ((RegisterField) {TMC6100_VH_MASK, TMC6100_VH_SHIFT, TMC6100_IOIN_OUTPUT, false}) +#define TMC6100_WL_MASK 0x00000010 +#define TMC6100_WL_SHIFT 4 +#define TMC6100_WL_FIELD ((RegisterField) {TMC6100_WL_MASK, TMC6100_WL_SHIFT, TMC6100_IOIN_OUTPUT, false}) +#define TMC6100_WH_MASK 0x00000020 +#define TMC6100_WH_SHIFT 5 +#define TMC6100_WH_FIELD ((RegisterField) {TMC6100_WH_MASK, TMC6100_WH_SHIFT, TMC6100_IOIN_OUTPUT, false}) +#define TMC6100_DRV_EN_MASK 0x00000040 +#define TMC6100_DRV_EN_SHIFT 6 +#define TMC6100_DRV_EN_FIELD ((RegisterField) {TMC6100_DRV_EN_MASK, TMC6100_DRV_EN_SHIFT, TMC6100_IOIN_OUTPUT, false}) +#define TMC6100_OTPW_MASK 0x00000100 +#define TMC6100_OTPW_SHIFT 8 +#define TMC6100_OTPW_FIELD ((RegisterField) {TMC6100_OTPW_MASK, TMC6100_OTPW_SHIFT, TMC6100_IOIN_OUTPUT, false}) +#define TMC6100_OT136_C_MASK 0x00000200 +#define TMC6100_OT136_C_SHIFT 9 +#define TMC6100_OT136_C_FIELD ((RegisterField) {TMC6100_OT136_C_MASK, TMC6100_OT136_C_SHIFT, TMC6100_IOIN_OUTPUT, false}) +#define TMC6100_OT143_C_MASK 0x00000400 +#define TMC6100_OT143_C_SHIFT 10 +#define TMC6100_OT143_C_FIELD ((RegisterField) {TMC6100_OT143_C_MASK, TMC6100_OT143_C_SHIFT, TMC6100_IOIN_OUTPUT, false}) +#define TMC6100_OT150_C_MASK 0x00000800 +#define TMC6100_OT150_C_SHIFT 11 +#define TMC6100_OT150_C_FIELD ((RegisterField) {TMC6100_OT150_C_MASK, TMC6100_OT150_C_SHIFT, TMC6100_IOIN_OUTPUT, false}) +#define TMC6100_VERSION_MASK 0xFF000000 +#define TMC6100_VERSION_SHIFT 24 +#define TMC6100_VERSION_FIELD ((RegisterField) {TMC6100_VERSION_MASK, TMC6100_VERSION_SHIFT, TMC6100_IOIN_OUTPUT, false}) +#define TMC6100_OTPBIT_MASK 0x00000007 +#define TMC6100_OTPBIT_SHIFT 0 +#define TMC6100_OTPBIT_FIELD ((RegisterField) {TMC6100_OTPBIT_MASK, TMC6100_OTPBIT_SHIFT, TMC6100_OTP_PROG, false}) +#define TMC6100_OTPBYTE_MASK 0x00000030 +#define TMC6100_OTPBYTE_SHIFT 4 +#define TMC6100_OTPBYTE_FIELD ((RegisterField) {TMC6100_OTPBYTE_MASK, TMC6100_OTPBYTE_SHIFT, TMC6100_OTP_PROG, false}) +#define TMC6100_OTPMAGIC_MASK 0x0000FF00 +#define TMC6100_OTPMAGIC_SHIFT 8 +#define TMC6100_OTPMAGIC_FIELD ((RegisterField) {TMC6100_OTPMAGIC_MASK, TMC6100_OTPMAGIC_SHIFT, TMC6100_OTP_PROG, false}) +#define TMC6100_OTP_BBM_MASK 0x000000C0 +#define TMC6100_OTP_BBM_SHIFT 6 +#define TMC6100_OTP_BBM_FIELD ((RegisterField) {TMC6100_OTP_BBM_MASK, TMC6100_OTP_BBM_SHIFT, TMC6100_OTP_READ, false}) +#define TMC6100_OTP_S2_LEVEL_MASK 0x00000020 +#define TMC6100_OTP_S2_LEVEL_SHIFT 5 +#define TMC6100_OTP_S2_LEVEL_FIELD ((RegisterField) {TMC6100_OTP_S2_LEVEL_MASK, TMC6100_OTP_S2_LEVEL_SHIFT, TMC6100_OTP_READ, false}) +#define TMC6100_OTP_FCLKTRIM_MASK 0x0000001F +#define TMC6100_OTP_FCLKTRIM_SHIFT 0 +#define TMC6100_OTP_FCLKTRIM_FIELD ((RegisterField) {TMC6100_OTP_FCLKTRIM_MASK, TMC6100_OTP_FCLKTRIM_SHIFT, TMC6100_OTP_READ, false}) +#define TMC6100_FACTORY_CONF_MASK 0x0000001F +#define TMC6100_FACTORY_CONF_SHIFT 0 +#define TMC6100_FACTORY_CONF_FIELD ((RegisterField) {TMC6100_FACTORY_CONF_MASK, TMC6100_FACTORY_CONF_SHIFT, TMC6100_FACTORY_CONF, false}) +#define TMC6100_S2VS_LEVEL_MASK 0x0000000F +#define TMC6100_S2VS_LEVEL_SHIFT 0 +#define TMC6100_S2VS_LEVEL_FIELD ((RegisterField) {TMC6100_S2VS_LEVEL_MASK, TMC6100_S2VS_LEVEL_SHIFT, TMC6100_SHORT_CONF, false}) +#define TMC6100_S2G_LEVEL_MASK 0x00000F00 +#define TMC6100_S2G_LEVEL_SHIFT 8 +#define TMC6100_S2G_LEVEL_FIELD ((RegisterField) {TMC6100_S2G_LEVEL_MASK, TMC6100_S2G_LEVEL_SHIFT, TMC6100_SHORT_CONF, false}) +#define TMC6100_SHORTFILTER_MASK 0x00030000 +#define TMC6100_SHORTFILTER_SHIFT 16 +#define TMC6100_SHORTFILTER_FIELD ((RegisterField) {TMC6100_SHORTFILTER_MASK, TMC6100_SHORTFILTER_SHIFT, TMC6100_SHORT_CONF, false}) +#define TMC6100_SHORTDELAY_MASK 0x00100000 +#define TMC6100_SHORTDELAY_SHIFT 20 +#define TMC6100_SHORTDELAY_FIELD ((RegisterField) {TMC6100_SHORTDELAY_MASK, TMC6100_SHORTDELAY_SHIFT, TMC6100_SHORT_CONF, false}) +#define TMC6100_RETRY_MASK 0x03000000 +#define TMC6100_RETRY_SHIFT 24 +#define TMC6100_RETRY_FIELD ((RegisterField) {TMC6100_RETRY_MASK, TMC6100_RETRY_SHIFT, TMC6100_SHORT_CONF, false}) +#define TMC6100_PROTECT_PARALLEL_MASK 0x10000000 +#define TMC6100_PROTECT_PARALLEL_SHIFT 28 +#define TMC6100_PROTECT_PARALLEL_FIELD ((RegisterField) {TMC6100_PROTECT_PARALLEL_MASK, TMC6100_PROTECT_PARALLEL_SHIFT, TMC6100_SHORT_CONF, false}) +#define TMC6100_DISABLE_S2G_MASK 0x20000000 +#define TMC6100_DISABLE_S2G_SHIFT 29 +#define TMC6100_DISABLE_S2G_FIELD ((RegisterField) {TMC6100_DISABLE_S2G_MASK, TMC6100_DISABLE_S2G_SHIFT, TMC6100_SHORT_CONF, false}) +#define TMC6100_DISABLE_S2VS_MASK 0x40000000 +#define TMC6100_DISABLE_S2VS_SHIFT 30 +#define TMC6100_DISABLE_S2VS_FIELD ((RegisterField) {TMC6100_DISABLE_S2VS_MASK, TMC6100_DISABLE_S2VS_SHIFT, TMC6100_SHORT_CONF, false}) +#define TMC6100_BBMCLKS_MASK 0x0000000F +#define TMC6100_BBMCLKS_SHIFT 0 +#define TMC6100_BBMCLKS_FIELD ((RegisterField) {TMC6100_BBMCLKS_MASK, TMC6100_BBMCLKS_SHIFT, TMC6100_DRV_CONF, false}) +#define TMC6100_OTSELECT_MASK 0x00030000 +#define TMC6100_OTSELECT_SHIFT 16 +#define TMC6100_OTSELECT_FIELD ((RegisterField) {TMC6100_OTSELECT_MASK, TMC6100_OTSELECT_SHIFT, TMC6100_DRV_CONF, false}) +#define TMC6100_DRVSTRENGTH_MASK 0x000C0000 +#define TMC6100_DRVSTRENGTH_SHIFT 18 +#define TMC6100_DRVSTRENGTH_FIELD ((RegisterField) {TMC6100_DRVSTRENGTH_MASK, TMC6100_DRVSTRENGTH_SHIFT, TMC6100_DRV_CONF, false}) + +#endif diff --git a/firmware/lib/tmc/ic/TMC6100/registercall_hierarchy_flowchart_SPI.svg b/firmware/lib/tmc/ic/TMC6100/registercall_hierarchy_flowchart_SPI.svg new file mode 100755 index 0000000..cbad58f --- /dev/null +++ b/firmware/lib/tmc/ic/TMC6100/registercall_hierarchy_flowchart_SPI.svg @@ -0,0 +1,3 @@ + + +

HAL

HAL

APP (Eval)

APP (Eval)

API

API
Read a register
  •  Call tmcXXXX_readRegister function
Read a register...
Returns the register read value
Returns the register read value
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
tmcXXXX.c
tmcXXXX.c
SPI.c
SPI.c
tmcXXXX_eval.c
tmcXXXX_eval.c

 Implementation of SPI_readWrite
  • Sends and receives bytes on the SPI bus
Implementation of SPI_readWrite...
Returns the raw reply data
Returns the raw reply data

Implementation of tmcXXXX_readWriteSPI
  • Sets the CSN pin to LOW
  • Takes the array of data to write
  • Calls hardware function SPI_readWrite
  • Upon completion of data transfer,
    sets CSN to 
    HIGH
Implementation of tmcXXXX_readWriteSPI...
Passes on the raw reply data to the API
Passes on the raw reply data to the API
Implementation of readRegisterSPI
  • Constructs the datagram
  • Calls HAL wrapper function 
Implementation of readRegisterSPI...
tmcXXXX_readWriteSPI
tmcXXXX_readWriteSPI
Parses the reply and returns the register value
Parses the reply and returns the register value
Implementation of tmcXXXX_readRegister 
  • Check which bus is active SPI/UART. (e.g. SPI)
  • Calls bus-specific function (e.g. readRegisterSPI)
 
Implementation of tmcXXXX_readRegister...
Returns the register read value
Returns the register read value
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC6100/uml-tmc-api.svg b/firmware/lib/tmc/ic/TMC6100/uml-tmc-api.svg new file mode 100755 index 0000000..5a5f8dd --- /dev/null +++ b/firmware/lib/tmc/ic/TMC6100/uml-tmc-api.svg @@ -0,0 +1,3 @@ + + +

TMCXXXX_HW_Abstraction.h



TMCXXXX_HW_Abstraction.h...
// Constants
#define TMCXXXX_MOTORS              
                          
// Register definitions
#define TMCXXXX_GCONF        
                          ⋮
// Register fields definitions
#define TMCXXXX_GCONF_OTPW_FIELD
                     
// Constants...

TMCXXXX.h



TMCXXXX.h...
extern void tmcXXXX_readWriteSPI();
extern void tmcXXXX_readWriteUART();
extern TMCXXXXBusType tmcXXXX_getBusType();
extern uint8_t tmcXXXX_getNodeAddress();
                                  ⋮
tmcXXXX_readRegister();
tmcXXXX_writeRegister();
                                  ⋮
extern void tmcXXXX_readWriteSPI();...

TMCXXXX.c



TMCXXXX.c...
const uint8_t tmcCRCTable_Poly7Reflected[256] = {...};
int32_t tmcXXXX_readRegister(){
/* Call tmcXXXX_getBusType();
 * Based on bus type, call readRegisterSPI/UART() that
 * further calls tmcXXXX_readWriteSPI/UART();
 * For UART it also calls tmcXXXX_getNodeAddress();
                                           ⋮
}
                                           ⋮
const uint8_t tmcCRCTable_Poly7Reflected[256] = {.....
TMC-API
TMC-API

TMCXXXX_Simple_Rotation.h


TMCXXXX_Simple_Rotation.h...
void initAllMotors();
             ⋮
  
void initAllMotors()...

TMCXXXX_Simple_Rotation.c


TMCXXXX_Simple_Rotation.c...
void initAllMotors(){

// Configuring registers to enable motor drivers etc..
tmcXXXX_writeRegister();
                    ⋮
}
                    ⋮
void initAllMotors(){...
Examples
Examples
User Project
User Project

User_Project.h


User_Project.h

User_Project.c








User_Project.c...

void tmcXXXX_readWriteSPI(){
                           ⋮
}
void tmcXXXX_readWriteUART(){
                           ⋮
}
TMCXXXXBusType tmcXXXX_getBusType(){
                           ⋮
}
uint8_t tmcXXXX_getNodeAddress(){
                           ⋮
}

// User Code
                           ⋮
void tmcXXXX_readWriteSPI(){...
#include "TMCXXXX_HW_Abstraction.h"
#include "TMCXXXX.h"
#include "TMCXXXX_Simple_Rotation.h"
                                ⋮
TMCXXXXBusType bus = IC_BUS_SPI/UART;
uint8_t nodeAddress = <nodeAddress>;
                                ⋮
#include "TMCXXXX_HW_Abstraction.h"...
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC6200/README.md b/firmware/lib/tmc/ic/TMC6200/README.md new file mode 100755 index 0000000..595c6f2 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC6200/README.md @@ -0,0 +1,43 @@ +# TMC6200 + + +## How to use + +To access the TMC6200's registers, the TMC-API offers two functions: **tmc6200_readRegister** and **tmc6200_writeRegister**. +Each of these functions takes in an **icID**, which is used to identify the IC when multiple ICs are connected. This identifier is passed down to the callback functions (see How to Integrate). + +## How to integrate: overview + +1. Include all the files of the TMC-API/ic/tmc/TMC6200 folder into the custom project. +2. Include the TMC6200.h file in the custom source code. +3. Implement the necessary callback functions (see below). +4. (optional): Take a look at the Examples subfolder for ready-made examples of the TMC-API usage. + +## Accessing the TMC6200 via SPI +The following diagram depicts how to access the TMC6200 via SPI using the TMC-API. + +![screenshot](registercall_hierarchy_flowchart_SPI.svg) + +The description of the functions, in the above flowchart, are as follows: +- The functions tmc6200_readRegister and tmc6200_writeRegister are used to read and write the registers respectively. These functions check the current active bus and calls the bus-specific function i.e readRegisterSPI or writeRegisterSPI. +- These bus specific functions constructs the datagram and further calls the bus specific callback 'tmcXXXX_readWriteSPI. +- This callback function further calls the hardware specific read/write function for SPI and needs to be implemented externally. + +### How to integrate: Callback functions +To communicate with TMC6200 IC, the TMC-API library needs to know which bus (UART, SPI) it shall use. For that, the callback function **'tmc6200_getBusType()'** needs to be implemented. +Additionally, implement the following callback functions to access the chip via SPI: +1. **tmc6200_readWriteSPI()**, which is a HAL wrapper function that provides the necessary hardware access. This function should also set the chip select pin CSN to low before starting the data transfer and set to high upon completion. Please refer to the datasheet of the IC for further details. + +## Further info +### Dependency graph for the ICs with new register R/W mechanism +This graph illustrates the relationships between files within the TMC-API library, highlighting dependencies and identifying the files that are essential for integrating the library into the custom projects. + +![screenshot](uml-tmc-api.svg) + +### Example usage: TMC-Evalsystem +**For a reference usage of the TMC-API**, visit the [TMC-Evalsystem](https://github.com/analogdevicesinc/TMC-EvalSystem) + +## Migration status +The TMC6200 has been reworked to the access system described above. For more infos on the status of this and other ICs, check out the [migration page](https://github.com/analogdevicesinc/TMC-API/issues/53). + + diff --git a/firmware/lib/tmc/ic/TMC6200/TMC6200.c b/firmware/lib/tmc/ic/TMC6200/TMC6200.c new file mode 100755 index 0000000..c7595c2 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC6200/TMC6200.c @@ -0,0 +1,55 @@ +/******************************************************************************* +* Copyright © 2018 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#include "TMC6200.h" + +static int32_t readRegisterSPI(uint16_t icID, uint8_t address); +static void writeRegisterSPI(uint16_t icID, uint8_t address, int32_t value); + +int32_t tmc6200_readRegister(uint16_t icID, uint8_t address) +{ + return readRegisterSPI(icID, address); +} +void tmc6200_writeRegister(uint16_t icID, uint8_t address, int32_t value) +{ + writeRegisterSPI(icID, address, value); +} + +int32_t readRegisterSPI(uint16_t icID, uint8_t address) +{ + uint8_t data[5] = { 0 }; + + // clear write bit + data[0] = address & TMC6200_ADDRESS_MASK; + + // Send the read request + tmc6200_readWriteSPI(icID, &data[0], sizeof(data)); + + // Rewrite address and clear write bit + data[0] = address & TMC6200_ADDRESS_MASK; + + // Send another request to receive the read reply + tmc6200_readWriteSPI(icID, &data[0], sizeof(data)); + + return ((int32_t)data[1] << 24) | ((int32_t) data[2] << 16) | ((int32_t) data[3] << 8) | ((int32_t) data[4]); +} + +void writeRegisterSPI(uint16_t icID, uint8_t address, int32_t value) +{ + uint8_t data[5] = { 0 }; + + data[0] = address | TMC6200_WRITE_BIT; + data[1] = 0xFF & (value>>24); + data[2] = 0xFF & (value>>16); + data[3] = 0xFF & (value>>8); + data[4] = 0xFF & (value>>0); + + // Send the write request + tmc6200_readWriteSPI(icID, &data[0], sizeof(data)); +} diff --git a/firmware/lib/tmc/ic/TMC6200/TMC6200.h b/firmware/lib/tmc/ic/TMC6200/TMC6200.h new file mode 100755 index 0000000..6f40f20 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC6200/TMC6200.h @@ -0,0 +1,69 @@ +/******************************************************************************* +* Copyright © 2018 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#ifndef TMC_IC_TMC6200_H_ +#define TMC_IC_TMC6200_H_ + +#include +#include +#include +#include "TMC6200_HW_Abstraction.h" + +// => TMC-API wrapper +extern void tmc6200_readWriteSPI(uint16_t icID, uint8_t *data, size_t dataLength); +// => TMC-API wrapper + +int32_t tmc6200_readRegister(uint16_t icID, uint8_t address); +void tmc6200_writeRegister(uint16_t icID, uint8_t address, int32_t value); + +typedef struct +{ + uint32_t mask; + uint8_t shift; + uint8_t address; + bool isSigned; +} RegisterField; + +static inline uint32_t tmc6200_fieldExtract(uint32_t data, RegisterField field) +{ + uint32_t value = (data & field.mask) >> field.shift; + + if (field.isSigned) + { + // Apply signedness conversion + uint32_t baseMask = field.mask >> field.shift; + uint32_t signMask = baseMask & (~baseMask >> 1); + value = (value ^ signMask) - signMask; + } + + return value; +} + +static inline uint32_t tmc6200_fieldRead(uint16_t icID, RegisterField field) +{ + uint32_t value = tmc6200_readRegister(icID, field.address); + + return tmc6200_fieldExtract(value, field); +} + +static inline uint32_t tmc6200_fieldUpdate(uint32_t data, RegisterField field, uint32_t value) +{ + return (data & (~field.mask)) | ((value << field.shift) & field.mask); +} + +static inline void tmc6200_fieldWrite(uint16_t icID, RegisterField field, uint32_t value) +{ + uint32_t regValue = tmc6200_readRegister(icID, field.address); + + regValue = tmc6200_fieldUpdate(regValue, field, value); + + tmc6200_writeRegister(icID, field.address, regValue); +} + +#endif /* TMC_IC_TMC6200_H_ */ diff --git a/firmware/lib/tmc/ic/TMC6200/TMC6200_HW_Abstraction.h b/firmware/lib/tmc/ic/TMC6200/TMC6200_HW_Abstraction.h new file mode 100755 index 0000000..aa1a8b4 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC6200/TMC6200_HW_Abstraction.h @@ -0,0 +1,183 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + +#ifndef TMC6200_HW_ABSTRACTION +#define TMC6200_HW_ABSTRACTION + + +// Constants +#define TMC6200_MOTORS 1 +#define TMC6200_WRITE_BIT 0x80 +#define TMC6200_ADDRESS_MASK 0x7F +#define TMC6200_MAX_VELOCITY 8388096 +#define TMC6200_MAX_ACCELERATION (uint16_t) 65535 + + +// Registers +#define TMC6200_GCONF 0x00 +#define TMC6200_GSTAT 0x01 +#define TMC6200_IOIN_OUTPUT 0x04 +#define TMC6200_OTP_PROG 0x06 +#define TMC6200_OTP_READ 0x07 +#define TMC6200_FACTORY_CONF 0x08 +#define TMC6200_SHORT_CONF 0x09 +#define TMC6200_DRV_CONF 0x0A + +// Register fields +#define TMC6200_DISABLE_MASK 0x00000001 +#define TMC6200_DISABLE_SHIFT 0 +#define TMC6200_DISABLE_FIELD ((RegisterField) {TMC6200_DISABLE_MASK, TMC6200_DISABLE_SHIFT, TMC6200_GCONF, false}) +#define TMC6200_SINGLELINE_MASK 0x00000002 +#define TMC6200_SINGLELINE_SHIFT 1 +#define TMC6200_SINGLELINE_FIELD ((RegisterField) {TMC6200_SINGLELINE_MASK, TMC6200_SINGLELINE_SHIFT, TMC6200_GCONF, false}) +#define TMC6200_FAULTDIRECT_MASK 0x00000004 +#define TMC6200_FAULTDIRECT_SHIFT 2 +#define TMC6200_FAULTDIRECT_FIELD ((RegisterField) {TMC6200_FAULTDIRECT_MASK, TMC6200_FAULTDIRECT_SHIFT, TMC6200_GCONF, false}) +#define TMC6200_UNUSED_MASK 0x00000008 +#define TMC6200_UNUSED_SHIFT 3 +#define TMC6200_UNUSED_FIELD ((RegisterField) {TMC6200_UNUSED_MASK, TMC6200_UNUSED_SHIFT, TMC6200_GCONF, false}) +#define TMC6200_AMPLIFICATION_MASK 0x00000030 +#define TMC6200_AMPLIFICATION_SHIFT 4 +#define TMC6200_AMPLIFICATION_FIELD ((RegisterField) {TMC6200_AMPLIFICATION_MASK, TMC6200_AMPLIFICATION_SHIFT, TMC6200_GCONF, false}) +#define TMC6200_AMPLIFIER_OFF_MASK 0x00000040 +#define TMC6200_AMPLIFIER_OFF_SHIFT 6 +#define TMC6200_AMPLIFIER_OFF_FIELD ((RegisterField) {TMC6200_AMPLIFIER_OFF_MASK, TMC6200_AMPLIFIER_OFF_SHIFT, TMC6200_GCONF, false}) +#define TMC6200_TEST_MODE_MASK 0x00000080 +#define TMC6200_TEST_MODE_SHIFT 7 +#define TMC6200_TEST_MODE_FIELD ((RegisterField) {TMC6200_TEST_MODE_MASK, TMC6200_TEST_MODE_SHIFT, TMC6200_GCONF, false}) +#define TMC6200_RESET_MASK 0x00000001 +#define TMC6200_RESET_SHIFT 0 +#define TMC6200_RESET_FIELD ((RegisterField) {TMC6200_RESET_MASK, TMC6200_RESET_SHIFT, TMC6200_GSTAT, false}) +#define TMC6200_DRV_OTPW_MASK 0x00000002 +#define TMC6200_DRV_OTPW_SHIFT 1 +#define TMC6200_DRV_OTPW_FIELD ((RegisterField) {TMC6200_DRV_OTPW_MASK, TMC6200_DRV_OTPW_SHIFT, TMC6200_GSTAT, false}) +#define TMC6200_DRV_OT_MASK 0x00000004 +#define TMC6200_DRV_OT_SHIFT 2 +#define TMC6200_DRV_OT_FIELD ((RegisterField) {TMC6200_DRV_OT_MASK, TMC6200_DRV_OT_SHIFT, TMC6200_GSTAT, false}) +#define TMC6200_UV_CP_MASK 0x00000008 +#define TMC6200_UV_CP_SHIFT 3 +#define TMC6200_UV_CP_FIELD ((RegisterField) {TMC6200_UV_CP_MASK, TMC6200_UV_CP_SHIFT, TMC6200_GSTAT, false}) +#define TMC6200_SHORTDET_U_MASK 0x00000010 +#define TMC6200_SHORTDET_U_SHIFT 4 +#define TMC6200_SHORTDET_U_FIELD ((RegisterField) {TMC6200_SHORTDET_U_MASK, TMC6200_SHORTDET_U_SHIFT, TMC6200_GSTAT, false}) +#define TMC6200_S2GU_MASK 0x00000020 +#define TMC6200_S2GU_SHIFT 5 +#define TMC6200_S2GU_FIELD ((RegisterField) {TMC6200_S2GU_MASK, TMC6200_S2GU_SHIFT, TMC6200_GSTAT, false}) +#define TMC6200_S2VSU_MASK 0x00000040 +#define TMC6200_S2VSU_SHIFT 6 +#define TMC6200_S2VSU_FIELD ((RegisterField) {TMC6200_S2VSU_MASK, TMC6200_S2VSU_SHIFT, TMC6200_GSTAT, false}) +#define TMC6200_SHORTDET_V_MASK 0x00000100 +#define TMC6200_SHORTDET_V_SHIFT 8 +#define TMC6200_SHORTDET_V_FIELD ((RegisterField) {TMC6200_SHORTDET_V_MASK, TMC6200_SHORTDET_V_SHIFT, TMC6200_GSTAT, false}) +#define TMC6200_S2GV_MASK 0x00000200 +#define TMC6200_S2GV_SHIFT 9 +#define TMC6200_S2GV_FIELD ((RegisterField) {TMC6200_S2GV_MASK, TMC6200_S2GV_SHIFT, TMC6200_GSTAT, false}) +#define TMC6200_S2VSV_MASK 0x00000400 +#define TMC6200_S2VSV_SHIFT 10 +#define TMC6200_S2VSV_FIELD ((RegisterField) {TMC6200_S2VSV_MASK, TMC6200_S2VSV_SHIFT, TMC6200_GSTAT, false}) +#define TMC6200_SHORTDET_W_MASK 0x00001000 +#define TMC6200_SHORTDET_W_SHIFT 12 +#define TMC6200_SHORTDET_W_FIELD ((RegisterField) {TMC6200_SHORTDET_W_MASK, TMC6200_SHORTDET_W_SHIFT, TMC6200_GSTAT, false}) +#define TMC6200_S2GW_MASK 0x00002000 +#define TMC6200_S2GW_SHIFT 13 +#define TMC6200_S2GW_FIELD ((RegisterField) {TMC6200_S2GW_MASK, TMC6200_S2GW_SHIFT, TMC6200_GSTAT, false}) +#define TMC6200_S2VSW_MASK 0x00004000 +#define TMC6200_S2VSW_SHIFT 14 +#define TMC6200_S2VSW_FIELD ((RegisterField) {TMC6200_S2VSW_MASK, TMC6200_S2VSW_SHIFT, TMC6200_GSTAT, false}) +#define TMC6200_UL_MASK 0x00000001 +#define TMC6200_UL_SHIFT 0 +#define TMC6200_UL_FIELD ((RegisterField) {TMC6200_UL_MASK, TMC6200_UL_SHIFT, TMC6200_IOIN_OUTPUT, false}) +#define TMC6200_UH_MASK 0x00000002 +#define TMC6200_UH_SHIFT 1 +#define TMC6200_UH_FIELD ((RegisterField) {TMC6200_UH_MASK, TMC6200_UH_SHIFT, TMC6200_IOIN_OUTPUT, false}) +#define TMC6200_VL_MASK 0x00000004 +#define TMC6200_VL_SHIFT 2 +#define TMC6200_VL_FIELD ((RegisterField) {TMC6200_VL_MASK, TMC6200_VL_SHIFT, TMC6200_IOIN_OUTPUT, false}) +#define TMC6200_VH_MASK 0x00000008 +#define TMC6200_VH_SHIFT 3 +#define TMC6200_VH_FIELD ((RegisterField) {TMC6200_VH_MASK, TMC6200_VH_SHIFT, TMC6200_IOIN_OUTPUT, false}) +#define TMC6200_WL_MASK 0x00000010 +#define TMC6200_WL_SHIFT 4 +#define TMC6200_WL_FIELD ((RegisterField) {TMC6200_WL_MASK, TMC6200_WL_SHIFT, TMC6200_IOIN_OUTPUT, false}) +#define TMC6200_WH_MASK 0x00000020 +#define TMC6200_WH_SHIFT 5 +#define TMC6200_WH_FIELD ((RegisterField) {TMC6200_WH_MASK, TMC6200_WH_SHIFT, TMC6200_IOIN_OUTPUT, false}) +#define TMC6200_DRV_EN_MASK 0x00000040 +#define TMC6200_DRV_EN_SHIFT 6 +#define TMC6200_DRV_EN_FIELD ((RegisterField) {TMC6200_DRV_EN_MASK, TMC6200_DRV_EN_SHIFT, TMC6200_IOIN_OUTPUT, false}) +#define TMC6200_OTPW_MASK 0x00000100 +#define TMC6200_OTPW_SHIFT 8 +#define TMC6200_OTPW_FIELD ((RegisterField) {TMC6200_OTPW_MASK, TMC6200_OTPW_SHIFT, TMC6200_IOIN_OUTPUT, false}) +#define TMC6200_OT136_C_MASK 0x00000200 +#define TMC6200_OT136_C_SHIFT 9 +#define TMC6200_OT136_C_FIELD ((RegisterField) {TMC6200_OT136_C_MASK, TMC6200_OT136_C_SHIFT, TMC6200_IOIN_OUTPUT, false}) +#define TMC6200_OT143_C_MASK 0x00000400 +#define TMC6200_OT143_C_SHIFT 10 +#define TMC6200_OT143_C_FIELD ((RegisterField) {TMC6200_OT143_C_MASK, TMC6200_OT143_C_SHIFT, TMC6200_IOIN_OUTPUT, false}) +#define TMC6200_OT150_C_MASK 0x00000800 +#define TMC6200_OT150_C_SHIFT 11 +#define TMC6200_OT150_C_FIELD ((RegisterField) {TMC6200_OT150_C_MASK, TMC6200_OT150_C_SHIFT, TMC6200_IOIN_OUTPUT, false}) +#define TMC6200_VERSION_MASK 0xFF000000 +#define TMC6200_VERSION_SHIFT 24 +#define TMC6200_VERSION_FIELD ((RegisterField) {TMC6200_VERSION_MASK, TMC6200_VERSION_SHIFT, TMC6200_IOIN_OUTPUT, false}) +#define TMC6200_OTPBIT_MASK 0x00000007 +#define TMC6200_OTPBIT_SHIFT 0 +#define TMC6200_OTPBIT_FIELD ((RegisterField) {TMC6200_OTPBIT_MASK, TMC6200_OTPBIT_SHIFT, TMC6200_OTP_PROG, false}) +#define TMC6200_OTPBYTE_MASK 0x00000030 +#define TMC6200_OTPBYTE_SHIFT 4 +#define TMC6200_OTPBYTE_FIELD ((RegisterField) {TMC6200_OTPBYTE_MASK, TMC6200_OTPBYTE_SHIFT, TMC6200_OTP_PROG, false}) +#define TMC6200_OTPMAGIC_MASK 0x0000FF00 +#define TMC6200_OTPMAGIC_SHIFT 8 +#define TMC6200_OTPMAGIC_FIELD ((RegisterField) {TMC6200_OTPMAGIC_MASK, TMC6200_OTPMAGIC_SHIFT, TMC6200_OTP_PROG, false}) +#define TMC6200_OTP_BBM_MASK 0x000000C0 +#define TMC6200_OTP_BBM_SHIFT 6 +#define TMC6200_OTP_BBM_FIELD ((RegisterField) {TMC6200_OTP_BBM_MASK, TMC6200_OTP_BBM_SHIFT, TMC6200_OTP_READ, false}) +#define TMC6200_OTP_S2_LEVEL_MASK 0x00000020 +#define TMC6200_OTP_S2_LEVEL_SHIFT 5 +#define TMC6200_OTP_S2_LEVEL_FIELD ((RegisterField) {TMC6200_OTP_S2_LEVEL_MASK, TMC6200_OTP_S2_LEVEL_SHIFT, TMC6200_OTP_READ, false}) +#define TMC6200_OTP_FCLKTRIM_MASK 0x0000001F +#define TMC6200_OTP_FCLKTRIM_SHIFT 0 +#define TMC6200_OTP_FCLKTRIM_FIELD ((RegisterField) {TMC6200_OTP_FCLKTRIM_MASK, TMC6200_OTP_FCLKTRIM_SHIFT, TMC6200_OTP_READ, false}) +#define TMC6200_FACTORY_CONF_MASK 0x0000001F +#define TMC6200_FACTORY_CONF_SHIFT 0 +#define TMC6200_FACTORY_CONF_FIELD ((RegisterField) {TMC6200_FACTORY_CONF_MASK, TMC6200_FACTORY_CONF_SHIFT, TMC6200_FACTORY_CONF, false}) +#define TMC6200_S2VS_LEVEL_MASK 0x0000000F +#define TMC6200_S2VS_LEVEL_SHIFT 0 +#define TMC6200_S2VS_LEVEL_FIELD ((RegisterField) {TMC6200_S2VS_LEVEL_MASK, TMC6200_S2VS_LEVEL_SHIFT, TMC6200_SHORT_CONF, false}) +#define TMC6200_S2G_LEVEL_MASK 0x00000F00 +#define TMC6200_S2G_LEVEL_SHIFT 8 +#define TMC6200_S2G_LEVEL_FIELD ((RegisterField) {TMC6200_S2G_LEVEL_MASK, TMC6200_S2G_LEVEL_SHIFT, TMC6200_SHORT_CONF, false}) +#define TMC6200_SHORTFILTER_MASK 0x00030000 +#define TMC6200_SHORTFILTER_SHIFT 16 +#define TMC6200_SHORTFILTER_FIELD ((RegisterField) {TMC6200_SHORTFILTER_MASK, TMC6200_SHORTFILTER_SHIFT, TMC6200_SHORT_CONF, false}) +#define TMC6200_SHORTDELAY_MASK 0x00100000 +#define TMC6200_SHORTDELAY_SHIFT 20 +#define TMC6200_SHORTDELAY_FIELD ((RegisterField) {TMC6200_SHORTDELAY_MASK, TMC6200_SHORTDELAY_SHIFT, TMC6200_SHORT_CONF, false}) +#define TMC6200_RETRY_MASK 0x03000000 +#define TMC6200_RETRY_SHIFT 24 +#define TMC6200_RETRY_FIELD ((RegisterField) {TMC6200_RETRY_MASK, TMC6200_RETRY_SHIFT, TMC6200_SHORT_CONF, false}) +#define TMC6200_PROTECT_PARALLEL_MASK 0x10000000 +#define TMC6200_PROTECT_PARALLEL_SHIFT 28 +#define TMC6200_PROTECT_PARALLEL_FIELD ((RegisterField) {TMC6200_PROTECT_PARALLEL_MASK, TMC6200_PROTECT_PARALLEL_SHIFT, TMC6200_SHORT_CONF, false}) +#define TMC6200_DISABLE_S2G_MASK 0x20000000 +#define TMC6200_DISABLE_S2G_SHIFT 29 +#define TMC6200_DISABLE_S2G_FIELD ((RegisterField) {TMC6200_DISABLE_S2G_MASK, TMC6200_DISABLE_S2G_SHIFT, TMC6200_SHORT_CONF, false}) +#define TMC6200_DISABLE_S2VS_MASK 0x40000000 +#define TMC6200_DISABLE_S2VS_SHIFT 30 +#define TMC6200_DISABLE_S2VS_FIELD ((RegisterField) {TMC6200_DISABLE_S2VS_MASK, TMC6200_DISABLE_S2VS_SHIFT, TMC6200_SHORT_CONF, false}) +#define TMC6200_BBMCLKS_MASK 0x0000000F +#define TMC6200_BBMCLKS_SHIFT 0 +#define TMC6200_BBMCLKS_FIELD ((RegisterField) {TMC6200_BBMCLKS_MASK, TMC6200_BBMCLKS_SHIFT, TMC6200_DRV_CONF, false}) +#define TMC6200_OTSELECT_MASK 0x00030000 +#define TMC6200_OTSELECT_SHIFT 16 +#define TMC6200_OTSELECT_FIELD ((RegisterField) {TMC6200_OTSELECT_MASK, TMC6200_OTSELECT_SHIFT, TMC6200_DRV_CONF, false}) +#define TMC6200_DRVSTRENGTH_MASK 0x000C0000 +#define TMC6200_DRVSTRENGTH_SHIFT 18 +#define TMC6200_DRVSTRENGTH_FIELD ((RegisterField) {TMC6200_DRVSTRENGTH_MASK, TMC6200_DRVSTRENGTH_SHIFT, TMC6200_DRV_CONF, false}) + +#endif diff --git a/firmware/lib/tmc/ic/TMC6200/registercall_hierarchy_flowchart_SPI.svg b/firmware/lib/tmc/ic/TMC6200/registercall_hierarchy_flowchart_SPI.svg new file mode 100755 index 0000000..cbad58f --- /dev/null +++ b/firmware/lib/tmc/ic/TMC6200/registercall_hierarchy_flowchart_SPI.svg @@ -0,0 +1,3 @@ + + +

HAL

HAL

APP (Eval)

APP (Eval)

API

API
Read a register
  •  Call tmcXXXX_readRegister function
Read a register...
Returns the register read value
Returns the register read value
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
tmcXXXX.c
tmcXXXX.c
SPI.c
SPI.c
tmcXXXX_eval.c
tmcXXXX_eval.c

 Implementation of SPI_readWrite
  • Sends and receives bytes on the SPI bus
Implementation of SPI_readWrite...
Returns the raw reply data
Returns the raw reply data

Implementation of tmcXXXX_readWriteSPI
  • Sets the CSN pin to LOW
  • Takes the array of data to write
  • Calls hardware function SPI_readWrite
  • Upon completion of data transfer,
    sets CSN to 
    HIGH
Implementation of tmcXXXX_readWriteSPI...
Passes on the raw reply data to the API
Passes on the raw reply data to the API
Implementation of readRegisterSPI
  • Constructs the datagram
  • Calls HAL wrapper function 
Implementation of readRegisterSPI...
tmcXXXX_readWriteSPI
tmcXXXX_readWriteSPI
Parses the reply and returns the register value
Parses the reply and returns the register value
Implementation of tmcXXXX_readRegister 
  • Check which bus is active SPI/UART. (e.g. SPI)
  • Calls bus-specific function (e.g. readRegisterSPI)
 
Implementation of tmcXXXX_readRegister...
Returns the register read value
Returns the register read value
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC6200/uml-tmc-api.svg b/firmware/lib/tmc/ic/TMC6200/uml-tmc-api.svg new file mode 100755 index 0000000..5a5f8dd --- /dev/null +++ b/firmware/lib/tmc/ic/TMC6200/uml-tmc-api.svg @@ -0,0 +1,3 @@ + + +

TMCXXXX_HW_Abstraction.h



TMCXXXX_HW_Abstraction.h...
// Constants
#define TMCXXXX_MOTORS              
                          
// Register definitions
#define TMCXXXX_GCONF        
                          ⋮
// Register fields definitions
#define TMCXXXX_GCONF_OTPW_FIELD
                     
// Constants...

TMCXXXX.h



TMCXXXX.h...
extern void tmcXXXX_readWriteSPI();
extern void tmcXXXX_readWriteUART();
extern TMCXXXXBusType tmcXXXX_getBusType();
extern uint8_t tmcXXXX_getNodeAddress();
                                  ⋮
tmcXXXX_readRegister();
tmcXXXX_writeRegister();
                                  ⋮
extern void tmcXXXX_readWriteSPI();...

TMCXXXX.c



TMCXXXX.c...
const uint8_t tmcCRCTable_Poly7Reflected[256] = {...};
int32_t tmcXXXX_readRegister(){
/* Call tmcXXXX_getBusType();
 * Based on bus type, call readRegisterSPI/UART() that
 * further calls tmcXXXX_readWriteSPI/UART();
 * For UART it also calls tmcXXXX_getNodeAddress();
                                           ⋮
}
                                           ⋮
const uint8_t tmcCRCTable_Poly7Reflected[256] = {.....
TMC-API
TMC-API

TMCXXXX_Simple_Rotation.h


TMCXXXX_Simple_Rotation.h...
void initAllMotors();
             ⋮
  
void initAllMotors()...

TMCXXXX_Simple_Rotation.c


TMCXXXX_Simple_Rotation.c...
void initAllMotors(){

// Configuring registers to enable motor drivers etc..
tmcXXXX_writeRegister();
                    ⋮
}
                    ⋮
void initAllMotors(){...
Examples
Examples
User Project
User Project

User_Project.h


User_Project.h

User_Project.c








User_Project.c...

void tmcXXXX_readWriteSPI(){
                           ⋮
}
void tmcXXXX_readWriteUART(){
                           ⋮
}
TMCXXXXBusType tmcXXXX_getBusType(){
                           ⋮
}
uint8_t tmcXXXX_getNodeAddress(){
                           ⋮
}

// User Code
                           ⋮
void tmcXXXX_readWriteSPI(){...
#include "TMCXXXX_HW_Abstraction.h"
#include "TMCXXXX.h"
#include "TMCXXXX_Simple_Rotation.h"
                                ⋮
TMCXXXXBusType bus = IC_BUS_SPI/UART;
uint8_t nodeAddress = <nodeAddress>;
                                ⋮
#include "TMCXXXX_HW_Abstraction.h"...
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC7300/README.md b/firmware/lib/tmc/ic/TMC7300/README.md new file mode 100755 index 0000000..96e98b7 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC7300/README.md @@ -0,0 +1,51 @@ +# TMC7300 + + +## How to use + +To access the TMC7300's registers, the TMC-API offers two functions: **tmc7300_readRegister** and **tmc7300_writeRegister**. +Each of these functions takes in an **icID**, which is used to identify the IC when multiple ICs are connected. This identifier is passed down to the callback functions (see How to Integrate). + +## How to integrate: overview + +1. Include all the files of the TMC-API/ic/tmc/TMC7300 folder into the custom project. +2. Include the TMC7300.h file in the custom source code. +3. Implement the necessary callback functions (see below). +4. (optional): Take a look at the Examples subfolder for ready-made examples of the TMC-API usage. + +## Accessing the TMC7300 via UART +The following diagram depicts how to access the TMC7300 via UART using the TMC-API. + +![screenshot](registercall_hierarchy_flowchart_UART.svg) + +The description of the functions, in the above flowchart, are as follows: +- The functions tmc7300_readRegister and tmc7300_writeRegister are used to read and write the registers respectively. These functions check the current active bus and calls the bus-specific function i.e readRegisterUART or writeRegisterUART. +- These bus specific functions constructs the datagram and further calls the bus specific callback 'tmcXXXX_readWriteUART. +- This callback function further calls the hardware specific read/write function for UART and needs to be implemented externally. + +### How to integrate: Callback functions +To communicate with TMC7300 IC, the TMC-API library needs to know which bus (UART) it shall use. +Additionally, implement the following callback functions to access the chip via UART: +1. **tmc7300_readWriteUART()**, which is a HAL wrapper function that provides the necessary hardware access. +2. **tmc7300_getNodeAddress()**, that returns the node/slave address. Node address could be set in NODECONF (0x3) register and the address could be incremented as defined by AD0, AD1 and AD2. (Node address + ADx) must be less than 255. For further details please consult the datasheet of TMC7300. + +### Sharing the CRC table with other TMC-API chips +The TMC7300 UART protocol uses an 8 bit CRC. For calculating this, a table-based algorithm is used. This table (tmcCRCTable_Poly7Reflected[256]) is 256 bytes big and identical across multiple different Trinamic chips (i.e. TMC7300). +If multiple Trinamic chips are being used in the same project, avoiding redundant copies of this table could save memory. It is possible to substitute this CRC table with another CRC table. + +### Option to use the cache logic for Write-Only registers +The chip features write-only registers that are unable to be read, necessitating the creation of a shadow copy to cache their contents. This copy is automatically updated whenever data is written to these registers. This cache logic could be enabled by setting the macro **TMC7300_CACHE** to **'1'** or disabled by setting to **'0'** respectively. If this feature is enabled then there comes another option to use **tmc7300_cache** function, which is already implemeted in the API, by defining **TMC7300_ENABLE_TMC_CACHE** macro to **'1** or one can implement their own function. The function **tmc7300_cache** works for both reading from and writing to the shadow array. It first checks whether the register has write-only access and data needs to be read from the hadow copy. On the basis of that, it returns **true** or **false**. The shadowRegisters on the premade cache implementation need to be one per chip. **TMC7300_IC_CACHE_COUNT** is set to '1' by default and is user-overwritable. If multiple chips are being used in the same project, increment its value to the number of chips connected. + +## Further info +### Dependency graph for the ICs with new register R/W mechanism +This graph illustrates the relationships between files within the TMC-API library, highlighting dependencies and identifying the files that are essential for integrating the library into the ustom projects. + +![screenshot](uml-tmc-api.svg) + +### Example usage: TMC-Evalsystem +**For a reference usage of the TMC-API**, visit the [TMC-Evalsystem](https://github.com/analogdevicesinc/TMC-EvalSystem) + +## Migration status +The TMC7300 has been reworked to the access system described above. For more infos on the status of this and other ICs, check out the [migration page](https://github.com/analogdevicesinc/TMC-API/issues/53). + + diff --git a/firmware/lib/tmc/ic/TMC7300/TMC7300.c b/firmware/lib/tmc/ic/TMC7300/TMC7300.c new file mode 100755 index 0000000..b47dd63 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC7300/TMC7300.c @@ -0,0 +1,252 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#include "TMC7300.h" + + +#ifdef TMC_API_EXTERNAL_CRC_TABLE +extern const uint8_t tmcCRCTable_Poly7Reflected[256]; +#else +const uint8_t tmcCRCTable_Poly7Reflected[256] = { + 0x00, 0x91, 0xE3, 0x72, 0x07, 0x96, 0xE4, 0x75, 0x0E, 0x9F, 0xED, 0x7C, 0x09, 0x98, 0xEA, 0x7B, + 0x1C, 0x8D, 0xFF, 0x6E, 0x1B, 0x8A, 0xF8, 0x69, 0x12, 0x83, 0xF1, 0x60, 0x15, 0x84, 0xF6, 0x67, + 0x38, 0xA9, 0xDB, 0x4A, 0x3F, 0xAE, 0xDC, 0x4D, 0x36, 0xA7, 0xD5, 0x44, 0x31, 0xA0, 0xD2, 0x43, + 0x24, 0xB5, 0xC7, 0x56, 0x23, 0xB2, 0xC0, 0x51, 0x2A, 0xBB, 0xC9, 0x58, 0x2D, 0xBC, 0xCE, 0x5F, + 0x70, 0xE1, 0x93, 0x02, 0x77, 0xE6, 0x94, 0x05, 0x7E, 0xEF, 0x9D, 0x0C, 0x79, 0xE8, 0x9A, 0x0B, + 0x6C, 0xFD, 0x8F, 0x1E, 0x6B, 0xFA, 0x88, 0x19, 0x62, 0xF3, 0x81, 0x10, 0x65, 0xF4, 0x86, 0x17, + 0x48, 0xD9, 0xAB, 0x3A, 0x4F, 0xDE, 0xAC, 0x3D, 0x46, 0xD7, 0xA5, 0x34, 0x41, 0xD0, 0xA2, 0x33, + 0x54, 0xC5, 0xB7, 0x26, 0x53, 0xC2, 0xB0, 0x21, 0x5A, 0xCB, 0xB9, 0x28, 0x5D, 0xCC, 0xBE, 0x2F, + 0xE0, 0x71, 0x03, 0x92, 0xE7, 0x76, 0x04, 0x95, 0xEE, 0x7F, 0x0D, 0x9C, 0xE9, 0x78, 0x0A, 0x9B, + 0xFC, 0x6D, 0x1F, 0x8E, 0xFB, 0x6A, 0x18, 0x89, 0xF2, 0x63, 0x11, 0x80, 0xF5, 0x64, 0x16, 0x87, + 0xD8, 0x49, 0x3B, 0xAA, 0xDF, 0x4E, 0x3C, 0xAD, 0xD6, 0x47, 0x35, 0xA4, 0xD1, 0x40, 0x32, 0xA3, + 0xC4, 0x55, 0x27, 0xB6, 0xC3, 0x52, 0x20, 0xB1, 0xCA, 0x5B, 0x29, 0xB8, 0xCD, 0x5C, 0x2E, 0xBF, + 0x90, 0x01, 0x73, 0xE2, 0x97, 0x06, 0x74, 0xE5, 0x9E, 0x0F, 0x7D, 0xEC, 0x99, 0x08, 0x7A, 0xEB, + 0x8C, 0x1D, 0x6F, 0xFE, 0x8B, 0x1A, 0x68, 0xF9, 0x82, 0x13, 0x61, 0xF0, 0x85, 0x14, 0x66, 0xF7, + 0xA8, 0x39, 0x4B, 0xDA, 0xAF, 0x3E, 0x4C, 0xDD, 0xA6, 0x37, 0x45, 0xD4, 0xA1, 0x30, 0x42, 0xD3, + 0xB4, 0x25, 0x57, 0xC6, 0xB3, 0x22, 0x50, 0xC1, 0xBA, 0x2B, 0x59, 0xC8, 0xBD, 0x2C, 0x5E, 0xCF, +}; +#endif +/*************************************************************** Cache Implementation *************************************************************************/ + +#if TMC7300_CACHE == 0 +static inline bool tmc7300_cache(uint16_t icID, TMC7300CacheOp operation, uint8_t address, uint32_t *value) +{ + UNUSED(icID); + UNUSED(address); + UNUSED(operation); + return false; +} +#else +#if TMC7300_ENABLE_TMC_CACHE == 1 + +uint8_t tmc7300_dirtyBits[TMC7300_IC_CACHE_COUNT][TMC7300_REGISTER_COUNT/8]= {0}; +int32_t tmc7300_shadowRegister[TMC7300_IC_CACHE_COUNT][TMC7300_REGISTER_COUNT]; + +void tmc7300_setDirtyBit(uint16_t icID, uint8_t index, bool value) +{ + if(index >= TMC7300_REGISTER_COUNT) + return; + + uint8_t *tmp = &tmc7300_dirtyBits[icID][index / 8]; + uint8_t shift = (index % 8); + uint8_t mask = 1 << shift; + *tmp = (((*tmp) & (~(mask))) | (((value) << (shift)) & (mask))); +} + +bool tmc7300_getDirtyBit(uint16_t icID, uint8_t index) +{ + if(index >= TMC7300_REGISTER_COUNT) + return false; + + uint8_t *tmp = &tmc7300_dirtyBits[icID][index / 8]; + uint8_t shift = (index % 8); + return ((*tmp) >> shift) & 1; +} +/* + * This function is used to cache the value written to the Write-Only registers in the form of shadow array. + * The shadow copy is then used to read these kinds of registers. + */ + +bool tmc7300_cache(uint16_t icID, TMC7300CacheOp operation, uint8_t address, uint32_t *value) +{ + if (operation == TMC7300_CACHE_READ) + { + // Check if the value should come from cache + + // Only supported chips have a cache + if (icID >= TMC7300_IC_CACHE_COUNT) + return false; + + // Only non-readable registers care about caching + // Note: This could also be used to cache i.e. RW config registers to reduce bus accesses + if (TMC7300_IS_READABLE(tmc7300_registerAccess[address])) + return false; + + // Grab the value from the cache + *value = tmc7300_shadowRegister[icID][address]; + return true; + } + else if (operation == TMC7300_CACHE_WRITE || operation == TMC7300_CACHE_FILL_DEFAULT) + { + // Fill the cache + + // only supported chips have a cache + if (icID >= TMC7300_IC_CACHE_COUNT) + return false; + + // Write to the shadow register. + tmc7300_shadowRegister[icID][address] = *value; + // For write operations, mark the register dirty + if (operation == TMC7300_CACHE_WRITE) + { + tmc7300_setDirtyBit(icID, address, true); + } + + return true; + } + return false; +} + +void tmc7300_initCache() +{ + // Check if we have constants defined + if(ARRAY_SIZE(tmc7300_RegisterConstants) == 0) + return; + + size_t i, j, id; + + for(i = 0, j = 0; i < TMC7300_REGISTER_COUNT; i++) + { + // We only need to worry about hardware preset, write-only registers + // that have not yet been written (no dirty bit) here. + if(tmc7300_registerAccess[i] != TMC7300_ACCESS_W_PRESET && tmc7300_registerAccess[i] != TMC7300_ACCESS_RW_PRESET) + continue; + + // Search the constant list for the current address. With the constant + // list being sorted in ascended order, we can walk through the list + // until the entry with an address equal or greater than i + while(j < ARRAY_SIZE(tmc7300_RegisterConstants) && (tmc7300_RegisterConstants[j].address < i)) + j++; + + // Abort when we reach the end of the constant list + if (j == ARRAY_SIZE(tmc7300_RegisterConstants)) + break; + + // If we have an entry for our current address, write the constant + if(tmc7300_RegisterConstants[j].address == i) + { + for (id = 0; id < TMC7300_IC_CACHE_COUNT; id++) + { + uint32_t temp = tmc7300_RegisterConstants[j].value; + tmc7300_cache(id, TMC7300_CACHE_FILL_DEFAULT, i, &temp); + } + } + } +} +#else +// User must implement their own cache +extern bool tmc7300_cache(uint16_t icID, TMC7300CacheOp operation, uint8_t address, uint32_t *value); +#endif +#endif + +/************************************************************* read / write Implementation *********************************************************************/ + + +static int32_t readRegisterUART(uint16_t icID, uint8_t registerAddress); +static void writeRegisterUART(uint16_t icID, uint8_t registerAddress, int32_t value ); +static uint8_t CRC8(uint8_t *data, uint32_t bytes); + +int32_t tmc7300_readRegister(uint16_t icID, uint8_t address) +{ + return readRegisterUART(icID, address); +} + + +void tmc7300_writeRegister(uint16_t icID, uint8_t address, int32_t value ) +{ + writeRegisterUART(icID, address, value); +} + + +int32_t readRegisterUART(uint16_t icID, uint8_t registerAddress) +{ + uint32_t value; + + // Read from cache for registers with write-only access + if (tmc7300_cache(icID, TMC7300_CACHE_READ, registerAddress, &value)) + return value; + + uint8_t data[8] = { 0 }; + registerAddress = registerAddress & TMC7300_ADDRESS_MASK; + + data[0] = 0x05; + data[1] = tmc7300_getNodeAddress(icID); + data[2] = registerAddress; + data[3] = CRC8(data, 3); + + if (!tmc7300_readWriteUART(icID, &data[0], 4, 8)) + return tmc7300_shadowRegister[0][registerAddress]; + + // Byte 0: Sync nibble correct? + if (data[0] != 0x05) + return 0; + + // Byte 1: Master address correct? + if (data[1] != 0xFF) + return 0; + + // Byte 2: Address correct? + if (data[2] != registerAddress) + return 0; + + // Byte 7: CRC correct? + if (data[7] != CRC8(data, 7)) + return 0; + + return ((uint32_t)data[3] << 24) | ((uint32_t)data[4] << 16) | (data[5] << 8) | data[6]; +} + +void writeRegisterUART(uint16_t icID, uint8_t registerAddress, int32_t value ) +{ + uint8_t data[8]; + + data[0] = 0x05; + data[1] = tmc7300_getNodeAddress(icID); + data[2] = registerAddress | TMC7300_WRITE_BIT; + data[3] = (value >> 24) & 0xFF; + data[4] = (value >> 16) & 0xFF; + data[5] = (value >> 8 ) & 0xFF; + data[6] = (value ) & 0xFF; + data[7] = CRC8(data, 7); + + tmc7300_readWriteUART(icID, &data[0], 8, 0); + + + // Write to the shadow register and mark the register dirty + //Cache the registers with write-only access + tmc7300_cache(icID, TMC7300_CACHE_WRITE, registerAddress, (uint32_t *)&value); +} + +static uint8_t CRC8(uint8_t *data, uint32_t bytes) +{ + uint8_t result = 0; + + while(bytes--) + result = tmcCRCTable_Poly7Reflected[result ^ *data++]; + + // Flip the result around + // swap odd and even bits + result = ((result >> 1) & 0x55) | ((result & 0x55) << 1); + // swap consecutive pairs + result = ((result >> 2) & 0x33) | ((result & 0x33) << 2); + // swap nibbles ... + result = ((result >> 4) & 0x0F) | ((result & 0x0F) << 4); + + return result; +} diff --git a/firmware/lib/tmc/ic/TMC7300/TMC7300.h b/firmware/lib/tmc/ic/TMC7300/TMC7300.h new file mode 100755 index 0000000..875282f --- /dev/null +++ b/firmware/lib/tmc/ic/TMC7300/TMC7300.h @@ -0,0 +1,203 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#ifndef TMC_IC_TMC7300_H_ +#define TMC_IC_TMC7300_H_ + +#include +#include +#include +#include "TMC7300_HW_Abstraction.h" + + +/******************************************************************************* + * API Configuration Defines + * These control optional features of the TMC-API implementation. + * These can be commented in/out here or defined from the build system. + *******************************************************************************/ + +// Uncomment if you want to save space..... +// and put the table into your own .c file +//#define TMC_API_EXTERNAL_CRC_TABLE 1 + +// To enable the cache mechanism in order to keep the copy of all registers, set TMC7300_CACHE to '1'. +// With this mechanism the value of write-only registers could be read from their shadow copies. +#ifndef TMC7300_CACHE +#define TMC7300_CACHE 1 +//#define TMC7300_CACHE 0 +#endif + +// To use the caching mechanism already implemented by the TMC-API, set TMC7300_ENABLE_TMC_CACHE to '1'. +// Set TMC7300_ENABLE_TMC_CACHE to '0' if one wants to have their own cache implementation. +#ifndef TMC7300_ENABLE_TMC_CACHE +#define TMC7300_ENABLE_TMC_CACHE 1 +//#define TMC7300_ENABLE_TMC_CACHE 0 +#endif + +/******************************************************************************/ + + +/************************************************************* read / write Implementation *********************************************************************/ + +// => TMC-API wrapper +extern bool tmc7300_readWriteUART(uint16_t icID, uint8_t *data, size_t writeLength, size_t readLength); +extern uint8_t tmc7300_getNodeAddress(uint16_t icID); +// => TMC-API wrapper + +int32_t tmc7300_readRegister(uint16_t icID, uint8_t address); +void tmc7300_writeRegister(uint16_t icID, uint8_t address, int32_t value); + +typedef struct +{ + uint32_t mask; + uint8_t shift; + uint8_t address; + bool isSigned; +} RegisterField; + +static inline uint32_t tmc7300_fieldExtract(uint32_t data, RegisterField field) +{ + uint32_t value = (data & field.mask) >> field.shift; + + if (field.isSigned) + { + // Apply signedness conversion + uint32_t baseMask = field.mask >> field.shift; + uint32_t signMask = baseMask & (~baseMask >> 1); + value = (value ^ signMask) - signMask; + } + + return value; +} + +static inline uint32_t tmc7300_fieldRead(uint16_t icID, RegisterField field) +{ + uint32_t value = tmc7300_readRegister(icID, field.address); + + return tmc7300_fieldExtract(value, field); +} + +static inline uint32_t tmc7300_fieldUpdate(uint32_t data, RegisterField field, uint32_t value) +{ + return (data & (~field.mask)) | ((value << field.shift) & field.mask); +} + +static inline void tmc7300_fieldWrite(uint16_t icID, RegisterField field, uint32_t value) +{ + uint32_t regValue = tmc7300_readRegister(icID, field.address); + + regValue = tmc7300_fieldUpdate(regValue, field, value); + + tmc7300_writeRegister(icID, field.address, regValue); +} +/**************************************************************** Cache Implementation *************************************************************************/ +#if TMC7300_CACHE == 1 +#ifdef TMC7300_ENABLE_TMC_CACHE + +// By default, support one IC in the cache +#ifndef TMC7300_IC_CACHE_COUNT +#define TMC7300_IC_CACHE_COUNT 1 +#endif + +#define TMC7300_ACCESS_DIRTY 0x08 // Register has been written since reset -> shadow register is valid for restore +#define TMC7300_ACCESS_READ 0x01 +#define TMC7300_ACCESS_W_PRESET 0x42 +#define TMC7300_ACCESS_RW_PRESET 0x43 +#define TMC7300_IS_READABLE(x) ((x) & TMC7300_ACCESS_READ) +#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) + +typedef enum { + TMC7300_CACHE_READ, + TMC7300_CACHE_WRITE, + // Special operation: Put content into the cache without marking the entry as dirty. + // Only used to initialize the cache with hardware defaults. This will allow reading + // from write-only registers that have a value inside them on reset. When using this + // operation, a restore will *not* rewrite that filled register! + TMC7300_CACHE_FILL_DEFAULT, +} TMC7300CacheOp; + +typedef struct{ + uint8_t address; + uint32_t value; +} TMC7300RegisterConstants; + +// Helper define: +// Most register permission arrays are initialized with 128 values. +// In those fields its quite hard to have an easy overview of available +// registers. For that, ____ is defined to 0, since 4 underscores are +// very easy to distinguish from the 2-digit hexadecimal values. +// This way, the used registers (permission != ACCESS_NONE) are easily spotted +// amongst unused (permission == ACCESS_NONE) registers. +#define ____ 0x00 + +// Helper define: +// Default reset values are not used if the corresponding register has a +// hardware preset. Since this is not directly visible in the default +// register reset values array, N_A is used as an indicator for a preset +// value, where any value will be ignored anyways (N_A: not available). +#define N_A 0 + +#define R00 0x00000007 // GCONF + +// Register access permissions: +// 0x00: none (reserved) +// 0x01: read +// 0x02: write +// 0x42: write, has hardware presets on reset +// 0x43: read/write, has hardware presets on reset +static const uint8_t tmc7300_registerAccess[TMC7300_REGISTER_COUNT] = +{ + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0x03, 0x23, 0x01, 0x02, ____, ____, 0x01, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x00 - 0x0F + 0x42, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x10 - 0x1F + ____, ____, 0x02, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x20 - 0x2F + ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x30 - 0x3F + ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x40 - 0x4F + ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x50 - 0x5F + ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, 0x43, ____, ____, 0x01, // 0x60 - 0x6F + 0x43, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____ // 0x70 - 0x7F +}; + +static const int32_t tmc7300_sampleRegisterPreset[TMC7300_REGISTER_COUNT] = +{ + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + R00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x00 - 0x0F + N_A, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x10 - 0x1F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x20 - 0x2F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x30 - 0x3F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x40 - 0x4F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0x50 - 0x5F + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, N_A, 0, 0, 0, // 0x60 - 0x6F + N_A, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // 0x70 - 0x7F +}; + +// Undefine the default register values. +// This prevents warnings in case multiple TMC-API chip headers are included at once +#undef R00 + +// Register constants (only required for 0x42 and 0x43 registers) +// This allows us to fill the shadow registers with the register content in +// order to provide the TMCL-IDE with correct values to display. +static const TMC7300RegisterConstants tmc7300_RegisterConstants[] = +{ // Use ascending addresses! + { 0x10, 0x00001F01 }, // CURRENT_LIMIT + { 0x6C, 0x13008001 }, // CHOPCONF + { 0x70, 0xC40D1024 }, // PWMCONF +}; + +extern uint8_t tmc7300_dirtyBits[TMC7300_IC_CACHE_COUNT][TMC7300_REGISTER_COUNT/8]; +extern int32_t tmc7300_shadowRegister[TMC7300_IC_CACHE_COUNT][TMC7300_REGISTER_COUNT]; +bool tmc7300_cache(uint16_t icID, TMC7300CacheOp operation, uint8_t address, uint32_t *value); +void tmc7300_initCache(void); +void tmc7300_setDirtyBit(uint16_t icID, uint8_t index, bool value); +bool tmc7300_getDirtyBit(uint16_t icID, uint8_t index); +#endif +#endif +/***************************************************************************************************************************************************/ +#endif /* TMC_IC_TMC7300_H_ */ diff --git a/firmware/lib/tmc/ic/TMC7300/TMC7300_HW_Abstraction.h b/firmware/lib/tmc/ic/TMC7300/TMC7300_HW_Abstraction.h new file mode 100755 index 0000000..2e72630 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC7300/TMC7300_HW_Abstraction.h @@ -0,0 +1,166 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + +#ifndef TMC7300_HW_ABSTRACTION +#define TMC7300_HW_ABSTRACTION + +// Constants +#define TMC7300_MOTORS 1 +#define TMC7300_REGISTER_COUNT 128 +#define TMC7300_WRITE_BIT 0x80 +#define TMC7300_ADDRESS_MASK 0x7F + + +// Registers +#define TMC7300_GCONF 0x00 +#define TMC7300_GSTAT 0x01 +#define TMC7300_IFCNT 0x02 +#define TMC7300_SLAVECONF 0x03 +#define TMC7300_IOIN 0x06 + +#define TMC7300_CURRENT_LIMIT 0x10 + +#define TMC7300_PWM_AB 0x22 + +#define TMC7300_CHOPCONF 0x6C +#define TMC7300_DRVSTATUS 0x6F +#define TMC7300_PWMCONF 0x70 + + +// Register fields +#define TMC7300_PWM_DIRECT_MASK 0x00000001 +#define TMC7300_PWM_DIRECT_SHIFT 0 +#define TMC7300_PWM_DIRECT_FIELD ((RegisterField) {TMC7300_PWM_DIRECT_MASK, TMC7300_PWM_DIRECT_SHIFT, TMC7300_GCONF, false}) +#define TMC7300_EXTCAP_MASK 0x00000002 +#define TMC7300_EXTCAP_SHIFT 1 +#define TMC7300_EXTCAP_FIELD ((RegisterField) {TMC7300_EXTCAP_MASK, TMC7300_EXTCAP_SHIFT, TMC7300_GCONF, false}) +#define TMC7300_PAR_MODE_MASK 0x00000004 +#define TMC7300_PAR_MODE_SHIFT 2 +#define TMC7300_PAR_MODE_FIELD ((RegisterField) {TMC7300_PAR_MODE_MASK, TMC7300_PAR_MODE_SHIFT, TMC7300_GCONF, false}) +#define TMC7300_TEST_MODE_MASK 0x00000080 +#define TMC7300_TEST_MODE_SHIFT 7 +#define TMC7300_TEST_MODE_FIELD ((RegisterField) {TMC7300_TEST_MODE_MASK, TMC7300_TEST_MODE_SHIFT, TMC7300_GCONF, false}) +#define TMC7300_RESET_MASK 0x00000001 +#define TMC7300_RESET_SHIFT 0 +#define TMC7300_RESET_FIELD ((RegisterField) {TMC7300_RESET_MASK, TMC7300_RESET_SHIFT, TMC7300_GSTAT, false}) +#define TMC7300_DRV_ERR_MASK 0x00000002 +#define TMC7300_DRV_ERR_SHIFT 1 +#define TMC7300_DRV_ERR_FIELD ((RegisterField) {TMC7300_DRV_ERR_MASK, TMC7300_DRV_ERR_SHIFT, TMC7300_GSTAT, false}) +#define TMC7300_U3V5_MASK 0x00000004 +#define TMC7300_U3V5_SHIFT 2 +#define TMC7300_U3V5_FIELD ((RegisterField) {TMC7300_U3V5_MASK, TMC7300_U3V5_SHIFT, TMC7300_GSTAT, false}) +#define TMC7300_IFCNT_MASK 0x000000FF +#define TMC7300_IFCNT_SHIFT 0 +#define TMC7300_IFCNT_FIELD ((RegisterField) {TMC7300_IFCNT_MASK, TMC7300_IFCNT_SHIFT, TMC7300_IFCNT, false}) +#define TMC7300_SLAVECONF_MASK 0x00000F00 +#define TMC7300_SLAVECONF_SHIFT 8 +#define TMC7300_SLAVECONF_FIELD ((RegisterField) {TMC7300_SLAVECONF_MASK, TMC7300_SLAVECONF_SHIFT, TMC7300_SLAVECONF, false}) +#define TMC7300_EN_MASK 0x00000001 +#define TMC7300_EN_SHIFT 0 +#define TMC7300_EN_FIELD ((RegisterField) {TMC7300_EN_MASK, TMC7300_EN_SHIFT, TMC7300_IOIN, false}) +#define TMC7300_NSTDBY_MASK 0x00000002 +#define TMC7300_NSTDBY_SHIFT 1 +#define TMC7300_NSTDBY_FIELD ((RegisterField) {TMC7300_NSTDBY_MASK, TMC7300_NSTDBY_SHIFT, TMC7300_IOIN, false}) +#define TMC7300_AD0_MASK 0x00000004 +#define TMC7300_AD0_SHIFT 2 +#define TMC7300_AD0_FIELD ((RegisterField) {TMC7300_AD0_MASK, TMC7300_AD0_SHIFT, TMC7300_IOIN, false}) +#define TMC7300_AD1_MASK 0x00000008 +#define TMC7300_AD1_SHIFT 3 +#define TMC7300_AD1_FIELD ((RegisterField) {TMC7300_AD1_MASK, TMC7300_AD1_SHIFT, TMC7300_IOIN, false}) +#define TMC7300_DIAG_MASK 0x00000010 +#define TMC7300_DIAG_SHIFT 4 +#define TMC7300_DIAG_FIELD ((RegisterField) {TMC7300_DIAG_MASK, TMC7300_DIAG_SHIFT, TMC7300_IOIN, false}) +#define TMC7300_UART_ENABLED_MASK 0x00000020 +#define TMC7300_UART_ENABLED_SHIFT 5 +#define TMC7300_UART_ENABLED_FIELD ((RegisterField) {TMC7300_UART_ENABLED_MASK, TMC7300_UART_ENABLED_SHIFT, TMC7300_IOIN, false}) +#define TMC7300_UART_INPUT_MASK 0x00000040 +#define TMC7300_UART_INPUT_SHIFT 6 +#define TMC7300_UART_INPUT_FIELD ((RegisterField) {TMC7300_UART_INPUT_MASK, TMC7300_UART_INPUT_SHIFT, TMC7300_IOIN, false}) +#define TMC7300_MODE_INPUT_MASK 0x00000080 +#define TMC7300_MODE_INPUT_SHIFT 7 +#define TMC7300_MODE_INPUT_FIELD ((RegisterField) {TMC7300_MODE_INPUT_MASK, TMC7300_MODE_INPUT_SHIFT, TMC7300_IOIN, false}) +#define TMC7300_A2_MASK 0x00000100 +#define TMC7300_A2_SHIFT 8 +#define TMC7300_A2_FIELD ((RegisterField) {TMC7300_A2_MASK, TMC7300_A2_SHIFT, TMC7300_IOIN, false}) +#define TMC7300_A1_MASK 0x00000200 +#define TMC7300_A1_SHIFT 9 +#define TMC7300_A1_FIELD ((RegisterField) {TMC7300_A1_MASK, TMC7300_A1_SHIFT, TMC7300_IOIN, false}) +#define TMC7300_COMP_A1A2_MASK 0x00000400 +#define TMC7300_COMP_A1A2_SHIFT 10 +#define TMC7300_COMP_A1A2_FIELD ((RegisterField) {TMC7300_COMP_A1A2_MASK, TMC7300_COMP_A1A2_SHIFT, TMC7300_IOIN, false}) +#define TMC7300_COMP_B1B2_MASK 0x00000800 +#define TMC7300_COMP_B1B2_SHIFT 11 +#define TMC7300_COMP_B1B2_FIELD ((RegisterField) {TMC7300_COMP_B1B2_MASK, TMC7300_COMP_B1B2_SHIFT, TMC7300_IOIN, false}) +#define TMC7300_VERSION_MASK 0xFF000000 +#define TMC7300_VERSION_SHIFT 24 +#define TMC7300_VERSION_FIELD ((RegisterField) {TMC7300_VERSION_MASK, TMC7300_VERSION_SHIFT, TMC7300_IOIN, false}) +#define TMC7300_MOTORRUN_MASK 0x00000001 +#define TMC7300_MOTORRUN_SHIFT 0 +#define TMC7300_MOTORRUN_FIELD ((RegisterField) {TMC7300_MOTORRUN_MASK, TMC7300_MOTORRUN_SHIFT, TMC7300_CURRENT_LIMIT, false}) +#define TMC7300_IRUN_MASK 0x00001F00 +#define TMC7300_IRUN_SHIFT 8 +#define TMC7300_IRUN_FIELD ((RegisterField) {TMC7300_IRUN_MASK, TMC7300_IRUN_SHIFT, TMC7300_CURRENT_LIMIT, false}) +#define TMC7300_PWM_A_MASK 0x000001FF +#define TMC7300_PWM_A_SHIFT 0 +#define TMC7300_PWM_A_FIELD ((RegisterField) {TMC7300_PWM_A_MASK, TMC7300_PWM_A_SHIFT, TMC7300_PWM_AB, true}) +#define TMC7300_PWM_B_MASK 0x01FF0000 +#define TMC7300_PWM_B_SHIFT 16 +#define TMC7300_PWM_B_FIELD ((RegisterField) {TMC7300_PWM_B_MASK, TMC7300_PWM_B_SHIFT, TMC7300_PWM_AB, true}) +#define TMC7300_PWM_AB_MASK 0x000001FF +#define TMC7300_PWM_AB_SHIFT 0 +#define TMC7300_PWM_AB_FIELD ((RegisterField) {TMC7300_PWM_AB_MASK, TMC7300_PWM_AB_SHIFT, TMC7300_PWM_AB, true}) +#define TMC7300_ENABLEDRV_MASK 0x00000001 +#define TMC7300_ENABLEDRV_SHIFT 0 +#define TMC7300_ENABLEDRV_FIELD ((RegisterField) {TMC7300_ENABLEDRV_MASK, TMC7300_ENABLEDRV_SHIFT, TMC7300_CHOPCONF, false}) +#define TMC7300_TBL_MASK 0x00018000 +#define TMC7300_TBL_SHIFT 15 +#define TMC7300_TBL_FIELD ((RegisterField) {TMC7300_TBL_MASK, TMC7300_TBL_SHIFT, TMC7300_CHOPCONF, false}) +#define TMC7300_DISS2G_MASK 0x40000000 +#define TMC7300_DISS2G_SHIFT 30 +#define TMC7300_DISS2G_FIELD ((RegisterField) {TMC7300_DISS2G_MASK, TMC7300_DISS2G_SHIFT, TMC7300_CHOPCONF, false}) +#define TMC7300_DISS2VS_MASK 0x80000000 +#define TMC7300_DISS2VS_SHIFT 31 +#define TMC7300_DISS2VS_FIELD ((RegisterField) {TMC7300_DISS2VS_MASK, TMC7300_DISS2VS_SHIFT, TMC7300_CHOPCONF, false}) +#define TMC7300_OTPW_MASK 0x00000001 +#define TMC7300_OTPW_SHIFT 0 +#define TMC7300_OTPW_FIELD ((RegisterField) {TMC7300_OTPW_MASK, TMC7300_OTPW_SHIFT, TMC7300_DRV_STATUS, false}) +#define TMC7300_OT_MASK 0x00000002 +#define TMC7300_OT_SHIFT 1 +#define TMC7300_OT_FIELD ((RegisterField) {TMC7300_OT_MASK, TMC7300_OT_SHIFT, TMC7300_DRV_STATUS, false}) +#define TMC7300_S2GA_MASK 0x00000004 +#define TMC7300_S2GA_SHIFT 2 +#define TMC7300_S2GA_FIELD ((RegisterField) {TMC7300_S2GA_MASK, TMC7300_S2GA_SHIFT, TMC7300_DRV_STATUS, false}) +#define TMC7300_S2GB_MASK 0x00000008 +#define TMC7300_S2GB_SHIFT 3 +#define TMC7300_S2GB_FIELD ((RegisterField) {TMC7300_S2GB_MASK, TMC7300_S2GB_SHIFT, TMC7300_DRV_STATUS, false}) +#define TMC7300_S2VSA_MASK 0x00000010 +#define TMC7300_S2VSA_SHIFT 4 +#define TMC7300_S2VSA_FIELD ((RegisterField) {TMC7300_S2VSA_MASK, TMC7300_S2VSA_SHIFT, TMC7300_DRV_STATUS, false}) +#define TMC7300_S2VSB_MASK 0x00000020 +#define TMC7300_S2VSB_SHIFT 5 +#define TMC7300_S2VSB_FIELD ((RegisterField) {TMC7300_S2VSB_MASK, TMC7300_S2VSB_SHIFT, TMC7300_DRV_STATUS, false}) +#define TMC7300_OLA_MASK 0x00000040 +#define TMC7300_OLA_SHIFT 6 +#define TMC7300_OLA_FIELD ((RegisterField) {TMC7300_OLA_MASK, TMC7300_OLA_SHIFT, TMC7300_DRV_STATUS, false}) +#define TMC7300_OLB_MASK 0x00000080 +#define TMC7300_OLB_SHIFT 7 +#define TMC7300_OLB_FIELD ((RegisterField) {TMC7300_OLB_MASK, TMC7300_OLB_SHIFT, TMC7300_DRV_STATUS, false}) +#define TMC7300_T120_MASK 0x00000100 +#define TMC7300_T120_SHIFT 8 +#define TMC7300_T120_FIELD ((RegisterField) {TMC7300_T120_MASK, TMC7300_T120_SHIFT, TMC7300_DRV_STATUS, false}) +#define TMC7300_T150_MASK 0x00000200 +#define TMC7300_T150_SHIFT 9 +#define TMC7300_T150_FIELD ((RegisterField) {TMC7300_T150_MASK, TMC7300_T150_SHIFT, TMC7300_DRV_STATUS, false}) +#define TMC7300_PWM_FREQ_MASK 0x00030000 +#define TMC7300_PWM_FREQ_SHIFT 16 +#define TMC7300_PWM_FREQ_FIELD ((RegisterField) {TMC7300_PWM_FREQ_MASK, TMC7300_PWM_FREQ_SHIFT, TMC7300_PWMCONF, false}) +#define TMC7300_FREEWHEEL_MASK 0x00300000 +#define TMC7300_FREEWHEEL_SHIFT 20 +#define TMC7300_FREEWHEEL_FIELD ((RegisterField) {TMC7300_FREEWHEEL_MASK, TMC7300_FREEWHEEL_SHIFT, TMC7300_PWMCONF, false}) + +#endif diff --git a/firmware/lib/tmc/ic/TMC7300/registercall_hierarchy_flowchart_UART.svg b/firmware/lib/tmc/ic/TMC7300/registercall_hierarchy_flowchart_UART.svg new file mode 100755 index 0000000..425f60a --- /dev/null +++ b/firmware/lib/tmc/ic/TMC7300/registercall_hierarchy_flowchart_UART.svg @@ -0,0 +1,3 @@ + + +

HAL

HAL

APP (Eval)

APP (Eval)

API

API
Read a register
  •  Call tmcXXXX_readRegister function
Read a register...
Returns the register read value
Returns the register read value
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
tmcXXXX.c
tmcXXXX.c
UART.c
UART.c
tmcXXXX_eval.c
tmcXXXX_eval.c

 Implementation of UART_readWrite
  • Sends and receives bytes on the UART bus
Implementation of UART_readWrite...
Returns the raw reply data
Returns the raw reply data

Implementation of tmcXXXX_readWriteUART
  • Takes the array of data to write
  • Calls hardware function UART_readWrite
Implementation of tmcXXXX_readWriteUART...
Passes on the raw reply data to the API
Passes on the raw reply data to the API
Implementation of readRegisterUART
  • Constructs the datagram
  • Calls HAL wrapper function 
Implementation of readRegisterUART...
tmcXXXX_readWriteUART
tmcXXXX_readWriteUART
Parses the reply and returns the register value
Parses the reply and returns the register value
Implementation of tmcXXXX_readRegister 
  • Check which bus is active SPI/UART. (e.g. UART)
  • Calls bus-specific function (e.g. readRegisterUART)
 
Implementation of tmcXXXX_readRegister...
Returns the register read value
Returns the register read value
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC7300/uml-tmc-api.svg b/firmware/lib/tmc/ic/TMC7300/uml-tmc-api.svg new file mode 100755 index 0000000..5a5f8dd --- /dev/null +++ b/firmware/lib/tmc/ic/TMC7300/uml-tmc-api.svg @@ -0,0 +1,3 @@ + + +

TMCXXXX_HW_Abstraction.h



TMCXXXX_HW_Abstraction.h...
// Constants
#define TMCXXXX_MOTORS              
                          
// Register definitions
#define TMCXXXX_GCONF        
                          ⋮
// Register fields definitions
#define TMCXXXX_GCONF_OTPW_FIELD
                     
// Constants...

TMCXXXX.h



TMCXXXX.h...
extern void tmcXXXX_readWriteSPI();
extern void tmcXXXX_readWriteUART();
extern TMCXXXXBusType tmcXXXX_getBusType();
extern uint8_t tmcXXXX_getNodeAddress();
                                  ⋮
tmcXXXX_readRegister();
tmcXXXX_writeRegister();
                                  ⋮
extern void tmcXXXX_readWriteSPI();...

TMCXXXX.c



TMCXXXX.c...
const uint8_t tmcCRCTable_Poly7Reflected[256] = {...};
int32_t tmcXXXX_readRegister(){
/* Call tmcXXXX_getBusType();
 * Based on bus type, call readRegisterSPI/UART() that
 * further calls tmcXXXX_readWriteSPI/UART();
 * For UART it also calls tmcXXXX_getNodeAddress();
                                           ⋮
}
                                           ⋮
const uint8_t tmcCRCTable_Poly7Reflected[256] = {.....
TMC-API
TMC-API

TMCXXXX_Simple_Rotation.h


TMCXXXX_Simple_Rotation.h...
void initAllMotors();
             ⋮
  
void initAllMotors()...

TMCXXXX_Simple_Rotation.c


TMCXXXX_Simple_Rotation.c...
void initAllMotors(){

// Configuring registers to enable motor drivers etc..
tmcXXXX_writeRegister();
                    ⋮
}
                    ⋮
void initAllMotors(){...
Examples
Examples
User Project
User Project

User_Project.h


User_Project.h

User_Project.c








User_Project.c...

void tmcXXXX_readWriteSPI(){
                           ⋮
}
void tmcXXXX_readWriteUART(){
                           ⋮
}
TMCXXXXBusType tmcXXXX_getBusType(){
                           ⋮
}
uint8_t tmcXXXX_getNodeAddress(){
                           ⋮
}

// User Code
                           ⋮
void tmcXXXX_readWriteSPI(){...
#include "TMCXXXX_HW_Abstraction.h"
#include "TMCXXXX.h"
#include "TMCXXXX_Simple_Rotation.h"
                                ⋮
TMCXXXXBusType bus = IC_BUS_SPI/UART;
uint8_t nodeAddress = <nodeAddress>;
                                ⋮
#include "TMCXXXX_HW_Abstraction.h"...
\ No newline at end of file diff --git a/firmware/lib/tmc/ic/TMC9660/README.md b/firmware/lib/tmc/ic/TMC9660/README.md new file mode 100755 index 0000000..8bc8217 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC9660/README.md @@ -0,0 +1,44 @@ +# TMC9660 + +Note: Currently only UART is supported + +## How to use + +To access the TMC9660 in bootloader, paramater or register mode, the TMC-API offers **tmc9660_bl_sendCommand**, **tmc9660_param_sendCommand** and **tmc9660_reg_sendCommand** functions respectively. + +Each of these functions takes in an **icID**, which is used to identify the IC when multiple ICs are connected. This identifier is passed down to the callback functions (see How to Integrate). + +## How to integrate: overview + +1. Include all the files of the TMC-API/ic/tmc/TMC9660 folder into your project. +2. Include the TMC9660.h file in your source code. +3. Include TMC9660_BL_HW_Abstraction.h if your code interacts with the TMC9660 bootloader. +4. Include TMC9660_PARAM_HW_Abstraction.h if your code interacts with the parameter mode. +5. Implement the necessary callback functions (see below). + +## Accessing the TMC9660 via UART + +- The function tmc9660_bl_sendCommand is used to send commands to the chip in bootloader mode. Bootloader commands are available as the TMC9660BlCommand enum type. Similarly the functions tmc9660_param_sendCommand and tmc9660_reg_sendCommand are used to access APs or registers in parameter or register mode respectively. +- These functions check the current active bus and calls the bus-specific function i.e tmc9660_bl_sendCommand_UART, tmc9660_param_sendCommand_UART or tmc9660_reg_sendCommand_UART. +- These bus specific functions constructs the datagram and further calls the bus specific callback 'tmc9660_readWriteUART. +- This callback function further calls the hardware specific read/write function for UART and needs to be implemented externally. +- All of these functions return a 32-bit status integer. Possible status error codes for Parameter mode are enumerated as TMC9660ParamStatus. + + +### How to integrate: Callback functions + +The following callback functions must be implemented your code: +1. **'tmc9660_getBusType()'** that returns the bus to use for the given icID. +2. **tmc9660_getBusAddresses()** that returns device and host addresses e.g; device=1, host=255. +3. **tmc_getMicrosecondTimestamp()** that returns a system timestamp in microseconds. +4. **tmc9660_readWriteUART()** that sends data via UART and, if requested, reads back data and returns it to the TMC-API. + +Additionally, the following function may be implemented if your application intents to use the TMC9660 fault pin: +- **tmc9660_isFaultPinAsserted()** that returns whether the TMC9660 fault pin is asserted. + +Note that in order to enable the TMC-API support for using the fault pin, the define TMC_API_TMC9660_FAULT_PIN_SUPPORTED must be set to 1. This can be done either by uncommenting the define at the top of the TMC9660.h header file, or by setting it as part of your build system. + + +### Sharing the CRC table with other TMC-API chips +The TMC9660 UART protocol uses an 8 bit CRC. For calculating this, a table-based algorithm is used. This table (tmcCRCTable_Poly7Reflected[256]) is 256 bytes big and identical across multiple different Trinamic chips (i.e. TMC2209). +If multiple Trinamic chips are being used in the same project, avoiding redundant copies of this table could save memory. It is possible to substitute this CRC table with another CRC table. diff --git a/firmware/lib/tmc/ic/TMC9660/TMC9660.c b/firmware/lib/tmc/ic/TMC9660/TMC9660.c new file mode 100755 index 0000000..dc21aa5 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC9660/TMC9660.c @@ -0,0 +1,358 @@ +/******************************************************************************* +* Copyright © 2025 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#include "TMC9660.h" + +// ToDo: Make the timing function & callback usable with multiple TMC-API chips in use. +void tmc_delayMicroseconds(uint32_t microseconds) +{ + uint32_t timestamp = tmc_getMicrosecondTimestamp(); + + while (tmc_getMicrosecondTimestamp() - timestamp < microseconds); +} + +#ifdef TMC_API_EXTERNAL_CRC_TABLE +extern const uint8_t tmcCRCTable_Poly7Reflected[256]; +#else +const uint8_t tmcCRCTable_Poly7Reflected[256] = { + 0x00, 0x91, 0xE3, 0x72, 0x07, 0x96, 0xE4, 0x75, 0x0E, 0x9F, 0xED, 0x7C, 0x09, 0x98, 0xEA, 0x7B, + 0x1C, 0x8D, 0xFF, 0x6E, 0x1B, 0x8A, 0xF8, 0x69, 0x12, 0x83, 0xF1, 0x60, 0x15, 0x84, 0xF6, 0x67, + 0x38, 0xA9, 0xDB, 0x4A, 0x3F, 0xAE, 0xDC, 0x4D, 0x36, 0xA7, 0xD5, 0x44, 0x31, 0xA0, 0xD2, 0x43, + 0x24, 0xB5, 0xC7, 0x56, 0x23, 0xB2, 0xC0, 0x51, 0x2A, 0xBB, 0xC9, 0x58, 0x2D, 0xBC, 0xCE, 0x5F, + 0x70, 0xE1, 0x93, 0x02, 0x77, 0xE6, 0x94, 0x05, 0x7E, 0xEF, 0x9D, 0x0C, 0x79, 0xE8, 0x9A, 0x0B, + 0x6C, 0xFD, 0x8F, 0x1E, 0x6B, 0xFA, 0x88, 0x19, 0x62, 0xF3, 0x81, 0x10, 0x65, 0xF4, 0x86, 0x17, + 0x48, 0xD9, 0xAB, 0x3A, 0x4F, 0xDE, 0xAC, 0x3D, 0x46, 0xD7, 0xA5, 0x34, 0x41, 0xD0, 0xA2, 0x33, + 0x54, 0xC5, 0xB7, 0x26, 0x53, 0xC2, 0xB0, 0x21, 0x5A, 0xCB, 0xB9, 0x28, 0x5D, 0xCC, 0xBE, 0x2F, + 0xE0, 0x71, 0x03, 0x92, 0xE7, 0x76, 0x04, 0x95, 0xEE, 0x7F, 0x0D, 0x9C, 0xE9, 0x78, 0x0A, 0x9B, + 0xFC, 0x6D, 0x1F, 0x8E, 0xFB, 0x6A, 0x18, 0x89, 0xF2, 0x63, 0x11, 0x80, 0xF5, 0x64, 0x16, 0x87, + 0xD8, 0x49, 0x3B, 0xAA, 0xDF, 0x4E, 0x3C, 0xAD, 0xD6, 0x47, 0x35, 0xA4, 0xD1, 0x40, 0x32, 0xA3, + 0xC4, 0x55, 0x27, 0xB6, 0xC3, 0x52, 0x20, 0xB1, 0xCA, 0x5B, 0x29, 0xB8, 0xCD, 0x5C, 0x2E, 0xBF, + 0x90, 0x01, 0x73, 0xE2, 0x97, 0x06, 0x74, 0xE5, 0x9E, 0x0F, 0x7D, 0xEC, 0x99, 0x08, 0x7A, 0xEB, + 0x8C, 0x1D, 0x6F, 0xFE, 0x8B, 0x1A, 0x68, 0xF9, 0x82, 0x13, 0x61, 0xF0, 0x85, 0x14, 0x66, 0xF7, + 0xA8, 0x39, 0x4B, 0xDA, 0xAF, 0x3E, 0x4C, 0xDD, 0xA6, 0x37, 0x45, 0xD4, 0xA1, 0x30, 0x42, 0xD3, + 0xB4, 0x25, 0x57, 0xC6, 0xB3, 0x22, 0x50, 0xC1, 0xBA, 0x2B, 0x59, 0xC8, 0xBD, 0x2C, 0x5E, 0xCF, +}; +#endif + +// Helper functions +static int32_t tmc9660_bl_sendCommand_UART(uint16_t icID, uint8_t cmd, uint32_t writeValue, uint32_t *readValue); +static int32_t tmc9660_param_sendCommand_UART(uint16_t icID, uint8_t cmd, uint16_t type, uint8_t index, uint32_t writeValue, uint32_t *readValue); +static int32_t tmc9660_param_getVersionASCII_UART(uint16_t icID, uint8_t *versionString); +static int32_t tmc9660_param_returnToBootloader_UART(uint16_t icID); +static int32_t tmc9660_reg_sendCommand_UART(uint16_t icID, uint8_t cmd, uint16_t registerOffset, uint8_t registerBlock, uint32_t writeValue, uint32_t *readValue); + +static uint8_t calcParamChecksum(uint8_t *data, uint32_t bytes); +static uint8_t CRC8(uint8_t *data, uint32_t bytes); + +/*** General functions implementation ********************************************/ +#if TMC_API_TMC9660_FAULT_PIN_SUPPORTED != 0 +void tmc9660_waitForFaultDeassertion(uint16_t icID) +{ + // ToDo: Support timeouts + while (tmc9660_isFaultPinAsserted(icID)); +} +#endif + +/*** Bootstrapping code implementation *******************************************/ + +int32_t tmc9660_bl_sendCommand(uint16_t icID, uint8_t cmd, uint32_t writeValue, uint32_t *readValue) +{ + TMC9660BusType bus = tmc9660_getBusType(icID); + + if(bus == TMC9660_BUS_SPI) + { + // ToDo: SPI support + } + else if(bus == TMC9660_BUS_UART) + { + return tmc9660_bl_sendCommand_UART(icID, cmd, writeValue, readValue); + } + + return -1; +} + +static int32_t tmc9660_bl_sendCommand_UART(uint16_t icID, uint8_t cmd, uint32_t writeValue, uint32_t *readValue) +{ + uint8_t data[8] = { 0 }; + TMC9660BusAddresses addresses = tmc9660_getBusAddresses(icID); + + data[0] = 0x55; // Sync byte + data[1] = 0x01 | (addresses.device); // Device Address + data[2] = cmd; // Command + data[3] = (writeValue >> 24) & 0xFF; + data[4] = (writeValue >> 16) & 0xFF; + data[5] = (writeValue >> 8 ) & 0xFF; + data[6] = (writeValue ) & 0xFF; + data[7] = CRC8(data, 7); + + if (!tmc9660_readWriteUART(icID, &data[0], 8, 8)) { + return -1; + } + + if (readValue) + { + *readValue = ((uint32_t)data[3] << 24) | ((uint32_t)data[4] << 16) | ((uint32_t)data[5] << 8) | data[6]; + } + + // Workaround: Wait a short moment before proceeding + tmc_delayMicroseconds(10); + + return data[2]; +} + +static uint8_t CRC8(uint8_t *data, uint32_t bytes) +{ + uint8_t result = 0; + while(bytes--) + result = tmcCRCTable_Poly7Reflected[result ^ *data++]; + + // Flip the result around + // swap odd and even bits + result = ((result >> 1) & 0x55) | ((result & 0x55) << 1); + // swap consecutive pairs + result = ((result >> 2) & 0x33) | ((result & 0x33) << 2); + // swap nibbles ... + result = ((result >> 4) & 0x0F) | ((result & 0x0F) << 4); + + return result; +} + +/*** Command sending implementation *******************************************/ + + +int32_t tmc9660_param_sendCommand(uint16_t icID, uint8_t cmd, uint16_t type, uint8_t index, uint32_t writeValue, uint32_t *readValue) +{ + TMC9660BusType bus = tmc9660_getBusType(icID); + + if(bus == TMC9660_BUS_SPI) + { + // ToDo: SPI support + } + else if(bus == TMC9660_BUS_UART) + { + return tmc9660_param_sendCommand_UART(icID, cmd, type, index, writeValue, readValue); + } + + return -1; +} + +int32_t tmc9660_param_getVersionASCII(uint16_t icID, uint8_t *versionString) +{ + TMC9660BusType bus = tmc9660_getBusType(icID); + + if(bus == TMC9660_BUS_SPI) + { + // ToDo: SPI support + } + else if(bus == TMC9660_BUS_UART) + { + return tmc9660_param_getVersionASCII_UART(icID, versionString); + } + + return -1; +} + +int32_t tmc9660_param_returnToBootloader(uint16_t icID) +{ + TMC9660BusType bus = tmc9660_getBusType(icID); + + if(bus == TMC9660_BUS_SPI) + { + // ToDo: SPI support + } + else if(bus == TMC9660_BUS_UART) + { + return tmc9660_param_returnToBootloader_UART(icID); + } + + return -1; +} + +static bool sendRequestUART(uint16_t icID, uint8_t cmd, uint16_t type, uint8_t index, uint32_t writeValue, uint8_t *data, TMC9660BusAddresses addresses, bool expectReply) +{ + // Create the request datagram + uint8_t syncByte = 0x01 | (addresses.device); + data[0] = syncByte; // Module Address & sync bit + data[1] = cmd; + data[2] = type & 0xFF; + data[3] = (type >> 8) << 4 | (index & 0x0F); // ToDo: Do we wanna do the 4/12 split at this function's arguments? + data[4] = (writeValue >> 24) & 0xFF; + data[5] = (writeValue >> 16) & 0xFF; + data[6] = (writeValue >> 8) & 0xFF; + data[7] = (writeValue) & 0xFF; + data[8] = calcParamChecksum(&data[0], 8); + + return tmc9660_readWriteUART(icID, &data[0], 9, (expectReply)? 9:0); +} + +static int32_t tmc9660_param_sendCommand_UART(uint16_t icID, uint8_t cmd, uint16_t type, uint8_t index, uint32_t writeValue, uint32_t *readValue) +{ + uint8_t data[9] = { 0 }; + TMC9660BusAddresses addresses = tmc9660_getBusAddresses(icID); + + if (!sendRequestUART(icID, cmd, type, index, writeValue, data, addresses, true)) + return -2; + + uint8_t syncByte = 0x01 | (addresses.device); + + // Unpack the reply + if (data[0] != addresses.host) + return -3; + if (data[1] != syncByte) + return -4; + if (data[8] != calcParamChecksum(&data[0], 8)) + return -5; + + if (readValue) + { + *readValue = ((uint32_t)data[4] << 24) | ((uint32_t)data[5] << 16) | (data[6] << 8) | data[7]; + } + + return data[2]; +} + +static int32_t tmc9660_param_getVersionASCII_UART(uint16_t icID, uint8_t *versionString) +{ + uint8_t data[9] = { 0 }; + TMC9660BusAddresses addresses = tmc9660_getBusAddresses(icID); + + if (!sendRequestUART(icID, TMC9660_CMD_GET_VERSION, 0, 0, 0, data, addresses, true)) + return -2; + + versionString[0] = data[1]; + versionString[1] = data[2]; + versionString[2] = data[3]; + versionString[3] = data[4]; + versionString[4] = data[5]; + versionString[5] = data[6]; + versionString[6] = data[7]; + versionString[7] = data[8]; + + return 0; +} + +static int32_t tmc9660_param_returnToBootloader_UART(uint16_t icID) +{ + uint8_t data[9] = { 0 }; + TMC9660BusAddresses addresses = tmc9660_getBusAddresses(icID); + + if (!sendRequestUART(icID, TMC9660_CMD_BOOT, 0x981, 0x2, 0xA3B4C5D6, data, addresses, false)) + return -2; + + return 0; +} + +int32_t tmc9660_reg_sendCommand(uint16_t icID, uint8_t cmd, uint16_t registerOffset, uint8_t registerBlock, uint32_t writeValue, uint32_t *readValue) +{ + TMC9660BusType bus = tmc9660_getBusType(icID); + + if(bus == TMC9660_BUS_SPI) + { + // ToDo: SPI support + } + else if(bus == TMC9660_BUS_UART) + { + return tmc9660_reg_sendCommand_UART(icID, cmd, registerOffset, registerBlock, writeValue, readValue); + } + + return -1; +} + +int32_t tmc9660_reg_getVersionASCII(uint16_t icID, uint8_t *versionString) +{ + // In the underlying protocol, register and parameter mode work identically + // for this special command + return tmc9660_param_getVersionASCII(icID, versionString); +} + +int32_t tmc9660_reg_returnToBootloader(uint16_t icID) +{ + // In the underlying protocol, register and parameter mode work identically + // for this special command + return tmc9660_param_returnToBootloader(icID); +} + +static int32_t tmc9660_reg_sendCommand_UART(uint16_t icID, uint8_t cmd, uint16_t registerOffset, uint8_t registerBlock, uint32_t writeValue, uint32_t *readValue) +{ + uint8_t data[9] = { 0 }; + TMC9660BusAddresses addresses = tmc9660_getBusAddresses(icID); + + // Create the request datagram + uint8_t syncByte = 0x01 | (addresses.device); + data[0] = syncByte; // Module Address & sync bit + data[1] = cmd; + data[2] = registerOffset & 0xFF; + data[3] = (registerOffset >> 8) << 5 | (registerBlock & 0x1F); + data[4] = (writeValue >> 24) & 0xFF; + data[5] = (writeValue >> 16) & 0xFF; + data[6] = (writeValue >> 8) & 0xFF; + data[7] = (writeValue) & 0xFF; + data[8] = calcParamChecksum(&data[0], 8); + + if (!tmc9660_readWriteUART(icID, &data[0], 9, 9)) + return -2; + + // Unpack the reply + if (data[0] != addresses.host) + return -3; + if (data[1] != syncByte) + return -4; + if (data[8] != calcParamChecksum(&data[0], 8)) + return -5; + + if (readValue) + { + *readValue = ((uint32_t)data[4] << 24) | ((uint32_t)data[5] << 16) | (data[6] << 8) | data[7]; + } + + return data[2]; +} + +static uint8_t calcParamChecksum(uint8_t *data, uint32_t bytes) +{ + uint8_t checksum = 0; + + for (uint32_t i = 0; i < bytes; i++) + { + checksum += data[i]; + } + + return checksum; +} + +/*******************************************************************************************************************************************************************/ + +uint32_t tmc9660_param_getParameter(uint16_t icID, uint16_t type) +{ + uint32_t value = 0; + + tmc9660_param_sendCommand(icID, TMC9660_CMD_GAP, type, 0, value, &value); + + return value; +} + +bool tmc9660_param_setParameter(uint16_t icID, uint16_t type, uint32_t value) +{ + int32_t result = tmc9660_param_sendCommand(icID, TMC9660_CMD_SAP, type, 0, value, &value); + + return result == TMC9660_PARAMSTATUS_OK; +} + +uint32_t tmc9660_param_getGlobalParameter(uint16_t icID, uint16_t index) +{ + uint32_t value = 0; + + tmc9660_param_sendCommand(icID, TMC9660_CMD_GGP, index, 0, value, &value); + + return value; +} + +bool tmc9660_param_setGlobalParameter(uint16_t icID, uint16_t index, uint32_t value) +{ + int32_t result = tmc9660_param_sendCommand(icID, TMC9660_CMD_SGP, index, 0, value, &value); + + return result == TMC9660_PARAMSTATUS_OK; +} diff --git a/firmware/lib/tmc/ic/TMC9660/TMC9660.h b/firmware/lib/tmc/ic/TMC9660/TMC9660.h new file mode 100755 index 0000000..ba1b25a --- /dev/null +++ b/firmware/lib/tmc/ic/TMC9660/TMC9660.h @@ -0,0 +1,196 @@ +/******************************************************************************* +* Copyright © 2025 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#ifndef TMC_IC_TMC9660_H_ +#define TMC_IC_TMC9660_H_ + +#include +#include +#include + +/******************************************************************************* +* API Configuration Defines +* These control optional features of the TMC-API implementation. +* These can be commented in/out here or defined from the build system. +*******************************************************************************/ + +// Uncomment if you want to save space..... +// and put the table into your own .c file +//#define TMC_API_EXTERNAL_CRC_TABLE 1 + +// Uncomment if you want to use fault pin related features +// If enabled, this requires an additional wrapper function +//#define TMC_API_TMC9660_FAULT_PIN_SUPPORTED 1 + +/*** TMC9660 constants ********************************************************/ +typedef enum TMC9660BusType_ { + TMC9660_BUS_SPI, + TMC9660_BUS_UART, +} TMC9660BusType; + +typedef struct TMC9660BusAddresses_ { + uint8_t device; + uint8_t host; +} TMC9660BusAddresses; + +typedef enum TMC9660BlCommand_ { + TMC9660_BLCMD_GET_INFO = 0, + TMC9660_BLCMD_GET_BANK = 8, + TMC9660_BLCMD_SET_BANK = 9, + TMC9660_BLCMD_GET_ADDRESS = 10, + TMC9660_BLCMD_SET_ADDRESS = 11, + TMC9660_BLCMD_READ_32 = 12, + TMC9660_BLCMD_READ_32_INC = 13, + TMC9660_BLCMD_READ_16 = 14, + TMC9660_BLCMD_READ_16_INC = 15, + TMC9660_BLCMD_READ_8 = 16, + TMC9660_BLCMD_READ_8_INC = 17, + TMC9660_BLCMD_WRITE_32 = 18, + TMC9660_BLCMD_WRITE_32_INC = 19, + TMC9660_BLCMD_WRITE_16 = 20, + TMC9660_BLCMD_WRITE_16_INC = 21, + TMC9660_BLCMD_WRITE_8 = 22, + TMC9660_BLCMD_WRITE_8_INC = 23, + TMC9660_BLCMD_NO_OP = 29, + TMC9660_BLCMD_OTP_LOAD = 30, + TMC9660_BLCMD_OTP_BURN = 31, + TMC9660_BLCMD_MEM_ISCONFIGURED = 32, + TMC9660_BLCMD_MEM_ISCONNECTED = 33, + TMC9660_BLCMD_FLASH_SENDCMD = 36, + TMC9660_BLCMD_FLASH_ERASE_SECTOR = 37, + TMC9660_BLCMD_MEM_IS_BUSY = 40, + TMC9660_BLCMD_BOOTSTRAP_RS485 = 0xFF, +} TMC9660BlCommand; + +typedef enum TMC9660Command_ { + TMC9660_CMD_MST = 3, + + TMC9660_CMD_SAP = 5, + TMC9660_CMD_GAP = 6, + TMC9660_CMD_STAP = 7, + + TMC9660_CMD_SGP = 9, + TMC9660_CMD_GGP = 10, + + TMC9660_CMD_RFS = 13, + TMC9660_CMD_SIO = 14, + TMC9660_CMD_GIO = 15, + + TMC9660_CMD_CALC = 19, + TMC9660_CMD_COMP = 20, + TMC9660_CMD_JC = 21, + TMC9660_CMD_JA = 22, + TMC9660_CMD_CSUB = 23, + TMC9660_CMD_RSUB = 24, + TMC9660_CMD_EI = 25, + TMC9660_CMD_DI = 26, + TMC9660_CMD_WAIT = 27, + TMC9660_CMD_STOP = 28, + + TMC9660_CMD_CALCX = 33, + TMC9660_CMD_AAP = 34, + TMC9660_CMD_AGP = 35, + TMC9660_CMD_CLE = 36, + TMC9660_CMD_VECT = 37, + TMC9660_CMD_RETI = 38, + + TMC9660_CMD_CALCVV = 40, + TMC9660_CMD_CALCVA = 41, + TMC9660_CMD_CALCAV = 42, + TMC9660_CMD_CALCVX = 43, + TMC9660_CMD_CALCXV = 44, + TMC9660_CMD_CALCV = 45, + + TMC9660_CMD_RST = 48, + TMC9660_CMD_DJNZ = 49, + + TMC9660_CMD_SIV = 55, + TMC9660_CMD_GIV = 56, + TMC9660_CMD_AIV = 57, + + TMC9660_CMD_APPL_STOP = 128, + TMC9660_CMD_APPL_RUN = 129, + TMC9660_CMD_APPL_STEP = 130, + TMC9660_CMD_APPL_RESET = 131, + TMC9660_CMD_DOWNLOAD_START = 132, + TMC9660_CMD_DOWNLOAD_END = 133, + TMC9660_CMD_READ_MEM = 134, + TMC9660_CMD_GET_STATUS = 135, + TMC9660_CMD_GET_VERSION = 136, + TMC9660_CMD_FACTORY_DEFAULT = 137, + + TMC9660_CMD_BREAKPOINT = 141, + TMC9660_CMD_RAMDEBUG = 142, + + TMC9660_CMD_GET_INFO = 157, + + TMC9660_CMD_BOOT = 242, +} TMC9660Command; + +typedef enum TMC9660ParamStatus_ { + TMC9660_PARAMSTATUS_CHKERROR = 1, // Checksum error during communication + TMC9660_PARAMSTATUS_INVALID_CMD = 2, // Invalid command number + TMC9660_PARAMSTATUS_WRONG_TYPE = 3, // Invalid type number + TMC9660_PARAMSTATUS_INVALID_VALUE = 4, // Invalid value + TMC9660_PARAMSTATUS_CMD_NOT_AVAILABLE = 6, // Command currently not available + TMC9660_PARAMSTATUS_CMD_LOAD_ERROR = 7, // Failed to load command into script memory + TMC9660_PARAMSTATUS_MAX_EXCEEDED = 9, // Maximum exceeded + TMC9660_PARAMSTATUS_CMD_DOWNLOAD_NOT_POSSIBLE = 10, // Loading into script memory not available + + TMC9660_PARAMSTATUS_OK = 100, // Success + TMC9660_PARAMSTATUS_CMD_LOADED = 101, // Command successfully loaded into script memory +} TMC9660ParamStatus; + +/*** TMC-API wrapper functions ************************************************/ +//extern void tmc9660_readWriteSPI(uint16_t icID, uint8_t *data, size_t dataLength); +extern bool tmc9660_readWriteUART(uint16_t icID, uint8_t *data, size_t writeLength, size_t readLength); + +#if TMC_API_TMC9660_FAULT_PIN_SUPPORTED != 0 +extern bool tmc9660_isFaultPinAsserted(uint16_t icID); +#endif + +extern TMC9660BusType tmc9660_getBusType(uint16_t icID); +extern TMC9660BusAddresses tmc9660_getBusAddresses(uint16_t icID); + +// ToDo: Make the timing function & callback usable with multiple TMC-API chips in use. +extern uint32_t tmc_getMicrosecondTimestamp(); + +/*** TMC-API shared functions *************************************************/ + +// ToDo: Make the timing function & callback usable with multiple TMC-API chips in use. +void tmc_delayMicroseconds(uint32_t microseconds); + +/*** TMC9660 general functions ************************************************/ +#if TMC_API_TMC9660_FAULT_PIN_SUPPORTED != 0 +void tmc9660_waitForFaultDeassertion(uint16_t icID); +#endif + +/*** TMC9660 Bootloader Mode functions ****************************************/ +int32_t tmc9660_bl_sendCommand(uint16_t icID, uint8_t cmd, uint32_t writeValue, uint32_t *readValue); + +/*** TMC9660 Parameter Mode functions *****************************************/ +int32_t tmc9660_param_sendCommand(uint16_t icID, uint8_t cmd, uint16_t type, uint8_t index, uint32_t writeValue, uint32_t *readValue); + +// Special case commands: These two functions run commands that are edge cases of the underlying protocol +int32_t tmc9660_param_getVersionASCII(uint16_t icID, uint8_t *versionString); +int32_t tmc9660_param_returnToBootloader(uint16_t icID); + +uint32_t tmc9660_param_getParameter(uint16_t icID, uint16_t type); +bool tmc9660_param_setParameter(uint16_t icID, uint16_t type, uint32_t value); + +uint32_t tmc9660_param_getGlobalParameter(uint16_t icID, uint16_t index); +bool tmc9660_param_setGlobalParameter(uint16_t icID, uint16_t index, uint32_t value); + +/*** TMC9660 Register Mode functions *****************************************/ +int32_t tmc9660_reg_sendCommand(uint16_t icID, uint8_t cmd, uint16_t registerOffset, uint8_t registerBlock, uint32_t writeValue, uint32_t *readValue); + +// Special case commands: These two functions run commands that are edge cases of the underlying protocol +int32_t tmc9660_reg_getVersionASCII(uint16_t icID, uint8_t *versionString); +int32_t tmc9660_reg_returnToBootloader(uint16_t icID); + +/******************************************************************************/ + +#endif /* TMC_IC_TMC9660_H_ */ diff --git a/firmware/lib/tmc/ic/TMC9660/TMC9660_BL_HW_Abstraction.h b/firmware/lib/tmc/ic/TMC9660/TMC9660_BL_HW_Abstraction.h new file mode 100755 index 0000000..06c4139 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC9660/TMC9660_BL_HW_Abstraction.h @@ -0,0 +1,693 @@ +/******************************************************************************* +* Copyright © 2025 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + +#ifndef TMC9660_BL_HW_ABSTRACTION_H_ +#define TMC9660_BL_HW_ABSTRACTION_H_ + +#include +#include + +#ifndef TMC_REGISTERFIELD32_DEFINED +#define TMC_REGISTERFIELD32_DEFINED +typedef struct +{ + uint32_t mask; + uint8_t shift; + uint32_t address; + bool isSigned; +} RegisterField32; + + +static inline uint32_t field_extract32(uint32_t data, RegisterField32 field) +{ + uint32_t value = (data & field.mask) >> field.shift; + + if (field.isSigned) + { + // Apply signedness conversion + uint32_t baseMask = field.mask >> field.shift; + uint32_t signMask = baseMask & (~baseMask >> 1); + value = (value ^ signMask) - signMask; + } + + return value; +} + +static inline uint32_t field_update32(uint32_t data, RegisterField32 field, uint32_t value) +{ + return (data & (~field.mask)) | ((value << field.shift) & field.mask); +} + +#endif /* TMC_REGISTERFIELD32_DEFINED */ + +#ifndef TMC_REGISTERFIELD16_DEFINED +#define TMC_REGISTERFIELD16_DEFINED +typedef struct +{ + uint16_t mask; + uint8_t shift; + uint32_t address; + bool isSigned; +} RegisterField16; + +static inline uint16_t field_extract16(uint16_t data, RegisterField16 field) +{ + uint16_t value = (data & field.mask) >> field.shift; + + if (field.isSigned) + { + // Apply signedness conversion + uint16_t baseMask = field.mask >> field.shift; + uint16_t signMask = baseMask & (~baseMask >> 1); + value = (value ^ signMask) - signMask; + } + + return value; +} + +static inline uint16_t field_update16(uint16_t data, RegisterField16 field, uint16_t value) +{ + return (data & (~field.mask)) | ((value << field.shift) & field.mask); +} +#endif /* TMC_REGISTERFIELD16_DEFINED */ + +// CONFIG addresses +#define CONFIG_BOOT_00_POWER 0x00020000 +#define CONFIG_BOOT_01_ADDRESS 0x00020002 +#define CONFIG_BOOT_02_UART_TXEN_DELAY 0x00020004 +#define CONFIG_BOOT_03_BOOT_INTERFACE 0x00020006 +#define CONFIG_BOOT_04_BOOTSTRAP 0x00020008 +#define CONFIG_BOOT_05_FLASH 0x0002000A +#define CONFIG_BOOT_06_EEPROM 0x0002000C +#define CONFIG_BOOT_07_GPIO_DATA_0_15_INIT 0x0002000E +#define CONFIG_BOOT_08_GPIO_DIR_0_15_INIT 0x00020010 +#define CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT 0x00020012 +#define CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT 0x00020014 +#define CONFIG_BOOT_0B_GPIO_16_18_INIT 0x00020016 +#define CONFIG_BOOT_0C_CLK_SEL_INIT 0x00020018 +#define CONFIG_BOOT_0E_PLL_CONFIG0 0x0002001C +#define CONFIG_BOOT_0F_PLL_CONFIG1 0x0002001E +#define CONFIG_BOOT_10_APP_CONFIG_0 0x00020020 +#define CONFIG_BOOT_11_APP_CONFIG_1 0x00020022 +#define CONFIG_BOOT_12_APP_CONFIG_2 0x00020024 +#define CONFIG_BOOT_13_APP_CONFIG_3 0x00020026 +#define CONFIG_BOOT_14_APP_CONFIG_4 0x00020028 +#define CONFIG_BOOT_15_RESERVED 0x0002002A +#define CONFIG_BOOT_16_RESERVED 0x0002002C +#define CONFIG_BOOT_17_RESERVED 0x0002002E +#define CONFIG_BOOT_18_RESERVED 0x00020030 +#define CONFIG_BOOT_19_RESERVED 0x00020032 +#define CONFIG_BOOT_1A_RESERVED 0x00020034 +#define CONFIG_BOOT_1B_RESERVED 0x00020036 +#define CONFIG_BOOT_1C_RESERVED 0x00020038 +#define CONFIG_BOOT_1D_RESERVED 0x0002003A +#define CONFIG_BOOT_1E_RESERVED 0x0002003C +#define CONFIG_BOOT_1F_RESERVED 0x0002003E + +// BOOT_00_POWER fields +#define CONFIG_BOOT_00_POWER_VEXT1_MASK 0x0003 +#define CONFIG_BOOT_00_POWER_VEXT1_SHIFT 0 +#define CONFIG_BOOT_00_POWER_VEXT1_FIELD ((RegisterField16) { CONFIG_BOOT_00_POWER_VEXT1_MASK, CONFIG_BOOT_00_POWER_VEXT1_SHIFT, CONFIG_BOOT_00_POWER, false }) +#define CONFIG_BOOT_00_POWER_VEXT2_MASK 0x000C +#define CONFIG_BOOT_00_POWER_VEXT2_SHIFT 2 +#define CONFIG_BOOT_00_POWER_VEXT2_FIELD ((RegisterField16) { CONFIG_BOOT_00_POWER_VEXT2_MASK, CONFIG_BOOT_00_POWER_VEXT2_SHIFT, CONFIG_BOOT_00_POWER, false }) +#define CONFIG_BOOT_00_POWER_SS_VEXT1_MASK 0x0030 +#define CONFIG_BOOT_00_POWER_SS_VEXT1_SHIFT 4 +#define CONFIG_BOOT_00_POWER_SS_VEXT1_FIELD ((RegisterField16) { CONFIG_BOOT_00_POWER_SS_VEXT1_MASK, CONFIG_BOOT_00_POWER_SS_VEXT1_SHIFT, CONFIG_BOOT_00_POWER, false }) +#define CONFIG_BOOT_00_POWER_SS_VEXT2_MASK 0x00C0 +#define CONFIG_BOOT_00_POWER_SS_VEXT2_SHIFT 6 +#define CONFIG_BOOT_00_POWER_SS_VEXT2_FIELD ((RegisterField16) { CONFIG_BOOT_00_POWER_SS_VEXT2_MASK, CONFIG_BOOT_00_POWER_SS_VEXT2_SHIFT, CONFIG_BOOT_00_POWER, false }) +#define CONFIG_BOOT_00_POWER_LDO_SHORT_FAULT_MASK 0x0100 +#define CONFIG_BOOT_00_POWER_LDO_SHORT_FAULT_SHIFT 8 +#define CONFIG_BOOT_00_POWER_LDO_SHORT_FAULT_FIELD ((RegisterField16) { CONFIG_BOOT_00_POWER_LDO_SHORT_FAULT_MASK, CONFIG_BOOT_00_POWER_LDO_SHORT_FAULT_SHIFT, CONFIG_BOOT_00_POWER, false }) + +// BOOT_01_ADDRESS fields +#define CONFIG_BOOT_01_DEVICE_ADDRESS_MASK 0x00FF +#define CONFIG_BOOT_01_DEVICE_ADDRESS_SHIFT 0 +#define CONFIG_BOOT_01_DEVICE_ADDRESS_FIELD ((RegisterField16) { CONFIG_BOOT_01_DEVICE_ADDRESS_MASK, CONFIG_BOOT_01_DEVICE_ADDRESS_SHIFT, CONFIG_BOOT_01_ADDRESS, false }) +#define CONFIG_BOOT_01_MASTER_ADDRESS_MASK 0xFF00 +#define CONFIG_BOOT_01_MASTER_ADDRESS_SHIFT 8 +#define CONFIG_BOOT_01_MASTER_ADDRESS_FIELD ((RegisterField16) { CONFIG_BOOT_01_MASTER_ADDRESS_MASK, CONFIG_BOOT_01_MASTER_ADDRESS_SHIFT, CONFIG_BOOT_01_ADDRESS, false }) + +// BOOT_02_UART_TXEN_DELAY fields +#define CONFIG_BOOT_02_UART_TXEN_POST_DELAY_MASK 0x00FF +#define CONFIG_BOOT_02_UART_TXEN_POST_DELAY_SHIFT 0 +#define CONFIG_BOOT_02_UART_TXEN_POST_DELAY_FIELD ((RegisterField16) { CONFIG_BOOT_02_UART_TXEN_POST_DELAY_MASK, CONFIG_BOOT_02_UART_TXEN_POST_DELAY_SHIFT, CONFIG_BOOT_02_UART_TXEN_DELAY, false }) +#define CONFIG_BOOT_02_UART_TXEN_PRE_DELAY_MASK 0xFF00 +#define CONFIG_BOOT_02_UART_TXEN_PRE_DELAY_SHIFT 8 +#define CONFIG_BOOT_02_UART_TXEN_PRE_DELAY_FIELD ((RegisterField16) { CONFIG_BOOT_02_UART_TXEN_PRE_DELAY_MASK, CONFIG_BOOT_02_UART_TXEN_PRE_DELAY_SHIFT, CONFIG_BOOT_02_UART_TXEN_DELAY, false }) + +// BOOT_03_BOOT_INTERFACE fields +#define CONFIG_BOOT_03_INTERFACE_BL_DISABLE_UART_MASK 0x0001 +#define CONFIG_BOOT_03_INTERFACE_BL_DISABLE_UART_SHIFT 0 +#define CONFIG_BOOT_03_INTERFACE_BL_DISABLE_UART_FIELD ((RegisterField16) { CONFIG_BOOT_03_INTERFACE_BL_DISABLE_UART_MASK, CONFIG_BOOT_03_INTERFACE_BL_DISABLE_UART_SHIFT, CONFIG_BOOT_03_BOOT_INTERFACE, false }) +#define CONFIG_BOOT_03_INTERFACE_BL_DISABLE_SPI_MASK 0x0002 +#define CONFIG_BOOT_03_INTERFACE_BL_DISABLE_SPI_SHIFT 1 +#define CONFIG_BOOT_03_INTERFACE_BL_DISABLE_SPI_FIELD ((RegisterField16) { CONFIG_BOOT_03_INTERFACE_BL_DISABLE_SPI_MASK, CONFIG_BOOT_03_INTERFACE_BL_DISABLE_SPI_SHIFT, CONFIG_BOOT_03_BOOT_INTERFACE, false }) +#define CONFIG_BOOT_03_INTERFACE_BL_SPI_SELECT_MASK 0x0004 +#define CONFIG_BOOT_03_INTERFACE_BL_SPI_SELECT_SHIFT 2 +#define CONFIG_BOOT_03_INTERFACE_BL_SPI_SELECT_FIELD ((RegisterField16) { CONFIG_BOOT_03_INTERFACE_BL_SPI_SELECT_MASK, CONFIG_BOOT_03_INTERFACE_BL_SPI_SELECT_SHIFT, CONFIG_BOOT_03_BOOT_INTERFACE, false }) +#define CONFIG_BOOT_03_INTERFACE_BL_UART_RX_MASK 0x0008 +#define CONFIG_BOOT_03_INTERFACE_BL_UART_RX_SHIFT 3 +#define CONFIG_BOOT_03_INTERFACE_BL_UART_RX_FIELD ((RegisterField16) { CONFIG_BOOT_03_INTERFACE_BL_UART_RX_MASK, CONFIG_BOOT_03_INTERFACE_BL_UART_RX_SHIFT, CONFIG_BOOT_03_BOOT_INTERFACE, false }) +#define CONFIG_BOOT_03_INTERFACE_BL_UART_TX_MASK 0x0010 +#define CONFIG_BOOT_03_INTERFACE_BL_UART_TX_SHIFT 4 +#define CONFIG_BOOT_03_INTERFACE_BL_UART_TX_FIELD ((RegisterField16) { CONFIG_BOOT_03_INTERFACE_BL_UART_TX_MASK, CONFIG_BOOT_03_INTERFACE_BL_UART_TX_SHIFT, CONFIG_BOOT_03_BOOT_INTERFACE, false }) +#define CONFIG_BOOT_03_INTERFACE_BL_UART_TXEN_MASK 0x0060 +#define CONFIG_BOOT_03_INTERFACE_BL_UART_TXEN_SHIFT 5 +#define CONFIG_BOOT_03_INTERFACE_BL_UART_TXEN_FIELD ((RegisterField16) { CONFIG_BOOT_03_INTERFACE_BL_UART_TXEN_MASK, CONFIG_BOOT_03_INTERFACE_BL_UART_TXEN_SHIFT, CONFIG_BOOT_03_BOOT_INTERFACE, false }) +#define CONFIG_BOOT_03_INTERFACE_BL_UART_BAUDRATE_MASK 0x0380 +#define CONFIG_BOOT_03_INTERFACE_BL_UART_BAUDRATE_SHIFT 7 +#define CONFIG_BOOT_03_INTERFACE_BL_UART_BAUDRATE_FIELD ((RegisterField16) { CONFIG_BOOT_03_INTERFACE_BL_UART_BAUDRATE_MASK, CONFIG_BOOT_03_INTERFACE_BL_UART_BAUDRATE_SHIFT, CONFIG_BOOT_03_BOOT_INTERFACE, false }) +#define CONFIG_BOOT_03_INTERFACE_BL_SPI0_SCK_MASK 0x0400 +#define CONFIG_BOOT_03_INTERFACE_BL_SPI0_SCK_SHIFT 10 +#define CONFIG_BOOT_03_INTERFACE_BL_SPI0_SCK_FIELD ((RegisterField16) { CONFIG_BOOT_03_INTERFACE_BL_SPI0_SCK_MASK, CONFIG_BOOT_03_INTERFACE_BL_SPI0_SCK_SHIFT, CONFIG_BOOT_03_BOOT_INTERFACE, false }) + +// BOOT_04_BOOTSTRAP fields +#define CONFIG_BOOT_04_BOOTSTRAP_BOOT_APP_MASK 0x0003 +#define CONFIG_BOOT_04_BOOTSTRAP_BOOT_APP_SHIFT 0 +#define CONFIG_BOOT_04_BOOTSTRAP_BOOT_APP_FIELD ((RegisterField16) { CONFIG_BOOT_04_BOOTSTRAP_BOOT_APP_MASK, CONFIG_BOOT_04_BOOTSTRAP_BOOT_APP_SHIFT, CONFIG_BOOT_04_BOOTSTRAP, false }) +#define CONFIG_BOOT_04_BOOTSTRAP_BL_ENTRY_FAULT_MASK 0x0004 +#define CONFIG_BOOT_04_BOOTSTRAP_BL_ENTRY_FAULT_SHIFT 2 +#define CONFIG_BOOT_04_BOOTSTRAP_BL_ENTRY_FAULT_FIELD ((RegisterField16) { CONFIG_BOOT_04_BOOTSTRAP_BL_ENTRY_FAULT_MASK, CONFIG_BOOT_04_BOOTSTRAP_BL_ENTRY_FAULT_SHIFT, CONFIG_BOOT_04_BOOTSTRAP, false }) +#define CONFIG_BOOT_04_BOOTSTRAP_BL_EXIT_FAULT_MASK 0x0008 +#define CONFIG_BOOT_04_BOOTSTRAP_BL_EXIT_FAULT_SHIFT 3 +#define CONFIG_BOOT_04_BOOTSTRAP_BL_EXIT_FAULT_FIELD ((RegisterField16) { CONFIG_BOOT_04_BOOTSTRAP_BL_EXIT_FAULT_MASK, CONFIG_BOOT_04_BOOTSTRAP_BL_EXIT_FAULT_SHIFT, CONFIG_BOOT_04_BOOTSTRAP, false }) +#define CONFIG_BOOT_04_BOOTSTRAP_EXT_MEM_RETRIES_MASK 0x00F0 +#define CONFIG_BOOT_04_BOOTSTRAP_EXT_MEM_RETRIES_SHIFT 4 +#define CONFIG_BOOT_04_BOOTSTRAP_EXT_MEM_RETRIES_FIELD ((RegisterField16) { CONFIG_BOOT_04_BOOTSTRAP_EXT_MEM_RETRIES_MASK, CONFIG_BOOT_04_BOOTSTRAP_EXT_MEM_RETRIES_SHIFT, CONFIG_BOOT_04_BOOTSTRAP, false }) +#define CONFIG_BOOT_04_BOOTSTRAP_DISABLE_SELF_TEST_MASK 0x0100 +#define CONFIG_BOOT_04_BOOTSTRAP_DISABLE_SELF_TEST_SHIFT 8 +#define CONFIG_BOOT_04_BOOTSTRAP_DISABLE_SELF_TEST_FIELD ((RegisterField16) { CONFIG_BOOT_04_BOOTSTRAP_DISABLE_SELF_TEST_MASK, CONFIG_BOOT_04_BOOTSTRAP_DISABLE_SELF_TEST_SHIFT, CONFIG_BOOT_04_BOOTSTRAP, false }) +#define CONFIG_BOOT_04_BOOTSTRAP_BL_CONFIG_FAULT_MASK 0x0200 +#define CONFIG_BOOT_04_BOOTSTRAP_BL_CONFIG_FAULT_SHIFT 9 +#define CONFIG_BOOT_04_BOOTSTRAP_BL_CONFIG_FAULT_FIELD ((RegisterField16) { CONFIG_BOOT_04_BOOTSTRAP_BL_CONFIG_FAULT_MASK, CONFIG_BOOT_04_BOOTSTRAP_BL_CONFIG_FAULT_SHIFT, CONFIG_BOOT_04_BOOTSTRAP, false }) +#define CONFIG_BOOT_04_BOOTSTRAP_LOAD_ROM_CODE_MASK 0x1000 +#define CONFIG_BOOT_04_BOOTSTRAP_LOAD_ROM_CODE_SHIFT 12 +#define CONFIG_BOOT_04_BOOTSTRAP_LOAD_ROM_CODE_FIELD ((RegisterField16) { CONFIG_BOOT_04_BOOTSTRAP_LOAD_ROM_CODE_MASK, CONFIG_BOOT_04_BOOTSTRAP_LOAD_ROM_CODE_SHIFT, CONFIG_BOOT_04_BOOTSTRAP, false }) + +// BOOT_05_FLASH fields +#define CONFIG_BOOT_05_SPI_FLASH_EN_MASK 0x0001 +#define CONFIG_BOOT_05_SPI_FLASH_EN_SHIFT 0 +#define CONFIG_BOOT_05_SPI_FLASH_EN_FIELD ((RegisterField16) { CONFIG_BOOT_05_SPI_FLASH_EN_MASK, CONFIG_BOOT_05_SPI_FLASH_EN_SHIFT, CONFIG_BOOT_05_FLASH, false }) +#define CONFIG_BOOT_05_FLASH_SPI_CS_SW_MASK 0x00F8 +#define CONFIG_BOOT_05_FLASH_SPI_CS_SW_SHIFT 3 +#define CONFIG_BOOT_05_FLASH_SPI_CS_SW_FIELD ((RegisterField16) { CONFIG_BOOT_05_FLASH_SPI_CS_SW_MASK, CONFIG_BOOT_05_FLASH_SPI_CS_SW_SHIFT, CONFIG_BOOT_05_FLASH, false }) +#define CONFIG_BOOT_05_FLASH_SPI_DIV_MASK 0x0F00 +#define CONFIG_BOOT_05_FLASH_SPI_DIV_SHIFT 8 +#define CONFIG_BOOT_05_FLASH_SPI_DIV_FIELD ((RegisterField16) { CONFIG_BOOT_05_FLASH_SPI_DIV_MASK, CONFIG_BOOT_05_FLASH_SPI_DIV_SHIFT, CONFIG_BOOT_05_FLASH, false }) + +// BOOT_06_EEPROM fields +#define CONFIG_BOOT_06_I2C_EEPROM_EN_MASK 0x0001 +#define CONFIG_BOOT_06_I2C_EEPROM_EN_SHIFT 0 +#define CONFIG_BOOT_06_I2C_EEPROM_EN_FIELD ((RegisterField16) { CONFIG_BOOT_06_I2C_EEPROM_EN_MASK, CONFIG_BOOT_06_I2C_EEPROM_EN_SHIFT, CONFIG_BOOT_06_EEPROM, false }) +#define CONFIG_BOOT_06_EEPROM_I2C_SDA_MASK 0x0006 +#define CONFIG_BOOT_06_EEPROM_I2C_SDA_SHIFT 1 +#define CONFIG_BOOT_06_EEPROM_I2C_SDA_FIELD ((RegisterField16) { CONFIG_BOOT_06_EEPROM_I2C_SDA_MASK, CONFIG_BOOT_06_EEPROM_I2C_SDA_SHIFT, CONFIG_BOOT_06_EEPROM, false }) +#define CONFIG_BOOT_06_EEPROM_I2C_SCL_MASK 0x0018 +#define CONFIG_BOOT_06_EEPROM_I2C_SCL_SHIFT 3 +#define CONFIG_BOOT_06_EEPROM_I2C_SCL_FIELD ((RegisterField16) { CONFIG_BOOT_06_EEPROM_I2C_SCL_MASK, CONFIG_BOOT_06_EEPROM_I2C_SCL_SHIFT, CONFIG_BOOT_06_EEPROM, false }) +#define CONFIG_BOOT_06_EEPROM_I2C_ADDR_MASK 0x00E0 +#define CONFIG_BOOT_06_EEPROM_I2C_ADDR_SHIFT 5 +#define CONFIG_BOOT_06_EEPROM_I2C_ADDR_FIELD ((RegisterField16) { CONFIG_BOOT_06_EEPROM_I2C_ADDR_MASK, CONFIG_BOOT_06_EEPROM_I2C_ADDR_SHIFT, CONFIG_BOOT_06_EEPROM, false }) +#define CONFIG_BOOT_06_EEPROM_I2C_MUL_MASK 0x0700 +#define CONFIG_BOOT_06_EEPROM_I2C_MUL_SHIFT 8 +#define CONFIG_BOOT_06_EEPROM_I2C_MUL_FIELD ((RegisterField16) { CONFIG_BOOT_06_EEPROM_I2C_MUL_MASK, CONFIG_BOOT_06_EEPROM_I2C_MUL_SHIFT, CONFIG_BOOT_06_EEPROM, false }) + +// BOOT_07_GPIO_DATA_0_15_INIT fields +#define CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO0_OUT_MASK 0x0001 +#define CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO0_OUT_SHIFT 0 +#define CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO0_OUT_FIELD ((RegisterField16) { CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO0_OUT_MASK, CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO0_OUT_SHIFT, CONFIG_BOOT_07_GPIO_DATA_0_15_INIT, false }) +#define CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO1_OUT_MASK 0x0002 +#define CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO1_OUT_SHIFT 1 +#define CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO1_OUT_FIELD ((RegisterField16) { CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO1_OUT_MASK, CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO1_OUT_SHIFT, CONFIG_BOOT_07_GPIO_DATA_0_15_INIT, false }) +#define CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO2_OUT_MASK 0x0004 +#define CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO2_OUT_SHIFT 2 +#define CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO2_OUT_FIELD ((RegisterField16) { CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO2_OUT_MASK, CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO2_OUT_SHIFT, CONFIG_BOOT_07_GPIO_DATA_0_15_INIT, false }) +#define CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO3_OUT_MASK 0x0008 +#define CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO3_OUT_SHIFT 3 +#define CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO3_OUT_FIELD ((RegisterField16) { CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO3_OUT_MASK, CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO3_OUT_SHIFT, CONFIG_BOOT_07_GPIO_DATA_0_15_INIT, false }) +#define CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO4_OUT_MASK 0x0010 +#define CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO4_OUT_SHIFT 4 +#define CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO4_OUT_FIELD ((RegisterField16) { CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO4_OUT_MASK, CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO4_OUT_SHIFT, CONFIG_BOOT_07_GPIO_DATA_0_15_INIT, false }) +#define CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO5_OUT_MASK 0x0020 +#define CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO5_OUT_SHIFT 5 +#define CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO5_OUT_FIELD ((RegisterField16) { CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO5_OUT_MASK, CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO5_OUT_SHIFT, CONFIG_BOOT_07_GPIO_DATA_0_15_INIT, false }) +#define CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO6_OUT_MASK 0x0040 +#define CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO6_OUT_SHIFT 6 +#define CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO6_OUT_FIELD ((RegisterField16) { CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO6_OUT_MASK, CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO6_OUT_SHIFT, CONFIG_BOOT_07_GPIO_DATA_0_15_INIT, false }) +#define CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO7_OUT_MASK 0x0080 +#define CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO7_OUT_SHIFT 7 +#define CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO7_OUT_FIELD ((RegisterField16) { CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO7_OUT_MASK, CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO7_OUT_SHIFT, CONFIG_BOOT_07_GPIO_DATA_0_15_INIT, false }) +#define CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO8_OUT_MASK 0x0100 +#define CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO8_OUT_SHIFT 8 +#define CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO8_OUT_FIELD ((RegisterField16) { CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO8_OUT_MASK, CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO8_OUT_SHIFT, CONFIG_BOOT_07_GPIO_DATA_0_15_INIT, false }) +#define CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO9_OUT_MASK 0x0200 +#define CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO9_OUT_SHIFT 9 +#define CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO9_OUT_FIELD ((RegisterField16) { CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO9_OUT_MASK, CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO9_OUT_SHIFT, CONFIG_BOOT_07_GPIO_DATA_0_15_INIT, false }) +#define CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO10_OUT_MASK 0x0400 +#define CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO10_OUT_SHIFT 10 +#define CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO10_OUT_FIELD ((RegisterField16) { CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO10_OUT_MASK, CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO10_OUT_SHIFT, CONFIG_BOOT_07_GPIO_DATA_0_15_INIT, false }) +#define CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO11_OUT_MASK 0x0800 +#define CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO11_OUT_SHIFT 11 +#define CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO11_OUT_FIELD ((RegisterField16) { CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO11_OUT_MASK, CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO11_OUT_SHIFT, CONFIG_BOOT_07_GPIO_DATA_0_15_INIT, false }) +#define CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO12_OUT_MASK 0x1000 +#define CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO12_OUT_SHIFT 12 +#define CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO12_OUT_FIELD ((RegisterField16) { CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO12_OUT_MASK, CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO12_OUT_SHIFT, CONFIG_BOOT_07_GPIO_DATA_0_15_INIT, false }) +#define CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO13_OUT_MASK 0x2000 +#define CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO13_OUT_SHIFT 13 +#define CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO13_OUT_FIELD ((RegisterField16) { CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO13_OUT_MASK, CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO13_OUT_SHIFT, CONFIG_BOOT_07_GPIO_DATA_0_15_INIT, false }) +#define CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO14_OUT_MASK 0x4000 +#define CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO14_OUT_SHIFT 14 +#define CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO14_OUT_FIELD ((RegisterField16) { CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO14_OUT_MASK, CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO14_OUT_SHIFT, CONFIG_BOOT_07_GPIO_DATA_0_15_INIT, false }) +#define CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO15_OUT_MASK 0x8000 +#define CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO15_OUT_SHIFT 15 +#define CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO15_OUT_FIELD ((RegisterField16) { CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO15_OUT_MASK, CONFIG_BOOT_07_GPIO_DATA_0_15_INIT_GPIO15_OUT_SHIFT, CONFIG_BOOT_07_GPIO_DATA_0_15_INIT, false }) + +// BOOT_08_GPIO_DIR_0_15_INIT fields +#define CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO0_OUT_EN_MASK 0x0001 +#define CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO0_OUT_EN_SHIFT 0 +#define CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO0_OUT_EN_FIELD ((RegisterField16) { CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO0_OUT_EN_MASK, CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO0_OUT_EN_SHIFT, CONFIG_BOOT_08_GPIO_DIR_0_15_INIT, false }) +#define CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO1_OUT_EN_MASK 0x0002 +#define CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO1_OUT_EN_SHIFT 1 +#define CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO1_OUT_EN_FIELD ((RegisterField16) { CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO1_OUT_EN_MASK, CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO1_OUT_EN_SHIFT, CONFIG_BOOT_08_GPIO_DIR_0_15_INIT, false }) +#define CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO2_OUT_EN_MASK 0x0004 +#define CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO2_OUT_EN_SHIFT 2 +#define CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO2_OUT_EN_FIELD ((RegisterField16) { CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO2_OUT_EN_MASK, CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO2_OUT_EN_SHIFT, CONFIG_BOOT_08_GPIO_DIR_0_15_INIT, false }) +#define CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO3_OUT_EN_MASK 0x0008 +#define CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO3_OUT_EN_SHIFT 3 +#define CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO3_OUT_EN_FIELD ((RegisterField16) { CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO3_OUT_EN_MASK, CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO3_OUT_EN_SHIFT, CONFIG_BOOT_08_GPIO_DIR_0_15_INIT, false }) +#define CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO4_OUT_EN_MASK 0x0010 +#define CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO4_OUT_EN_SHIFT 4 +#define CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO4_OUT_EN_FIELD ((RegisterField16) { CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO4_OUT_EN_MASK, CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO4_OUT_EN_SHIFT, CONFIG_BOOT_08_GPIO_DIR_0_15_INIT, false }) +#define CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO5_OUT_EN_MASK 0x0020 +#define CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO5_OUT_EN_SHIFT 5 +#define CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO5_OUT_EN_FIELD ((RegisterField16) { CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO5_OUT_EN_MASK, CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO5_OUT_EN_SHIFT, CONFIG_BOOT_08_GPIO_DIR_0_15_INIT, false }) +#define CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO6_OUT_EN_MASK 0x0040 +#define CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO6_OUT_EN_SHIFT 6 +#define CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO6_OUT_EN_FIELD ((RegisterField16) { CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO6_OUT_EN_MASK, CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO6_OUT_EN_SHIFT, CONFIG_BOOT_08_GPIO_DIR_0_15_INIT, false }) +#define CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO7_OUT_EN_MASK 0x0080 +#define CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO7_OUT_EN_SHIFT 7 +#define CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO7_OUT_EN_FIELD ((RegisterField16) { CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO7_OUT_EN_MASK, CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO7_OUT_EN_SHIFT, CONFIG_BOOT_08_GPIO_DIR_0_15_INIT, false }) +#define CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO8_OUT_EN_MASK 0x0100 +#define CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO8_OUT_EN_SHIFT 8 +#define CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO8_OUT_EN_FIELD ((RegisterField16) { CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO8_OUT_EN_MASK, CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO8_OUT_EN_SHIFT, CONFIG_BOOT_08_GPIO_DIR_0_15_INIT, false }) +#define CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO9_OUT_EN_MASK 0x0200 +#define CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO9_OUT_EN_SHIFT 9 +#define CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO9_OUT_EN_FIELD ((RegisterField16) { CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO9_OUT_EN_MASK, CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO9_OUT_EN_SHIFT, CONFIG_BOOT_08_GPIO_DIR_0_15_INIT, false }) +#define CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO10_OUT_EN_MASK 0x0400 +#define CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO10_OUT_EN_SHIFT 10 +#define CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO10_OUT_EN_FIELD ((RegisterField16) { CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO10_OUT_EN_MASK, CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO10_OUT_EN_SHIFT, CONFIG_BOOT_08_GPIO_DIR_0_15_INIT, false }) +#define CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO11_OUT_EN_MASK 0x0800 +#define CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO11_OUT_EN_SHIFT 11 +#define CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO11_OUT_EN_FIELD ((RegisterField16) { CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO11_OUT_EN_MASK, CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO11_OUT_EN_SHIFT, CONFIG_BOOT_08_GPIO_DIR_0_15_INIT, false }) +#define CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO12_OUT_EN_MASK 0x1000 +#define CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO12_OUT_EN_SHIFT 12 +#define CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO12_OUT_EN_FIELD ((RegisterField16) { CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO12_OUT_EN_MASK, CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO12_OUT_EN_SHIFT, CONFIG_BOOT_08_GPIO_DIR_0_15_INIT, false }) +#define CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO13_OUT_EN_MASK 0x2000 +#define CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO13_OUT_EN_SHIFT 13 +#define CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO13_OUT_EN_FIELD ((RegisterField16) { CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO13_OUT_EN_MASK, CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO13_OUT_EN_SHIFT, CONFIG_BOOT_08_GPIO_DIR_0_15_INIT, false }) +#define CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO14_OUT_EN_MASK 0x4000 +#define CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO14_OUT_EN_SHIFT 14 +#define CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO14_OUT_EN_FIELD ((RegisterField16) { CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO14_OUT_EN_MASK, CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO14_OUT_EN_SHIFT, CONFIG_BOOT_08_GPIO_DIR_0_15_INIT, false }) +#define CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO15_OUT_EN_MASK 0x8000 +#define CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO15_OUT_EN_SHIFT 15 +#define CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO15_OUT_EN_FIELD ((RegisterField16) { CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO15_OUT_EN_MASK, CONFIG_BOOT_08_GPIO_DIR_0_15_INIT_GPIO15_OUT_EN_SHIFT, CONFIG_BOOT_08_GPIO_DIR_0_15_INIT, false }) + +// BOOT_09_GPIO_PULLUP_0_15_INIT fields +#define CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO0_PU_MASK 0x0001 +#define CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO0_PU_SHIFT 0 +#define CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO0_PU_FIELD ((RegisterField16) { CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO0_PU_MASK, CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO0_PU_SHIFT, CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT, false }) +#define CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO1_PU_MASK 0x0002 +#define CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO1_PU_SHIFT 1 +#define CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO1_PU_FIELD ((RegisterField16) { CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO1_PU_MASK, CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO1_PU_SHIFT, CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT, false }) +#define CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO2_PU_MASK 0x0004 +#define CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO2_PU_SHIFT 2 +#define CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO2_PU_FIELD ((RegisterField16) { CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO2_PU_MASK, CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO2_PU_SHIFT, CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT, false }) +#define CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO3_PU_MASK 0x0008 +#define CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO3_PU_SHIFT 3 +#define CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO3_PU_FIELD ((RegisterField16) { CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO3_PU_MASK, CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO3_PU_SHIFT, CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT, false }) +#define CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO4_PU_MASK 0x0010 +#define CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO4_PU_SHIFT 4 +#define CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO4_PU_FIELD ((RegisterField16) { CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO4_PU_MASK, CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO4_PU_SHIFT, CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT, false }) +#define CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO5_PU_MASK 0x0020 +#define CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO5_PU_SHIFT 5 +#define CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO5_PU_FIELD ((RegisterField16) { CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO5_PU_MASK, CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO5_PU_SHIFT, CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT, false }) +#define CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO6_PU_MASK 0x0040 +#define CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO6_PU_SHIFT 6 +#define CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO6_PU_FIELD ((RegisterField16) { CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO6_PU_MASK, CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO6_PU_SHIFT, CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT, false }) +#define CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO7_PU_MASK 0x0080 +#define CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO7_PU_SHIFT 7 +#define CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO7_PU_FIELD ((RegisterField16) { CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO7_PU_MASK, CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO7_PU_SHIFT, CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT, false }) +#define CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO8_PU_MASK 0x0100 +#define CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO8_PU_SHIFT 8 +#define CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO8_PU_FIELD ((RegisterField16) { CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO8_PU_MASK, CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO8_PU_SHIFT, CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT, false }) +#define CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO9_PU_MASK 0x0200 +#define CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO9_PU_SHIFT 9 +#define CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO9_PU_FIELD ((RegisterField16) { CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO9_PU_MASK, CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO9_PU_SHIFT, CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT, false }) +#define CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO10_PU_MASK 0x0400 +#define CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO10_PU_SHIFT 10 +#define CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO10_PU_FIELD ((RegisterField16) { CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO10_PU_MASK, CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO10_PU_SHIFT, CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT, false }) +#define CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO11_PU_MASK 0x0800 +#define CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO11_PU_SHIFT 11 +#define CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO11_PU_FIELD ((RegisterField16) { CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO11_PU_MASK, CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO11_PU_SHIFT, CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT, false }) +#define CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO12_PU_MASK 0x1000 +#define CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO12_PU_SHIFT 12 +#define CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO12_PU_FIELD ((RegisterField16) { CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO12_PU_MASK, CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO12_PU_SHIFT, CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT, false }) +#define CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO13_PU_MASK 0x2000 +#define CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO13_PU_SHIFT 13 +#define CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO13_PU_FIELD ((RegisterField16) { CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO13_PU_MASK, CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO13_PU_SHIFT, CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT, false }) +#define CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO14_PU_MASK 0x4000 +#define CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO14_PU_SHIFT 14 +#define CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO14_PU_FIELD ((RegisterField16) { CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO14_PU_MASK, CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO14_PU_SHIFT, CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT, false }) +#define CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO15_PU_MASK 0x8000 +#define CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO15_PU_SHIFT 15 +#define CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO15_PU_FIELD ((RegisterField16) { CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO15_PU_MASK, CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT_GPIO15_PU_SHIFT, CONFIG_BOOT_09_GPIO_PULLUP_0_15_INIT, false }) + +// BOOT_0A_GPIO_PULLDOWN_0_15_INIT fields +#define CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO0_PD_MASK 0x0001 +#define CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO0_PD_SHIFT 0 +#define CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO0_PD_FIELD ((RegisterField16) { CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO0_PD_MASK, CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO0_PD_SHIFT, CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT, false }) +#define CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO1_PD_MASK 0x0002 +#define CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO1_PD_SHIFT 1 +#define CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO1_PD_FIELD ((RegisterField16) { CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO1_PD_MASK, CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO1_PD_SHIFT, CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT, false }) +#define CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO2_PD_MASK 0x0004 +#define CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO2_PD_SHIFT 2 +#define CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO2_PD_FIELD ((RegisterField16) { CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO2_PD_MASK, CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO2_PD_SHIFT, CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT, false }) +#define CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO3_PD_MASK 0x0008 +#define CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO3_PD_SHIFT 3 +#define CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO3_PD_FIELD ((RegisterField16) { CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO3_PD_MASK, CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO3_PD_SHIFT, CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT, false }) +#define CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO4_PD_MASK 0x0010 +#define CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO4_PD_SHIFT 4 +#define CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO4_PD_FIELD ((RegisterField16) { CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO4_PD_MASK, CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO4_PD_SHIFT, CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT, false }) +#define CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO5_PD_MASK 0x0020 +#define CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO5_PD_SHIFT 5 +#define CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO5_PD_FIELD ((RegisterField16) { CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO5_PD_MASK, CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO5_PD_SHIFT, CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT, false }) +#define CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO6_PD_MASK 0x0040 +#define CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO6_PD_SHIFT 6 +#define CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO6_PD_FIELD ((RegisterField16) { CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO6_PD_MASK, CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO6_PD_SHIFT, CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT, false }) +#define CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO7_PD_MASK 0x0080 +#define CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO7_PD_SHIFT 7 +#define CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO7_PD_FIELD ((RegisterField16) { CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO7_PD_MASK, CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO7_PD_SHIFT, CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT, false }) +#define CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO8_PD_MASK 0x0100 +#define CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO8_PD_SHIFT 8 +#define CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO8_PD_FIELD ((RegisterField16) { CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO8_PD_MASK, CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO8_PD_SHIFT, CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT, false }) +#define CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO9_PD_MASK 0x0200 +#define CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO9_PD_SHIFT 9 +#define CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO9_PD_FIELD ((RegisterField16) { CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO9_PD_MASK, CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO9_PD_SHIFT, CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT, false }) +#define CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO10_PD_MASK 0x0400 +#define CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO10_PD_SHIFT 10 +#define CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO10_PD_FIELD ((RegisterField16) { CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO10_PD_MASK, CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO10_PD_SHIFT, CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT, false }) +#define CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO11_PD_MASK 0x0800 +#define CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO11_PD_SHIFT 11 +#define CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO11_PD_FIELD ((RegisterField16) { CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO11_PD_MASK, CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO11_PD_SHIFT, CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT, false }) +#define CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO12_PD_MASK 0x1000 +#define CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO12_PD_SHIFT 12 +#define CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO12_PD_FIELD ((RegisterField16) { CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO12_PD_MASK, CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO12_PD_SHIFT, CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT, false }) +#define CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO13_PD_MASK 0x2000 +#define CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO13_PD_SHIFT 13 +#define CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO13_PD_FIELD ((RegisterField16) { CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO13_PD_MASK, CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO13_PD_SHIFT, CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT, false }) +#define CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO14_PD_MASK 0x4000 +#define CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO14_PD_SHIFT 14 +#define CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO14_PD_FIELD ((RegisterField16) { CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO14_PD_MASK, CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO14_PD_SHIFT, CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT, false }) +#define CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO15_PD_MASK 0x8000 +#define CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO15_PD_SHIFT 15 +#define CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO15_PD_FIELD ((RegisterField16) { CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO15_PD_MASK, CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT_GPIO15_PD_SHIFT, CONFIG_BOOT_0A_GPIO_PULLDOWN_0_15_INIT, false }) + +// BOOT_0B_GPIO_16_18_INIT fields +#define CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO16_OUT_MASK 0x0001 +#define CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO16_OUT_SHIFT 0 +#define CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO16_OUT_FIELD ((RegisterField16) { CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO16_OUT_MASK, CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO16_OUT_SHIFT, CONFIG_BOOT_0B_GPIO_16_18_INIT, false }) +#define CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO17_OUT_MASK 0x0002 +#define CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO17_OUT_SHIFT 1 +#define CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO17_OUT_FIELD ((RegisterField16) { CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO17_OUT_MASK, CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO17_OUT_SHIFT, CONFIG_BOOT_0B_GPIO_16_18_INIT, false }) +#define CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO18_OUT_MASK 0x0004 +#define CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO18_OUT_SHIFT 2 +#define CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO18_OUT_FIELD ((RegisterField16) { CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO18_OUT_MASK, CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO18_OUT_SHIFT, CONFIG_BOOT_0B_GPIO_16_18_INIT, false }) +#define CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO16_OUT_EN_MASK 0x0008 +#define CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO16_OUT_EN_SHIFT 3 +#define CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO16_OUT_EN_FIELD ((RegisterField16) { CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO16_OUT_EN_MASK, CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO16_OUT_EN_SHIFT, CONFIG_BOOT_0B_GPIO_16_18_INIT, false }) +#define CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO17_OUT_EN_MASK 0x0010 +#define CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO17_OUT_EN_SHIFT 4 +#define CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO17_OUT_EN_FIELD ((RegisterField16) { CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO17_OUT_EN_MASK, CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO17_OUT_EN_SHIFT, CONFIG_BOOT_0B_GPIO_16_18_INIT, false }) +#define CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO18_OUT_EN_MASK 0x0020 +#define CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO18_OUT_EN_SHIFT 5 +#define CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO18_OUT_EN_FIELD ((RegisterField16) { CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO18_OUT_EN_MASK, CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO18_OUT_EN_SHIFT, CONFIG_BOOT_0B_GPIO_16_18_INIT, false }) +#define CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO16_PD_MASK 0x0040 +#define CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO16_PD_SHIFT 6 +#define CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO16_PD_FIELD ((RegisterField16) { CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO16_PD_MASK, CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO16_PD_SHIFT, CONFIG_BOOT_0B_GPIO_16_18_INIT, false }) +#define CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO17_PD_MASK 0x0080 +#define CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO17_PD_SHIFT 7 +#define CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO17_PD_FIELD ((RegisterField16) { CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO17_PD_MASK, CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO17_PD_SHIFT, CONFIG_BOOT_0B_GPIO_16_18_INIT, false }) +#define CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO18_PD_MASK 0x0100 +#define CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO18_PD_SHIFT 8 +#define CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO18_PD_FIELD ((RegisterField16) { CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO18_PD_MASK, CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO18_PD_SHIFT, CONFIG_BOOT_0B_GPIO_16_18_INIT, false }) +#define CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO16_PU_MASK 0x0200 +#define CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO16_PU_SHIFT 9 +#define CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO16_PU_FIELD ((RegisterField16) { CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO16_PU_MASK, CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO16_PU_SHIFT, CONFIG_BOOT_0B_GPIO_16_18_INIT, false }) +#define CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO17_PU_MASK 0x0400 +#define CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO17_PU_SHIFT 10 +#define CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO17_PU_FIELD ((RegisterField16) { CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO17_PU_MASK, CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO17_PU_SHIFT, CONFIG_BOOT_0B_GPIO_16_18_INIT, false }) +#define CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO18_PU_MASK 0x0800 +#define CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO18_PU_SHIFT 11 +#define CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO18_PU_FIELD ((RegisterField16) { CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO18_PU_MASK, CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO18_PU_SHIFT, CONFIG_BOOT_0B_GPIO_16_18_INIT, false }) +#define CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO2_ANALOG_EN_MASK 0x1000 +#define CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO2_ANALOG_EN_SHIFT 12 +#define CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO2_ANALOG_EN_FIELD ((RegisterField16) { CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO2_ANALOG_EN_MASK, CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO2_ANALOG_EN_SHIFT, CONFIG_BOOT_0B_GPIO_16_18_INIT, false }) +#define CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO3_ANALOG_EN_MASK 0x2000 +#define CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO3_ANALOG_EN_SHIFT 13 +#define CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO3_ANALOG_EN_FIELD ((RegisterField16) { CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO3_ANALOG_EN_MASK, CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO3_ANALOG_EN_SHIFT, CONFIG_BOOT_0B_GPIO_16_18_INIT, false }) +#define CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO4_ANALOG_EN_MASK 0x4000 +#define CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO4_ANALOG_EN_SHIFT 14 +#define CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO4_ANALOG_EN_FIELD ((RegisterField16) { CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO4_ANALOG_EN_MASK, CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO4_ANALOG_EN_SHIFT, CONFIG_BOOT_0B_GPIO_16_18_INIT, false }) +#define CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO5_ANALOG_EN_MASK 0x8000 +#define CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO5_ANALOG_EN_SHIFT 15 +#define CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO5_ANALOG_EN_FIELD ((RegisterField16) { CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO5_ANALOG_EN_MASK, CONFIG_BOOT_0B_GPIO_16_18_INIT_GPIO5_ANALOG_EN_SHIFT, CONFIG_BOOT_0B_GPIO_16_18_INIT, false }) + +// BOOT_0C_CLK_SEL_INIT fields +#define CONFIG_BOOT_0C_CLK_SEL_INIT_PLL_FB_DIV_MASK 0x0000007F +#define CONFIG_BOOT_0C_CLK_SEL_INIT_PLL_FB_DIV_SHIFT 0 +#define CONFIG_BOOT_0C_CLK_SEL_INIT_PLL_FB_DIV_FIELD ((RegisterField32) { CONFIG_BOOT_0C_CLK_SEL_INIT_PLL_FB_DIV_MASK, CONFIG_BOOT_0C_CLK_SEL_INIT_PLL_FB_DIV_SHIFT, CONFIG_BOOT_0C_CLK_SEL_INIT, false }) +#define CONFIG_BOOT_0C_CLK_SEL_INIT_EXT_NOT_XTAL_MASK 0x00000100 +#define CONFIG_BOOT_0C_CLK_SEL_INIT_EXT_NOT_XTAL_SHIFT 8 +#define CONFIG_BOOT_0C_CLK_SEL_INIT_EXT_NOT_XTAL_FIELD ((RegisterField32) { CONFIG_BOOT_0C_CLK_SEL_INIT_EXT_NOT_XTAL_MASK, CONFIG_BOOT_0C_CLK_SEL_INIT_EXT_NOT_XTAL_SHIFT, CONFIG_BOOT_0C_CLK_SEL_INIT, false }) +#define CONFIG_BOOT_0C_CLK_SEL_INIT_XTAL_CFG_MASK 0x00000E00 +#define CONFIG_BOOT_0C_CLK_SEL_INIT_XTAL_CFG_SHIFT 9 +#define CONFIG_BOOT_0C_CLK_SEL_INIT_XTAL_CFG_FIELD ((RegisterField32) { CONFIG_BOOT_0C_CLK_SEL_INIT_XTAL_CFG_MASK, CONFIG_BOOT_0C_CLK_SEL_INIT_XTAL_CFG_SHIFT, CONFIG_BOOT_0C_CLK_SEL_INIT, false }) +#define CONFIG_BOOT_0C_CLK_SEL_INIT_XTAL_BOOST_MASK 0x00001000 +#define CONFIG_BOOT_0C_CLK_SEL_INIT_XTAL_BOOST_SHIFT 12 +#define CONFIG_BOOT_0C_CLK_SEL_INIT_XTAL_BOOST_FIELD ((RegisterField32) { CONFIG_BOOT_0C_CLK_SEL_INIT_XTAL_BOOST_MASK, CONFIG_BOOT_0C_CLK_SEL_INIT_XTAL_BOOST_SHIFT, CONFIG_BOOT_0C_CLK_SEL_INIT, false }) +#define CONFIG_BOOT_0C_CLK_SEL_INIT_EXT_NOT_INT_MASK 0x00002000 +#define CONFIG_BOOT_0C_CLK_SEL_INIT_EXT_NOT_INT_SHIFT 13 +#define CONFIG_BOOT_0C_CLK_SEL_INIT_EXT_NOT_INT_FIELD ((RegisterField32) { CONFIG_BOOT_0C_CLK_SEL_INIT_EXT_NOT_INT_MASK, CONFIG_BOOT_0C_CLK_SEL_INIT_EXT_NOT_INT_SHIFT, CONFIG_BOOT_0C_CLK_SEL_INIT, false }) +#define CONFIG_BOOT_0C_CLK_SEL_INIT_PLL_OUT_SEL_MASK 0x00030000 +#define CONFIG_BOOT_0C_CLK_SEL_INIT_PLL_OUT_SEL_SHIFT 16 +#define CONFIG_BOOT_0C_CLK_SEL_INIT_PLL_OUT_SEL_FIELD ((RegisterField32) { CONFIG_BOOT_0C_CLK_SEL_INIT_PLL_OUT_SEL_MASK, CONFIG_BOOT_0C_CLK_SEL_INIT_PLL_OUT_SEL_SHIFT, CONFIG_BOOT_0C_CLK_SEL_INIT, false }) +#define CONFIG_BOOT_0C_CLK_SEL_INIT_RDIV_MASK 0x007C0000 +#define CONFIG_BOOT_0C_CLK_SEL_INIT_RDIV_SHIFT 18 +#define CONFIG_BOOT_0C_CLK_SEL_INIT_RDIV_FIELD ((RegisterField32) { CONFIG_BOOT_0C_CLK_SEL_INIT_RDIV_MASK, CONFIG_BOOT_0C_CLK_SEL_INIT_RDIV_SHIFT, CONFIG_BOOT_0C_CLK_SEL_INIT, false }) +#define CONFIG_BOOT_0C_CLK_SEL_INIT_SYS_CLK_DIV_MASK 0x01800000 +#define CONFIG_BOOT_0C_CLK_SEL_INIT_SYS_CLK_DIV_SHIFT 23 +#define CONFIG_BOOT_0C_CLK_SEL_INIT_SYS_CLK_DIV_FIELD ((RegisterField32) { CONFIG_BOOT_0C_CLK_SEL_INIT_SYS_CLK_DIV_MASK, CONFIG_BOOT_0C_CLK_SEL_INIT_SYS_CLK_DIV_SHIFT, CONFIG_BOOT_0C_CLK_SEL_INIT, false }) +#define CONFIG_BOOT_0C_CLK_SEL_INIT_PLL_STATUS_MASK 0x40000000 +#define CONFIG_BOOT_0C_CLK_SEL_INIT_PLL_STATUS_SHIFT 30 +#define CONFIG_BOOT_0C_CLK_SEL_INIT_PLL_STATUS_FIELD ((RegisterField32) { CONFIG_BOOT_0C_CLK_SEL_INIT_PLL_STATUS_MASK, CONFIG_BOOT_0C_CLK_SEL_INIT_PLL_STATUS_SHIFT, CONFIG_BOOT_0C_CLK_SEL_INIT, false }) +#define CONFIG_BOOT_0C_CLK_SEL_INIT_PLL_CONFIG_BOOT_MASK 0x80000000 +#define CONFIG_BOOT_0C_CLK_SEL_INIT_PLL_CONFIG_BOOT_SHIFT 31 +#define CONFIG_BOOT_0C_CLK_SEL_INIT_PLL_CONFIG_BOOT_FIELD ((RegisterField32) { CONFIG_BOOT_0C_CLK_SEL_INIT_PLL_CONFIG_BOOT_MASK, CONFIG_BOOT_0C_CLK_SEL_INIT_PLL_CONFIG_BOOT_SHIFT, CONFIG_BOOT_0C_CLK_SEL_INIT, false }) + +// BOOT_0E_PLL_CONFIG0 fields +#define CONFIG_BOOT_0E_CONFIG0_ONE_PER_MIN_MASK 0x001F +#define CONFIG_BOOT_0E_CONFIG0_ONE_PER_MIN_SHIFT 0 +#define CONFIG_BOOT_0E_CONFIG0_ONE_PER_MIN_FIELD ((RegisterField16) { CONFIG_BOOT_0E_CONFIG0_ONE_PER_MIN_MASK, CONFIG_BOOT_0E_CONFIG0_ONE_PER_MIN_SHIFT, CONFIG_BOOT_0E_PLL_CONFIG0, false }) +#define CONFIG_BOOT_0E_CONFIG0_PLL_DEL_SEL_MASK 0x0060 +#define CONFIG_BOOT_0E_CONFIG0_PLL_DEL_SEL_SHIFT 5 +#define CONFIG_BOOT_0E_CONFIG0_PLL_DEL_SEL_FIELD ((RegisterField16) { CONFIG_BOOT_0E_CONFIG0_PLL_DEL_SEL_MASK, CONFIG_BOOT_0E_CONFIG0_PLL_DEL_SEL_SHIFT, CONFIG_BOOT_0E_PLL_CONFIG0, false }) +#define CONFIG_BOOT_0E_CONFIG0_N16_PER_MIN_MSB_MASK 0x0080 +#define CONFIG_BOOT_0E_CONFIG0_N16_PER_MIN_MSB_SHIFT 7 +#define CONFIG_BOOT_0E_CONFIG0_N16_PER_MIN_MSB_FIELD ((RegisterField16) { CONFIG_BOOT_0E_CONFIG0_N16_PER_MIN_MSB_MASK, CONFIG_BOOT_0E_CONFIG0_N16_PER_MIN_MSB_SHIFT, CONFIG_BOOT_0E_PLL_CONFIG0, false }) +#define CONFIG_BOOT_0E_CONFIG0_ONE_PER_MAX_MASK 0x1F00 +#define CONFIG_BOOT_0E_CONFIG0_ONE_PER_MAX_SHIFT 8 +#define CONFIG_BOOT_0E_CONFIG0_ONE_PER_MAX_FIELD ((RegisterField16) { CONFIG_BOOT_0E_CONFIG0_ONE_PER_MAX_MASK, CONFIG_BOOT_0E_CONFIG0_ONE_PER_MAX_SHIFT, CONFIG_BOOT_0E_PLL_CONFIG0, false }) +#define CONFIG_BOOT_0E_CONFIG0_PLL_ERR_OTP_MASK 0x2000 +#define CONFIG_BOOT_0E_CONFIG0_PLL_ERR_OTP_SHIFT 13 +#define CONFIG_BOOT_0E_CONFIG0_PLL_ERR_OTP_FIELD ((RegisterField16) { CONFIG_BOOT_0E_CONFIG0_PLL_ERR_OTP_MASK, CONFIG_BOOT_0E_CONFIG0_PLL_ERR_OTP_SHIFT, CONFIG_BOOT_0E_PLL_CONFIG0, false }) +#define CONFIG_BOOT_0E_CONFIG0_SEL_ERR_OTP_MASK 0x4000 +#define CONFIG_BOOT_0E_CONFIG0_SEL_ERR_OTP_SHIFT 14 +#define CONFIG_BOOT_0E_CONFIG0_SEL_ERR_OTP_FIELD ((RegisterField16) { CONFIG_BOOT_0E_CONFIG0_SEL_ERR_OTP_MASK, CONFIG_BOOT_0E_CONFIG0_SEL_ERR_OTP_SHIFT, CONFIG_BOOT_0E_PLL_CONFIG0, false }) +#define CONFIG_BOOT_0E_CONFIG0_N16_PER_MAX_MSB_MASK 0x8000 +#define CONFIG_BOOT_0E_CONFIG0_N16_PER_MAX_MSB_SHIFT 15 +#define CONFIG_BOOT_0E_CONFIG0_N16_PER_MAX_MSB_FIELD ((RegisterField16) { CONFIG_BOOT_0E_CONFIG0_N16_PER_MAX_MSB_MASK, CONFIG_BOOT_0E_CONFIG0_N16_PER_MAX_MSB_SHIFT, CONFIG_BOOT_0E_PLL_CONFIG0, false }) + +// BOOT_0F_PLL_CONFIG1 fields +#define CONFIG_BOOT_0F_PLL_CONFIG1_N16_PER_MIN_MASK 0x00FF +#define CONFIG_BOOT_0F_PLL_CONFIG1_N16_PER_MIN_SHIFT 0 +#define CONFIG_BOOT_0F_PLL_CONFIG1_N16_PER_MIN_FIELD ((RegisterField16) { CONFIG_BOOT_0F_PLL_CONFIG1_N16_PER_MIN_MASK, CONFIG_BOOT_0F_PLL_CONFIG1_N16_PER_MIN_SHIFT, CONFIG_BOOT_0F_PLL_CONFIG1, false }) +#define CONFIG_BOOT_0F_PLL_CONFIG1_N16_PER_MAX_MASK 0xFF00 +#define CONFIG_BOOT_0F_PLL_CONFIG1_N16_PER_MAX_SHIFT 8 +#define CONFIG_BOOT_0F_PLL_CONFIG1_N16_PER_MAX_FIELD ((RegisterField16) { CONFIG_BOOT_0F_PLL_CONFIG1_N16_PER_MAX_MASK, CONFIG_BOOT_0F_PLL_CONFIG1_N16_PER_MAX_SHIFT, CONFIG_BOOT_0F_PLL_CONFIG1, false }) + +// BOOT_10_APP_CONFIG_0 fields +#define CONFIG_BOOT_10_APP_CONFIG_0_HALL_ENABLE_MASK 0x0001 +#define CONFIG_BOOT_10_APP_CONFIG_0_HALL_ENABLE_SHIFT 0 +#define CONFIG_BOOT_10_APP_CONFIG_0_HALL_ENABLE_FIELD ((RegisterField16) { CONFIG_BOOT_10_APP_CONFIG_0_HALL_ENABLE_MASK, CONFIG_BOOT_10_APP_CONFIG_0_HALL_ENABLE_SHIFT, CONFIG_BOOT_10_APP_CONFIG_0, false }) +#define CONFIG_BOOT_10_APP_CONFIG_0_ABN1_ENABLE_MASK 0x0002 +#define CONFIG_BOOT_10_APP_CONFIG_0_ABN1_ENABLE_SHIFT 1 +#define CONFIG_BOOT_10_APP_CONFIG_0_ABN1_ENABLE_FIELD ((RegisterField16) { CONFIG_BOOT_10_APP_CONFIG_0_ABN1_ENABLE_MASK, CONFIG_BOOT_10_APP_CONFIG_0_ABN1_ENABLE_SHIFT, CONFIG_BOOT_10_APP_CONFIG_0, false }) +#define CONFIG_BOOT_10_APP_CONFIG_0_HALL_UX_MASK 0x0030 +#define CONFIG_BOOT_10_APP_CONFIG_0_HALL_UX_SHIFT 4 +#define CONFIG_BOOT_10_APP_CONFIG_0_HALL_UX_FIELD ((RegisterField16) { CONFIG_BOOT_10_APP_CONFIG_0_HALL_UX_MASK, CONFIG_BOOT_10_APP_CONFIG_0_HALL_UX_SHIFT, CONFIG_BOOT_10_APP_CONFIG_0, false }) +#define CONFIG_BOOT_10_APP_CONFIG_0_HALL_V_MASK 0x00C0 +#define CONFIG_BOOT_10_APP_CONFIG_0_HALL_V_SHIFT 6 +#define CONFIG_BOOT_10_APP_CONFIG_0_HALL_V_FIELD ((RegisterField16) { CONFIG_BOOT_10_APP_CONFIG_0_HALL_V_MASK, CONFIG_BOOT_10_APP_CONFIG_0_HALL_V_SHIFT, CONFIG_BOOT_10_APP_CONFIG_0, false }) +#define CONFIG_BOOT_10_APP_CONFIG_0_HALL_WY_MASK 0x0300 +#define CONFIG_BOOT_10_APP_CONFIG_0_HALL_WY_SHIFT 8 +#define CONFIG_BOOT_10_APP_CONFIG_0_HALL_WY_FIELD ((RegisterField16) { CONFIG_BOOT_10_APP_CONFIG_0_HALL_WY_MASK, CONFIG_BOOT_10_APP_CONFIG_0_HALL_WY_SHIFT, CONFIG_BOOT_10_APP_CONFIG_0, false }) +#define CONFIG_BOOT_10_APP_CONFIG_0_ABN1_A_MASK 0x0C00 +#define CONFIG_BOOT_10_APP_CONFIG_0_ABN1_A_SHIFT 10 +#define CONFIG_BOOT_10_APP_CONFIG_0_ABN1_A_FIELD ((RegisterField16) { CONFIG_BOOT_10_APP_CONFIG_0_ABN1_A_MASK, CONFIG_BOOT_10_APP_CONFIG_0_ABN1_A_SHIFT, CONFIG_BOOT_10_APP_CONFIG_0, false }) +#define CONFIG_BOOT_10_APP_CONFIG_0_ABN1_B_MASK 0x3000 +#define CONFIG_BOOT_10_APP_CONFIG_0_ABN1_B_SHIFT 12 +#define CONFIG_BOOT_10_APP_CONFIG_0_ABN1_B_FIELD ((RegisterField16) { CONFIG_BOOT_10_APP_CONFIG_0_ABN1_B_MASK, CONFIG_BOOT_10_APP_CONFIG_0_ABN1_B_SHIFT, CONFIG_BOOT_10_APP_CONFIG_0, false }) +#define CONFIG_BOOT_10_APP_CONFIG_0_ABN1_N_MASK 0xC000 +#define CONFIG_BOOT_10_APP_CONFIG_0_ABN1_N_SHIFT 14 +#define CONFIG_BOOT_10_APP_CONFIG_0_ABN1_N_FIELD ((RegisterField16) { CONFIG_BOOT_10_APP_CONFIG_0_ABN1_N_MASK, CONFIG_BOOT_10_APP_CONFIG_0_ABN1_N_SHIFT, CONFIG_BOOT_10_APP_CONFIG_0, false }) + +// BOOT_11_APP_CONFIG_1 fields +#define CONFIG_BOOT_11_APP_CONFIG_1_REF_L_PIN_MASK 0x0003 +#define CONFIG_BOOT_11_APP_CONFIG_1_REF_L_PIN_SHIFT 0 +#define CONFIG_BOOT_11_APP_CONFIG_1_REF_L_PIN_FIELD ((RegisterField16) { CONFIG_BOOT_11_APP_CONFIG_1_REF_L_PIN_MASK, CONFIG_BOOT_11_APP_CONFIG_1_REF_L_PIN_SHIFT, CONFIG_BOOT_11_APP_CONFIG_1, false }) +#define CONFIG_BOOT_11_APP_CONFIG_1_REF_R_PIN_MASK 0x000C +#define CONFIG_BOOT_11_APP_CONFIG_1_REF_R_PIN_SHIFT 2 +#define CONFIG_BOOT_11_APP_CONFIG_1_REF_R_PIN_FIELD ((RegisterField16) { CONFIG_BOOT_11_APP_CONFIG_1_REF_R_PIN_MASK, CONFIG_BOOT_11_APP_CONFIG_1_REF_R_PIN_SHIFT, CONFIG_BOOT_11_APP_CONFIG_1, false }) +#define CONFIG_BOOT_11_APP_CONFIG_1_REF_H_PIN_MASK 0x0070 +#define CONFIG_BOOT_11_APP_CONFIG_1_REF_H_PIN_SHIFT 4 +#define CONFIG_BOOT_11_APP_CONFIG_1_REF_H_PIN_FIELD ((RegisterField16) { CONFIG_BOOT_11_APP_CONFIG_1_REF_H_PIN_MASK, CONFIG_BOOT_11_APP_CONFIG_1_REF_H_PIN_SHIFT, CONFIG_BOOT_11_APP_CONFIG_1, false }) +#define CONFIG_BOOT_11_APP_CONFIG_1_STEPDIR_ENABLE_MASK 0x0100 +#define CONFIG_BOOT_11_APP_CONFIG_1_STEPDIR_ENABLE_SHIFT 8 +#define CONFIG_BOOT_11_APP_CONFIG_1_STEPDIR_ENABLE_FIELD ((RegisterField16) { CONFIG_BOOT_11_APP_CONFIG_1_STEPDIR_ENABLE_MASK, CONFIG_BOOT_11_APP_CONFIG_1_STEPDIR_ENABLE_SHIFT, CONFIG_BOOT_11_APP_CONFIG_1, false }) +#define CONFIG_BOOT_11_APP_CONFIG_1_STEP_PIN_MASK 0x0600 +#define CONFIG_BOOT_11_APP_CONFIG_1_STEP_PIN_SHIFT 9 +#define CONFIG_BOOT_11_APP_CONFIG_1_STEP_PIN_FIELD ((RegisterField16) { CONFIG_BOOT_11_APP_CONFIG_1_STEP_PIN_MASK, CONFIG_BOOT_11_APP_CONFIG_1_STEP_PIN_SHIFT, CONFIG_BOOT_11_APP_CONFIG_1, false }) +#define CONFIG_BOOT_11_APP_CONFIG_1_DIR_PIN_MASK 0x0800 +#define CONFIG_BOOT_11_APP_CONFIG_1_DIR_PIN_SHIFT 11 +#define CONFIG_BOOT_11_APP_CONFIG_1_DIR_PIN_FIELD ((RegisterField16) { CONFIG_BOOT_11_APP_CONFIG_1_DIR_PIN_MASK, CONFIG_BOOT_11_APP_CONFIG_1_DIR_PIN_SHIFT, CONFIG_BOOT_11_APP_CONFIG_1, false }) +#define CONFIG_BOOT_11_APP_CONFIG_1_ABN2_ENABLE_MASK 0x1000 +#define CONFIG_BOOT_11_APP_CONFIG_1_ABN2_ENABLE_SHIFT 12 +#define CONFIG_BOOT_11_APP_CONFIG_1_ABN2_ENABLE_FIELD ((RegisterField16) { CONFIG_BOOT_11_APP_CONFIG_1_ABN2_ENABLE_MASK, CONFIG_BOOT_11_APP_CONFIG_1_ABN2_ENABLE_SHIFT, CONFIG_BOOT_11_APP_CONFIG_1, false }) +#define CONFIG_BOOT_11_APP_CONFIG_1_ABN2_A_MASK 0x2000 +#define CONFIG_BOOT_11_APP_CONFIG_1_ABN2_A_SHIFT 13 +#define CONFIG_BOOT_11_APP_CONFIG_1_ABN2_A_FIELD ((RegisterField16) { CONFIG_BOOT_11_APP_CONFIG_1_ABN2_A_MASK, CONFIG_BOOT_11_APP_CONFIG_1_ABN2_A_SHIFT, CONFIG_BOOT_11_APP_CONFIG_1, false }) +#define CONFIG_BOOT_11_APP_CONFIG_1_ABN2_B_MASK 0xC000 +#define CONFIG_BOOT_11_APP_CONFIG_1_ABN2_B_SHIFT 14 +#define CONFIG_BOOT_11_APP_CONFIG_1_ABN2_B_FIELD ((RegisterField16) { CONFIG_BOOT_11_APP_CONFIG_1_ABN2_B_MASK, CONFIG_BOOT_11_APP_CONFIG_1_ABN2_B_SHIFT, CONFIG_BOOT_11_APP_CONFIG_1, false }) + +// BOOT_12_APP_CONFIG_2 fields +#define CONFIG_BOOT_12_APP_CONFIG_2_WDG_DISABLE_MASK 0x0001 +#define CONFIG_BOOT_12_APP_CONFIG_2_WDG_DISABLE_SHIFT 0 +#define CONFIG_BOOT_12_APP_CONFIG_2_WDG_DISABLE_FIELD ((RegisterField16) { CONFIG_BOOT_12_APP_CONFIG_2_WDG_DISABLE_MASK, CONFIG_BOOT_12_APP_CONFIG_2_WDG_DISABLE_SHIFT, CONFIG_BOOT_12_APP_CONFIG_2, false }) +#define CONFIG_BOOT_12_APP_CONFIG_2_WDG_TIMEOUT_MASK 0x000E +#define CONFIG_BOOT_12_APP_CONFIG_2_WDG_TIMEOUT_SHIFT 1 +#define CONFIG_BOOT_12_APP_CONFIG_2_WDG_TIMEOUT_FIELD ((RegisterField16) { CONFIG_BOOT_12_APP_CONFIG_2_WDG_TIMEOUT_MASK, CONFIG_BOOT_12_APP_CONFIG_2_WDG_TIMEOUT_SHIFT, CONFIG_BOOT_12_APP_CONFIG_2, false }) +#define CONFIG_BOOT_12_APP_CONFIG_2_BRAKECHOPPER_ENABLE_MASK 0x0010 +#define CONFIG_BOOT_12_APP_CONFIG_2_BRAKECHOPPER_ENABLE_SHIFT 4 +#define CONFIG_BOOT_12_APP_CONFIG_2_BRAKECHOPPER_ENABLE_FIELD ((RegisterField16) { CONFIG_BOOT_12_APP_CONFIG_2_BRAKECHOPPER_ENABLE_MASK, CONFIG_BOOT_12_APP_CONFIG_2_BRAKECHOPPER_ENABLE_SHIFT, CONFIG_BOOT_12_APP_CONFIG_2, false }) +#define CONFIG_BOOT_12_APP_CONFIG_2_BRAKECHOPPER_OUTPUT_MASK 0x03E0 +#define CONFIG_BOOT_12_APP_CONFIG_2_BRAKECHOPPER_OUTPUT_SHIFT 5 +#define CONFIG_BOOT_12_APP_CONFIG_2_BRAKECHOPPER_OUTPUT_FIELD ((RegisterField16) { CONFIG_BOOT_12_APP_CONFIG_2_BRAKECHOPPER_OUTPUT_MASK, CONFIG_BOOT_12_APP_CONFIG_2_BRAKECHOPPER_OUTPUT_SHIFT, CONFIG_BOOT_12_APP_CONFIG_2, false }) +#define CONFIG_BOOT_12_APP_CONFIG_2_MECH_BRAKE_ENABLE_MASK 0x1000 +#define CONFIG_BOOT_12_APP_CONFIG_2_MECH_BRAKE_ENABLE_SHIFT 12 +#define CONFIG_BOOT_12_APP_CONFIG_2_MECH_BRAKE_ENABLE_FIELD ((RegisterField16) { CONFIG_BOOT_12_APP_CONFIG_2_MECH_BRAKE_ENABLE_MASK, CONFIG_BOOT_12_APP_CONFIG_2_MECH_BRAKE_ENABLE_SHIFT, CONFIG_BOOT_12_APP_CONFIG_2, false }) +#define CONFIG_BOOT_12_APP_CONFIG_2_MECH_BRAKE_OUTPUT_MASK 0x6000 +#define CONFIG_BOOT_12_APP_CONFIG_2_MECH_BRAKE_OUTPUT_SHIFT 13 +#define CONFIG_BOOT_12_APP_CONFIG_2_MECH_BRAKE_OUTPUT_FIELD ((RegisterField16) { CONFIG_BOOT_12_APP_CONFIG_2_MECH_BRAKE_OUTPUT_MASK, CONFIG_BOOT_12_APP_CONFIG_2_MECH_BRAKE_OUTPUT_SHIFT, CONFIG_BOOT_12_APP_CONFIG_2, false }) + +// BOOT_13_APP_CONFIG_3 fields +#define CONFIG_BOOT_13_APP_CONFIG_3_SPI_ENC_ENABLE_MASK 0x0001 +#define CONFIG_BOOT_13_APP_CONFIG_3_SPI_ENC_ENABLE_SHIFT 0 +#define CONFIG_BOOT_13_APP_CONFIG_3_SPI_ENC_ENABLE_FIELD ((RegisterField16) { CONFIG_BOOT_13_APP_CONFIG_3_SPI_ENC_ENABLE_MASK, CONFIG_BOOT_13_APP_CONFIG_3_SPI_ENC_ENABLE_SHIFT, CONFIG_BOOT_13_APP_CONFIG_3, false }) +#define CONFIG_BOOT_13_APP_CONFIG_3_SPI_ENC_BLOCK_MASK 0x0002 +#define CONFIG_BOOT_13_APP_CONFIG_3_SPI_ENC_BLOCK_SHIFT 1 +#define CONFIG_BOOT_13_APP_CONFIG_3_SPI_ENC_BLOCK_FIELD ((RegisterField16) { CONFIG_BOOT_13_APP_CONFIG_3_SPI_ENC_BLOCK_MASK, CONFIG_BOOT_13_APP_CONFIG_3_SPI_ENC_BLOCK_SHIFT, CONFIG_BOOT_13_APP_CONFIG_3, false }) +#define CONFIG_BOOT_13_APP_CONFIG_3_SPI_ENC_MODE_MASK 0x000C +#define CONFIG_BOOT_13_APP_CONFIG_3_SPI_ENC_MODE_SHIFT 2 +#define CONFIG_BOOT_13_APP_CONFIG_3_SPI_ENC_MODE_FIELD ((RegisterField16) { CONFIG_BOOT_13_APP_CONFIG_3_SPI_ENC_MODE_MASK, CONFIG_BOOT_13_APP_CONFIG_3_SPI_ENC_MODE_SHIFT, CONFIG_BOOT_13_APP_CONFIG_3, false }) +#define CONFIG_BOOT_13_APP_CONFIG_3_SPI_ENC_FREQ_MASK 0x00F0 +#define CONFIG_BOOT_13_APP_CONFIG_3_SPI_ENC_FREQ_SHIFT 4 +#define CONFIG_BOOT_13_APP_CONFIG_3_SPI_ENC_FREQ_FIELD ((RegisterField16) { CONFIG_BOOT_13_APP_CONFIG_3_SPI_ENC_FREQ_MASK, CONFIG_BOOT_13_APP_CONFIG_3_SPI_ENC_FREQ_SHIFT, CONFIG_BOOT_13_APP_CONFIG_3, false }) +#define CONFIG_BOOT_13_APP_CONFIG_3_SPI_ENC_CS_PIN_MASK 0x0300 +#define CONFIG_BOOT_13_APP_CONFIG_3_SPI_ENC_CS_PIN_SHIFT 8 +#define CONFIG_BOOT_13_APP_CONFIG_3_SPI_ENC_CS_PIN_FIELD ((RegisterField16) { CONFIG_BOOT_13_APP_CONFIG_3_SPI_ENC_CS_PIN_MASK, CONFIG_BOOT_13_APP_CONFIG_3_SPI_ENC_CS_PIN_SHIFT, CONFIG_BOOT_13_APP_CONFIG_3, false }) +#define CONFIG_BOOT_13_APP_CONFIG_3_SPI_ENC_CS_POL_MASK 0x0400 +#define CONFIG_BOOT_13_APP_CONFIG_3_SPI_ENC_CS_POL_SHIFT 10 +#define CONFIG_BOOT_13_APP_CONFIG_3_SPI_ENC_CS_POL_FIELD ((RegisterField16) { CONFIG_BOOT_13_APP_CONFIG_3_SPI_ENC_CS_POL_MASK, CONFIG_BOOT_13_APP_CONFIG_3_SPI_ENC_CS_POL_SHIFT, CONFIG_BOOT_13_APP_CONFIG_3, false }) + +// BOOT_14_APP_CONFIG_4 fields +#define CONFIG_BOOT_14_APP_CONFIG_4_MEM_TMCL_SCRIPT_MASK 0x0003 +#define CONFIG_BOOT_14_APP_CONFIG_4_MEM_TMCL_SCRIPT_SHIFT 0 +#define CONFIG_BOOT_14_APP_CONFIG_4_MEM_TMCL_SCRIPT_FIELD ((RegisterField16) { CONFIG_BOOT_14_APP_CONFIG_4_MEM_TMCL_SCRIPT_MASK, CONFIG_BOOT_14_APP_CONFIG_4_MEM_TMCL_SCRIPT_SHIFT, CONFIG_BOOT_14_APP_CONFIG_4, false }) +#define CONFIG_BOOT_14_APP_CONFIG_4_MEM_PARAMETERS_MASK 0x000C +#define CONFIG_BOOT_14_APP_CONFIG_4_MEM_PARAMETERS_SHIFT 2 +#define CONFIG_BOOT_14_APP_CONFIG_4_MEM_PARAMETERS_FIELD ((RegisterField16) { CONFIG_BOOT_14_APP_CONFIG_4_MEM_PARAMETERS_MASK, CONFIG_BOOT_14_APP_CONFIG_4_MEM_PARAMETERS_SHIFT, CONFIG_BOOT_14_APP_CONFIG_4, false }) +#define CONFIG_BOOT_14_APP_CONFIG_4_MEM_STIMULUS_MASK 0x0010 +#define CONFIG_BOOT_14_APP_CONFIG_4_MEM_STIMULUS_SHIFT 4 +#define CONFIG_BOOT_14_APP_CONFIG_4_MEM_STIMULUS_FIELD ((RegisterField16) { CONFIG_BOOT_14_APP_CONFIG_4_MEM_STIMULUS_MASK, CONFIG_BOOT_14_APP_CONFIG_4_MEM_STIMULUS_SHIFT, CONFIG_BOOT_14_APP_CONFIG_4, false }) + +// BOOT_15_RESERVED fields +#define CONFIG_BOOT_15_RESERVED_MASK 0xFFFF +#define CONFIG_BOOT_15_RESERVED_SHIFT 0 +#define CONFIG_BOOT_15_RESERVED_FIELD ((RegisterField16) { CONFIG_BOOT_15_RESERVED_MASK, CONFIG_BOOT_15_RESERVED_SHIFT, CONFIG_BOOT_15_RESERVED, false }) + +// BOOT_16_RESERVED fields +#define CONFIG_BOOT_16_RESERVED_MASK 0xFFFF +#define CONFIG_BOOT_16_RESERVED_SHIFT 0 +#define CONFIG_BOOT_16_RESERVED_FIELD ((RegisterField16) { CONFIG_BOOT_16_RESERVED_MASK, CONFIG_BOOT_16_RESERVED_SHIFT, CONFIG_BOOT_16_RESERVED, false }) + +// BOOT_17_RESERVED fields +#define CONFIG_BOOT_17_RESERVED_MASK 0xFFFF +#define CONFIG_BOOT_17_RESERVED_SHIFT 0 +#define CONFIG_BOOT_17_RESERVED_FIELD ((RegisterField16) { CONFIG_BOOT_17_RESERVED_MASK, CONFIG_BOOT_17_RESERVED_SHIFT, CONFIG_BOOT_17_RESERVED, false }) + +// BOOT_18_RESERVED fields +#define CONFIG_BOOT_18_RESERVED_MASK 0xFFFF +#define CONFIG_BOOT_18_RESERVED_SHIFT 0 +#define CONFIG_BOOT_18_RESERVED_FIELD ((RegisterField16) { CONFIG_BOOT_18_RESERVED_MASK, CONFIG_BOOT_18_RESERVED_SHIFT, CONFIG_BOOT_18_RESERVED, false }) + +// BOOT_19_RESERVED fields +#define CONFIG_BOOT_19_RESERVED_MASK 0xFFFF +#define CONFIG_BOOT_19_RESERVED_SHIFT 0 +#define CONFIG_BOOT_19_RESERVED_FIELD ((RegisterField16) { CONFIG_BOOT_19_RESERVED_MASK, CONFIG_BOOT_19_RESERVED_SHIFT, CONFIG_BOOT_19_RESERVED, false }) + +// BOOT_1A_RESERVED fields +#define CONFIG_BOOT_1A_RESERVED_MASK 0xFFFF +#define CONFIG_BOOT_1A_RESERVED_SHIFT 0 +#define CONFIG_BOOT_1A_RESERVED_FIELD ((RegisterField16) { CONFIG_BOOT_1A_RESERVED_MASK, CONFIG_BOOT_1A_RESERVED_SHIFT, CONFIG_BOOT_1A_RESERVED, false }) + +// BOOT_1B_RESERVED fields +#define CONFIG_BOOT_1B_RESERVED_MASK 0xFFFF +#define CONFIG_BOOT_1B_RESERVED_SHIFT 0 +#define CONFIG_BOOT_1B_RESERVED_FIELD ((RegisterField16) { CONFIG_BOOT_1B_RESERVED_MASK, CONFIG_BOOT_1B_RESERVED_SHIFT, CONFIG_BOOT_1B_RESERVED, false }) + +// BOOT_1C_RESERVED fields +#define CONFIG_BOOT_1C_RESERVED_MASK 0xFFFF +#define CONFIG_BOOT_1C_RESERVED_SHIFT 0 +#define CONFIG_BOOT_1C_RESERVED_FIELD ((RegisterField16) { CONFIG_BOOT_1C_RESERVED_MASK, CONFIG_BOOT_1C_RESERVED_SHIFT, CONFIG_BOOT_1C_RESERVED, false }) + +// BOOT_1D_RESERVED fields +#define CONFIG_BOOT_1D_RESERVED_MASK 0xFFFF +#define CONFIG_BOOT_1D_RESERVED_SHIFT 0 +#define CONFIG_BOOT_1D_RESERVED_FIELD ((RegisterField16) { CONFIG_BOOT_1D_RESERVED_MASK, CONFIG_BOOT_1D_RESERVED_SHIFT, CONFIG_BOOT_1D_RESERVED, false }) + +// BOOT_1E_RESERVED fields +#define CONFIG_BOOT_1E_RESERVED_MASK 0xFFFF +#define CONFIG_BOOT_1E_RESERVED_SHIFT 0 +#define CONFIG_BOOT_1E_RESERVED_FIELD ((RegisterField16) { CONFIG_BOOT_1E_RESERVED_MASK, CONFIG_BOOT_1E_RESERVED_SHIFT, CONFIG_BOOT_1E_RESERVED, false }) + +// BOOT_1F_RESERVED fields +#define CONFIG_BOOT_1F_RESERVED_MASK 0xFFFF +#define CONFIG_BOOT_1F_RESERVED_SHIFT 0 +#define CONFIG_BOOT_1F_RESERVED_FIELD ((RegisterField16) { CONFIG_BOOT_1F_RESERVED_MASK, CONFIG_BOOT_1F_RESERVED_SHIFT, CONFIG_BOOT_1F_RESERVED, false }) + +#endif /* TMC9660_BL_HW_ABSTRACTION_H_ */ diff --git a/firmware/lib/tmc/ic/TMC9660/TMC9660_PARAM_HW_Abstraction.h b/firmware/lib/tmc/ic/TMC9660/TMC9660_PARAM_HW_Abstraction.h new file mode 100755 index 0000000..e9998d6 --- /dev/null +++ b/firmware/lib/tmc/ic/TMC9660/TMC9660_PARAM_HW_Abstraction.h @@ -0,0 +1,297 @@ +/******************************************************************************* +* Copyright © 2025 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + +#ifndef TMC9660_PARAM_HW_ABSTRACTION_H_ +#define TMC9660_PARAM_HW_ABSTRACTION_H_ + +#define TMC9660_PARAM_MOTOR_TYPE 0 +#define TMC9660_PARAM_MOTOR_POLE_PAIRS 1 +#define TMC9660_PARAM_MOTOR_DIRECTION 2 +#define TMC9660_PARAM_MOTOR_PWM_FREQUENCY 3 +#define TMC9660_PARAM_COMMUTATION_MODE 4 +#define TMC9660_PARAM_OUTPUT_VOLTAGE_LIMIT 5 +#define TMC9660_PARAM_MAX_TORQUE 6 +#define TMC9660_PARAM_MAX_FLUX 7 +#define TMC9660_PARAM_PWM_SWITCHING_SCHEME 8 +#define TMC9660_PARAM_IDLE_MOTOR_PWM_BEHAVIOR 9 +#define TMC9660_PARAM_ADC_SHUNT_TYPE 12 +#define TMC9660_PARAM_ADC_I0_RAW 13 +#define TMC9660_PARAM_ADC_I1_RAW 14 +#define TMC9660_PARAM_ADC_I2_RAW 15 +#define TMC9660_PARAM_ADC_I3_RAW 16 +#define TMC9660_PARAM_CSA_GAIN_ADC_I0_TO_ADC_I2 17 +#define TMC9660_PARAM_CSA_GAIN_ADC_I3 18 +#define TMC9660_PARAM_CSA_FILTER_ADC_I0_TO_ADC_I2 19 +#define TMC9660_PARAM_CSA_FILTER_ADC_I3 20 +#define TMC9660_PARAM_CURRENT_SCALING_FACTOR 21 +#define TMC9660_PARAM_PHASE_UX1_ADC_MAPPING 22 +#define TMC9660_PARAM_PHASE_VX2_ADC_MAPPING 23 +#define TMC9660_PARAM_PHASE_WY1_ADC_MAPPING 24 +#define TMC9660_PARAM_PHASE_Y2_ADC_MAPPING 25 +#define TMC9660_PARAM_ADC_I0_SCALE 26 +#define TMC9660_PARAM_ADC_I1_SCALE 27 +#define TMC9660_PARAM_ADC_I2_SCALE 28 +#define TMC9660_PARAM_ADC_I3_SCALE 29 +#define TMC9660_PARAM_ADC_I0_INVERTED 30 +#define TMC9660_PARAM_ADC_I1_INVERTED 31 +#define TMC9660_PARAM_ADC_I2_INVERTED 32 +#define TMC9660_PARAM_ADC_I3_INVERTED 33 +#define TMC9660_PARAM_ADC_I0_OFFSET 34 +#define TMC9660_PARAM_ADC_I1_OFFSET 35 +#define TMC9660_PARAM_ADC_I2_OFFSET 36 +#define TMC9660_PARAM_ADC_I3_OFFSET 37 +#define TMC9660_PARAM_ADC_I0 38 +#define TMC9660_PARAM_ADC_I1 39 +#define TMC9660_PARAM_ADC_I2 40 +#define TMC9660_PARAM_ADC_I3 41 +#define TMC9660_PARAM_OPENLOOP_ANGLE 45 +#define TMC9660_PARAM_OPENLOOP_CURRENT 46 +#define TMC9660_PARAM_OPENLOOP_VOLTAGE 47 +#define TMC9660_PARAM_ACCELERATION_FF_GAIN 50 +#define TMC9660_PARAM_ACCELERATION_FF_SHIFT 51 +#define TMC9660_PARAM_RAMP_ENABLE 52 +#define TMC9660_PARAM_DIRECT_VELOCITY_MODE 53 +#define TMC9660_PARAM_RAMP_AMAX 54 +#define TMC9660_PARAM_RAMP_A1 55 +#define TMC9660_PARAM_RAMP_A2 56 +#define TMC9660_PARAM_RAMP_DMAX 57 +#define TMC9660_PARAM_RAMP_D1 58 +#define TMC9660_PARAM_RAMP_D2 59 +#define TMC9660_PARAM_RAMP_VMAX 60 +#define TMC9660_PARAM_RAMP_V1 61 +#define TMC9660_PARAM_RAMP_V2 62 +#define TMC9660_PARAM_RAMP_VSTART 63 +#define TMC9660_PARAM_RAMP_VSTOP 64 +#define TMC9660_PARAM_RAMP_TVMAX 65 +#define TMC9660_PARAM_RAMP_TZEROWAIT 66 +#define TMC9660_PARAM_ACCELERATION_FEEDFORWARD_ENABLE 67 +#define TMC9660_PARAM_VELOCITY_FEEDFORWARD_ENABLE 68 +#define TMC9660_PARAM_RAMP_VELOCITY 69 +#define TMC9660_PARAM_RAMP_POSITION 70 +#define TMC9660_PARAM_HALL_PHI_E 74 +#define TMC9660_PARAM_HALL_SECTOR_OFFSET 75 +#define TMC9660_PARAM_HALL_FILTER_LENGTH 76 +#define TMC9660_PARAM_HALL_POSITION_0_OFFSET 77 +#define TMC9660_PARAM_HALL_POSITION_60_OFFSET 78 +#define TMC9660_PARAM_HALL_POSITION_120_OFFSET 79 +#define TMC9660_PARAM_HALL_POSITION_180_OFFSET 80 +#define TMC9660_PARAM_HALL_POSITION_240_OFFSET 81 +#define TMC9660_PARAM_HALL_POSITION_300_OFFSET 82 +#define TMC9660_PARAM_HALL_INVERT_DIRECTION 83 +#define TMC9660_PARAM_HALL_EXTRAPOLATION_ENABLE 84 +#define TMC9660_PARAM_HALL_PHI_E_OFFSET 85 +#define TMC9660_PARAM_ABN_1_PHI_E 89 +#define TMC9660_PARAM_ABN_1_STEPS 90 +#define TMC9660_PARAM_ABN_1_DIRECTION 91 +#define TMC9660_PARAM_ABN_1_INIT_METHOD 92 +#define TMC9660_PARAM_ABN_1_INIT_STATE 93 +#define TMC9660_PARAM_ABN_1_INIT_DELAY 94 +#define TMC9660_PARAM_ABN_1_INIT_VELOCITY 95 +#define TMC9660_PARAM_ABN_1_N_CHANNEL_PHI_E_OFFSET 96 +#define TMC9660_PARAM_ABN_1_N_CHANNEL_INVERTED 97 +#define TMC9660_PARAM_ABN_1_N_CHANNEL_FILTERING 98 +#define TMC9660_PARAM_ABN_1_CLEAR_ON_NEXT_NULL 99 +#define TMC9660_PARAM_ABN_1_VALUE 100 +#define TMC9660_PARAM_TARGET_TORQUE 104 +#define TMC9660_PARAM_ACTUAL_TORQUE 105 +#define TMC9660_PARAM_TARGET_FLUX 106 +#define TMC9660_PARAM_ACTUAL_FLUX 107 +#define TMC9660_PARAM_TORQUE_OFFSET 108 +#define TMC9660_PARAM_TORQUE_P 109 +#define TMC9660_PARAM_TORQUE_I 110 +#define TMC9660_PARAM_FLUX_P 111 +#define TMC9660_PARAM_FLUX_I 112 +#define TMC9660_PARAM_SEPARATE_TORQUE_FLUX_PI_PARAMTERS 113 +#define TMC9660_PARAM_CURRENT_NORM_P 114 +#define TMC9660_PARAM_CURRENT_NORM_I 115 +#define TMC9660_PARAM_TORQUE_PI_ERROR 116 +#define TMC9660_PARAM_FLUX_PI_ERROR 117 +#define TMC9660_PARAM_TORQUE_PI_INTEGRATOR 118 +#define TMC9660_PARAM_FLUX_PI_INTEGRATOR 119 +#define TMC9660_PARAM_FLUX_OFFSET 120 +#define TMC9660_PARAM_VELOCITY_SENSOR_SELECTION 123 +#define TMC9660_PARAM_TARGET_VELOCITY 124 +#define TMC9660_PARAM_ACTUAL_VELOCITY 125 +#define TMC9660_PARAM_VELOCITY_OFFSET 126 +#define TMC9660_PARAM_VELOCITY_P 127 +#define TMC9660_PARAM_VELOCITY_I 128 +#define TMC9660_PARAM_VELOCITY_NORM_P 129 +#define TMC9660_PARAM_VELOCITY_NORM_I 130 +#define TMC9660_PARAM_VELOCITY_PI_INTEGRATOR 131 +#define TMC9660_PARAM_VELOCITY_PI_ERROR 132 +#define TMC9660_PARAM_VELOCITY_SCALING_FACTOR 133 +#define TMC9660_PARAM_STOP_ON_VELOCITY_DEVIATION 134 +#define TMC9660_PARAM_VELOCITY_LOOP_DOWNSAMPLING 135 +#define TMC9660_PARAM_VELOCITY_REACHED_THRESHOLD 136 +#define TMC9660_PARAM_VELOCITY_METER_SWITCH_THRESHOLD 137 +#define TMC9660_PARAM_VELOCITY_METER_SWITCH_HYSTERESIS 138 +#define TMC9660_PARAM_VELOCITY_METER_MODE 139 +#define TMC9660_PARAM_POSITION_SENSOR_SELECTION 142 +#define TMC9660_PARAM_TARGET_POSITION 143 +#define TMC9660_PARAM_ACTUAL_POSITION 144 +#define TMC9660_PARAM_POSITION_SCALING_FACTOR 145 +#define TMC9660_PARAM_POSITION_P 146 +#define TMC9660_PARAM_POSITION_I 147 +#define TMC9660_PARAM_POSITION_NORM_P 148 +#define TMC9660_PARAM_POSITION_NORM_I 149 +#define TMC9660_PARAM_POSITION_PI_INTEGRATOR 150 +#define TMC9660_PARAM_POSITION_PI_ERROR 151 +#define TMC9660_PARAM_STOP_ON_POSITION_DEVIATION 152 +#define TMC9660_PARAM_POSITION_LOOP_DOWNSAMPLING 153 +#define TMC9660_PARAM_LATCH_POSITION 154 +#define TMC9660_PARAM_POSITION_LIMIT_LOW 155 +#define TMC9660_PARAM_POSITION_LIMIT_HIGH 156 +#define TMC9660_PARAM_POSITION_REACHED_THRESHOLD 157 +#define TMC9660_PARAM_REFERENCE_SWITCH_ENABLE 161 +#define TMC9660_PARAM_REFERENCE_SWITCH_POLARITY_AND_SWAP 162 +#define TMC9660_PARAM_REFERENCE_SWITCH_LATCH_SETTINGS 163 +#define TMC9660_PARAM_EVENT_STOP_SETTINGS 164 +#define TMC9660_PARAM_REFERENCE_SWITCH_SEARCH_MODE 165 +#define TMC9660_PARAM_REFERENCE_SWITCH_SEARCH_SPEED 166 +#define TMC9660_PARAM_REFERENCE_SWITCH_SPEED 167 +#define TMC9660_PARAM_RIGHT_LIMIT_SWITCH_POSITION 168 +#define TMC9660_PARAM_HOME_SWITCH_POSITION 169 +#define TMC9660_PARAM_LAST_REFERENCE_POSITION 170 +#define TMC9660_PARAM_ABN_2_STEPS 174 +#define TMC9660_PARAM_ABN_2_DIRECTION 175 +#define TMC9660_PARAM_ABN_2_GEAR_RATIO 176 +#define TMC9660_PARAM_ABN_2_ENABLE 177 +#define TMC9660_PARAM_ABN_2_VALUE 178 +#define TMC9660_PARAM_SPI_ENCODE_CS_SETTLE_DELAY_TIME 181 +#define TMC9660_PARAM_SPI_ENCODER_CS_IDLE_DELAY_TIME 182 +#define TMC9660_PARAM_SPI_ENCODER_MAIN_TRANSFER_CMD_SIZE 183 +#define TMC9660_PARAM_SPI_ENCODER_SECONDARY_TRANSFER_CMD_SIZE 184 +#define TMC9660_PARAM_SPI_ENCODER_TRANSFER_DATA_3_0 185 +#define TMC9660_PARAM_SPI_ENCODER_TRANSFER_DATA_7_4 186 +#define TMC9660_PARAM_SPI_ENCODER_TRANSFER_DATA_11_8 187 +#define TMC9660_PARAM_SPI_ENCODER_TRANSFER_DATA_15_12 188 +#define TMC9660_PARAM_SPI_ENCODER_TRANSFER 189 +#define TMC9660_PARAM_SPI_ENCODER_POSITION_COUNTER_MASK 190 +#define TMC9660_PARAM_SPI_ENCODER_POSITION_COUNTER_SHIFT 191 +#define TMC9660_PARAM_SPI_ENCODER_POSITION_COUNTER_VALUE 192 +#define TMC9660_PARAM_SPI_ENCODER_COMMUTATION_ANGLE 193 +#define TMC9660_PARAM_SPI_ENCODER_INITIALIZATION_METHOD 194 +#define TMC9660_PARAM_SPI_ENCODER_DIRECTION 195 +#define TMC9660_PARAM_SPI_ENCODER_OFFSET 196 +#define TMC9660_PARAM_SPI_LUT_CORRECTION_ENABLE 197 +#define TMC9660_PARAM_SPI_LUT_ADDRESS_SELECT 198 +#define TMC9660_PARAM_SPI_LUT_DATA 199 +#define TMC9660_PARAM_SPI_LUT_COMMON_SHIFT_FACTOR 201 +#define TMC9660_PARAM_STEP_DIR_STEP_DIVIDER_SHIFT 205 +#define TMC9660_PARAM_STEP_DIR_ENABLE 206 +#define TMC9660_PARAM_STEP_DIR_EXTRAPOLATION_ENABLE 207 +#define TMC9660_PARAM_STEP_DIR_STEP_SIGNAL_TIMEOUT_LIMIT 208 +#define TMC9660_PARAM_STEP_DIR_MAXIMUM_EXTRAPOLATION_VELOCITY 209 +#define TMC9660_PARAM_BRAKE_CHOPPER_ENABLE 212 +#define TMC9660_PARAM_BRAKE_CHOPPER_VOLTAGE_LIMIT 213 +#define TMC9660_PARAM_BRAKE_CHOPPER_HYSTERESIS 214 +#define TMC9660_PARAM_RELEASE_BRAKE 216 +#define TMC9660_PARAM_BRAKE_RELEASING_DUTY_CYCLE 217 +#define TMC9660_PARAM_BRAKE_HOLDING_DUTY_CYCLE 218 +#define TMC9660_PARAM_BRAKE_RELEASING_DURATION 219 +#define TMC9660_PARAM_INVERT_BRAKE_OUTPUT 221 +#define TMC9660_PARAM_THERMAL_WINDING_TIME_CONSTANT_1 224 +#define TMC9660_PARAM_IIT_LIMIT_1 225 +#define TMC9660_PARAM_IIT_SUM_1 226 +#define TMC9660_PARAM_THERMAL_WINDING_TIME_CONSTANT_2 227 +#define TMC9660_PARAM_IIT_LIMIT_2 228 +#define TMC9660_PARAM_IIT_SUM_2 229 +#define TMC9660_PARAM_RESET_IIT_SUMS 230 +#define TMC9660_PARAM_ACTUAL_TOTAL_MOTOR_CURRENT 231 +#define TMC9660_PARAM_BREAK_BEFORE_MAKE_TIME_LOW_UVW 235 +#define TMC9660_PARAM_BREAK_BEFORE_MAKE_TIME_HIGH_UVW 236 +#define TMC9660_PARAM_BREAK_BEFORE_MAKE_TIME_LOW_Y2 237 +#define TMC9660_PARAM_BREAK_BEFORE_MAKE_TIME_HIGH_Y2 238 +#define TMC9660_PARAM_USE_ADAPTIVE_DRIVE_TIME_UVW 239 +#define TMC9660_PARAM_USE_ADAPTIVE_DRIVE_TIME_Y2 240 +#define TMC9660_PARAM_DRIVE_TIME_SINK_UVW 241 +#define TMC9660_PARAM_DRIVE_TIME_SOURCE_UVW 242 +#define TMC9660_PARAM_DRIVE_TIME_SINK_Y2 243 +#define TMC9660_PARAM_DRIVE_TIME_SOURCE_Y2 244 +#define TMC9660_PARAM_UVW_SINK_CURRENT 245 +#define TMC9660_PARAM_UVW_SOURCE_CURRENT 246 +#define TMC9660_PARAM_Y2_SINK_CURRENT 247 +#define TMC9660_PARAM_Y2_SOURCE_CURRENT 248 +#define TMC9660_PARAM_BOOTSTRAP_CURRENT_LIMIT 249 +#define TMC9660_PARAM_UNDERVOLTAGE_PROTECTION_SUPPLY_LEVEL 250 +#define TMC9660_PARAM_UNDERVOLTAGE_PROTECTION_VDRV_ENABLE 251 +#define TMC9660_PARAM_UNDERVOLTAGE_PROTECTION_BST_UVW_ENABLE 252 +#define TMC9660_PARAM_UNDERVOLTAGE_PROTECTION_BST_Y2_ENABLE 253 +#define TMC9660_PARAM_OVERCURRENT_PROTECTION_UVW_LOW_SIDE_ENABLE 254 +#define TMC9660_PARAM_OVERCURRENT_PROTECTION_UVW_HIGH_SIDE_ENABLE 255 +#define TMC9660_PARAM_OVERCURRENT_PROTECTION_Y2_LOW_SIDE_ENABLE 256 +#define TMC9660_PARAM_OVERCURRENT_PROTECTION_Y2_HIGH_SIDE_ENABLE 257 +#define TMC9660_PARAM_OVERCURRENT_PROTECTION_UVW_LOW_SIDE_THRESHOLD 258 +#define TMC9660_PARAM_OVERCURRENT_PROTECTION_UVW_HIGH_SIDE_THRESHOLD 259 +#define TMC9660_PARAM_OVERCURRENT_PROTECTION_Y2_LOW_SIDE_THRESHOLD 260 +#define TMC9660_PARAM_OVERCURRENT_PROTECTION_Y2_HIGH_SIDE_THRESHOLD 261 +#define TMC9660_PARAM_OVERCURRENT_PROTECTION_UVW_LOW_SIDE_BLANKING 262 +#define TMC9660_PARAM_OVERCURRENT_PROTECTION_UVW_HIGH_SIDE_BLANKING 263 +#define TMC9660_PARAM_OVERCURRENT_PROTECTION_Y2_LOW_SIDE_BLANKING 264 +#define TMC9660_PARAM_OVERCURRENT_PROTECTION_Y2_HIGH_SIDE_BLANKING 265 +#define TMC9660_PARAM_OVERCURRENT_PROTECTION_UVW_LOW_SIDE_DEGLITCH 266 +#define TMC9660_PARAM_OVERCURRENT_PROTECTION_UVW_HIGH_SIDE_DEGLITCH 267 +#define TMC9660_PARAM_OVERCURRENT_PROTECTION_Y2_LOW_SIDE_DEGLITCH 268 +#define TMC9660_PARAM_OVERCURRENT_PROTECTION_Y2_HIGH_SIDE_DEGLITCH 269 +#define TMC9660_PARAM_OVERCURRENT_PROTECTION_UVW_LOW_SIDE_USE_VDS 270 +#define TMC9660_PARAM_OVERCURRENT_PROTECTION_Y2_LOW_SIDE_USE_VDS 271 +#define TMC9660_PARAM_VGS_SHORT_ON_PROTECTION_UVW_LOW_SIDE_ENABLE 272 +#define TMC9660_PARAM_VGS_SHORT_OFF_PROTECTION_UVW_LOW_SIDE_ENABLE 273 +#define TMC9660_PARAM_VGS_SHORT_ON_PROTECTION_UVW_HIGH_SIDE_ENABLE 274 +#define TMC9660_PARAM_VGS_SHORT_OFF_PROTECTION_UVW_HIGH_SIDE_ENABLE 275 +#define TMC9660_PARAM_VGS_SHORT_ON_PROTECTION_Y2_LOW_SIDE_ENABLE 276 +#define TMC9660_PARAM_VGS_SHORT_OFF_PROTECTION_Y2_LOW_SIDE_ENABLE 277 +#define TMC9660_PARAM_VGS_SHORT_ON_PROTECTION_Y2_HIGH_SIDE_ENABLE 278 +#define TMC9660_PARAM_VGS_SHORT_OFF_PROTECTION_Y2_HIGH_SIDE_ENABLE 279 +#define TMC9660_PARAM_VGS_SHORT_PROTECTION_UVW_BLANKING 280 +#define TMC9660_PARAM_VGS_SHORT_PROTECTION_Y2_BLANKING 281 +#define TMC9660_PARAM_VGS_SHORT_PROTECTION_UVW_DEGLITCH 282 +#define TMC9660_PARAM_VGS_SHORT_PROTECTION_Y2_DEGLITCH 283 +#define TMC9660_PARAM_GDRV_RETRY_BEHAVIOUR 286 +#define TMC9660_PARAM_DRIVE_FAULT_BEHAVIOUR 287 +#define TMC9660_PARAM_FAULT_HANDLER_NUMBER_OF_RETRIES 288 +#define TMC9660_PARAM_GENERAL_STATUS_FLAGS 289 +#define TMC9660_PARAM_SUPPLY_VOLTAGE 290 +#define TMC9660_PARAM_SUPPLY_OVERVOLTAGE_WARNING_THRESHOLD 291 +#define TMC9660_PARAM_SUPPLY_UNDERVOLTAGE_WARNING_THRESHOLD 292 +#define TMC9660_PARAM_EXTERNAL_TEMPERATURE 293 +#define TMC9660_PARAM_EXTERNAL_TEMPERATURE_SHUTDOWN_THRESHOLD 294 +#define TMC9660_PARAM_EXTERNAL_TEMPERATURE_WARNING_THRESHOLD 295 +#define TMC9660_PARAM_CHIP_TEMPERATURE 296 +#define TMC9660_PARAM_CHIP_TEMPERATURE_SHUTDOWN_THRESHOLD 297 +#define TMC9660_PARAM_CHIP_TEMPERATURE_WARNING_THRESHOLD 298 +#define TMC9660_PARAM_GENERAL_ERROR_FLAGS 299 +#define TMC9660_PARAM_GDRV_ERROR_FLAGS 300 +#define TMC9660_PARAM_ADC_STATUS_FLAGS 301 +#define TMC9660_PARAM_MCC_INPUTS_RAW 304 +#define TMC9660_PARAM_FOC_VOLTAGE_UX 305 +#define TMC9660_PARAM_FOC_VOLTAGE_WY 306 +#define TMC9660_PARAM_FOC_VOLTAGE_V 307 +#define TMC9660_PARAM_FIELDWEAKENING_I 308 +#define TMC9660_PARAM_FIELDWEAKENING_VOLTAGE_THRESHOLD 310 +#define TMC9660_PARAM_FOC_CURRENT_UX 311 +#define TMC9660_PARAM_FOC_CURRENT_V 312 +#define TMC9660_PARAM_FOC_CURRENT_WY 313 +#define TMC9660_PARAM_FOC_VOLTAGE_UQ 314 +#define TMC9660_PARAM_FOC_CURRENT_IQ 315 +#define TMC9660_PARAM_TARGET_TORQUE_BIQUAD_FILTER_ENABLE 318 +#define TMC9660_PARAM_TARGET_TORQUE_BIQUAD_FILTER_ACOEFF_1 319 +#define TMC9660_PARAM_TARGET_TORQUE_BIQUAD_FILTER_ACOEFF_2 320 +#define TMC9660_PARAM_TARGET_TORQUE_BIQUAD_FILTER_BCOEFF_0 321 +#define TMC9660_PARAM_TARGET_TORQUE_BIQUAD_FILTER_BCOEFF_1 322 +#define TMC9660_PARAM_TARGET_TORQUE_BIQUAD_FILTER_BCOEFF_2 323 +#define TMC9660_PARAM_ACTUAL_VELOCITY_BIQUAD_FILTER_ENABLE 324 +#define TMC9660_PARAM_ACTUAL_VELOCITY_BIQUAD_FILTER_ACOEFF_1 325 +#define TMC9660_PARAM_ACTUAL_VELOCITY_BIQUAD_FILTER_ACOEFF_2 326 +#define TMC9660_PARAM_ACTUAL_VELOCITY_BIQUAD_FILTER_BCOEFF_0 327 +#define TMC9660_PARAM_ACTUAL_VELOCITY_BIQUAD_FILTER_BCOEFF_1 328 +#define TMC9660_PARAM_ACTUAL_VELOCITY_BIQUAD_FILTER_BCOEFF_2 329 +#define TMC9660_PARAM_TORQUE_FLUX_COMBINED_TARGET_VALUES 330 +#define TMC9660_PARAM_TORQUE_FLUX_COMBINED_ACTUAL_VALUES 331 +#define TMC9660_PARAM_VOLTAGE_D_Q_COMBINED_ACTUAL_VALUES 332 +#define TMC9660_PARAM_INTEGRATED_ACTUAL_TORQUE_VALUE 333 +#define TMC9660_PARAM_INTEGRATED_ACTUAL_VELOCITY_VALUE 334 + +#endif /* TMC9660_PARAM_HW_ABSTRACTION_H_ */ diff --git a/firmware/lib/tmc/ramp/LinearRamp.c b/firmware/lib/tmc/ramp/LinearRamp.c new file mode 100755 index 0000000..5c128b1 --- /dev/null +++ b/firmware/lib/tmc/ramp/LinearRamp.c @@ -0,0 +1,163 @@ +/******************************************************************************* +* Copyright © 2018 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +/* + * This is a basic proof-of-concept implementation of a linear motion ramp + * generator. It is designed to run with 1 calculation / ms. + * + * + */ +#include "LinearRamp.h" + +void tmc_linearRamp_init(TMC_LinearRamp *linearRamp) +{ + linearRamp->maxVelocity = 0; + linearRamp->targetPosition = 0; + linearRamp->targetVelocity = 0; + linearRamp->rampVelocity = 0; + linearRamp->acceleration = 0; + linearRamp->encoderSteps = u16_MAX; + linearRamp->lastdVRest = 0; + linearRamp->lastdXRest = 0; + linearRamp->rampEnabled = false; +} + +void tmc_linearRamp_computeRampVelocity(TMC_LinearRamp *linearRamp) +{ + if (linearRamp->rampEnabled) + { + // update target velocity according actual set acceleration + // (scaling pre-factor of 1000 used for 1ms velocity ramp handling) + + int32_t dV = linearRamp->acceleration; + + // to ensure that small velocity changes at high set acceleration are also possible + int32_t maxDTV = abs(linearRamp->targetVelocity - linearRamp->rampVelocity); + if (maxDTV < (dV/1000)) + dV = maxDTV*1000; + + dV += linearRamp->lastdVRest; + linearRamp->lastdVRest = dV % 1000; + + if (linearRamp->rampVelocity < linearRamp->targetVelocity) + { + // accelerate motor + linearRamp->rampVelocity += dV/1000; // divide with pre-factor + } + else if (linearRamp->rampVelocity > linearRamp->targetVelocity) + { + // decelerate motor + linearRamp->rampVelocity -= dV/1000; // divide with pre-factor + } + } + else + { + // use target velocity directly + linearRamp->rampVelocity = linearRamp->targetVelocity; + } + + // limit ramp velocity + linearRamp->rampVelocity = tmc_limitInt(linearRamp->rampVelocity, -linearRamp->maxVelocity, linearRamp->maxVelocity); +} + +void tmc_linearRamp_computeRampPosition(TMC_LinearRamp *linearRamp) +{ + if (linearRamp->rampEnabled) + { + // update target position according actual set acceleration and max velocity + // (scaling pre-factor of 1000 used for 1ms position ramp handling) + + // limit position difference for further computations + int32_t targetPositionsDifference = linearRamp->targetPosition-linearRamp->rampPosition; + + // limit the sqrti value in case of high position differences + int64_t sqrtiValue = tmc_limitS64(((int64_t)120 * (int64_t)linearRamp->acceleration * (int64_t)(abs(targetPositionsDifference))) / (int64_t)linearRamp->encoderSteps, 0, (int64_t)linearRamp->maxVelocity*(int64_t)linearRamp->maxVelocity); + + // compute max allowed ramp velocity to ramp down to target + int32_t maxRampStop = tmc_sqrti(sqrtiValue); + + // compute max allowed ramp velocity + int32_t maxRampTargetVelocity = 0; + if (targetPositionsDifference > 0) + { + maxRampTargetVelocity = tmc_limitInt(maxRampStop, 0, (int32_t)linearRamp->maxVelocity); + } + else if (targetPositionsDifference < 0) + { + maxRampTargetVelocity = tmc_limitInt(-maxRampStop, -(int32_t)linearRamp->maxVelocity, 0); + } + else + { + //maxRampTargetVelocity = 0; + } + + int32_t dV = linearRamp->acceleration; // pre-factor ~ 1/1000 + + // to ensure that small velocity changes at high set acceleration are also possible + int32_t maxDTV = abs(maxRampTargetVelocity - linearRamp->rampVelocity); + if (maxDTV < (dV / 1000)) + dV = maxDTV * 1000; + + dV += linearRamp->lastdVRest; + linearRamp->lastdVRest = dV % 1000; + + // do velocity ramping + if (maxRampTargetVelocity > linearRamp->rampVelocity) + { + linearRamp->rampVelocity += dV / 1000; + } + else if (maxRampTargetVelocity < linearRamp->rampVelocity) + { + linearRamp->rampVelocity -= dV / 1000; + } + + // do position ramping using actual ramp velocity to update dX + int64_t dX = ((int64_t)linearRamp->rampVelocity * (int64_t)linearRamp->encoderSteps) / ((int64_t)60) + linearRamp->lastdXRest; + + // scale actual target position + int64_t tempActualTargetPosition = (int64_t)linearRamp->rampPosition * 1000; + + // reset helper variables if ramp position reached target position + if (abs(linearRamp->targetPosition - linearRamp->rampPosition) < abs((int32_t)dX/1000)) + { + // sync ramp position with target position on small deviations + linearRamp->rampPosition = linearRamp->targetPosition; + + // update actual target position + tempActualTargetPosition = (int64_t)linearRamp->rampPosition * 1000; + + dX = 0; + linearRamp->lastdXRest = 0; + linearRamp->rampVelocity = 0; + } + else + { + // update actual target position + tempActualTargetPosition += dX; + } + + int64_t absTempActualTargetPosition = (tempActualTargetPosition >= 0) ? tempActualTargetPosition : -tempActualTargetPosition; + + if (tempActualTargetPosition >= 0) + linearRamp->lastdXRest = (absTempActualTargetPosition % 1000); + else if (tempActualTargetPosition < 0) + linearRamp->lastdXRest = -(absTempActualTargetPosition % 1000); + + // scale actual target position back + linearRamp->rampPosition = tempActualTargetPosition / 1000; + } + else + { + // use target position directly + linearRamp->rampPosition = linearRamp->targetPosition; + + // hold ramp velocity in reset + linearRamp->rampVelocity = 0; + } +} diff --git a/firmware/lib/tmc/ramp/LinearRamp.h b/firmware/lib/tmc/ramp/LinearRamp.h new file mode 100755 index 0000000..ad15a17 --- /dev/null +++ b/firmware/lib/tmc/ramp/LinearRamp.h @@ -0,0 +1,34 @@ +/******************************************************************************* +* Copyright © 2018 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#ifndef TMC_LINEAR_RAMP_H_ +#define TMC_LINEAR_RAMP_H_ + + #include "tmc/helpers/API_Header.h" + #include "tmc/helpers/Functions.h" + + typedef struct + { + uint32_t maxVelocity; + int32_t targetPosition; + int32_t rampPosition; + int32_t targetVelocity; + int32_t rampVelocity; + int32_t acceleration; + uint16_t encoderSteps; + int32_t lastdVRest; + int32_t lastdXRest; + uint8_t rampEnabled; + } TMC_LinearRamp; + + void tmc_linearRamp_init(TMC_LinearRamp *linearRamp); + void tmc_linearRamp_computeRampVelocity(TMC_LinearRamp *linearRamp); + void tmc_linearRamp_computeRampPosition(TMC_LinearRamp *linearRamp); + +#endif /* TMC_LINEAR_RAMP_H_ */ diff --git a/firmware/lib/tmc/ramp/LinearRamp1.c b/firmware/lib/tmc/ramp/LinearRamp1.c new file mode 100755 index 0000000..b9f4bc6 --- /dev/null +++ b/firmware/lib/tmc/ramp/LinearRamp1.c @@ -0,0 +1,303 @@ +/******************************************************************************* +* Copyright © 2018 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2023 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#include "LinearRamp1.h" +#include "tmc/helpers/Functions.h" + +void tmc_ramp_linear_init(TMC_LinearRamp *linearRamp) +{ + linearRamp->maxVelocity = 0; + linearRamp->targetPosition = 0; + linearRamp->targetVelocity = 0; + linearRamp->rampVelocity = 0; + linearRamp->rampPosition = 0; + linearRamp->acceleration = 0; + linearRamp->rampEnabled = true; + linearRamp->accumulatorVelocity = 0; + linearRamp->accumulatorPosition = 0; + linearRamp->rampMode = TMC_RAMP_LINEAR_MODE_VELOCITY; + linearRamp->state = TMC_RAMP_LINEAR_STATE_IDLE; + linearRamp->precision = TMC_RAMP_LINEAR_DEFAULT_PRECISION; + linearRamp->homingDistance = TMC_RAMP_LINEAR_DEFAULT_HOMING_DISTANCE; + linearRamp->stopVelocity = TMC_RAMP_LINEAR_DEFAULT_STOP_VELOCITY; +} + +void tmc_ramp_linear_set_enabled(TMC_LinearRamp *linearRamp, bool enabled) +{ + linearRamp->rampEnabled = enabled; +} + +void tmc_ramp_linear_set_maxVelocity(TMC_LinearRamp *linearRamp, uint32_t maxVelocity) +{ + linearRamp->maxVelocity = maxVelocity; +} + +void tmc_ramp_linear_set_targetPosition(TMC_LinearRamp *linearRamp, int32_t targetPosition) +{ + linearRamp->targetPosition = targetPosition; +} + +void tmc_ramp_linear_set_rampPosition(TMC_LinearRamp *linearRamp, int32_t rampPosition) +{ + linearRamp->rampPosition = rampPosition; +} + +void tmc_ramp_linear_set_targetVelocity(TMC_LinearRamp *linearRamp, int32_t targetVelocity) +{ + linearRamp->targetVelocity = targetVelocity; +} + +void tmc_ramp_linear_set_rampVelocity(TMC_LinearRamp *linearRamp, int32_t rampVelocity) +{ + linearRamp->rampVelocity = rampVelocity; +} + +void tmc_ramp_linear_set_acceleration(TMC_LinearRamp *linearRamp, int32_t acceleration) +{ + linearRamp->acceleration = acceleration; +} + +void tmc_ramp_linear_set_mode(TMC_LinearRamp *linearRamp, TMC_LinearRamp_Mode mode) +{ + linearRamp->rampMode = mode; +} + +void tmc_ramp_linear_set_precision(TMC_LinearRamp * linearRamp, uint32_t precision) +{ + linearRamp->precision = precision; +} + +void tmc_ramp_linear_set_homingDistance(TMC_LinearRamp *linearRamp, uint32_t homingDistance) +{ + linearRamp->homingDistance = homingDistance; +} + +void tmc_ramp_linear_set_stopVelocity(TMC_LinearRamp *linearRamp, uint32_t stopVelocity) +{ + linearRamp->stopVelocity = stopVelocity; +} + +bool tmc_ramp_linear_get_enabled(TMC_LinearRamp *linearRamp) +{ + return linearRamp->rampEnabled; +} + +uint32_t tmc_ramp_linear_get_maxVelocity(TMC_LinearRamp *linearRamp) +{ + return linearRamp->maxVelocity; +} + +int32_t tmc_ramp_linear_get_targetPosition(TMC_LinearRamp *linearRamp) +{ + return linearRamp->targetPosition; +} + +int32_t tmc_ramp_linear_get_rampPosition(TMC_LinearRamp *linearRamp) +{ + return linearRamp->rampPosition; +} + +int32_t tmc_ramp_linear_get_targetVelocity(TMC_LinearRamp *linearRamp) +{ + return linearRamp->targetVelocity; +} + +int32_t tmc_ramp_linear_get_rampVelocity(TMC_LinearRamp *linearRamp) +{ + return linearRamp->rampVelocity; +} + +int32_t tmc_ramp_linear_get_acceleration(TMC_LinearRamp *linearRamp) +{ + return linearRamp->acceleration; +} + +TMC_LinearRamp_State tmc_ramp_linear_get_state(TMC_LinearRamp *linearRamp) +{ + return linearRamp->state; +} + +TMC_LinearRamp_Mode tmc_ramp_linear_get_mode(TMC_LinearRamp *linearRamp) +{ + return linearRamp->rampMode; +} + +uint32_t tmc_ramp_linear_get_precision(TMC_LinearRamp *linearRamp) +{ + return linearRamp->precision; +} + +// The maximum acceleration depends on the precision value +uint32_t tmc_ramp_linear_get_acceleration_limit(TMC_LinearRamp *linearRamp) +{ + return (0xFFFFFFFFu / linearRamp->precision) * linearRamp->precision; +} + +uint32_t tmc_ramp_linear_get_velocity_limit(TMC_LinearRamp *linearRamp) +{ + return linearRamp->precision; +} + +uint32_t tmc_ramp_linear_get_homingDistance(TMC_LinearRamp *linearRamp) +{ + return linearRamp->homingDistance; +} + +uint32_t tmc_ramp_linear_get_stopVelocity(TMC_LinearRamp *linearRamp) +{ + return linearRamp->stopVelocity; +} + +int32_t tmc_ramp_linear_compute(TMC_LinearRamp *linearRamp) +{ + tmc_ramp_linear_compute_position(linearRamp); + return tmc_ramp_linear_compute_velocity(linearRamp); +} + +int32_t tmc_ramp_linear_compute_velocity(TMC_LinearRamp *linearRamp) +{ + bool accelerating = linearRamp->rampVelocity != linearRamp->targetVelocity; + + if (linearRamp->rampEnabled) + { + // Add current acceleration to accumulator + linearRamp->accumulatorVelocity += linearRamp->acceleration; + + // Calculate the velocity delta value and keep the remainder of the velocity accumulator + int32_t dv = linearRamp->accumulatorVelocity / linearRamp->precision; + linearRamp->accumulatorVelocity = linearRamp->accumulatorVelocity % linearRamp->precision; + + // Add dv to rampVelocity, and regulate to target velocity + if(linearRamp->rampVelocity < linearRamp->targetVelocity) + linearRamp->rampVelocity = MIN(linearRamp->rampVelocity + dv, linearRamp->targetVelocity); + else if(linearRamp->rampVelocity > linearRamp->targetVelocity) + linearRamp->rampVelocity = MAX(linearRamp->rampVelocity - dv, linearRamp->targetVelocity); + } + else + { + // use target velocity directly + linearRamp->rampVelocity = linearRamp->targetVelocity; + // Reset accumulator + linearRamp->accumulatorVelocity = 0; + } + + // Calculate the velocity delta value and keep the remainder of the position accumulator + linearRamp->accumulatorPosition += linearRamp->rampVelocity; + int32_t dx = linearRamp->accumulatorPosition / (int32_t) linearRamp->precision; + linearRamp->accumulatorPosition = linearRamp->accumulatorPosition % (int32_t) linearRamp->precision; + + if(dx == 0) + return dx; + + // Change actual position determined by position change + linearRamp->rampPosition += (dx < 0) ? (-1) : (1); + + // Count acceleration steps needed for decelerating later + linearRamp->accelerationSteps += (abs(linearRamp->rampVelocity) < abs(linearRamp->targetVelocity)) ? accelerating : -accelerating; + if (linearRamp->accelerationSteps < 0) + linearRamp->accelerationSteps = 0; + + return dx; +} + +void tmc_ramp_linear_compute_position(TMC_LinearRamp *linearRamp) +{ + if (!linearRamp->rampEnabled) + return; + + if (linearRamp->rampMode != TMC_RAMP_LINEAR_MODE_POSITION) + return; + + // Calculate steps needed to target + int32_t diffx = 0; + + switch(linearRamp->state) { + case TMC_RAMP_LINEAR_STATE_IDLE: + if(linearRamp->rampVelocity == 0) + linearRamp->accelerationSteps = 0; + + if(linearRamp->rampPosition == linearRamp->targetPosition) + break; + + linearRamp->state = TMC_RAMP_LINEAR_STATE_DRIVING; + break; + case TMC_RAMP_LINEAR_STATE_DRIVING: + // Calculate distance to target (positive = driving towards target) + if(linearRamp->rampVelocity > 0) + diffx = linearRamp->targetPosition - linearRamp->rampPosition; + else if(linearRamp->rampVelocity < 0) + diffx = -(linearRamp->targetPosition - linearRamp->rampPosition); + else + diffx = abs(linearRamp->targetPosition - linearRamp->rampPosition); + + // Steps left required for braking? + // (+ 1 to compensate rounding (flooring) errors of the position accumulator) + if(linearRamp->accelerationSteps + 1 >= diffx) + { + linearRamp->targetVelocity = 0; + linearRamp->state = TMC_RAMP_LINEAR_STATE_BRAKING; + } + else + { // Driving - apply VMAX (this also allows mid-ramp VMAX changes) + linearRamp->targetVelocity = (linearRamp->targetPosition > linearRamp->rampPosition) ? linearRamp->maxVelocity : -linearRamp->maxVelocity; + } + break; + case TMC_RAMP_LINEAR_STATE_BRAKING: + if(linearRamp->targetPosition == linearRamp->rampPosition) + { + if(abs(linearRamp->rampVelocity) <= linearRamp->stopVelocity) + { // Position reached, velocity within cutoff threshold (or zero) + linearRamp->rampVelocity = 0; + linearRamp->targetVelocity = 0; + linearRamp->state = TMC_RAMP_LINEAR_STATE_IDLE; + } + else + { + // We're still too fast, we're going to miss the target position + // Let the deceleration continue until velocity is zero, then either + // home when within homing distance or start a new ramp (RAMP_DRIVING) + // towards the target. + } + } + else + { // We're not at the target position + if(linearRamp->rampVelocity != 0) + { // Still decelerating + + // Calculate distance to target (positive = driving towards target) + if(linearRamp->rampVelocity > 0) + diffx = linearRamp->targetPosition - linearRamp->rampPosition; + else if(linearRamp->rampVelocity < 0) + diffx = -(linearRamp->targetPosition - linearRamp->rampPosition); + else + diffx = abs(linearRamp->targetPosition - linearRamp->rampPosition); + + // Enough space to accelerate again? + // (+ 1 to compensate rounding (flooring) errors of the position accumulator) + if(linearRamp->accelerationSteps + 1 < diffx) + { + linearRamp->state = TMC_RAMP_LINEAR_STATE_DRIVING; + } + } + else + { // Standing still (not at the target position) + if(abs(linearRamp->targetPosition - linearRamp->rampPosition) <= linearRamp->homingDistance) + { // Within homing distance - drive with stop velocity + linearRamp->targetVelocity = (linearRamp->targetPosition > linearRamp->rampPosition)? linearRamp->stopVelocity : -linearRamp->stopVelocity; + } + else + { // Not within homing distance - start a new motion by switching to RAMP_IDLE + // Since (targetPosition != actualPosition) a new ramp will be started. + linearRamp->state = TMC_RAMP_LINEAR_STATE_IDLE; + } + } + } + break; + } +} diff --git a/firmware/lib/tmc/ramp/LinearRamp1.h b/firmware/lib/tmc/ramp/LinearRamp1.h new file mode 100755 index 0000000..cbbbfee --- /dev/null +++ b/firmware/lib/tmc/ramp/LinearRamp1.h @@ -0,0 +1,89 @@ +/******************************************************************************* +* Copyright © 2018 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2023 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#ifndef TMC_RAMP_LINEARRAMP1_H_ +#define TMC_RAMP_LINEARRAMP1_H_ + +#include "tmc/helpers/API_Header.h" +#include "Ramp.h" + +// Default precision of the calculations. Internal calculations use a precision +// of 1/TMC_RAMP_LINEAR_PRECISION for acceleration and velocity. +// When using 2**N as precision, this results in N digits of precision. +#define TMC_RAMP_LINEAR_DEFAULT_PRECISION ((uint32_t)1<<17) + +// Position mode: When hitting the target position a velocity below the V_STOP threshold will be cut off to velocity 0 +#define TMC_RAMP_LINEAR_DEFAULT_HOMING_DISTANCE 5 + +// Position mode: When barely missing the target position by HOMING_DISTANCE or less, the remainder will be driven with V_STOP velocity +#define TMC_RAMP_LINEAR_DEFAULT_STOP_VELOCITY 5 + +typedef enum { + TMC_RAMP_LINEAR_MODE_VELOCITY, + TMC_RAMP_LINEAR_MODE_POSITION +} TMC_LinearRamp_Mode; + +typedef enum { + TMC_RAMP_LINEAR_STATE_IDLE, + TMC_RAMP_LINEAR_STATE_DRIVING, + TMC_RAMP_LINEAR_STATE_BRAKING +} TMC_LinearRamp_State; + +typedef struct +{ + uint32_t maxVelocity; + int32_t targetPosition; + int32_t rampPosition; + int32_t targetVelocity; + int32_t rampVelocity; + int32_t acceleration; + bool rampEnabled; + int32_t accumulatorVelocity; + int32_t accumulatorPosition; + TMC_LinearRamp_Mode rampMode; + TMC_LinearRamp_State state; + int32_t accelerationSteps; + uint32_t precision; + uint32_t homingDistance; + uint32_t stopVelocity; +} TMC_LinearRamp; + +void tmc_ramp_linear_init(TMC_LinearRamp *linearRamp); +int32_t tmc_ramp_linear_compute(TMC_LinearRamp *linearRamp); +int32_t tmc_ramp_linear_compute_velocity(TMC_LinearRamp *linearRamp); +void tmc_ramp_linear_compute_position(TMC_LinearRamp *linearRamp); + +void tmc_ramp_linear_set_enabled(TMC_LinearRamp *linearRamp, bool enabled); +void tmc_ramp_linear_set_maxVelocity(TMC_LinearRamp *linearRamp, uint32_t maxVelocity); +void tmc_ramp_linear_set_targetPosition(TMC_LinearRamp *linearRamp, int32_t targetPosition); +void tmc_ramp_linear_set_rampPosition(TMC_LinearRamp *linearRamp, int32_t rampPosition); +void tmc_ramp_linear_set_targetVelocity(TMC_LinearRamp *linearRamp, int32_t targetVelocity); +void tmc_ramp_linear_set_rampVelocity(TMC_LinearRamp *linearRamp, int32_t rampVelocity); +void tmc_ramp_linear_set_acceleration(TMC_LinearRamp *linearRamp, int32_t acceleration); +void tmc_ramp_linear_set_mode(TMC_LinearRamp *linearRamp, TMC_LinearRamp_Mode mode); +void tmc_ramp_linear_set_precision(TMC_LinearRamp * linearRamp, uint32_t precision); +void tmc_ramp_linear_set_homingDistance(TMC_LinearRamp *linearRamp, uint32_t homingDistance); +void tmc_ramp_linear_set_stopVelocity(TMC_LinearRamp *linearRamp, uint32_t stopVelocity); + +bool tmc_ramp_linear_get_enabled(TMC_LinearRamp *linearRamp); +uint32_t tmc_ramp_linear_get_maxVelocity(TMC_LinearRamp *linearRamp); +int32_t tmc_ramp_linear_get_targetPosition(TMC_LinearRamp *linearRamp); +int32_t tmc_ramp_linear_get_rampPosition(TMC_LinearRamp *linearRamp); +int32_t tmc_ramp_linear_get_targetVelocity(TMC_LinearRamp *linearRamp); +int32_t tmc_ramp_linear_get_rampVelocity(TMC_LinearRamp *linearRamp); +int32_t tmc_ramp_linear_get_acceleration(TMC_LinearRamp *linearRamp); +TMC_LinearRamp_State tmc_ramp_linear_get_state(TMC_LinearRamp *linearRamp); +TMC_LinearRamp_Mode tmc_ramp_linear_get_mode(TMC_LinearRamp *linearRamp); +uint32_t tmc_ramp_linear_get_precision(TMC_LinearRamp *linearRamp); +uint32_t tmc_ramp_linear_get_acceleration_limit(TMC_LinearRamp *linearRamp); +uint32_t tmc_ramp_linear_get_velocity_limit(TMC_LinearRamp *linearRamp); +uint32_t tmc_ramp_linear_get_homingDistance(TMC_LinearRamp *linearRamp); +uint32_t tmc_ramp_linear_get_stopVelocity(TMC_LinearRamp *linearRamp); + +#endif /* TMC_RAMP_LINEARRAMP1_H_ */ diff --git a/firmware/lib/tmc/ramp/Ramp.c b/firmware/lib/tmc/ramp/Ramp.c new file mode 100755 index 0000000..66087f5 --- /dev/null +++ b/firmware/lib/tmc/ramp/Ramp.c @@ -0,0 +1,91 @@ +/******************************************************************************* +* Copyright © 2018 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2023 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#include "Ramp.h" + +void tmc_ramp_init(void *ramp, TMC_RampType type) +{ + switch(type) { + case TMC_RAMP_TYPE_LINEAR: + default: + tmc_ramp_linear_init((TMC_LinearRamp *)ramp); + break; + } +} + +int32_t tmc_ramp_compute(void *ramp, TMC_RampType type, uint32_t delta) +{ + uint32_t i; + int32_t dxSum = 0; + + switch(type) { + case TMC_RAMP_TYPE_LINEAR: + default: + for (i = 0; i < delta; i++) + { + dxSum += tmc_ramp_linear_compute((TMC_LinearRamp *)ramp); + } + break; + } + + return dxSum; +} + +int32_t tmc_ramp_get_rampVelocity(void *ramp, TMC_RampType type) +{ + int32_t v = 0; + switch(type) { + case TMC_RAMP_TYPE_LINEAR: + v = tmc_ramp_linear_get_rampVelocity((TMC_LinearRamp *)ramp); + break; + } + return v; +} + +int32_t tmc_ramp_get_rampPosition(void *ramp, TMC_RampType type) +{ + int32_t x = 0; + switch(type) { + case TMC_RAMP_TYPE_LINEAR: + x = tmc_ramp_linear_get_rampPosition((TMC_LinearRamp *)ramp); + break; + } + return x; +} + +bool tmc_ramp_get_enabled(void *ramp, TMC_RampType type) +{ + bool enabled = false; + switch(type) { + case TMC_RAMP_TYPE_LINEAR: + enabled = tmc_ramp_linear_get_enabled((TMC_LinearRamp *)ramp); + break; + } + return enabled; +} + +void tmc_ramp_set_enabled(void *ramp, TMC_RampType type, bool enabled) +{ + switch(type) { + case TMC_RAMP_TYPE_LINEAR: + default: + tmc_ramp_linear_set_enabled((TMC_LinearRamp *)ramp, enabled); + break; + } +} + +void tmc_ramp_toggle_enabled(void *ramp, TMC_RampType type) +{ + switch(type) { + case TMC_RAMP_TYPE_LINEAR: + default: + tmc_ramp_linear_set_enabled((TMC_LinearRamp *)ramp, !tmc_ramp_get_enabled(ramp, type)); + break; + } +} diff --git a/firmware/lib/tmc/ramp/Ramp.h b/firmware/lib/tmc/ramp/Ramp.h new file mode 100755 index 0000000..179ad85 --- /dev/null +++ b/firmware/lib/tmc/ramp/Ramp.h @@ -0,0 +1,40 @@ +/******************************************************************************* +* Copyright © 2018 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2023 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#ifndef TMC_RAMP_RAMP_H_ +#define TMC_RAMP_RAMP_H_ + +#include "LinearRamp1.h" + +typedef enum { + TMC_RAMP_TYPE_LINEAR +} TMC_RampType; + +// Initializes ramp parameters for given type +void tmc_ramp_init(void *ramp, TMC_RampType type); + +// Computes new ramp state after delta ticks have passed +// Note: To call this function periodically with a fixed delta-time, use delta = 1 and +// define the units of acceleration as v/delta-time. If you want to specify a different unit, +// change delta to your preference. +// Returns the position difference of the calculation. +int32_t tmc_ramp_compute(void *ramp, TMC_RampType type, uint32_t delta); + +// Returns the current ramp velocity computed by the given ramp +int32_t tmc_ramp_get_rampVelocity(void *ramp, TMC_RampType type); + +// Returns the current ramp position computed by the given ramp +int32_t tmc_ramp_get_rampPosition(void *ramp, TMC_RampType type); + +// Enable/disable ramps +bool tmc_ramp_get_enabled(void *ramp, TMC_RampType type); +void tmc_ramp_set_enabled(void *ramp, TMC_RampType type, bool enabled); +void tmc_ramp_toggle_enabled(void *ramp, TMC_RampType type); + +#endif /* TMC_RAMP_RAMP_H_ */ diff --git a/firmware/lib/tmc/src/API_Header.h b/firmware/lib/tmc/src/API_Header.h new file mode 100755 index 0000000..d9d57f1 --- /dev/null +++ b/firmware/lib/tmc/src/API_Header.h @@ -0,0 +1,42 @@ +/******************************************************************************* +* Copyright © 2016 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2023 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#ifndef TMC_API_HEADER_H_ +#define TMC_API_HEADER_H_ + +#include "Config.h" +#include "Macros.h" +#include "Constants.h" +#include "Bits.h" +#include "CRC.h" +#include "RegisterAccess.h" +#include +#include "Types.h" + +// TODO: Restructure these. +/* + * Goal: Just give these values here as status back to the IDE when used with EvalSystem. + * Currently, this is obtained by just leaving out implementation specific error bits here. + */ +typedef enum { + TMC_ERROR_NONE = 0x00, + TMC_ERROR_GENERIC = 0x01, + TMC_ERROR_FUNCTION = 0x02, + TMC_ERROR_MOTOR = 0x08, + TMC_ERROR_VALUE = 0x10, + TMC_ERROR_CHIP = 0x40 +} TMCError; + +typedef enum { + TMC_COMM_DEFAULT, + TMC_COMM_SPI, + TMC_COMM_UART +} TMC_Comm_Mode; + +#endif /* TMC_API_HEADER_H_ */ diff --git a/firmware/lib/tmc/src/Bits.h b/firmware/lib/tmc/src/Bits.h new file mode 100755 index 0000000..2dbf074 --- /dev/null +++ b/firmware/lib/tmc/src/Bits.h @@ -0,0 +1,92 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2023 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +// BIT DEFINITION +#ifndef TMC_BITS_H_ +#define TMC_BITS_H_ + +#define BIT0 0x00000001 +#define BIT1 0x00000002 +#define BIT2 0x00000004 +#define BIT3 0x00000008 +#define BIT4 0x00000010 +#define BIT5 0x00000020 +#define BIT6 0x00000040 +#define BIT7 0x00000080 +#define BIT8 0x00000100 +#define BIT9 0x00000200 +#define BIT10 0x00000400 +#define BIT11 0x00000800 +#define BIT12 0x00001000 +#define BIT13 0x00002000 +#define BIT14 0x00004000 +#define BIT15 0x00008000 +#define BIT16 0x00010000 +#define BIT17 0x00020000 +#define BIT18 0x00040000 +#define BIT19 0x00080000 +#define BIT20 0x00100000 +#define BIT21 0x00200000 +#define BIT22 0x00400000 +#define BIT23 0x00800000 +#define BIT24 0x01000000 +#define BIT25 0x02000000 +#define BIT26 0x04000000 +#define BIT27 0x08000000 +#define BIT28 0x10000000 +#define BIT29 0x20000000 +#define BIT30 0x40000000 +#define BIT31 0x80000000 + +#define BYTE0_MASK 0x00000000000000FF +#define BYTE0_SHIFT 0 +#define BYTE1_MASK 0x000000000000FF00 +#define BYTE1_SHIFT 8 +#define BYTE2_MASK 0x0000000000FF0000 +#define BYTE2_SHIFT 16 +#define BYTE3_MASK 0x00000000FF000000 +#define BYTE3_SHIFT 24 +#define BYTE4_MASK 0x000000FF00000000 +#define BYTE4_SHIFT 32 +#define BYTE5_MASK 0x0000FF0000000000 +#define BYTE5_SHIFT 40 +#define BYTE6_MASK 0x00FF000000000000 +#define BYTE6_SHIFT 48 +#define BYTE7_MASK 0xFF00000000000000 +#define BYTE7_SHIFT 56 + +#define SHORT0_MASK (BYTE0_MASK|BYTE1_MASK) +#define SHORT0_SHIFT BYTE0_SHIFT +#define SHORT1_MASK (BYTE2_MASK|BYTE3_MASK) +#define SHORT1_SHIFT BYTE2_SHIFT +#define SHORT2_MASK (BYTE4_MASK|BYTE5_MASK) +#define SHORT2_SHIFT BYTE4_SHIFT +#define SHORT3_MASK (BYTE6_MASK|BYTE7_MASK) +#define SHORT3_SHIFT BYTE6_SHIFT + +#define WORD0_MASK (SHORT0_MASK|SHORT1_MASK) +#define WORD0_SHIFT SHORT0_SHIFT +#define WORD1_MASK (SHORT2_MASK|SHORT3_MASK) +#define WORD1_SHIFT SHORT2_SHIFT + +#define NIBBLE(value, n) (((value) >> ((n) << 2)) & 0x0F) +#define BYTE(value, n) (((value) >> ((n) << 3)) & 0xFF) +#define SHORT(value, n) (((value) >> ((n) << 4)) & 0xFFFF) +#define WORD(value, n) (((value) >> ((n) << 5)) & 0xFFFFFFFF) + +#define _8_16(__1, __0) (((__1) << BYTE1_SHIFT) | ((__0) << BYTE0_SHIFT)) + +#define _8_32(__3, __2, __1, __0) (((__3) << BYTE3_SHIFT) | ((__2) << BYTE2_SHIFT) | ((__1) << BYTE1_SHIFT) | ((__0) << BYTE0_SHIFT)) +#define _16_32(__1, __0) (((__1) << SHORT1_SHIFT) | ((__0) << SHORT0_SHIFT)) + +#define _8_64(__7, __6, __5, __4, __3, __2, __1, __0) (((__7) << BYTE7_SHIFT) | ((__6) << BYTE6_SHIFT) | ((__5) << BYTE5_SHIFT) | ((__4) << BYTE4_SHIFT) | ((__3) << BYTE3_SHIFT) | ((__2) << BYTE2_SHIFT) | ((__1) << BYTE1_SHIFT) | ((__0) << BYTE0_SHIFT)) +#define _16_64(__3, __2, __1, __0) (((__3) << SHORT3_SHIFT) | ((__2) << SHORT2_SHIFT) | ((__1) << SHORT1_SHIFT) | ((__0) << SHORT0_SHIFT)) +#define _32_64(__1, __0) (((__1) << WORD1_SHIFT) | ((__0) << WORD0_SHIFT)) + +#endif /* TMC_BITS_H_ */ diff --git a/firmware/lib/tmc/src/CRC.c b/firmware/lib/tmc/src/CRC.c new file mode 100755 index 0000000..3ba8ef4 --- /dev/null +++ b/firmware/lib/tmc/src/CRC.c @@ -0,0 +1,214 @@ +/******************************************************************************* +* Copyright © 2017 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2023 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + +/* + * This is a generic implementation for a CRC8 generator supporting + * both compile-time (1) and run-time initialized Lookup tables for efficient CRC8 calculation. + * You can store multiple tables for different polynomials and (non-)reflected CRCs. + * The different tables are referenced by an index, with an upper limit set at compile time (CRC_TABLE_COUNT). + * + * To generate CRCs you must first generate the Lookup-table by calling fillCRCTable() + * with any index. CRCs can then be generated from any data buffer by calling CRC() + * with the same index previously given to fillCRCTable(). + * + * The table generation has been optimized for speed so that the runtime + * table generation can even be done during normal operation if required. + * However, as long as the required polynomials are known on initialization, + * the table generation should be done at that time. + * On the Landungsbruecke the initialization of a CRC table takes ~250µs. (2) + * Should your application still have problems with the table calculation time, + * this algorithm could probably be speed up by preparing a 2- or 4-bit lookup table + * to speed up the actual table generation. + * + * (1): For compile-time CRC tables, just fill the table(s) by initializing CRCTables[] to the proper values. + * (2): Tested by toggling a GPIO pin, generating a table in-between and measuring the GPIO pulse width. + */ + +#include "CRC.h" + +typedef struct { + uint8_t table[256]; + uint8_t polynomial; + bool isReflected; +} CRCTypeDef; + +CRCTypeDef CRCTables[CRC_TABLE_COUNT] = { 0 }; + +static uint8_t flipByte(uint8_t value); +static uint32_t flipBitsInBytes(uint32_t value); + +/* This function generates the Lookup table used for CRC calculations. + * + * Arguments: + * uint8_t polynomial: The CRC polynomial for which the table will be generated. + * bool isReflected: Indicator whether the CRC table will be reflected or not. + * uint8_t index: The index of the table to be filled. + * + * How it works: + * A CRC calculation of a byte can be done by taking the byte to be CRC'd, + * shifting it left by one (appending a 0) and - if a 1 has been shifted out - + * XOR-ing in the CRC polynomial. After 8 iterations the result will be the + * CRC of the Byte. + * + * The function below does this in a compact way, by using all 4 bytes of a + * uint32_t to do 4 separate CRC bytes at once. + * For this to work without the Byte shifting interfering with adjacent bytes, + * the polynomial has the 8th bit (0x100) set. That way, if the shifted-out bit + * is 1, the following XOR-ing with the CRC polynomial will set that 1 to a 0, + * resulting in the shifted-in 0 for the adjacent byte. + * This process will go from the the lowest to the highest byte, resulting in + * fully independent byte-wise CRC calculations. For the highest byte, the value + * of the shifted-out byte needs to be stored before shifting the bytes (isMSBSet). + * + * The for-loop that iterates over all uint8_t values starts out with the + * uint8_t values 3 to 0 stored in one uint32_t: 0x03020100 + * for each iteration each uint8_t value will increase by 4.. + * 0 -> 4 -> 8 -> C -> ... + * 1 -> 5 -> 9 -> D -> ... + * 2 -> 6 -> A -> E -> ... + * 3 -> 7 -> B -> F -> ... + * ..resulting in an increase of the uint32_t by 0x04040404: + * 0x03020100 -> 0x07060504 -> 0x0B0A0908 -> 0x0F0E0D0C -> ... + * The loop ends as soon as we have iterated over all uint8_t values. + * We detect that by looking for the byte-wise overflow into the next byte: + * 0xFFFEFDFC <- last uint32_t value to be calculated + * 0xFF, 0xFE, 0xFD, 0xFC <- the corresponding uint8_t values + * 0x103, 0x102, 0x101, 0x100 <- incremented uint8_t values (overflow into the next byte!) + * 0x04030200 <- uint32_t value with the overflowed bytes + * + * We have the lower uint8_t values at the lower bytes of the uint32_t. + * This allows us to simply store the lowest byte of the uint32_t, + * right-shift the uint32_t by 8 and increment the table pointer. + * After 4 iterations of that all 4 bytes of the uint32_t are stored in the table. + */ +uint8_t tmc_fillCRC8Table(uint8_t polynomial, bool isReflected, uint8_t index) +{ + uint32_t CRCdata; + // Helper pointer for traversing the result table + uint8_t *table; + + if(index >= CRC_TABLE_COUNT) + return 0; + + CRCTables[index].polynomial = polynomial; + CRCTables[index].isReflected = isReflected; + table = &CRCTables[index].table[0]; + + // Extend the polynomial to correct byte MSBs shifting into next bytes + uint32_t poly = (uint32_t) polynomial | 0x0100; + + // Iterate over all 256 possible uint8_t values, compressed into a uint32_t (see detailed explanation above) + uint32_t i; + for(i = 0x03020100; i != 0x04030200; i+=0x04040404) + { + // For reflected table: Flip the bits of each input byte + CRCdata = (isReflected)? flipBitsInBytes(i) : i; + + // Iterate over 8 Bits + int j; + for(j = 0; j < 8; j++) + { + // Store value of soon-to-be shifted out byte + uint8_t isMSBSet = (CRCdata & 0x80000000)? 1:0; + + // CRC Shift + CRCdata <<= 1; + + // XOR the bytes when required, lowest to highest + CRCdata ^= (CRCdata & 0x00000100)? (poly ) : 0; + CRCdata ^= (CRCdata & 0x00010000)? (poly << 8 ) : 0; + CRCdata ^= (CRCdata & 0x01000000)? (poly << 16) : 0; + CRCdata ^= (isMSBSet)? (poly << 24) : 0; + } + + // For reflected table: Flip the bits of each output byte + CRCdata = (isReflected)? flipBitsInBytes(CRCdata) : CRCdata; + // Store the CRC result bytes in the table array + *table++ = (uint8_t) CRCdata; + CRCdata >>= 8; + *table++ = (uint8_t) CRCdata; + CRCdata >>= 8; + *table++ = (uint8_t) CRCdata; + CRCdata >>= 8; + *table++ = (uint8_t) CRCdata; + } + + return 1; +} + +/* This function calculates the CRC from a data buffer + * + * Arguments: + * uint8_t *data: A pointer to the data that will be CRC'd. + * uint32_t bytes: The length of the data buffer. + * uint8_t index: The index of the CRC table to be used. + */ +uint8_t tmc_CRC8(uint8_t *data, uint32_t bytes, uint8_t index) +{ + uint8_t result = 0; + uint8_t *table; + + if(index >= CRC_TABLE_COUNT) + return 0; + + table = &CRCTables[index].table[0]; + + while(bytes--) + result = table[result ^ *data++]; + + return (CRCTables[index].isReflected)? flipByte(result) : result; +} + +uint8_t tmc_tableGetPolynomial(uint8_t index) +{ + if(index >= CRC_TABLE_COUNT) + return 0; + + return CRCTables[index].polynomial; +} + +bool tmc_tableIsReflected(uint8_t index) +{ + if(index >= CRC_TABLE_COUNT) + return false; + + return CRCTables[index].isReflected; +} + +// Helper functions +static uint8_t flipByte(uint8_t value) +{ + // swap odd and even bits + value = ((value >> 1) & 0x55) | ((value & 0x55) << 1); + // swap consecutive pairs + value = ((value >> 2) & 0x33) | ((value & 0x33) << 2); + // swap nibbles ... + value = ((value >> 4) & 0x0F) | ((value & 0x0F) << 4); + + return value; +} + +/* This helper function switches all bits within each byte. + * The byte order remains the same: + * [b31 b30 b29 b28 b27 b26 b25 b24 .. b7 b6 b5 b4 b3 b2 b1 b0] + * || + * \||/ + * \/ + * [b24 b25 b26 b27 b28 b29 b30 b31 .. b0 b1 b2 b3 b4 b5 b6 b7] + */ +static uint32_t flipBitsInBytes(uint32_t value) +{ + // swap odd and even bits + value = ((value >> 1) & 0x55555555) | ((value & 0x55555555) << 1); + // swap consecutive pairs + value = ((value >> 2) & 0x33333333) | ((value & 0x33333333) << 2); + // swap nibbles ... + value = ((value >> 4) & 0x0F0F0F0F) | ((value & 0x0F0F0F0F) << 4); + + return value; +} diff --git a/firmware/lib/tmc/src/CRC.h b/firmware/lib/tmc/src/CRC.h new file mode 100755 index 0000000..dea02fb --- /dev/null +++ b/firmware/lib/tmc/src/CRC.h @@ -0,0 +1,25 @@ +/******************************************************************************* +* Copyright © 2017 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2023 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#ifndef TMC_HELPERS_CRC_H_ +#define TMC_HELPERS_CRC_H_ + + #include "Types.h" + + // Amount of CRC tables available + // Each table takes ~260 bytes (257 bytes, one bool and structure padding) + #define CRC_TABLE_COUNT 2 + + uint8_t tmc_fillCRC8Table(uint8_t polynomial, bool isReflected, uint8_t index); + uint8_t tmc_CRC8(uint8_t *data, uint32_t bytes, uint8_t index); + + uint8_t tmc_tableGetPolynomial(uint8_t index); + bool tmc_tableIsReflected(uint8_t index); + +#endif /* TMC_HELPERS_CRC_H_ */ diff --git a/firmware/lib/tmc/src/Config.h b/firmware/lib/tmc/src/Config.h new file mode 100755 index 0000000..a9ceed3 --- /dev/null +++ b/firmware/lib/tmc/src/Config.h @@ -0,0 +1,41 @@ +/******************************************************************************* +* Copyright © 2018 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2023 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#ifndef TMC_HELPERS_CONFIG_H_ +#define TMC_HELPERS_CONFIG_H_ + +#include "Constants.h" +#include "Types.h" + +// Callback functions have IC-dependent parameters +// To store the function pointers we use this dummy type, which is never +// called without casting it to the IC-specific type first. +// (Casting between function pointers is allowed by the C standard) +typedef void (*tmc_callback_config)(void); + +// States of a configuration +typedef enum { + CONFIG_READY, + CONFIG_RESET, + CONFIG_RESTORE +} ConfigState; + +// structure for configuration mechanism +typedef struct +{ + ConfigState state; + uint8_t configIndex; + int32_t shadowRegister[TMC_REGISTER_COUNT]; + uint8_t (*reset) (void); + uint8_t (*restore) (void); + tmc_callback_config callback; + uint8_t channel; +} ConfigurationTypeDef; + +#endif /* TMC_HELPERS_CONFIG_H_ */ diff --git a/firmware/lib/tmc/src/Constants.h b/firmware/lib/tmc/src/Constants.h new file mode 100755 index 0000000..e5e4216 --- /dev/null +++ b/firmware/lib/tmc/src/Constants.h @@ -0,0 +1,24 @@ +/******************************************************************************* +* Copyright © 2018 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2023 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#ifndef TMC_HELPERS_CONSTANTS_H_ +#define TMC_HELPERS_CONSTANTS_H_ + +#define TMC_WRITE_BIT 0x80 + +#define TMC_ADDRESS_MASK 0x7F + +#define TMC_DEFAULT_MOTOR 0 + +//#define TMC_DIRECTION_RIGHT TRUE +//#define TMC_DIRECTION_LEFT FALSE + +#define TMC_REGISTER_COUNT 128 // Default register count + +#endif /* TMC_HELPERS_CONSTANTS_H_ */ diff --git a/firmware/lib/tmc/src/Functions.c b/firmware/lib/tmc/src/Functions.c new file mode 100755 index 0000000..535fed6 --- /dev/null +++ b/firmware/lib/tmc/src/Functions.c @@ -0,0 +1,173 @@ +/******************************************************************************* +* Copyright © 2018 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2023 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#include "Functions.h" + +int32_t tmc_limitInt(int32_t value, int32_t min, int32_t max) +{ + if (value > max) + return max; + else if (value < min) + return min; + else + return value; +} + +int64_t tmc_limitS64(int64_t value, int64_t min, int64_t max) +{ + if (value > max) + return max; + else if (value < min) + return min; + else + return value; +} + +/* lookup table for square root function */ +static const unsigned char sqrttable[256] = +{ + 0, 16, 22, 27, 32, 35, 39, 42, 45, 48, 50, 53, 55, 57, 59, 61, + 64, 65, 67, 69, 71, 73, 75, 76, 78, 80, 81, 83, 84, 86, 87, 89, + 90, 91, 93, 94, 96, 97, 98, 99, 101, 102, 103, 104, 106, 107, 108, 109, + 110, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, + 128, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, + 143, 144, 144, 145, 146, 147, 148, 149, 150, 150, 151, 152, 153, 154, 155, 155, + 156, 157, 158, 159, 160, 160, 161, 162, 163, 163, 164, 165, 166, 167, 167, 168, + 169, 170, 170, 171, 172, 173, 173, 174, 175, 176, 176, 177, 178, 178, 179, 180, + 181, 181, 182, 183, 183, 184, 185, 185, 186, 187, 187, 188, 189, 189, 190, 191, + 192, 192, 193, 193, 194, 195, 195, 196, 197, 197, 198, 199, 199, 200, 201, 201, + 202, 203, 203, 204, 204, 205, 206, 206, 207, 208, 208, 209, 209, 210, 211, 211, + 212, 212, 213, 214, 214, 215, 215, 216, 217, 217, 218, 218, 219, 219, 220, 221, + 221, 222, 222, 223, 224, 224, 225, 225, 226, 226, 227, 227, 228, 229, 229, 230, + 230, 231, 231, 232, 232, 233, 234, 234, 235, 235, 236, 236, 237, 237, 238, 238, + 239, 240, 240, 241, 241, 242, 242, 243, 243, 244, 244, 245, 245, 246, 246, 247, + 247, 248, 248, 249, 249, 250, 250, 251, 251, 252, 252, 253, 253, 254, 254, 255 +}; + +int32_t tmc_sqrti(int32_t x) +{ + int32_t xn; + + // Negative parameter? + if (x < 0) + return -1; + + if (x < 0x0100) + return (int32_t) sqrttable[x] >> 4; + + if (x >= 0x00010000) + { + if (x >= 0x01000000) + { + if (x >= 0x10000000) + { + if (x >= 0x40000000) + { + // 0x40000000 <= x < 0x7FFFFFFF + xn = (int32_t) sqrttable[x >> 24] << 8; + } + else + { + // 0x10000000 <= x < 0x40000000 + xn = (int32_t) sqrttable[x >> 22] << 7; + } + } + else + { + if (x >= 0x04000000) + { + // 0x04000000 <= x < 0x10000000 + xn = (int32_t) sqrttable[x >> 20] << 6; + } + else + { + // 0x01000000 <= x < 0x04000000 + xn = (int32_t) sqrttable[x >> 18] << 5; + } + } + + // Two steps of the babylonian method + xn = (xn + 1 + (x / xn)) >> 1; + xn = (xn + 1 + (x / xn)) >> 1; + } + else + { + if (x >= 0x00100000) + { + if (x >= 0x00400000) + { + // 0x00400000 <= x < 0x01000000 + xn = (int32_t) sqrttable[x >> 16] << 4; + } + else + { + // 0x00100000 <= x < 0x00400000 + xn = (int32_t) sqrttable[x >> 14] << 3; + } + } + else + { + if (x >= 0x00040000) + { + // 0x00040000 <= x < 0x00100000 + xn = (int32_t) sqrttable[x >> 12] << 2; + } + else + { + // 0x00010000 <= x < 0x00040000 + xn = (int32_t) sqrttable[x >> 10] << 1; + } + } + + // One step of the babylonian method + xn = (xn + 1 + (x / xn)) >> 1; + } + } + else + { + if (x >= 0x1000) + { + if (x >= 0x4000) + { + // 0x4000 <= x < 0x00010000 + xn = (int32_t) (sqrttable[x >> 8] ) + 1; + } + else + { + // 0x1000 <= x < 0x4000 + xn = (int32_t) (sqrttable[x >> 6] >> 1) + 1; + } + } + else + { + if (x >= 0x0400) + { + // 0x0400 <= x < 0x1000 + xn = (int32_t) (sqrttable[x >> 4] >> 2) + 1; + } + else + { + // 0x0100 <= x < 0x0400 + xn = (int32_t) (sqrttable[x >> 2] >> 3) + 1; + } + } + } + + // Make sure that our result is floored + if ((xn * xn) > x) + xn--; + + return xn; +} + +int32_t tmc_filterPT1(int64_t *akku, int32_t newValue, int32_t lastValue, uint8_t actualFilter, uint8_t maxFilter) +{ + *akku += (newValue-lastValue) << (maxFilter-actualFilter); + return *akku >> maxFilter; +} diff --git a/firmware/lib/tmc/src/Functions.h b/firmware/lib/tmc/src/Functions.h new file mode 100755 index 0000000..93dac20 --- /dev/null +++ b/firmware/lib/tmc/src/Functions.h @@ -0,0 +1,20 @@ +/******************************************************************************* +* Copyright © 2018 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2023 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#ifndef TMC_FUNCTIONS_H_ +#define TMC_FUNCTIONS_H_ + +#include "API_Header.h" + +int32_t tmc_limitInt(int32_t value, int32_t min, int32_t max); +int64_t tmc_limitS64(int64_t value, int64_t min, int64_t max); +int32_t tmc_sqrti(int32_t x); +int32_t tmc_filterPT1(int64_t *akku, int32_t newValue, int32_t lastValue, uint8_t actualFilter, uint8_t maxFilter); + +#endif /* TMC_FUNCTIONS_H_ */ diff --git a/firmware/lib/tmc/src/Macros.h b/firmware/lib/tmc/src/Macros.h new file mode 100755 index 0000000..37771cd --- /dev/null +++ b/firmware/lib/tmc/src/Macros.h @@ -0,0 +1,59 @@ +/******************************************************************************* +* Copyright © 2018 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2023 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +#ifndef TMC_MACROS_H_ +#define TMC_MACROS_H_ + +/* Cast a n bit signed int to a 32 bit signed int + * This is done by checking the MSB of the signed int (Bit n). + * If it is 1, the value is negative and the Bits 32 to n+1 are set to 1 + * If it is 0, the value remains unchanged + */ +#define CAST_Sn_TO_S32(value, n) ((value) | (((value) & ((uint32_t)1<<((n)-1)))? ~(((uint32_t)1<<(n))-1) : 0 )) + +// Min/Max macros +#ifndef MIN + #define MIN(a,b) (((a)<(b)) ? (a) : (b)) +#endif +#ifndef MAX + #define MAX(a,b) (((a)>(b)) ? (a) : (b)) +#endif + +// Static Array length +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) +#endif + +// Generic mask/shift macros +#define FIELD_GET(data, mask, shift) \ + (((data) & (mask)) >> (shift)) +#define FIELD_SET(data, mask, shift, value) \ + (((data) & (~(mask))) | (((value) << (shift)) & (mask))) + +// Register read/write/update macros using Mask/Shift: +#define FIELD_READ(read, motor, address, mask, shift) \ + FIELD_GET(read(motor, address), mask, shift) +#define FIELD_WRITE(write, motor, address, mask, shift, value) \ + (write(motor, address, ((value)<<(shift)) & (mask))) +#define FIELD_UPDATE(read, write, motor, address, mask, shift, value) \ + (write(motor, address, FIELD_SET(read(motor, address), mask, shift, value))) + +// Macro to surpress unused parameter warnings +#ifndef UNUSED + #define UNUSED(x) (void)(x) +#endif + +// Memory access helpers +// Force the compiler to access a location exactly once +#define ACCESS_ONCE(x) *((volatile typeof(x) *) (&x)) + +// Macro to remove write bit for shadow register array access +#define TMC_ADDRESS(x) ((x) & (TMC_ADDRESS_MASK)) + +#endif /* TMC_MACROS_H_ */ diff --git a/firmware/lib/tmc/src/README.md b/firmware/lib/tmc/src/README.md new file mode 100755 index 0000000..4fc0bd4 --- /dev/null +++ b/firmware/lib/tmc/src/README.md @@ -0,0 +1,68 @@ +# TMC5160 + + +## How to use + +To access the TMC5160's registers, the TMC-API offers two functions: **tmc5160_readRegister** and **tmc5160_writeRegister**. +Each of these functions takes in an **icID**, which is used to identify the IC when multiple ICs are connected. This identifier is passed down to the callback functions (see How to Integrate). + +## How to integrate: overview + +1. Include all the files of the TMC-API/ic/tmc/TMC5160 folder into the custom project. +2. Include the TMC5160.h file in the custom source code. +3. Implement the necessary callback functions (see below). +4. (optional): Take a look at the Examples subfolder for ready-made examples of the TMC-API usage. + +## Accessing the TMC5160 via UART +The following diagram depicts how to access the TMC5160 via UART using the TMC-API. + +![screenshot](registercall_hierarchy_flowchart_UART.svg) + +The description of the functions, in the above flowchart, are as follows: +- The functions tmc5160_readRegister and tmc5160_writeRegister are used to read and write the registers respectively. These functions check the current active bus and calls the bus-specific function i.e readRegisterUART or writeRegisterUART. +- These bus specific functions constructs the datagram and further calls the bus specific callback 'tmcXXXX_readWriteUART. +- This callback function further calls the hardware specific read/write function for UART and needs to be implemented externally. + +### Necessary hardware modification to use UART +To use UART with the Eval-Kit: pin 39 (DIO17) and 40 (DIO18) should be connected with a 1k ohm resistor. Pin 37 (DIO15) and 40(DIO18) should be shorted. Additionally bend the 37 and 38 on the Landungsbrücke side of the Eselsbrücke out. For more information checkout the latest TMC5160-EVAL UART Info Application Note at https://www.analog.com/en/resources/evaluation-hardware-and-software/evaluation-boards-kits/tmc5160-eval.html + +### How to integrate: Callback functions +To communicate with TMC5160 IC, the TMC-API library needs to know which bus (UART, SPI) it shall use. For that, the callback function **'tmc5160_getBusType()'** needs to be implemented. +Additionally, implement the following callback functions to access the chip via UART: +1. **tmc5160_readWriteUART()**, which is a HAL wrapper function that provides the necessary hardware access. +2. **tmc5160_getNodeAddress()**, that returns the node/slave address. Node address could be set in NODECONF (0x3) register and the address could be incremented as defined by AD0, AD1 and AD2. (Node address + ADx) must be less than 255. For further details please consult the datasheet of TMC5160. + +### Sharing the CRC table with other TMC-API chips +The TMC5160 UART protocol uses an 8 bit CRC. For calculating this, a table-based algorithm is used. This table (tmcCRCTable_Poly7Reflected[256]) is 256 bytes big and identical across multiple different Trinamic chips (i.e. TMC2209). +If multiple Trinamic chips are being used in the same project, avoiding redundant copies of this table could save memory. It is possible to substitute this CRC table with another CRC table. + +## Accessing the TMC5160 via SPI +The following diagram depicts how to access the TMC5160 via SPI using the TMC-API. + +![screenshot](registercall_hierarchy_flowchart_SPI.svg) + +The description of the functions, in the above flowchart, are as follows: +- The functions tmc5160_readRegister and tmc5160_writeRegister are used to read and write the registers respectively. These functions check the current active bus and calls the bus-specific function i.e readRegisterSPI or writeRegisterSPI. +- These bus specific functions constructs the datagram and further calls the bus specific callback 'tmcXXXX_readWriteSPI. +- This callback function further calls the hardware specific read/write function for SPI and needs to be implemented externally. + +### How to integrate: Callback functions +To communicate with TMC5160 IC, the TMC-API library needs to know which bus (UART, SPI) it shall use. For that, the callback function **'tmc5160_getBusType()'** needs to be implemented. +Additionally, implement the following callback functions to access the chip via SPI: +1. **tmc5160_readWriteSPI()**, which is a HAL wrapper function that provides the necessary hardware access. This function should also set the chip select pin CSN to low before starting the data transfer and set to high upon completion. Please refer to the datasheet of the IC for further details. + +### Option to use the cache logic for Write-Only registers +The chip features write-only registers that are unable to be read, necessitating the creation of a shadow copy to cache their contents. This copy is automatically updated whenever data is written to these registers. This cache logic could be enabled by setting the macro **TMC5160_CACHE** to **'1'** or disabled by setting to **'0'** respectively. If this feature is enabled then there comes another option to use **tmc5160_cache** function, which is already implemeted in the API, by defining **TMC5160_ENABLE_TMC_CACHE** macro to **'1'** or one can implement their own function. The function **tmc5160_cache** works for both reading from and writing to the shadow array. It first checks whether the register has write-only access and data needs to be read from the hadow copy. On the basis of that, it returns **true** or **false**. The shadowRegisters on the premade cache implementation need to be one per chip. **TMC5160_IC_CACHE_COUNT** is set to '1' by default and is user-overwritable. If multiple chips are being used in the same project, increment its value to the number of chips connected. + +## Further info +### Dependency graph for the ICs with new register R/W mechanism +This graph illustrates the relationships between files within the TMC-API library, highlighting dependencies and identifying the files that are essential for integrating the library into the custom projects. + +![screenshot](uml-tmc-api.svg) + +### Example usage: TMC-Evalsystem +**For a reference usage of the TMC-API**, visit the [TMC-Evalsystem](https://github.com/analogdevicesinc/TMC-EvalSystem) + +## Migration status +The TMC5160 has been reworked to the access system described above. For more infos on the status of this and other ICs, check out the [migration page](https://github.com/analogdevicesinc/TMC-API/issues/53). + diff --git a/firmware/lib/tmc/src/RegisterAccess.h b/firmware/lib/tmc/src/RegisterAccess.h new file mode 100755 index 0000000..7990589 --- /dev/null +++ b/firmware/lib/tmc/src/RegisterAccess.h @@ -0,0 +1,86 @@ +/******************************************************************************* +* Copyright © 2017 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2023 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + +/* + * The permission system aims to allow a general-purpose implementation for + * all common hardware register usages. This includes: + * - Trivial Cases: Read, Write, Read & Write + * + * - Read & Write accesses that route to different values/functions of a chip. + * (e.g. serial communication, where read/write corresponds to RX/TX) + * - Read to clear, write to clear. This does not directly affect the access, + * but can be used to implement a software shadow register for flags + * (ORing the read value into a shadow register instead of overwriting). + * - Registers with default values that are not known (e.g. Factory configuration + * values that should not be overwritten by default). + */ + +#ifndef TMC_HELPERS_REGISTERACCESS_H +#define TMC_HELPERS_REGISTERACCESS_H + +// Register access bits +/* Lower nibble is used for read/write, higher nibble is used for + * special case registers. This makes it easy to identify the read/write + * part of the permissions in a hexadecimal permission number. + * The dirty bit will only ever be set at runtime, so we keep the easily + * readable lower nibble. + */ +#define TMC_ACCESS_NONE 0x00 + +#define TMC_ACCESS_READ 0x01 +#define TMC_ACCESS_WRITE 0x02 + // 0x04 is currently unused +#define TMC_ACCESS_DIRTY 0x08 // Register has been written since reset -> shadow register is valid for restore + +// Special Register bits +#define TMC_ACCESS_RW_SPECIAL 0x10 // Read and write are independent - different values and/or different functions +#define TMC_ACCESS_FLAGS 0x20 // Register has read or write to clear flags. +#define TMC_ACCESS_HW_PRESET 0x40 // Register has hardware presets (e.g. Factory calibrations) - do not write a default value + // 0x80 is currently unused + +// Permission combinations +#define TMC_ACCESS_RW (TMC_ACCESS_READ | TMC_ACCESS_WRITE) // 0x03 - Read and write +#define TMC_ACCESS_RW_SEPARATE (TMC_ACCESS_RW | TMC_ACCESS_RW_SPECIAL) // 0x13 - Read and write, with separate values/functions +#define TMC_ACCESS_R_FLAGS (TMC_ACCESS_READ | TMC_ACCESS_FLAGS) // 0x21 - Read, has flags (read to clear) +#define TMC_ACCESS_RW_FLAGS (TMC_ACCESS_RW | TMC_ACCESS_FLAGS) // 0x23 - Read and write, has flags (read or write to clear) +#define TMC_ACCESS_W_PRESET (TMC_ACCESS_WRITE | TMC_ACCESS_HW_PRESET) // 0x42 - Write, has hardware preset - skipped in reset routine +#define TMC_ACCESS_RW_PRESET (TMC_ACCESS_RW | TMC_ACCESS_HW_PRESET) // 0x43 - Read and write, has hardware presets - skipped in reset routine + +// Helper macros +#define TMC_IS_READABLE(x) ((x) & TMC_ACCESS_READ) +#define TMC_IS_WRITABLE(x) ((x) & TMC_ACCESS_WRITE) +#define TMC_IS_DIRTY(x) ((x) & TMC_ACCESS_DIRTY) +#define TMC_IS_PRESET(x) ((x) & TMC_ACCESS_HW_PRESET) +#define TMC_IS_RESETTABLE(x) (((x) & (TMC_ACCESS_W_PRESET)) == TMC_ACCESS_WRITE) // Write bit set, Hardware preset bit not set +#define TMC_IS_RESTORABLE(x) (((x) & TMC_ACCESS_WRITE) && (!(x & TMC_ACCESS_HW_PRESET) || (x & TMC_ACCESS_DIRTY))) // Write bit set, if it's a hardware preset register, it needs to be dirty + +// Struct for listing registers that have constant contents which we cannot +// obtain by reading them due to the register not being read-back. +typedef struct +{ + uint8_t address; + uint32_t value; +} TMCRegisterConstant; + +// Helper define: +// Most register permission arrays are initialized with 128 values. +// In those fields its quite hard to have an easy overview of available +// registers. For that, ____ is defined to 0, since 4 underscores are +// very easy to distinguish from the 2-digit hexadecimal values. +// This way, the used registers (permission != ACCESS_NONE) are easily spotted +// amongst unused (permission == ACCESS_NONE) registers. +#define ____ 0x00 + +// Helper define: +// Default reset values are not used if the corresponding register has a +// hardware preset. Since this is not directly visible in the default +// register reset values array, N_A is used as an indicator for a preset +// value, where any value will be ignored anyways (N_A: not available). +#define N_A 0 + +#endif /* TMC_HELPERS_REGISTERACCESS_H */ diff --git a/firmware/lib/tmc/src/TMC5160.c b/firmware/lib/tmc/src/TMC5160.c new file mode 100755 index 0000000..9c26438 --- /dev/null +++ b/firmware/lib/tmc/src/TMC5160.c @@ -0,0 +1,554 @@ +/******************************************************************************* + * Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG + * (now owned by Analog Devices Inc.), + * + * Copyright © 2024 Analog Devices Inc. All Rights Reserved. + * This software is proprietary to Analog Devices, Inc. and its licensors. + *******************************************************************************/ + +#include "TMC5160.h" +#ifdef TMC_API_EXTERNAL_CRC_TABLE +extern const uint8_t tmcCRCTable_Poly7Reflected[256]; +#else +const uint8_t tmcCRCTable_Poly7Reflected[256] = { + 0x00, + 0x91, + 0xE3, + 0x72, + 0x07, + 0x96, + 0xE4, + 0x75, + 0x0E, + 0x9F, + 0xED, + 0x7C, + 0x09, + 0x98, + 0xEA, + 0x7B, + 0x1C, + 0x8D, + 0xFF, + 0x6E, + 0x1B, + 0x8A, + 0xF8, + 0x69, + 0x12, + 0x83, + 0xF1, + 0x60, + 0x15, + 0x84, + 0xF6, + 0x67, + 0x38, + 0xA9, + 0xDB, + 0x4A, + 0x3F, + 0xAE, + 0xDC, + 0x4D, + 0x36, + 0xA7, + 0xD5, + 0x44, + 0x31, + 0xA0, + 0xD2, + 0x43, + 0x24, + 0xB5, + 0xC7, + 0x56, + 0x23, + 0xB2, + 0xC0, + 0x51, + 0x2A, + 0xBB, + 0xC9, + 0x58, + 0x2D, + 0xBC, + 0xCE, + 0x5F, + 0x70, + 0xE1, + 0x93, + 0x02, + 0x77, + 0xE6, + 0x94, + 0x05, + 0x7E, + 0xEF, + 0x9D, + 0x0C, + 0x79, + 0xE8, + 0x9A, + 0x0B, + 0x6C, + 0xFD, + 0x8F, + 0x1E, + 0x6B, + 0xFA, + 0x88, + 0x19, + 0x62, + 0xF3, + 0x81, + 0x10, + 0x65, + 0xF4, + 0x86, + 0x17, + 0x48, + 0xD9, + 0xAB, + 0x3A, + 0x4F, + 0xDE, + 0xAC, + 0x3D, + 0x46, + 0xD7, + 0xA5, + 0x34, + 0x41, + 0xD0, + 0xA2, + 0x33, + 0x54, + 0xC5, + 0xB7, + 0x26, + 0x53, + 0xC2, + 0xB0, + 0x21, + 0x5A, + 0xCB, + 0xB9, + 0x28, + 0x5D, + 0xCC, + 0xBE, + 0x2F, + 0xE0, + 0x71, + 0x03, + 0x92, + 0xE7, + 0x76, + 0x04, + 0x95, + 0xEE, + 0x7F, + 0x0D, + 0x9C, + 0xE9, + 0x78, + 0x0A, + 0x9B, + 0xFC, + 0x6D, + 0x1F, + 0x8E, + 0xFB, + 0x6A, + 0x18, + 0x89, + 0xF2, + 0x63, + 0x11, + 0x80, + 0xF5, + 0x64, + 0x16, + 0x87, + 0xD8, + 0x49, + 0x3B, + 0xAA, + 0xDF, + 0x4E, + 0x3C, + 0xAD, + 0xD6, + 0x47, + 0x35, + 0xA4, + 0xD1, + 0x40, + 0x32, + 0xA3, + 0xC4, + 0x55, + 0x27, + 0xB6, + 0xC3, + 0x52, + 0x20, + 0xB1, + 0xCA, + 0x5B, + 0x29, + 0xB8, + 0xCD, + 0x5C, + 0x2E, + 0xBF, + 0x90, + 0x01, + 0x73, + 0xE2, + 0x97, + 0x06, + 0x74, + 0xE5, + 0x9E, + 0x0F, + 0x7D, + 0xEC, + 0x99, + 0x08, + 0x7A, + 0xEB, + 0x8C, + 0x1D, + 0x6F, + 0xFE, + 0x8B, + 0x1A, + 0x68, + 0xF9, + 0x82, + 0x13, + 0x61, + 0xF0, + 0x85, + 0x14, + 0x66, + 0xF7, + 0xA8, + 0x39, + 0x4B, + 0xDA, + 0xAF, + 0x3E, + 0x4C, + 0xDD, + 0xA6, + 0x37, + 0x45, + 0xD4, + 0xA1, + 0x30, + 0x42, + 0xD3, + 0xB4, + 0x25, + 0x57, + 0xC6, + 0xB3, + 0x22, + 0x50, + 0xC1, + 0xBA, + 0x2B, + 0x59, + 0xC8, + 0xBD, + 0x2C, + 0x5E, + 0xCF, +}; +#endif + +/**************************************************************** Cache Implementation *************************************************************************/ +#if TMC5160_CACHE == 0 +static inline bool tmc5160_cache(uint16_t icID, TMC5160CacheOp operation, uint8_t address, uint32_t *value) +{ + UNUSED(icID); + UNUSED(address); + UNUSED(operation); + return false; +} +#else +#if TMC5160_ENABLE_TMC_CACHE == 1 +uint8_t tmc5160_dirtyBits[TMC5160_IC_CACHE_COUNT][TMC5160_REGISTER_COUNT / 8] = {0}; +int32_t tmc5160_shadowRegister[TMC5160_IC_CACHE_COUNT][TMC5160_REGISTER_COUNT]; + +void tmc5160_setDirtyBit(uint16_t icID, uint8_t index, bool value) +{ + if (index >= TMC5160_REGISTER_COUNT) + return; + + uint8_t *tmp = &tmc5160_dirtyBits[icID][index / 8]; + uint8_t shift = (index % 8); + uint8_t mask = 1 << shift; + *tmp = (((*tmp) & (~(mask))) | (((value) << (shift)) & (mask))); +} + +bool tmc5160_getDirtyBit(uint16_t icID, uint8_t index) +{ + if (index >= TMC5160_REGISTER_COUNT) + return false; + + uint8_t *tmp = &tmc5160_dirtyBits[icID][index / 8]; + uint8_t shift = (index % 8); + return ((*tmp) >> shift) & 1; +} + +/* + * This function is used to cache the value written to the Write-Only registers in the form of shadow array. + * The shadow copy is then used to read these kinds of registers. + */ +bool tmc5160_cache(uint16_t icID, TMC5160CacheOp operation, uint8_t address, uint32_t *value) +{ + if (operation == TMC5160_CACHE_READ) + { + // Check if the value should come from cache + + // Only supported chips have a cache + if (icID >= TMC5160_IC_CACHE_COUNT) + return false; + + // Only non-readable registers care about caching + // Note: This could also be used to cache i.e. RW config registers to reduce bus accesses + if (TMC5160_IS_READABLE(tmc5160_registerAccess[address])) + return false; + + // Grab the value from the cache + *value = tmc5160_shadowRegister[icID][address]; + return true; + } + else if (operation == TMC5160_CACHE_WRITE || operation == TMC5160_CACHE_FILL_DEFAULT) + { + // Fill the cache + + // only supported chips have a cache + if (icID >= TMC5160_IC_CACHE_COUNT) + return false; + + // Write to the shadow register and mark the register dirty + tmc5160_shadowRegister[icID][address] = *value; + if (operation == TMC5160_CACHE_WRITE) + { + tmc5160_setDirtyBit(icID, address, true); + } + return true; + } + return false; +} +void tmc5160_initCache() +{ + // Check if we have constants defined + if (ARRAY_SIZE(tmc5160_RegisterConstants) == 0) + return; + + size_t i, j, id; + + for (i = 0, j = 0; i < TMC5160_REGISTER_COUNT; i++) + { + // We only need to worry about hardware preset, write-only registers + // that have not yet been written (no dirty bit) here. + if (tmc5160_registerAccess[i] != TMC5160_ACCESS_W_PRESET) + continue; + + // Search the constant list for the current address. With the constant + // list being sorted in ascended order, we can walk through the list + // until the entry with an address equal or greater than i + while (j < ARRAY_SIZE(tmc5160_RegisterConstants) && (tmc5160_RegisterConstants[j].address < i)) + j++; + + // Abort when we reach the end of the constant list + if (j == ARRAY_SIZE(tmc5160_RegisterConstants)) + break; + + // If we have an entry for our current address, write the constant + if (tmc5160_RegisterConstants[j].address == i) + { + for (id = 0; id < TMC5160_IC_CACHE_COUNT; id++) + { + uint32_t temp = tmc5160_RegisterConstants[j].value; + tmc5160_cache(id, TMC5160_CACHE_FILL_DEFAULT, i, &temp); + } + } + } +} +#else +// User must implement their own cache +extern bool tmc5160_cache(uint16_t icID, TMC5160CacheOp operation, uint8_t address, uint32_t *value); +#endif +#endif +/************************************************************** Register read / write Implementation ******************************************************************/ +static int32_t readRegisterSPI(uint16_t icID, uint8_t address); +static void writeRegisterSPI(uint16_t icID, uint8_t address, int32_t value); +// static int32_t readRegisterUART(uint16_t icID, uint8_t registerAddress); +// static void writeRegisterUART(uint16_t icID, uint8_t registerAddress, int32_t value); +static uint8_t CRC8(uint8_t *data, uint32_t bytes); + +int32_t tmc5160_readRegister(uint16_t icID, uint8_t address) +{ + uint32_t value; + + // Read from cache for registers with write-only access + if (tmc5160_cache(icID, TMC5160_CACHE_READ, address, &value)) + return value; + + TMC5160BusType bus = tmc5160_getBusType(icID); + + if (bus == IC_BUS_SPI) + { + return readRegisterSPI(icID, address); + } + else if (bus == IC_BUS_UART) + { + // return readRegisterUART(icID, address); + } + + // ToDo: Error handling + return -1; +} + +void tmc5160_writeRegister(uint16_t icID, uint8_t address, int32_t value) +{ + TMC5160BusType bus = tmc5160_getBusType(icID); + + if (bus == IC_BUS_SPI) + { + writeRegisterSPI(icID, address, value); + } + else if (bus == IC_BUS_UART) + { + // writeRegisterUART(icID, address, value); + } +} + +int32_t readRegisterSPI(uint16_t icID, uint8_t address) +{ + uint8_t data[5] = {0}; + + address = address & TMC5160_ADDRESS_MASK; + + // clear write bit + data[0] = address; + + // Send the read request + tmc5160_readWriteSPI(icID, &data[0], sizeof(data)); + + // Rewrite address and clear write bit + data[0] = address; + + // Send another request to receive the read reply + tmc5160_readWriteSPI(icID, &data[0], sizeof(data)); + + return ((int32_t)data[1] << 24) | + ((int32_t)data[2] << 16) | + ((int32_t)data[3] << 8) | // Added cast + ((int32_t)data[4]); +} + +void writeRegisterSPI(uint16_t icID, uint8_t address, int32_t value) +{ + uint8_t data[5] = {0}; + + data[0] = address | TMC5160_WRITE_BIT; + data[1] = 0xFF & (value >> 24); + data[2] = 0xFF & (value >> 16); + data[3] = 0xFF & (value >> 8); + data[4] = 0xFF & (value >> 0); + + // Send the write request + tmc5160_readWriteSPI(icID, &data[0], sizeof(data)); + + // Cache the registers with write-only access + tmc5160_cache(icID, TMC5160_CACHE_WRITE, address, (uint32_t *)&value); +} + +/* int32_t readRegisterUART(uint16_t icID, uint8_t address) +{ + uint8_t data[8] = { 0 }; + + address = address & TMC5160_ADDRESS_MASK; + data[0] = 0x05; + //data[1] = tmc5160_getNodeAddress(icID); //targetAddressUart; + data[2] = address; + data[3] = CRC8(data, 3); + + if (!tmc5160_readWriteUART(icID, &data[0], 4, 8)) + return 0; + + // Byte 0: Sync nibble correct? + if (data[0] != 0x05) + return 0; + + // Byte 1: Master address correct? + if (data[1] != 0xFF) + return 0; + + // Byte 2: Address correct? + if (data[2] != address) + return 0; + + // Byte 7: CRC correct? + if (data[7] != CRC8(data, 7)) + return 0; + + return ((uint32_t)data[3] << 24) | ((uint32_t)data[4] << 16) | (data[5] << 8) | data[6]; +} + +void writeRegisterUART(uint16_t icID, uint8_t address, int32_t value) +{ + uint8_t data[8]; + + data[0] = 0x05; + data[1] = tmc5160_getNodeAddress(icID); //targetAddressUart; + data[2] = address | TMC5160_WRITE_BIT; + data[3] = (value >> 24) & 0xFF; + data[4] = (value >> 16) & 0xFF; + data[5] = (value >> 8 ) & 0xFF; + data[6] = (value ) & 0xFF; + data[7] = CRC8(data, 7); + + tmc5160_readWriteUART(icID, &data[0], 8, 0); + + //Cache the registers with write-only access + tmc5160_cache(icID, TMC5160_CACHE_WRITE, address, (uint32_t *)&value); +} */ + +void tmc5160_rotateMotor(uint16_t icID, int32_t velocity) +{ + tmc5160_writeRegister(icID, TMC5160_VMAX, (velocity >= 0) ? velocity : -velocity); + tmc5160_fieldWrite(icID, TMC5160_RAMPMODE_FIELD, (velocity >= 0) ? TMC5160_MODE_VELPOS : TMC5160_MODE_VELNEG); +} + +void tmc5160_moveTo(uint16_t icID, int32_t pos, int32_t velocity) +{ + tmc5160_writeRegister(icID, TMC5160_RAMPMODE, TMC5160_MODE_POSITION); + tmc5160_writeRegister(icID, TMC5160_VMAX, velocity); + tmc5160_writeRegister(icID, TMC5160_XTARGET, pos); +} + +static uint8_t CRC8(uint8_t *data, uint32_t bytes) +{ + uint8_t result = 0; + while (bytes--) + result = tmcCRCTable_Poly7Reflected[result ^ *data++]; + + // Flip the result around + // swap odd and even bits + result = ((result >> 1) & 0x55) | ((result & 0x55) << 1); + // swap consecutive pairs + result = ((result >> 2) & 0x33) | ((result & 0x33) << 2); + // swap nibbles ... + result = ((result >> 4) & 0x0F) | ((result & 0x0F) << 4); + + return result; +} diff --git a/firmware/lib/tmc/src/TMC5160.h b/firmware/lib/tmc/src/TMC5160.h new file mode 100755 index 0000000..6f94207 --- /dev/null +++ b/firmware/lib/tmc/src/TMC5160.h @@ -0,0 +1,374 @@ +/******************************************************************************* + * Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG + * (now owned by Analog Devices Inc.), + * + * Copyright © 2024 Analog Devices Inc. All Rights Reserved. + * This software is proprietary to Analog Devices, Inc. and its licensors. + *******************************************************************************/ + +#ifndef TMC_IC_TMC5160_H_ +#define TMC_IC_TMC5160_H_ + +#include "TMC5160_HW_Abstraction.h" +#include +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + + /******************************************************************************* + * API Configuration Defines + * These control optional features of the TMC-API implementation. + * These can be commented in/out here or defined from the build system. + *******************************************************************************/ + + // Uncomment if you want to save space..... + // and put the table into your own .c file + // #define TMC_API_EXTERNAL_CRC_TABLE 1 + +#ifndef TMC5160_CACHE +#define TMC5160_CACHE 1 +// #define TMC5160_CACHE 0 +#endif + +// To use the caching mechanism already implemented by the TMC-API, set TMC5160_ENABLE_TMC_CACHE to '1'. +// Set TMC5160_ENABLE_TMC_CACHE to '0' if one wants to have their own cache implementation. +#ifndef TMC5160_ENABLE_TMC_CACHE +#define TMC5160_ENABLE_TMC_CACHE 1 +// #define TMC5160_ENABLE_TMC_CACHE 0 +#endif + + /******************************************************************************/ + + typedef enum + { + IC_BUS_SPI, + IC_BUS_UART, + } TMC5160BusType; + + typedef struct + { + uint32_t mask; + uint8_t shift; + uint8_t address; + bool isSigned; + } RegisterField; + + // => TMC-API wrapper + extern void tmc5160_readWriteSPI(uint16_t icID, uint8_t *data, size_t dataLength); + extern bool tmc5160_readWriteUART(uint16_t icID, uint8_t *data, size_t writeLength, size_t readLength); + extern TMC5160BusType tmc5160_getBusType(uint16_t icID); + // extern uint8_t tmc5160_getNodeAddress(uint16_t icID); + // => TMC-API wrapper + + int32_t tmc5160_readRegister(uint16_t icID, uint8_t address); + void tmc5160_writeRegister(uint16_t icID, uint8_t address, int32_t value); + void tmc5160_rotateMotor(uint16_t icID, int32_t velocity); + void tmc5160_moveTo(uint16_t icID, int32_t pos,int32_t velocity); + static inline uint32_t tmc5160_fieldExtract(uint32_t data, RegisterField field) + { + uint32_t value = (data & field.mask) >> field.shift; + + if (field.isSigned) + { + // Apply signedness conversion + uint32_t baseMask = field.mask >> field.shift; + uint32_t signMask = baseMask & (~baseMask >> 1); + value = (value ^ signMask) - signMask; + } + + return value; + } + + static inline uint32_t tmc5160_fieldRead(uint16_t icID, RegisterField field) + { + uint32_t value = tmc5160_readRegister(icID, field.address); + + return tmc5160_fieldExtract(value, field); + } + + static inline uint32_t tmc5160_fieldUpdate(uint32_t data, RegisterField field, uint32_t value) + { + return (data & (~field.mask)) | ((value << field.shift) & field.mask); + } + + static inline void tmc5160_fieldWrite(uint16_t icID, RegisterField field, uint32_t value) + { + uint32_t regValue = tmc5160_readRegister(icID, field.address); + + regValue = tmc5160_fieldUpdate(regValue, field, value); + + tmc5160_writeRegister(icID, field.address, regValue); + } + + /**************************************************************** Cache Implementation *************************************************************************/ + +#if TMC5160_CACHE == 1 +#if TMC5160_ENABLE_TMC_CACHE == 1 + +// By default, support one IC in the cache +#ifndef TMC5160_IC_CACHE_COUNT +#define TMC5160_IC_CACHE_COUNT 2 +#endif + + typedef enum + { + TMC5160_CACHE_READ, + TMC5160_CACHE_WRITE, + + // Special operation: Put content into the cache without marking the entry as dirty. + // Only used to initialize the cache with hardware defaults. This will allow reading + // from write-only registers that have a value inside them on reset. When using this + // operation, a restore will *not* rewrite that filled register! + TMC5160_CACHE_FILL_DEFAULT + + } TMC5160CacheOp; + + typedef struct + { + uint8_t address; + uint32_t value; + } TMC5160RegisterConstants; + +#define TMC5160_ACCESS_DIRTY 0x08 // Register has been written since reset -> shadow register is valid for restore +#define TMC5160_ACCESS_READ 0x01 +#define TMC5160_ACCESS_W_PRESET 0x42 +#define TMC5160_IS_READABLE(x) ((x) & TMC5160_ACCESS_READ) +#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) + +// Default Register values +#define R00 0x0000000C // GCONF +#define R09 0x00010606 // SHORTCONF +#define R0A 0x00080400 // DRVCONF +#define R0B 100 // GLOBALSCALER +#define R10 0x00071F08 // IHOLD_IRUN +#define R11 0x00000008 // TPOWERDOWN +#define R13 0 // TPWMTHRS +#define R14 0 // TCOOLTHRS +#define R15 0 // THIGH +#define R21 500000 // Act Position +#define R24 0 // A1 +#define R26 0 // AMAX +#define R25 0x00000000 // V1 +#define R27 500000 // VMAX +#define R28 0 // DMAX +#define R2A 0 // D1 +#define R2B 0x00000100 // VSTOP +#define R2D 500000 // targetPos +#define R34 0x085F // Binary: 0000 1000 0101 1111 // SWMODE +#define R38 0x400 // Set Decimal Encoder Const (0x400) or off (0x00) +#define R39 500000 // XENC +#define R3A 0x000C1F40 // ENC_CONST 0x000C1388 bei 4096pps und 0x000C1F40 +#define R3D 1000 // ENC Deviation Write ONLY +#define R6C 0x00410043 // CHOPCONF +#define R6D 0x00000000 // COOLCONF +#define R70 0x010C1E3C // PWMCONF + +#define ____ 0x00 +#ifndef N_A +#define N_A 0x00 +#endif + + static const int32_t tmc5160_sampleRegisterPreset[TMC5160_REGISTER_COUNT] = + { + // 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F + R00, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + R09, + R0A, + R0B, + 0, + 0, + 0, + 0, // 0x00 - 0x0F + R10, + R11, + 0, + R13, + R14, + R15, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, // 0x10 - 0x1F + 0, + R21, + 0, + 0, + R24, + R25, + R26, + R27, + R28, + 0, + R2A, + R2B, + 0, + R2D, + 0, + 0, // 0x20 - 0x2F + 0, + 0, + 0, + 0, + R34, + 0, + 0, + 0, + R38, + R39, + R3A, + 0, + 0, + R3D, + 0, + 0, // 0x30 - 0x3F + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, // 0x40 - 0x4F + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, // 0x50 - 0x5F + N_A, + N_A, + N_A, + N_A, + N_A, + N_A, + N_A, + N_A, + N_A, + N_A, + 0, + 0, + R6C, + R6D, + 0, + 0, // 0x60 - 0x6F + R70, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, // 0x70 - 0x7F + }; + +// Undefine the default register values. +// This prevents warnings in case multiple TMC-API chip headers are included at once +#undef R00 +#undef R09 +#undef R0A +#undef R10 +#undef R11 +#undef R2B +#undef R3A +#undef R6C +#undef R70 + + // Register access permissions: + // 0x00: none (reserved) + // 0x01: read + // 0x02: write + // 0x03: read/write + // 0x13: read/write, separate functions/values for reading or writing + // 0x23: read/write, flag register (write to clear) + // 0x42: write, has hardware presets on reset + static const uint8_t tmc5160_registerAccess[TMC5160_REGISTER_COUNT] = + { + // 0 1 2 3 4 5 6 7 8 9 A B C D E F + 0x03, 0x23, 0x01, 0x02, 0x13, 0x02, 0x02, 0x01, 0x03, 0x02, 0x02, 0x02, 0x01, ____, ____, ____, // 0x00 - 0x0F + 0x02, 0x02, 0x01, 0x02, 0x02, 0x02, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x10 - 0x1F + 0x03, 0x03, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, ____, 0x02, 0x02, 0x02, 0x03, ____, ____, // 0x20 - 0x2F + ____, ____, ____, 0x02, 0x03, 0x23, 0x01, ____, 0x03, 0x03, 0x02, 0x23, 0x01, 0x02, ____, ____, // 0x30 - 0x3F + ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x40 - 0x4F + ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, // 0x50 - 0x5F + 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x01, 0x01, 0x03, 0x02, 0x02, 0x01, // 0x60 - 0x6F + 0x42, 0x01, 0x01, 0x01, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____ // 0x70 - 0x7F + }; + + // Register constants (only required for 0x42 registers, since we do not have + // any way to find out the content but want to hold the actual value in the + // shadow register so an application (i.e. the TMCL IDE) can still display + // the values. This only works when the register content is constant. + static const TMC5160RegisterConstants tmc5160_RegisterConstants[] = + { + // Use ascending addresses! + {0x60, 0xAAAAB554}, // MSLUT[0] + {0x61, 0x4A9554AA}, // MSLUT[1] + {0x62, 0x24492929}, // MSLUT[2] + {0x63, 0x10104222}, // MSLUT[3] + {0x64, 0xFBFFFFFF}, // MSLUT[4] + {0x65, 0xB5BB777D}, // MSLUT[5] + {0x66, 0x49295556}, // MSLUT[6] + {0x67, 0x00404222}, // MSLUT[7] + {0x68, 0xFFFF8056}, // MSLUTSEL + {0x69, 0x00F70000}, // MSLUTSTART + {0x70, 0xC40C001E} // PWMCONF + }; + + extern uint8_t tmc5160_dirtyBits[TMC5160_IC_CACHE_COUNT][TMC5160_REGISTER_COUNT / 8]; + extern int32_t tmc5160_shadowRegister[TMC5160_IC_CACHE_COUNT][TMC5160_REGISTER_COUNT]; + void tmc5160_setDirtyBit(uint16_t icID, uint8_t index, bool value); + bool tmc5160_getDirtyBit(uint16_t icID, uint8_t index); + extern bool tmc5160_cache(uint16_t icID, TMC5160CacheOp operation, uint8_t address, uint32_t *value); + void tmc5160_initCache(void); +#endif +#endif + +/***************************************************************************************************************************************************/ +#ifdef __cplusplus +} +#endif +#endif /* TMC_IC_TMC5160_H_ */ diff --git a/firmware/lib/tmc/src/TMC5160_HW_Abstraction.h b/firmware/lib/tmc/src/TMC5160_HW_Abstraction.h new file mode 100755 index 0000000..722847e --- /dev/null +++ b/firmware/lib/tmc/src/TMC5160_HW_Abstraction.h @@ -0,0 +1,1619 @@ +/******************************************************************************* +* Copyright © 2019 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2024 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + +#ifndef TMC5160_HW_ABSTRACTION +#define TMC5160_HW_ABSTRACTION + +// constants + +#define TMC5160_REGISTER_COUNT 128 +#define TMC5160_MOTORS 1 +#define TMC5160_WRITE_BIT 0x80 +#define TMC5160_ADDRESS_MASK 0x7F +#define TMC5160_MAX_VELOCITY 8388096 +#define TMC5160_MAX_ACCELERATION 65535 + +// ramp modes (Register TMC5160_RAMPMODE) +#define TMC5160_MODE_POSITION 0 +#define TMC5160_MODE_VELPOS 1 +#define TMC5160_MODE_VELNEG 2 +#define TMC5160_MODE_HOLD 3 + +// limit switch mode bits (Register TMC5160_SWMODE) +#define TMC5160_SW_STOPL_ENABLE 0x0001 +#define TMC5160_SW_STOPR_ENABLE 0x0002 +#define TMC5160_SW_STOPL_POLARITY 0x0004 +#define TMC5160_SW_STOPR_POLARITY 0x0008 +#define TMC5160_SW_SWAP_LR 0x0010 +#define TMC5160_SW_LATCH_L_ACT 0x0020 +#define TMC5160_SW_LATCH_L_INACT 0x0040 +#define TMC5160_SW_LATCH_R_ACT 0x0080 +#define TMC5160_SW_LATCH_R_INACT 0x0100 +#define TMC5160_SW_LATCH_ENC 0x0200 +#define TMC5160_SW_SG_STOP 0x0400 +#define TMC5160_SW_SOFTSTOP 0x0800 + +// Status bits (Register TMC5160_RAMPSTAT) +#define TMC5160_RS_STOPL 0x0001 +#define TMC5160_RS_STOPR 0x0002 +#define TMC5160_RS_LATCHL 0x0004 +#define TMC5160_RS_LATCHR 0x0008 +#define TMC5160_RS_EV_STOPL 0x0010 +#define TMC5160_RS_EV_STOPR 0x0020 +#define TMC5160_RS_EV_STOP_SG 0x0040 +#define TMC5160_RS_EV_POSREACHED 0x0080 +#define TMC5160_RS_VELREACHED 0x0100 +#define TMC5160_RS_POSREACHED 0x0200 +#define TMC5160_RS_VZERO 0x0400 +#define TMC5160_RS_ZEROWAIT 0x0800 +#define TMC5160_RS_SECONDMOVE 0x1000 +#define TMC5160_RS_SG 0x2000 + +// Encoderbits (Register TMC5160_ENCMODE) +#define TMC5160_EM_DECIMAL 0x0400 +#define TMC5160_EM_LATCH_XACT 0x0200 +#define TMC5160_EM_CLR_XENC 0x0100 +#define TMC5160_EM_NEG_EDGE 0x0080 +#define TMC5160_EM_POS_EDGE 0x0040 +#define TMC5160_EM_CLR_ONCE 0x0020 +#define TMC5160_EM_CLR_CONT 0x0010 +#define TMC5160_EM_IGNORE_AB 0x0008 +#define TMC5160_EM_POL_N 0x0004 +#define TMC5160_EM_POL_B 0x0002 +#define TMC5160_EM_POL_A 0x0001 + + +// Registers in TMC5160 + +#define TMC5160_GCONF 0x00 +#define TMC5160_GSTAT 0x01 +#define TMC5160_IFCNT 0x02 +#define TMC5160_SLAVECONF 0x03 +#define TMC5160_INP_OUT 0x04 +#define TMC5160_X_COMPARE 0x05 +#define TMC5160_OTP_PROG 0x06 +#define TMC5160_OTP_READ 0x07 +#define TMC5160_FACTORY_CONF 0x08 +#define TMC5160_SHORT_CONF 0x09 +#define TMC5160_DRV_CONF 0x0A +#define TMC5160_GLOBAL_SCALER 0x0B +#define TMC5160_OFFSET_READ 0x0C +#define TMC5160_IHOLD_IRUN 0x10 +#define TMC5160_TPOWERDOWN 0x11 +#define TMC5160_TSTEP 0x12 +#define TMC5160_TPWMTHRS 0x13 +#define TMC5160_TCOOLTHRS 0x14 +#define TMC5160_THIGH 0x15 + +#define TMC5160_RAMPMODE 0x20 +#define TMC5160_XACTUAL 0x21 +#define TMC5160_VACTUAL 0x22 +#define TMC5160_VSTART 0x23 +#define TMC5160_A1 0x24 +#define TMC5160_V1 0x25 +#define TMC5160_AMAX 0x26 +#define TMC5160_VMAX 0x27 +#define TMC5160_DMAX 0x28 +#define TMC5160_D1 0x2A +#define TMC5160_VSTOP 0x2B +#define TMC5160_TZEROWAIT 0x2C +#define TMC5160_XTARGET 0x2D + +#define TMC5160_VDCMIN 0x33 +#define TMC5160_SWMODE 0x34 +#define TMC5160_RAMPSTAT 0x35 +#define TMC5160_XLATCH 0x36 +#define TMC5160_ENCMODE 0x38 +#define TMC5160_XENC 0x39 +#define TMC5160_ENC_CONST 0x3A +#define TMC5160_ENC_STATUS 0x3B +#define TMC5160_ENC_LATCH 0x3C +#define TMC5160_ENC_DEVIATION 0x3D + +#define TMC5160_MSLUT0 0x60 +#define TMC5160_MSLUT1 0x61 +#define TMC5160_MSLUT2 0x62 +#define TMC5160_MSLUT3 0x63 +#define TMC5160_MSLUT4 0x64 +#define TMC5160_MSLUT5 0x65 +#define TMC5160_MSLUT6 0x66 +#define TMC5160_MSLUT7 0x67 +#define TMC5160_MSLUTSEL 0x68 +#define TMC5160_MSLUTSTART 0x69 +#define TMC5160_MSCNT 0x6A +#define TMC5160_MSCURACT 0x6B +#define TMC5160_CHOPCONF 0x6C +#define TMC5160_COOLCONF 0x6D +#define TMC5160_DCCTRL 0x6E +#define TMC5160_DRV_STATUS 0x6F +#define TMC5160_PWMCONF 0x70 +#define TMC5160_PWM_SCALE 0x71 +#define TMC5160_PWM_AUTO 0x72 +#define TMC5160_LOST_STEPS 0x73 + + +// Fields in TMC5160 + +// Status fields returned with every SPI transaction +#define TMC5160_SPI_STATUS_RESET_FLAG_MASK 0x01 /* GSTAT0 - 1: Signals, that a reset has occurred (clear by reading GSTAT) */ +#define TMC5160_SPI_STATUS_RESET_FLAG_SHIFT 0 +#define TMC5160_SPI_STATUS_RESET_FLAG_FIELD ((RegisterField) {TMC5160_SPI_STATUS_RESET_FLAG_MASK, TMC5160_SPI_STATUS_RESET_FLAG_SHIFT, TMC5160_GSTAT, false}) +#define TMC5160_SPI_STATUS_DRIVER_ERROR_MASK 0x02 /* GSTAT1 – 1: Signals driver 1 driver error (clear by reading GSTAT) */ +#define TMC5160_SPI_STATUS_DRIVER_ERROR_SHIFT 1 +#define TMC5160_SPI_STATUS_DRIVER_ERROR_FIELD ((RegisterField) {TMC5160_SPI_STATUS_DRIVER_ERROR_MASK, TMC5160_SPI_STATUS_DRIVER_ERROR_SHIFT, TMC5160_GSTAT, false}) +#define TMC5160_SPI_STATUS_SG2_MASK 0x04 /* DRV_STATUS[24] – 1: Signals StallGuard flag active */ +#define TMC5160_SPI_STATUS_SG2_SHIFT 2 +#define TMC5160_SPI_STATUS_SG2_FIELD ((RegisterField) {TMC5160_SPI_STATUS_SG2_MASK, TMC5160_SPI_STATUS_SG2_SHIFT, TMC5160_DRV_STATUS, false}) +#define TMC5160_SPI_STATUS_STANDSTILL_MASK 0x08 /* DRV_STATUS[31] – 1: Signals motor stand still */ +#define TMC5160_SPI_STATUS_STANDSTILL_SHIFT 3 +#define TMC5160_SPI_STATUS_STANDSTILL_FIELD ((RegisterField) {TMC5160_SPI_STATUS_STANDSTILL_MASK, TMC5160_SPI_STATUS_STANDSTILL_SHIFT, TMC5160_DRV_STATUS, false}) +#define TMC5160_SPI_STATUS_VELOCITY_REACHED_MASK 0x10 /* RAMPSTAT[8] – 1: Signals target velocity reached (motion controller only) */ +#define TMC5160_SPI_STATUS_VELOCITY_REACHED_SHIFT 4 +#define TMC5160_SPI_STATUS_VELOCITY_REACHED_FIELD ((RegisterField) {TMC5160_SPI_STATUS_VELOCITY_REACHED_MASK, TMC5160_SPI_STATUS_VELOCITY_REACHED_SHIFT, TMC5160_RAMPSTAT, false}) +#define TMC5160_SPI_STATUS_POSITION_REACHED_MASK 0x20 /* RAMPSTAT[9] – 1: Signals target position reached (motion controller only) */ +#define TMC5160_SPI_STATUS_POSITION_REACHED_SHIFT 5 +#define TMC5160_SPI_STATUS_POSITION_REACHED_FIELD ((RegisterField) {TMC5160_SPI_STATUS_POSITION_REACHED_MASK, TMC5160_SPI_STATUS_POSITION_REACHED_SHIFT, TMC5160_RAMPSTAT, false}) +#define TMC5160_SPI_STATUS_STATUS_STOP_L_MASK 0x40 /* RAMPSTAT0 – 1: Signals stop left switch status (motion controller only) */ +#define TMC5160_SPI_STATUS_STATUS_STOP_L_SHIFT 6 +#define TMC5160_SPI_STATUS_STATUS_STOP_L_FIELD ((RegisterField) {TMC5160_SPI_STATUS_STATUS_STOP_L_MASK, TMC5160_SPI_STATUS_STATUS_STOP_L_SHIFT, TMC5160_RAMPSTAT, false}) +#define TMC5160_SPI_STATUS_STATUS_STOP_R_MASK 0x80 /* RAMPSTAT1 – 1: Signals stop right switch status (motion controller only) */ +#define TMC5160_SPI_STATUS_STATUS_STOP_R_SHIFT 7 +#define TMC5160_SPI_STATUS_STATUS_STOP_R_FIELD ((RegisterField) {TMC5160_SPI_STATUS_STATUS_STOP_R_MASK, TMC5160_SPI_STATUS_STATUS_STOP_R_SHIFT, TMC5160_RAMPSTAT, false}) + +// Register fields in TMC5160 +#define TMC5160_RECALIBRATE_MASK 0x00000001 +#define TMC5160_RECALIBRATE_SHIFT 0 +#define TMC5160_RECALIBRATE_FIELD ((RegisterField) {TMC5160_RECALIBRATE_MASK, TMC5160_RECALIBRATE_SHIFT, TMC5160_GCONF, false}) +#define TMC5160_FASTSTANDSTILL_MASK 0x00000002 +#define TMC5160_FASTSTANDSTILL_SHIFT 1 +#define TMC5160_FASTSTANDSTILL_FIELD ((RegisterField) {TMC5160_FASTSTANDSTILL_MASK, TMC5160_FASTSTANDSTILL_SHIFT, TMC5160_GCONF, false}) +#define TMC5160_EN_PWM_MODE_MASK 0x00000004 +#define TMC5160_EN_PWM_MODE_SHIFT 2 +#define TMC5160_EN_PWM_MODE_FIELD ((RegisterField) {TMC5160_EN_PWM_MODE_MASK, TMC5160_EN_PWM_MODE_SHIFT, TMC5160_GCONF, false}) +#define TMC5160_MULTISTEP_FILT_MASK 0x00000008 +#define TMC5160_MULTISTEP_FILT_SHIFT 3 +#define TMC5160_MULTISTEP_FILT_FIELD ((RegisterField) {TMC5160_MULTISTEP_FILT_MASK, TMC5160_MULTISTEP_FILT_SHIFT, TMC5160_GCONF, false}) +#define TMC5160_SHAFT_MASK 0x00000010 +#define TMC5160_SHAFT_SHIFT 4 +#define TMC5160_SHAFT_FIELD ((RegisterField) {TMC5160_SHAFT_MASK, TMC5160_SHAFT_SHIFT, TMC5160_GCONF, false}) +#define TMC5160_DIAG0_ERROR__ONLY_WITH_SD_MODE_1__MASK 0x00000020 +#define TMC5160_DIAG0_ERROR__ONLY_WITH_SD_MODE_1__SHIFT 5 +#define TMC5160_DIAG0_ERROR__ONLY_WITH_SD_MODE_1__FIELD ((RegisterField) {TMC5160_DIAG0_ERROR__ONLY_WITH_SD_MODE_1__MASK, TMC5160_DIAG0_ERROR__ONLY_WITH_SD_MODE_1__SHIFT, TMC5160_GCONF, false}) +#define TMC5160_DIAG0_OTPW__ONLY_WITH_SD_MODE_1__MASK 0x00000040 +#define TMC5160_DIAG0_OTPW__ONLY_WITH_SD_MODE_1__SHIFT 6 +#define TMC5160_DIAG0_OTPW__ONLY_WITH_SD_MODE_1__FIELD ((RegisterField) {TMC5160_DIAG0_OTPW__ONLY_WITH_SD_MODE_1__MASK, TMC5160_DIAG0_OTPW__ONLY_WITH_SD_MODE_1__SHIFT, TMC5160_GCONF, false}) +#define TMC5160_DIAG0_STALL_MASK 0x00000080 +#define TMC5160_DIAG0_STALL_SHIFT 7 +#define TMC5160_DIAG0_STALL_FIELD ((RegisterField) {TMC5160_DIAG0_STALL_MASK, TMC5160_DIAG0_STALL_SHIFT, TMC5160_GCONF, false}) +#define TMC5160_DIAG1_STALL_MASK 0x00000100 +#define TMC5160_DIAG1_STALL_SHIFT 8 +#define TMC5160_DIAG1_STALL_FIELD ((RegisterField) {TMC5160_DIAG1_STALL_MASK, TMC5160_DIAG1_STALL_SHIFT, TMC5160_GCONF, false}) +#define TMC5160_DIAG1_INDEX_MASK 0x00000200 +#define TMC5160_DIAG1_INDEX_SHIFT 9 +#define TMC5160_DIAG1_INDEX_FIELD ((RegisterField) {TMC5160_DIAG1_INDEX_MASK, TMC5160_DIAG1_INDEX_SHIFT, TMC5160_GCONF, false}) +#define TMC5160_DIAG1_ONSTATE_MASK 0x00000400 +#define TMC5160_DIAG1_ONSTATE_SHIFT 10 +#define TMC5160_DIAG1_ONSTATE_FIELD ((RegisterField) {TMC5160_DIAG1_ONSTATE_MASK, TMC5160_DIAG1_ONSTATE_SHIFT, TMC5160_GCONF, false}) +#define TMC5160_DIAG1_STEPS_SKIPPED_MASK 0x00000800 +#define TMC5160_DIAG1_STEPS_SKIPPED_SHIFT 11 +#define TMC5160_DIAG1_STEPS_SKIPPED_FIELD ((RegisterField) {TMC5160_DIAG1_STEPS_SKIPPED_MASK, TMC5160_DIAG1_STEPS_SKIPPED_SHIFT, TMC5160_GCONF, false}) +#define TMC5160_DIAG0_INT_PUSHPULL_MASK 0x00001000 +#define TMC5160_DIAG0_INT_PUSHPULL_SHIFT 12 +#define TMC5160_DIAG0_INT_PUSHPULL_FIELD ((RegisterField) {TMC5160_DIAG0_INT_PUSHPULL_MASK, TMC5160_DIAG0_INT_PUSHPULL_SHIFT, TMC5160_GCONF, false}) +#define TMC5160_DIAG1_POSCOMP_PUSHPULL_MASK 0x00002000 +#define TMC5160_DIAG1_POSCOMP_PUSHPULL_SHIFT 13 +#define TMC5160_DIAG1_POSCOMP_PUSHPULL_FIELD ((RegisterField) {TMC5160_DIAG1_POSCOMP_PUSHPULL_MASK, TMC5160_DIAG1_POSCOMP_PUSHPULL_SHIFT, TMC5160_GCONF, false}) +#define TMC5160_SMALL_HYSTERESIS_MASK 0x00004000 +#define TMC5160_SMALL_HYSTERESIS_SHIFT 14 +#define TMC5160_SMALL_HYSTERESIS_FIELD ((RegisterField) {TMC5160_SMALL_HYSTERESIS_MASK, TMC5160_SMALL_HYSTERESIS_SHIFT, TMC5160_GCONF, false}) +#define TMC5160_STOP_ENABLE_MASK 0x00008000 +#define TMC5160_STOP_ENABLE_SHIFT 15 +#define TMC5160_STOP_ENABLE_FIELD ((RegisterField) {TMC5160_STOP_ENABLE_MASK, TMC5160_STOP_ENABLE_SHIFT, TMC5160_GCONF, false}) +#define TMC5160_DIRECT_MODE_MASK 0x00010000 +#define TMC5160_DIRECT_MODE_SHIFT 16 +#define TMC5160_DIRECT_MODE_FIELD ((RegisterField) {TMC5160_DIRECT_MODE_MASK, TMC5160_DIRECT_MODE_SHIFT, TMC5160_GCONF, false}) +#define TMC5160_TEST_MODE_MASK 0x00020000 +#define TMC5160_TEST_MODE_SHIFT 17 +#define TMC5160_TEST_MODE_FIELD ((RegisterField) {TMC5160_TEST_MODE_MASK, TMC5160_TEST_MODE_SHIFT, TMC5160_GCONF, false}) +#define TMC5160_RECALIBRATE_MASK 0x00000001 +#define TMC5160_RECALIBRATE_SHIFT 0 +#define TMC5160_RECALIBRATE_FIELD ((RegisterField) {TMC5160_RECALIBRATE_MASK, TMC5160_RECALIBRATE_SHIFT, TMC5160_GCONF, false}) +#define TMC5160_FASTSTANDSTILL_MASK 0x00000002 +#define TMC5160_FASTSTANDSTILL_SHIFT 1 +#define TMC5160_FASTSTANDSTILL_FIELD ((RegisterField) {TMC5160_FASTSTANDSTILL_MASK, TMC5160_FASTSTANDSTILL_SHIFT, TMC5160_GCONF, false}) +#define TMC5160_EN_PWM_MODE_MASK 0x00000004 +#define TMC5160_EN_PWM_MODE_SHIFT 2 +#define TMC5160_EN_PWM_MODE_FIELD ((RegisterField) {TMC5160_EN_PWM_MODE_MASK, TMC5160_EN_PWM_MODE_SHIFT, TMC5160_GCONF, false}) +#define TMC5160_MULTISTEP_FILT_MASK 0x00000008 +#define TMC5160_MULTISTEP_FILT_SHIFT 3 +#define TMC5160_MULTISTEP_FILT_FIELD ((RegisterField) {TMC5160_MULTISTEP_FILT_MASK, TMC5160_MULTISTEP_FILT_SHIFT, TMC5160_GCONF, false}) +#define TMC5160_SHAFT_MASK 0x00000010 +#define TMC5160_SHAFT_SHIFT 4 +#define TMC5160_SHAFT_FIELD ((RegisterField) {TMC5160_SHAFT_MASK, TMC5160_SHAFT_SHIFT, TMC5160_GCONF, false}) +#define TMC5160_DIAG0_STEP_MASK 0x00000080 +#define TMC5160_DIAG0_STEP_SHIFT 7 +#define TMC5160_DIAG0_STEP_FIELD ((RegisterField) {TMC5160_DIAG0_STEP_MASK, TMC5160_DIAG0_STEP_SHIFT, TMC5160_GCONF, false}) +#define TMC5160_DIAG1_DIR_MASK 0x00000100 +#define TMC5160_DIAG1_DIR_SHIFT 8 +#define TMC5160_DIAG1_DIR_FIELD ((RegisterField) {TMC5160_DIAG1_DIR_MASK, TMC5160_DIAG1_DIR_SHIFT, TMC5160_GCONF, false}) +#define TMC5160_DIAG0_INT_PUSHPULL_MASK 0x00001000 +#define TMC5160_DIAG0_INT_PUSHPULL_SHIFT 12 +#define TMC5160_DIAG0_INT_PUSHPULL_FIELD ((RegisterField) {TMC5160_DIAG0_INT_PUSHPULL_MASK, TMC5160_DIAG0_INT_PUSHPULL_SHIFT, TMC5160_GCONF, false}) +#define TMC5160_DIAG1_POSCOMP_PUSHPULL_MASK 0x00002000 +#define TMC5160_DIAG1_POSCOMP_PUSHPULL_SHIFT 13 +#define TMC5160_DIAG1_POSCOMP_PUSHPULL_FIELD ((RegisterField) {TMC5160_DIAG1_POSCOMP_PUSHPULL_MASK, TMC5160_DIAG1_POSCOMP_PUSHPULL_SHIFT, TMC5160_GCONF, false}) +#define TMC5160_SMALL_HYSTERESIS_MASK 0x00004000 +#define TMC5160_SMALL_HYSTERESIS_SHIFT 14 +#define TMC5160_SMALL_HYSTERESIS_FIELD ((RegisterField) {TMC5160_SMALL_HYSTERESIS_MASK, TMC5160_SMALL_HYSTERESIS_SHIFT, TMC5160_GCONF, false}) +#define TMC5160_STOP_ENABLE_MASK 0x00008000 +#define TMC5160_STOP_ENABLE_SHIFT 15 +#define TMC5160_STOP_ENABLE_FIELD ((RegisterField) {TMC5160_STOP_ENABLE_MASK, TMC5160_STOP_ENABLE_SHIFT, TMC5160_GCONF, false}) +#define TMC5160_DIRECT_MODE_MASK 0x00010000 +#define TMC5160_DIRECT_MODE_SHIFT 16 +#define TMC5160_DIRECT_MODE_FIELD ((RegisterField) {TMC5160_DIRECT_MODE_MASK, TMC5160_DIRECT_MODE_SHIFT, TMC5160_GCONF, false}) +#define TMC5160_TEST_MODE_MASK 0x00020000 +#define TMC5160_TEST_MODE_SHIFT 17 +#define TMC5160_TEST_MODE_FIELD ((RegisterField) {TMC5160_TEST_MODE_MASK, TMC5160_TEST_MODE_SHIFT, TMC5160_GCONF, false}) +#define TMC5160_RESET_MASK 0x00000001 +#define TMC5160_RESET_SHIFT 0 +#define TMC5160_RESET_FIELD ((RegisterField) {TMC5160_RESET_MASK, TMC5160_RESET_SHIFT, TMC5160_GSTAT, false}) +#define TMC5160_DRV_ERR_MASK 0x00000002 +#define TMC5160_DRV_ERR_SHIFT 1 +#define TMC5160_DRV_ERR_FIELD ((RegisterField) {TMC5160_DRV_ERR_MASK, TMC5160_DRV_ERR_SHIFT, TMC5160_GSTAT, false}) +#define TMC5160_UV_CP_MASK 0x00000004 +#define TMC5160_UV_CP_SHIFT 2 +#define TMC5160_UV_CP_FIELD ((RegisterField) {TMC5160_UV_CP_MASK, TMC5160_UV_CP_SHIFT, TMC5160_GSTAT, false}) +#define TMC5160_IFCNT_MASK 0x000000FF +#define TMC5160_IFCNT_SHIFT 0 +#define TMC5160_IFCNT_FIELD ((RegisterField) {TMC5160_IFCNT_MASK, TMC5160_IFCNT_SHIFT, TMC5160_IFCNT, false}) +#define TMC5160_SLAVEADDR_MASK 0x000000FF +#define TMC5160_SLAVEADDR_SHIFT 0 +#define TMC5160_SLAVEADDR_FIELD ((RegisterField) {TMC5160_SLAVEADDR_MASK, TMC5160_SLAVEADDR_SHIFT, TMC5160_SLAVECONF, false}) +#define TMC5160_SENDDELAY_MASK 0x00000F00 +#define TMC5160_SENDDELAY_SHIFT 8 +#define TMC5160_SENDDELAY_FIELD ((RegisterField) {TMC5160_SENDDELAY_MASK, TMC5160_SENDDELAY_SHIFT, TMC5160_SLAVECONF, false}) +#define TMC5160_REFL_STEP_MASK 0x00000001 +#define TMC5160_REFL_STEP_SHIFT 0 +#define TMC5160_REFL_STEP_FIELD ((RegisterField) {TMC5160_REFL_STEP_MASK, TMC5160_REFL_STEP_SHIFT, TMC5160_INP_OUT, false}) +#define TMC5160_REFR_DIR_MASK 0x00000002 +#define TMC5160_REFR_DIR_SHIFT 1 +#define TMC5160_REFR_DIR_FIELD ((RegisterField) {TMC5160_REFR_DIR_MASK, TMC5160_REFR_DIR_SHIFT, TMC5160_INP_OUT, false}) +#define TMC5160_ENCB_DCEN_CFG4_MASK 0x00000004 +#define TMC5160_ENCB_DCEN_CFG4_SHIFT 2 +#define TMC5160_ENCB_DCEN_CFG4_FIELD ((RegisterField) {TMC5160_ENCB_DCEN_CFG4_MASK, TMC5160_ENCB_DCEN_CFG4_SHIFT, TMC5160_INP_OUT, false}) +#define TMC5160_ENCA_DCIN_CFG5_MASK 0x00000008 +#define TMC5160_ENCA_DCIN_CFG5_SHIFT 3 +#define TMC5160_ENCA_DCIN_CFG5_FIELD ((RegisterField) {TMC5160_ENCA_DCIN_CFG5_MASK, TMC5160_ENCA_DCIN_CFG5_SHIFT, TMC5160_INP_OUT, false}) +#define TMC5160_DRV_ENN_CFG6_MASK 0x00000010 +#define TMC5160_DRV_ENN_CFG6_SHIFT 4 +#define TMC5160_DRV_ENN_CFG6_FIELD ((RegisterField) {TMC5160_DRV_ENN_CFG6_MASK, TMC5160_DRV_ENN_CFG6_SHIFT, TMC5160_INP_OUT, false}) +#define TMC5160_ENC_N_DCO_MASK 0x00000020 +#define TMC5160_ENC_N_DCO_SHIFT 5 +#define TMC5160_ENC_N_DCO_FIELD ((RegisterField) {TMC5160_ENC_N_DCO_MASK, TMC5160_ENC_N_DCO_SHIFT, TMC5160_INP_OUT, false}) +#define TMC5160_SD_MODE_MASK 0x00000040 +#define TMC5160_SD_MODE_SHIFT 6 +#define TMC5160_SD_MODE_FIELD ((RegisterField) {TMC5160_SD_MODE_MASK, TMC5160_SD_MODE_SHIFT, TMC5160_INP_OUT, false}) +#define TMC5160_SWCOMP_IN_MASK 0x00000080 +#define TMC5160_SWCOMP_IN_SHIFT 7 +#define TMC5160_SWCOMP_IN_FIELD ((RegisterField) {TMC5160_SWCOMP_IN_MASK, TMC5160_SWCOMP_IN_SHIFT, TMC5160_INP_OUT, false}) +#define TMC5160_VERSION_MASK 0xFF000000 +#define TMC5160_VERSION_SHIFT 24 +#define TMC5160_VERSION_FIELD ((RegisterField) {TMC5160_VERSION_MASK, TMC5160_VERSION_SHIFT, TMC5160_INP_OUT, false}) +#define TMC5160_OUTPUT_PIN_POLARITY_MASK 0x00000001 +#define TMC5160_OUTPUT_PIN_POLARITY_SHIFT 0 +#define TMC5160_OUTPUT_PIN_POLARITY_FIELD ((RegisterField) {TMC5160_OUTPUT_PIN_POLARITY_MASK, TMC5160_OUTPUT_PIN_POLARITY_SHIFT, TMC5160_INP_OUT, false}) +#define TMC5160_X_COMPARE_MASK 0xFFFFFFFF +#define TMC5160_X_COMPARE_SHIFT 0 +#define TMC5160_X_COMPARE_FIELD ((RegisterField) {TMC5160_X_COMPARE_MASK, TMC5160_X_COMPARE_SHIFT, TMC5160_X_COMPARE, false}) +#define TMC5160_OTPBIT_MASK 0x00000007 +#define TMC5160_OTPBIT_SHIFT 0 +#define TMC5160_OTPBIT_FIELD ((RegisterField) {TMC5160_OTPBIT_MASK, TMC5160_OTPBIT_SHIFT, TMC5160_OTP_PROG, false}) +#define TMC5160_OTPBYTE_MASK 0x00000030 +#define TMC5160_OTPBYTE_SHIFT 4 +#define TMC5160_OTPBYTE_FIELD ((RegisterField) {TMC5160_OTPBYTE_MASK, TMC5160_OTPBYTE_SHIFT, TMC5160_OTP_PROG, false}) +#define TMC5160_OTPMAGIC_MASK 0x0000FF00 +#define TMC5160_OTPMAGIC_SHIFT 8 +#define TMC5160_OTPMAGIC_FIELD ((RegisterField) {TMC5160_OTPMAGIC_MASK, TMC5160_OTPMAGIC_SHIFT, TMC5160_OTP_PROG, false}) +#define TMC5160_OTP_TBL_MASK 0x00000080 +#define TMC5160_OTP_TBL_SHIFT 7 +#define TMC5160_OTP_TBL_FIELD ((RegisterField) {TMC5160_OTP_TBL_MASK, TMC5160_OTP_TBL_SHIFT, TMC5160_OTP_READ, false}) +#define TMC5160_OTP_BBM_MASK 0x00000040 +#define TMC5160_OTP_BBM_SHIFT 6 +#define TMC5160_OTP_BBM_FIELD ((RegisterField) {TMC5160_OTP_BBM_MASK, TMC5160_OTP_BBM_SHIFT, TMC5160_OTP_READ, false}) +#define TMC5160_OTP_S2_LEVEL_MASK 0x00000020 +#define TMC5160_OTP_S2_LEVEL_SHIFT 5 +#define TMC5160_OTP_S2_LEVEL_FIELD ((RegisterField) {TMC5160_OTP_S2_LEVEL_MASK, TMC5160_OTP_S2_LEVEL_SHIFT, TMC5160_OTP_READ, false}) +#define TMC5160_OTP_FCLKTRIM_MASK 0x0000001F +#define TMC5160_OTP_FCLKTRIM_SHIFT 0 +#define TMC5160_OTP_FCLKTRIM_FIELD ((RegisterField) {TMC5160_OTP_FCLKTRIM_MASK, TMC5160_OTP_FCLKTRIM_SHIFT, TMC5160_OTP_READ, false}) +#define TMC5160_FCLKTRIM_MASK 0x0000001F +#define TMC5160_FCLKTRIM_SHIFT 0 +#define TMC5160_FCLKTRIM_FIELD ((RegisterField) {TMC5160_FCLKTRIM_MASK, TMC5160_FCLKTRIM_SHIFT, TMC5160_FACTORY_CONF, false}) +#define TMC5160_S2VS_LEVEL_MASK 0x0000000F +#define TMC5160_S2VS_LEVEL_SHIFT 0 +#define TMC5160_S2VS_LEVEL_FIELD ((RegisterField) {TMC5160_S2VS_LEVEL_MASK, TMC5160_S2VS_LEVEL_SHIFT, TMC5160_SHORT_CONF, false}) +#define TMC5160_S2GND_LEVEL_MASK 0x00000F00 +#define TMC5160_S2GND_LEVEL_SHIFT 8 +#define TMC5160_S2GND_LEVEL_FIELD ((RegisterField) {TMC5160_S2GND_LEVEL_MASK, TMC5160_S2GND_LEVEL_SHIFT, TMC5160_SHORT_CONF, false}) +#define TMC5160_SHORTFILTER_MASK 0x00030000 +#define TMC5160_SHORTFILTER_SHIFT 16 +#define TMC5160_SHORTFILTER_FIELD ((RegisterField) {TMC5160_SHORTFILTER_MASK, TMC5160_SHORTFILTER_SHIFT, TMC5160_SHORT_CONF, false}) +#define TMC5160_SHORTDELAY_MASK 0x00040000 +#define TMC5160_SHORTDELAY_SHIFT 18 +#define TMC5160_SHORTDELAY_FIELD ((RegisterField) {TMC5160_SHORTDELAY_MASK, TMC5160_SHORTDELAY_SHIFT, TMC5160_SHORT_CONF, false}) +#define TMC5160_BBMTIME_MASK 0x0000001F +#define TMC5160_BBMTIME_SHIFT 0 +#define TMC5160_BBMTIME_FIELD ((RegisterField) {TMC5160_BBMTIME_MASK, TMC5160_BBMTIME_SHIFT, TMC5160_DRV_CONF, false}) +#define TMC5160_BBMCLKS_MASK 0x00000F00 +#define TMC5160_BBMCLKS_SHIFT 8 +#define TMC5160_BBMCLKS_FIELD ((RegisterField) {TMC5160_BBMCLKS_MASK, TMC5160_BBMCLKS_SHIFT, TMC5160_DRV_CONF, false}) +#define TMC5160_OTSELECT_MASK 0x00030000 +#define TMC5160_OTSELECT_SHIFT 16 +#define TMC5160_OTSELECT_FIELD ((RegisterField) {TMC5160_OTSELECT_MASK, TMC5160_OTSELECT_SHIFT, TMC5160_DRV_CONF, false}) +#define TMC5160_DRVSTRENGTH_MASK 0x000C0000 +#define TMC5160_DRVSTRENGTH_SHIFT 18 +#define TMC5160_DRVSTRENGTH_FIELD ((RegisterField) {TMC5160_DRVSTRENGTH_MASK, TMC5160_DRVSTRENGTH_SHIFT, TMC5160_DRV_CONF, false}) +#define TMC5160_FILT_ISENSE_MASK 0x00300000 +#define TMC5160_FILT_ISENSE_SHIFT 20 +#define TMC5160_FILT_ISENSE_FIELD ((RegisterField) {TMC5160_FILT_ISENSE_MASK, TMC5160_FILT_ISENSE_SHIFT, TMC5160_DRV_CONF, false}) +#define TMC5160_GLOBAL_SCALER_MASK 0x000000FF +#define TMC5160_GLOBAL_SCALER_SHIFT 0 +#define TMC5160_GLOBAL_SCALER_FIELD ((RegisterField) {TMC5160_GLOBAL_SCALER_MASK, TMC5160_GLOBAL_SCALER_SHIFT, TMC5160_GLOBAL_SCALER, false}) +#define TMC5160_OFFSET_READ_A_MASK 0x0000FF00 +#define TMC5160_OFFSET_READ_A_SHIFT 8 +#define TMC5160_OFFSET_READ_A_FIELD ((RegisterField) {TMC5160_OFFSET_READ_A_MASK, TMC5160_OFFSET_READ_A_SHIFT, TMC5160_OFFSET_READ, true}) +#define TMC5160_OFFSET_READ_B_MASK 0x000000FF +#define TMC5160_OFFSET_READ_B_SHIFT 0 +#define TMC5160_OFFSET_READ_B_FIELD ((RegisterField) {TMC5160_OFFSET_READ_B_MASK, TMC5160_OFFSET_READ_B_SHIFT, TMC5160_OFFSET_READ, true}) +#define TMC5160_IHOLD_MASK 0x0000001F +#define TMC5160_IHOLD_SHIFT 0 +#define TMC5160_IHOLD_FIELD ((RegisterField) {TMC5160_IHOLD_MASK, TMC5160_IHOLD_SHIFT, TMC5160_IHOLD_IRUN, false}) +#define TMC5160_IRUN_MASK 0x00001F00 +#define TMC5160_IRUN_SHIFT 8 +#define TMC5160_IRUN_FIELD ((RegisterField) {TMC5160_IRUN_MASK, TMC5160_IRUN_SHIFT, TMC5160_IHOLD_IRUN, false}) +#define TMC5160_IHOLDDELAY_MASK 0x000F0000 +#define TMC5160_IHOLDDELAY_SHIFT 16 +#define TMC5160_IHOLDDELAY_FIELD ((RegisterField) {TMC5160_IHOLDDELAY_MASK, TMC5160_IHOLDDELAY_SHIFT, TMC5160_IHOLD_IRUN, false}) +#define TMC5160_TPOWERDOWN_MASK 0x000000FF +#define TMC5160_TPOWERDOWN_SHIFT 0 +#define TMC5160_TPOWERDOWN_FIELD ((RegisterField) {TMC5160_TPOWERDOWN_MASK, TMC5160_TPOWERDOWN_SHIFT, TMC5160_TPOWERDOWN, false}) +#define TMC5160_TSTEP_MASK 0x000FFFFF +#define TMC5160_TSTEP_SHIFT 0 +#define TMC5160_TSTEP_FIELD ((RegisterField) {TMC5160_TSTEP_MASK, TMC5160_TSTEP_SHIFT, TMC5160_TSTEP, false}) +#define TMC5160_TPWMTHRS_MASK 0x000FFFFF +#define TMC5160_TPWMTHRS_SHIFT 0 +#define TMC5160_TPWMTHRS_FIELD ((RegisterField) {TMC5160_TPWMTHRS_MASK, TMC5160_TPWMTHRS_SHIFT, TMC5160_TPWMTHRS, false}) +#define TMC5160_TCOOLTHRS_MASK 0x000FFFFF +#define TMC5160_TCOOLTHRS_SHIFT 0 +#define TMC5160_TCOOLTHRS_FIELD ((RegisterField) {TMC5160_TCOOLTHRS_MASK, TMC5160_TCOOLTHRS_SHIFT, TMC5160_TCOOLTHRS, false}) +#define TMC5160_THIGH_MASK 0x000FFFFF +#define TMC5160_THIGH_SHIFT 0 +#define TMC5160_THIGH_FIELD ((RegisterField) {TMC5160_THIGH_MASK, TMC5160_THIGH_SHIFT, TMC5160_THIGH, false}) +#define TMC5160_RAMPMODE_MASK 0x00000003 +#define TMC5160_RAMPMODE_SHIFT 0 +#define TMC5160_RAMPMODE_FIELD ((RegisterField) {TMC5160_RAMPMODE_MASK, TMC5160_RAMPMODE_SHIFT, TMC5160_RAMPMODE, false}) +#define TMC5160_XACTUAL_MASK 0xFFFFFFFF +#define TMC5160_XACTUAL_SHIFT 0 +#define TMC5160_XACTUAL_FIELD ((RegisterField) {TMC5160_XACTUAL_MASK, TMC5160_XACTUAL_SHIFT, TMC5160_XACTUAL, true}) +#define TMC5160_VACTUAL_MASK 0x00FFFFFF +#define TMC5160_VACTUAL_SHIFT 0 +#define TMC5160_VACTUAL_FIELD ((RegisterField) {TMC5160_VACTUAL_MASK, TMC5160_VACTUAL_SHIFT, TMC5160_VACTUAL, true}) +#define TMC5160_VSTART_MASK 0x0003FFFF +#define TMC5160_VSTART_SHIFT 0 +#define TMC5160_VSTART_FIELD ((RegisterField) {TMC5160_VSTART_MASK, TMC5160_VSTART_SHIFT, TMC5160_VSTART, false}) +#define TMC5160_A1_MASK 0x0000FFFF +#define TMC5160_A1_SHIFT 0 +#define TMC5160_A1_FIELD ((RegisterField) {TMC5160_A1_MASK, TMC5160_A1_SHIFT, TMC5160_A1, false}) +#define TMC5160_V1__MASK 0x000FFFFF +#define TMC5160_V1__SHIFT 0 +#define TMC5160_V1__FIELD ((RegisterField) {TMC5160_V1__MASK, TMC5160_V1__SHIFT, TMC5160_V1, false}) +#define TMC5160_AMAX_MASK 0x0000FFFF +#define TMC5160_AMAX_SHIFT 0 +#define TMC5160_AMAX_FIELD ((RegisterField) {TMC5160_AMAX_MASK, TMC5160_AMAX_SHIFT, TMC5160_AMAX, false}) +#define TMC5160_VMAX_MASK 0x007FFFFF +#define TMC5160_VMAX_SHIFT 0 +#define TMC5160_VMAX_FIELD ((RegisterField) {TMC5160_VMAX_MASK, TMC5160_VMAX_SHIFT, TMC5160_VMAX, false}) +#define TMC5160_DMAX_MASK 0x0000FFFF +#define TMC5160_DMAX_SHIFT 0 +#define TMC5160_DMAX_FIELD ((RegisterField) {TMC5160_DMAX_MASK, TMC5160_DMAX_SHIFT, TMC5160_DMAX, false}) +#define TMC5160_D1_MASK 0x0000FFFF +#define TMC5160_D1_SHIFT 0 +#define TMC5160_D1_FIELD ((RegisterField) {TMC5160_D1_MASK, TMC5160_D1_SHIFT, TMC5160_D1, false}) +#define TMC5160_VSTOP_MASK 0x0003FFFF +#define TMC5160_VSTOP_SHIFT 0 +#define TMC5160_VSTOP_FIELD ((RegisterField) {TMC5160_VSTOP_MASK, TMC5160_VSTOP_SHIFT, TMC5160_VSTOP, false}) +#define TMC5160_TZEROWAIT_MASK 0x0000FFFF +#define TMC5160_TZEROWAIT_SHIFT 0 +#define TMC5160_TZEROWAIT_FIELD ((RegisterField) {TMC5160_TZEROWAIT_MASK, TMC5160_TZEROWAIT_SHIFT, TMC5160_TZEROWAIT, false}) +#define TMC5160_XTARGET_MASK 0xFFFFFFFF +#define TMC5160_XTARGET_SHIFT 0 +#define TMC5160_XTARGET_FIELD ((RegisterField) {TMC5160_XTARGET_MASK, TMC5160_XTARGET_SHIFT, TMC5160_XTARGET, true}) +#define TMC5160_VDCMIN_MASK 0x007FFFFF +#define TMC5160_VDCMIN_SHIFT 0 +#define TMC5160_VDCMIN_FIELD ((RegisterField) {TMC5160_VDCMIN_MASK, TMC5160_VDCMIN_SHIFT, TMC5160_VDCMIN, false}) +#define TMC5160_STOP_L_ENABLE_MASK 0x00000001 +#define TMC5160_STOP_L_ENABLE_SHIFT 0 +#define TMC5160_STOP_L_ENABLE_FIELD ((RegisterField) {TMC5160_STOP_L_ENABLE_MASK, TMC5160_STOP_L_ENABLE_SHIFT, TMC5160_SWMODE, false}) +#define TMC5160_STOP_R_ENABLE_MASK 0x00000002 +#define TMC5160_STOP_R_ENABLE_SHIFT 1 +#define TMC5160_STOP_R_ENABLE_FIELD ((RegisterField) {TMC5160_STOP_R_ENABLE_MASK, TMC5160_STOP_R_ENABLE_SHIFT, TMC5160_SWMODE, false}) +#define TMC5160_POL_STOP_L_MASK 0x00000004 +#define TMC5160_POL_STOP_L_SHIFT 2 +#define TMC5160_POL_STOP_L_FIELD ((RegisterField) {TMC5160_POL_STOP_L_MASK, TMC5160_POL_STOP_L_SHIFT, TMC5160_SWMODE, false}) +#define TMC5160_POL_STOP_R_MASK 0x00000008 +#define TMC5160_POL_STOP_R_SHIFT 3 +#define TMC5160_POL_STOP_R_FIELD ((RegisterField) {TMC5160_POL_STOP_R_MASK, TMC5160_POL_STOP_R_SHIFT, TMC5160_SWMODE, false}) +#define TMC5160_SWAP_LR_MASK 0x00000010 +#define TMC5160_SWAP_LR_SHIFT 4 +#define TMC5160_SWAP_LR_FIELD ((RegisterField) {TMC5160_SWAP_LR_MASK, TMC5160_SWAP_LR_SHIFT, TMC5160_SWMODE, false}) +#define TMC5160_LATCH_L_ACTIVE_MASK 0x00000020 +#define TMC5160_LATCH_L_ACTIVE_SHIFT 5 +#define TMC5160_LATCH_L_ACTIVE_FIELD ((RegisterField) {TMC5160_LATCH_L_ACTIVE_MASK, TMC5160_LATCH_L_ACTIVE_SHIFT, TMC5160_SWMODE, false}) +#define TMC5160_LATCH_L_INACTIVE_MASK 0x00000040 +#define TMC5160_LATCH_L_INACTIVE_SHIFT 6 +#define TMC5160_LATCH_L_INACTIVE_FIELD ((RegisterField) {TMC5160_LATCH_L_INACTIVE_MASK, TMC5160_LATCH_L_INACTIVE_SHIFT, TMC5160_SWMODE, false}) +#define TMC5160_LATCH_R_ACTIVE_MASK 0x00000080 +#define TMC5160_LATCH_R_ACTIVE_SHIFT 7 +#define TMC5160_LATCH_R_ACTIVE_FIELD ((RegisterField) {TMC5160_LATCH_R_ACTIVE_MASK, TMC5160_LATCH_R_ACTIVE_SHIFT, TMC5160_SWMODE, false}) +#define TMC5160_LATCH_R_INACTIVE_MASK 0x00000100 +#define TMC5160_LATCH_R_INACTIVE_SHIFT 8 +#define TMC5160_LATCH_R_INACTIVE_FIELD ((RegisterField) {TMC5160_LATCH_R_INACTIVE_MASK, TMC5160_LATCH_R_INACTIVE_SHIFT, TMC5160_SWMODE, false}) +#define TMC5160_EN_LATCH_ENCODER_MASK 0x00000200 +#define TMC5160_EN_LATCH_ENCODER_SHIFT 9 +#define TMC5160_EN_LATCH_ENCODER_FIELD ((RegisterField) {TMC5160_EN_LATCH_ENCODER_MASK, TMC5160_EN_LATCH_ENCODER_SHIFT, TMC5160_SWMODE, false}) +#define TMC5160_SG_STOP_MASK 0x00000400 +#define TMC5160_SG_STOP_SHIFT 10 +#define TMC5160_SG_STOP_FIELD ((RegisterField) {TMC5160_SG_STOP_MASK, TMC5160_SG_STOP_SHIFT, TMC5160_SWMODE, false}) +#define TMC5160_EN_SOFTSTOP_MASK 0x00000800 +#define TMC5160_EN_SOFTSTOP_SHIFT 11 +#define TMC5160_EN_SOFTSTOP_FIELD ((RegisterField) {TMC5160_EN_SOFTSTOP_MASK, TMC5160_EN_SOFTSTOP_SHIFT, TMC5160_SWMODE, false}) +#define TMC5160_STATUS_STOP_L_MASK 0x00000001 +#define TMC5160_STATUS_STOP_L_SHIFT 0 +#define TMC5160_STATUS_STOP_L_FIELD ((RegisterField) {TMC5160_STATUS_STOP_L_MASK, TMC5160_STATUS_STOP_L_SHIFT, TMC5160_RAMPSTAT, false}) +#define TMC5160_STATUS_STOP_R_MASK 0x00000002 +#define TMC5160_STATUS_STOP_R_SHIFT 1 +#define TMC5160_STATUS_STOP_R_FIELD ((RegisterField) {TMC5160_STATUS_STOP_R_MASK, TMC5160_STATUS_STOP_R_SHIFT, TMC5160_RAMPSTAT, false}) +#define TMC5160_STATUS_LATCH_L_MASK 0x00000004 +#define TMC5160_STATUS_LATCH_L_SHIFT 2 +#define TMC5160_STATUS_LATCH_L_FIELD ((RegisterField) {TMC5160_STATUS_LATCH_L_MASK, TMC5160_STATUS_LATCH_L_SHIFT, TMC5160_RAMPSTAT, false}) +#define TMC5160_STATUS_LATCH_R_MASK 0x00000008 +#define TMC5160_STATUS_LATCH_R_SHIFT 3 +#define TMC5160_STATUS_LATCH_R_FIELD ((RegisterField) {TMC5160_STATUS_LATCH_R_MASK, TMC5160_STATUS_LATCH_R_SHIFT, TMC5160_RAMPSTAT, false}) +#define TMC5160_EVENT_STOP_L_MASK 0x00000010 +#define TMC5160_EVENT_STOP_L_SHIFT 4 +#define TMC5160_EVENT_STOP_L_FIELD ((RegisterField) {TMC5160_EVENT_STOP_L_MASK, TMC5160_EVENT_STOP_L_SHIFT, TMC5160_RAMPSTAT, false}) +#define TMC5160_EVENT_STOP_R_MASK 0x00000020 +#define TMC5160_EVENT_STOP_R_SHIFT 5 +#define TMC5160_EVENT_STOP_R_FIELD ((RegisterField) {TMC5160_EVENT_STOP_R_MASK, TMC5160_EVENT_STOP_R_SHIFT, TMC5160_RAMPSTAT, false}) +#define TMC5160_EVENT_STOP_SG_MASK 0x00000040 +#define TMC5160_EVENT_STOP_SG_SHIFT 6 +#define TMC5160_EVENT_STOP_SG_FIELD ((RegisterField) {TMC5160_EVENT_STOP_SG_MASK, TMC5160_EVENT_STOP_SG_SHIFT, TMC5160_RAMPSTAT, false}) +#define TMC5160_EVENT_POS_REACHED_MASK 0x00000080 +#define TMC5160_EVENT_POS_REACHED_SHIFT 7 +#define TMC5160_EVENT_POS_REACHED_FIELD ((RegisterField) {TMC5160_EVENT_POS_REACHED_MASK, TMC5160_EVENT_POS_REACHED_SHIFT, TMC5160_RAMPSTAT, false}) +#define TMC5160_VELOCITY_REACHED_MASK 0x00000100 +#define TMC5160_VELOCITY_REACHED_SHIFT 8 +#define TMC5160_VELOCITY_REACHED_FIELD ((RegisterField) {TMC5160_VELOCITY_REACHED_MASK, TMC5160_VELOCITY_REACHED_SHIFT, TMC5160_RAMPSTAT, false}) +#define TMC5160_POSITION_REACHED_MASK 0x00000200 +#define TMC5160_POSITION_REACHED_SHIFT 9 +#define TMC5160_POSITION_REACHED_FIELD ((RegisterField) {TMC5160_POSITION_REACHED_MASK, TMC5160_POSITION_REACHED_SHIFT, TMC5160_RAMPSTAT, false}) +#define TMC5160_VZERO_MASK 0x00000400 +#define TMC5160_VZERO_SHIFT 10 +#define TMC5160_VZERO_FIELD ((RegisterField) {TMC5160_VZERO_MASK, TMC5160_VZERO_SHIFT, TMC5160_RAMPSTAT, false}) +#define TMC5160_T_ZEROWAIT_ACTIVE_MASK 0x00000800 +#define TMC5160_T_ZEROWAIT_ACTIVE_SHIFT 11 +#define TMC5160_T_ZEROWAIT_ACTIVE_FIELD ((RegisterField) {TMC5160_T_ZEROWAIT_ACTIVE_MASK, TMC5160_T_ZEROWAIT_ACTIVE_SHIFT, TMC5160_RAMPSTAT, false}) +#define TMC5160_SECOND_MOVE_MASK 0x00001000 +#define TMC5160_SECOND_MOVE_SHIFT 12 +#define TMC5160_SECOND_MOVE_FIELD ((RegisterField) {TMC5160_SECOND_MOVE_MASK, TMC5160_SECOND_MOVE_SHIFT, TMC5160_RAMPSTAT, false}) +#define TMC5160_STATUS_SG_MASK 0x00002000 +#define TMC5160_STATUS_SG_SHIFT 13 +#define TMC5160_STATUS_SG_FIELD ((RegisterField) {TMC5160_STATUS_SG_MASK, TMC5160_STATUS_SG_SHIFT, TMC5160_RAMPSTAT, false}) +#define TMC5160_XLATCH_MASK 0xFFFFFFFF +#define TMC5160_XLATCH_SHIFT 0 +#define TMC5160_XLATCH_FIELD ((RegisterField) {TMC5160_XLATCH_MASK, TMC5160_XLATCH_SHIFT, TMC5160_XLATCH, false}) +#define TMC5160_POL_A_MASK 0x00000001 +#define TMC5160_POL_A_SHIFT 0 +#define TMC5160_POL_A_FIELD ((RegisterField) {TMC5160_POL_A_MASK, TMC5160_POL_A_SHIFT, TMC5160_ENCMODE, false}) +#define TMC5160_POL_B_MASK 0x00000002 +#define TMC5160_POL_B_SHIFT 1 +#define TMC5160_POL_B_FIELD ((RegisterField) {TMC5160_POL_B_MASK, TMC5160_POL_B_SHIFT, TMC5160_ENCMODE, false}) +#define TMC5160_POL_N_MASK 0x00000004 +#define TMC5160_POL_N_SHIFT 2 +#define TMC5160_POL_N_FIELD ((RegisterField) {TMC5160_POL_N_MASK, TMC5160_POL_N_SHIFT, TMC5160_ENCMODE, false}) +#define TMC5160_IGNORE_AB_MASK 0x00000008 +#define TMC5160_IGNORE_AB_SHIFT 3 +#define TMC5160_IGNORE_AB_FIELD ((RegisterField) {TMC5160_IGNORE_AB_MASK, TMC5160_IGNORE_AB_SHIFT, TMC5160_ENCMODE, false}) +#define TMC5160_CLR_CONT_MASK 0x00000010 +#define TMC5160_CLR_CONT_SHIFT 4 +#define TMC5160_CLR_CONT_FIELD ((RegisterField) {TMC5160_CLR_CONT_MASK, TMC5160_CLR_CONT_SHIFT, TMC5160_ENCMODE, false}) +#define TMC5160_CLR_ONCE_MASK 0x00000020 +#define TMC5160_CLR_ONCE_SHIFT 5 +#define TMC5160_CLR_ONCE_FIELD ((RegisterField) {TMC5160_CLR_ONCE_MASK, TMC5160_CLR_ONCE_SHIFT, TMC5160_ENCMODE, false}) +#define TMC5160_POS_EDGE_NEG_EDGE_MASK 0x000000C0 +#define TMC5160_POS_EDGE_NEG_EDGE_SHIFT 6 +#define TMC5160_POS_EDGE_NEG_EDGE_FIELD ((RegisterField) {TMC5160_POS_EDGE_NEG_EDGE_MASK, TMC5160_POS_EDGE_NEG_EDGE_SHIFT, TMC5160_ENCMODE, false}) +#define TMC5160_CLR_ENC_X_MASK 0x00000100 +#define TMC5160_CLR_ENC_X_SHIFT 8 +#define TMC5160_CLR_ENC_X_FIELD ((RegisterField) {TMC5160_CLR_ENC_X_MASK, TMC5160_CLR_ENC_X_SHIFT, TMC5160_ENCMODE, false}) +#define TMC5160_LATCH_X_ACT_MASK 0x00000200 +#define TMC5160_LATCH_X_ACT_SHIFT 9 +#define TMC5160_LATCH_X_ACT_FIELD ((RegisterField) {TMC5160_LATCH_X_ACT_MASK, TMC5160_LATCH_X_ACT_SHIFT, TMC5160_ENCMODE, false}) +#define TMC5160_ENC_SEL_DECIMAL_MASK 0x00000400 +#define TMC5160_ENC_SEL_DECIMAL_SHIFT 10 +#define TMC5160_ENC_SEL_DECIMAL_FIELD ((RegisterField) {TMC5160_ENC_SEL_DECIMAL_MASK, TMC5160_ENC_SEL_DECIMAL_SHIFT, TMC5160_ENCMODE, false}) +#define TMC5160_X_ENC_MASK 0xFFFFFFFF +#define TMC5160_X_ENC_SHIFT 0 +#define TMC5160_X_ENC_FIELD ((RegisterField) {TMC5160_X_ENC_MASK, TMC5160_X_ENC_SHIFT, TMC5160_X_ENC, true}) +#define TMC5160_INTEGER_MASK 0xFFFF0000 +#define TMC5160_INTEGER_SHIFT 16 +#define TMC5160_INTEGER_FIELD ((RegisterField) {TMC5160_INTEGER_MASK, TMC5160_INTEGER_SHIFT, TMC5160_ENC_CONST, false}) +#define TMC5160_FRACTIONAL_MASK 0x0000FFFF +#define TMC5160_FRACTIONAL_SHIFT 0 +#define TMC5160_FRACTIONAL_FIELD ((RegisterField) {TMC5160_FRACTIONAL_MASK, TMC5160_FRACTIONAL_SHIFT, TMC5160_ENC_CONST, false}) +#define TMC5160_N_EVENT_MASK 0x00000001 +#define TMC5160_N_EVENT_SHIFT 0 +#define TMC5160_N_EVENT_FIELD ((RegisterField) {TMC5160_N_EVENT_MASK, TMC5160_N_EVENT_SHIFT, TMC5160_ENC_STATUS, false}) +#define TMC5160_DEVIATION_WARN_MASK 0x00000002 +#define TMC5160_DEVIATION_WARN_SHIFT 1 +#define TMC5160_DEVIATION_WARN_FIELD ((RegisterField) {TMC5160_DEVIATION_WARN_MASK, TMC5160_DEVIATION_WARN_SHIFT, TMC5160_ENC_STATUS, false}) +#define TMC5160_ENC_LATCH_MASK 0xFFFFFFFF +#define TMC5160_ENC_LATCH_SHIFT 0 +#define TMC5160_ENC_LATCH_FIELD ((RegisterField) {TMC5160_ENC_LATCH_MASK, TMC5160_ENC_LATCH_SHIFT, TMC5160_ENC_LATCH, true}) +#define TMC5160_ENC_DEVIATION_MASK 0x000FFFFF +#define TMC5160_ENC_DEVIATION_SHIFT 0 +#define TMC5160_ENC_DEVIATION_FIELD ((RegisterField) {TMC5160_ENC_DEVIATION_MASK, TMC5160_ENC_DEVIATION_SHIFT, TMC5160_ENC_DEVIATION, false}) +#define TMC5160_OFS0_MASK 0x00000001 +#define TMC5160_OFS0_SHIFT 0 +#define TMC5160_OFS0_FIELD ((RegisterField) {TMC5160_OFS0_MASK, TMC5160_OFS0_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS1_MASK 0x00000002 +#define TMC5160_OFS1_SHIFT 1 +#define TMC5160_OFS1_FIELD ((RegisterField) {TMC5160_OFS1_MASK, TMC5160_OFS1_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS2_MASK 0x00000004 +#define TMC5160_OFS2_SHIFT 2 +#define TMC5160_OFS2_FIELD ((RegisterField) {TMC5160_OFS2_MASK, TMC5160_OFS2_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS3_MASK 0x00000008 +#define TMC5160_OFS3_SHIFT 3 +#define TMC5160_OFS3_FIELD ((RegisterField) {TMC5160_OFS3_MASK, TMC5160_OFS3_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS4_MASK 0x00000010 +#define TMC5160_OFS4_SHIFT 4 +#define TMC5160_OFS4_FIELD ((RegisterField) {TMC5160_OFS4_MASK, TMC5160_OFS4_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS5_MASK 0x00000020 +#define TMC5160_OFS5_SHIFT 5 +#define TMC5160_OFS5_FIELD ((RegisterField) {TMC5160_OFS5_MASK, TMC5160_OFS5_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS6_MASK 0x00000040 +#define TMC5160_OFS6_SHIFT 6 +#define TMC5160_OFS6_FIELD ((RegisterField) {TMC5160_OFS6_MASK, TMC5160_OFS6_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS7_MASK 0x00000080 +#define TMC5160_OFS7_SHIFT 7 +#define TMC5160_OFS7_FIELD ((RegisterField) {TMC5160_OFS7_MASK, TMC5160_OFS7_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS8_MASK 0x00000100 +#define TMC5160_OFS8_SHIFT 8 +#define TMC5160_OFS8_FIELD ((RegisterField) {TMC5160_OFS8_MASK, TMC5160_OFS8_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS9_MASK 0x00000200 +#define TMC5160_OFS9_SHIFT 9 +#define TMC5160_OFS9_FIELD ((RegisterField) {TMC5160_OFS9_MASK, TMC5160_OFS9_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS10_MASK 0x00000400 +#define TMC5160_OFS10_SHIFT 10 +#define TMC5160_OFS10_FIELD ((RegisterField) {TMC5160_OFS10_MASK, TMC5160_OFS10_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS11_MASK 0x00000800 +#define TMC5160_OFS11_SHIFT 11 +#define TMC5160_OFS11_FIELD ((RegisterField) {TMC5160_OFS11_MASK, TMC5160_OFS11_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS12_MASK 0x00001000 +#define TMC5160_OFS12_SHIFT 12 +#define TMC5160_OFS12_FIELD ((RegisterField) {TMC5160_OFS12_MASK, TMC5160_OFS12_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS13_MASK 0x00002000 +#define TMC5160_OFS13_SHIFT 13 +#define TMC5160_OFS13_FIELD ((RegisterField) {TMC5160_OFS13_MASK, TMC5160_OFS13_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS14_MASK 0x00004000 +#define TMC5160_OFS14_SHIFT 14 +#define TMC5160_OFS14_FIELD ((RegisterField) {TMC5160_OFS14_MASK, TMC5160_OFS14_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS15_MASK 0x00008000 +#define TMC5160_OFS15_SHIFT 15 +#define TMC5160_OFS15_FIELD ((RegisterField) {TMC5160_OFS15_MASK, TMC5160_OFS15_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS16_MASK 0x00010000 +#define TMC5160_OFS16_SHIFT 16 +#define TMC5160_OFS16_FIELD ((RegisterField) {TMC5160_OFS16_MASK, TMC5160_OFS16_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS17_MASK 0x00020000 +#define TMC5160_OFS17_SHIFT 17 +#define TMC5160_OFS17_FIELD ((RegisterField) {TMC5160_OFS17_MASK, TMC5160_OFS17_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS18_MASK 0x00040000 +#define TMC5160_OFS18_SHIFT 18 +#define TMC5160_OFS18_FIELD ((RegisterField) {TMC5160_OFS18_MASK, TMC5160_OFS18_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS19_MASK 0x00080000 +#define TMC5160_OFS19_SHIFT 19 +#define TMC5160_OFS19_FIELD ((RegisterField) {TMC5160_OFS19_MASK, TMC5160_OFS19_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS20_MASK 0x00100000 +#define TMC5160_OFS20_SHIFT 20 +#define TMC5160_OFS20_FIELD ((RegisterField) {TMC5160_OFS20_MASK, TMC5160_OFS20_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS21_MASK 0x00200000 +#define TMC5160_OFS21_SHIFT 21 +#define TMC5160_OFS21_FIELD ((RegisterField) {TMC5160_OFS21_MASK, TMC5160_OFS21_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS22_MASK 0x00400000 +#define TMC5160_OFS22_SHIFT 22 +#define TMC5160_OFS22_FIELD ((RegisterField) {TMC5160_OFS22_MASK, TMC5160_OFS22_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS23_MASK 0x00800000 +#define TMC5160_OFS23_SHIFT 23 +#define TMC5160_OFS23_FIELD ((RegisterField) {TMC5160_OFS23_MASK, TMC5160_OFS23_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS24_MASK 0x01000000 +#define TMC5160_OFS24_SHIFT 24 +#define TMC5160_OFS24_FIELD ((RegisterField) {TMC5160_OFS24_MASK, TMC5160_OFS24_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS25_MASK 0x02000000 +#define TMC5160_OFS25_SHIFT 25 +#define TMC5160_OFS25_FIELD ((RegisterField) {TMC5160_OFS25_MASK, TMC5160_OFS25_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS26_MASK 0x04000000 +#define TMC5160_OFS26_SHIFT 26 +#define TMC5160_OFS26_FIELD ((RegisterField) {TMC5160_OFS26_MASK, TMC5160_OFS26_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS27_MASK 0x08000000 +#define TMC5160_OFS27_SHIFT 27 +#define TMC5160_OFS27_FIELD ((RegisterField) {TMC5160_OFS27_MASK, TMC5160_OFS27_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS28_MASK 0x10000000 +#define TMC5160_OFS28_SHIFT 28 +#define TMC5160_OFS28_FIELD ((RegisterField) {TMC5160_OFS28_MASK, TMC5160_OFS28_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS29_MASK 0x20000000 +#define TMC5160_OFS29_SHIFT 29 +#define TMC5160_OFS29_FIELD ((RegisterField) {TMC5160_OFS29_MASK, TMC5160_OFS29_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS30_MASK 0x40000000 +#define TMC5160_OFS30_SHIFT 30 +#define TMC5160_OFS30_FIELD ((RegisterField) {TMC5160_OFS30_MASK, TMC5160_OFS30_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS31_MASK 0x80000000 +#define TMC5160_OFS31_SHIFT 31 +#define TMC5160_OFS31_FIELD ((RegisterField) {TMC5160_OFS31_MASK, TMC5160_OFS31_SHIFT, TMC5160_MSLUT0, false}) +#define TMC5160_OFS32_MASK 0x00000001 +#define TMC5160_OFS32_SHIFT 0 +#define TMC5160_OFS32_FIELD ((RegisterField) {TMC5160_OFS32_MASK, TMC5160_OFS32_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS33_MASK 0x00000002 +#define TMC5160_OFS33_SHIFT 1 +#define TMC5160_OFS33_FIELD ((RegisterField) {TMC5160_OFS33_MASK, TMC5160_OFS33_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS34_MASK 0x00000004 +#define TMC5160_OFS34_SHIFT 2 +#define TMC5160_OFS34_FIELD ((RegisterField) {TMC5160_OFS34_MASK, TMC5160_OFS34_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS35_MASK 0x00000008 +#define TMC5160_OFS35_SHIFT 3 +#define TMC5160_OFS35_FIELD ((RegisterField) {TMC5160_OFS35_MASK, TMC5160_OFS35_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS36_MASK 0x00000010 +#define TMC5160_OFS36_SHIFT 4 +#define TMC5160_OFS36_FIELD ((RegisterField) {TMC5160_OFS36_MASK, TMC5160_OFS36_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS37_MASK 0x00000020 +#define TMC5160_OFS37_SHIFT 5 +#define TMC5160_OFS37_FIELD ((RegisterField) {TMC5160_OFS37_MASK, TMC5160_OFS37_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS38_MASK 0x00000040 +#define TMC5160_OFS38_SHIFT 6 +#define TMC5160_OFS38_FIELD ((RegisterField) {TMC5160_OFS38_MASK, TMC5160_OFS38_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS39_MASK 0x00000080 +#define TMC5160_OFS39_SHIFT 7 +#define TMC5160_OFS39_FIELD ((RegisterField) {TMC5160_OFS39_MASK, TMC5160_OFS39_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS40_MASK 0x00000100 +#define TMC5160_OFS40_SHIFT 8 +#define TMC5160_OFS40_FIELD ((RegisterField) {TMC5160_OFS40_MASK, TMC5160_OFS40_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS41_MASK 0x00000200 +#define TMC5160_OFS41_SHIFT 9 +#define TMC5160_OFS41_FIELD ((RegisterField) {TMC5160_OFS41_MASK, TMC5160_OFS41_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS42_MASK 0x00000400 +#define TMC5160_OFS42_SHIFT 10 +#define TMC5160_OFS42_FIELD ((RegisterField) {TMC5160_OFS42_MASK, TMC5160_OFS42_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS43_MASK 0x00000800 +#define TMC5160_OFS43_SHIFT 11 +#define TMC5160_OFS43_FIELD ((RegisterField) {TMC5160_OFS43_MASK, TMC5160_OFS43_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS44_MASK 0x00001000 +#define TMC5160_OFS44_SHIFT 12 +#define TMC5160_OFS44_FIELD ((RegisterField) {TMC5160_OFS44_MASK, TMC5160_OFS44_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS45_MASK 0x00002000 +#define TMC5160_OFS45_SHIFT 13 +#define TMC5160_OFS45_FIELD ((RegisterField) {TMC5160_OFS45_MASK, TMC5160_OFS45_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS46_MASK 0x00004000 +#define TMC5160_OFS46_SHIFT 14 +#define TMC5160_OFS46_FIELD ((RegisterField) {TMC5160_OFS46_MASK, TMC5160_OFS46_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS47_MASK 0x00008000 +#define TMC5160_OFS47_SHIFT 15 +#define TMC5160_OFS47_FIELD ((RegisterField) {TMC5160_OFS47_MASK, TMC5160_OFS47_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS48_MASK 0x00010000 +#define TMC5160_OFS48_SHIFT 16 +#define TMC5160_OFS48_FIELD ((RegisterField) {TMC5160_OFS48_MASK, TMC5160_OFS48_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS49_MASK 0x00020000 +#define TMC5160_OFS49_SHIFT 17 +#define TMC5160_OFS49_FIELD ((RegisterField) {TMC5160_OFS49_MASK, TMC5160_OFS49_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS50_MASK 0x00040000 +#define TMC5160_OFS50_SHIFT 18 +#define TMC5160_OFS50_FIELD ((RegisterField) {TMC5160_OFS50_MASK, TMC5160_OFS50_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS51_MASK 0x00080000 +#define TMC5160_OFS51_SHIFT 19 +#define TMC5160_OFS51_FIELD ((RegisterField) {TMC5160_OFS51_MASK, TMC5160_OFS51_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS52_MASK 0x00100000 +#define TMC5160_OFS52_SHIFT 20 +#define TMC5160_OFS52_FIELD ((RegisterField) {TMC5160_OFS52_MASK, TMC5160_OFS52_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS53_MASK 0x00200000 +#define TMC5160_OFS53_SHIFT 21 +#define TMC5160_OFS53_FIELD ((RegisterField) {TMC5160_OFS53_MASK, TMC5160_OFS53_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS54_MASK 0x00400000 +#define TMC5160_OFS54_SHIFT 22 +#define TMC5160_OFS54_FIELD ((RegisterField) {TMC5160_OFS54_MASK, TMC5160_OFS54_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS55_MASK 0x00800000 +#define TMC5160_OFS55_SHIFT 23 +#define TMC5160_OFS55_FIELD ((RegisterField) {TMC5160_OFS55_MASK, TMC5160_OFS55_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS56_MASK 0x01000000 +#define TMC5160_OFS56_SHIFT 24 +#define TMC5160_OFS56_FIELD ((RegisterField) {TMC5160_OFS56_MASK, TMC5160_OFS56_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS57_MASK 0x02000000 +#define TMC5160_OFS57_SHIFT 25 +#define TMC5160_OFS57_FIELD ((RegisterField) {TMC5160_OFS57_MASK, TMC5160_OFS57_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS58_MASK 0x04000000 +#define TMC5160_OFS58_SHIFT 26 +#define TMC5160_OFS58_FIELD ((RegisterField) {TMC5160_OFS58_MASK, TMC5160_OFS58_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS59_MASK 0x08000000 +#define TMC5160_OFS59_SHIFT 27 +#define TMC5160_OFS59_FIELD ((RegisterField) {TMC5160_OFS59_MASK, TMC5160_OFS59_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS60_MASK 0x10000000 +#define TMC5160_OFS60_SHIFT 28 +#define TMC5160_OFS60_FIELD ((RegisterField) {TMC5160_OFS60_MASK, TMC5160_OFS60_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS61_MASK 0x20000000 +#define TMC5160_OFS61_SHIFT 29 +#define TMC5160_OFS61_FIELD ((RegisterField) {TMC5160_OFS61_MASK, TMC5160_OFS61_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS62_MASK 0x40000000 +#define TMC5160_OFS62_SHIFT 30 +#define TMC5160_OFS62_FIELD ((RegisterField) {TMC5160_OFS62_MASK, TMC5160_OFS62_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS63_MASK 0x80000000 +#define TMC5160_OFS63_SHIFT 31 +#define TMC5160_OFS63_FIELD ((RegisterField) {TMC5160_OFS63_MASK, TMC5160_OFS63_SHIFT, TMC5160_MSLUT1, false}) +#define TMC5160_OFS64_MASK 0x00000001 +#define TMC5160_OFS64_SHIFT 0 +#define TMC5160_OFS64_FIELD ((RegisterField) {TMC5160_OFS64_MASK, TMC5160_OFS64_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS65_MASK 0x00000002 +#define TMC5160_OFS65_SHIFT 1 +#define TMC5160_OFS65_FIELD ((RegisterField) {TMC5160_OFS65_MASK, TMC5160_OFS65_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS66_MASK 0x00000004 +#define TMC5160_OFS66_SHIFT 2 +#define TMC5160_OFS66_FIELD ((RegisterField) {TMC5160_OFS66_MASK, TMC5160_OFS66_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS67_MASK 0x00000008 +#define TMC5160_OFS67_SHIFT 3 +#define TMC5160_OFS67_FIELD ((RegisterField) {TMC5160_OFS67_MASK, TMC5160_OFS67_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS68_MASK 0x00000010 +#define TMC5160_OFS68_SHIFT 4 +#define TMC5160_OFS68_FIELD ((RegisterField) {TMC5160_OFS68_MASK, TMC5160_OFS68_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS69_MASK 0x00000020 +#define TMC5160_OFS69_SHIFT 5 +#define TMC5160_OFS69_FIELD ((RegisterField) {TMC5160_OFS69_MASK, TMC5160_OFS69_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS70_MASK 0x00000040 +#define TMC5160_OFS70_SHIFT 6 +#define TMC5160_OFS70_FIELD ((RegisterField) {TMC5160_OFS70_MASK, TMC5160_OFS70_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS71_MASK 0x00000080 +#define TMC5160_OFS71_SHIFT 7 +#define TMC5160_OFS71_FIELD ((RegisterField) {TMC5160_OFS71_MASK, TMC5160_OFS71_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS72_MASK 0x00000100 +#define TMC5160_OFS72_SHIFT 8 +#define TMC5160_OFS72_FIELD ((RegisterField) {TMC5160_OFS72_MASK, TMC5160_OFS72_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS73_MASK 0x00000200 +#define TMC5160_OFS73_SHIFT 9 +#define TMC5160_OFS73_FIELD ((RegisterField) {TMC5160_OFS73_MASK, TMC5160_OFS73_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS74_MASK 0x00000400 +#define TMC5160_OFS74_SHIFT 10 +#define TMC5160_OFS74_FIELD ((RegisterField) {TMC5160_OFS74_MASK, TMC5160_OFS74_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS75_MASK 0x00000800 +#define TMC5160_OFS75_SHIFT 11 +#define TMC5160_OFS75_FIELD ((RegisterField) {TMC5160_OFS75_MASK, TMC5160_OFS75_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS76_MASK 0x00001000 +#define TMC5160_OFS76_SHIFT 12 +#define TMC5160_OFS76_FIELD ((RegisterField) {TMC5160_OFS76_MASK, TMC5160_OFS76_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS77_MASK 0x00002000 +#define TMC5160_OFS77_SHIFT 13 +#define TMC5160_OFS77_FIELD ((RegisterField) {TMC5160_OFS77_MASK, TMC5160_OFS77_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS78_MASK 0x00004000 +#define TMC5160_OFS78_SHIFT 14 +#define TMC5160_OFS78_FIELD ((RegisterField) {TMC5160_OFS78_MASK, TMC5160_OFS78_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS79_MASK 0x00008000 +#define TMC5160_OFS79_SHIFT 15 +#define TMC5160_OFS79_FIELD ((RegisterField) {TMC5160_OFS79_MASK, TMC5160_OFS79_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS80_MASK 0x00010000 +#define TMC5160_OFS80_SHIFT 16 +#define TMC5160_OFS80_FIELD ((RegisterField) {TMC5160_OFS80_MASK, TMC5160_OFS80_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS81_MASK 0x00020000 +#define TMC5160_OFS81_SHIFT 17 +#define TMC5160_OFS81_FIELD ((RegisterField) {TMC5160_OFS81_MASK, TMC5160_OFS81_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS82_MASK 0x00040000 +#define TMC5160_OFS82_SHIFT 18 +#define TMC5160_OFS82_FIELD ((RegisterField) {TMC5160_OFS82_MASK, TMC5160_OFS82_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS83_MASK 0x00080000 +#define TMC5160_OFS83_SHIFT 19 +#define TMC5160_OFS83_FIELD ((RegisterField) {TMC5160_OFS83_MASK, TMC5160_OFS83_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS84_MASK 0x00100000 +#define TMC5160_OFS84_SHIFT 20 +#define TMC5160_OFS84_FIELD ((RegisterField) {TMC5160_OFS84_MASK, TMC5160_OFS84_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS85_MASK 0x00200000 +#define TMC5160_OFS85_SHIFT 21 +#define TMC5160_OFS85_FIELD ((RegisterField) {TMC5160_OFS85_MASK, TMC5160_OFS85_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS86_MASK 0x00400000 +#define TMC5160_OFS86_SHIFT 22 +#define TMC5160_OFS86_FIELD ((RegisterField) {TMC5160_OFS86_MASK, TMC5160_OFS86_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS87_MASK 0x00800000 +#define TMC5160_OFS87_SHIFT 23 +#define TMC5160_OFS87_FIELD ((RegisterField) {TMC5160_OFS87_MASK, TMC5160_OFS87_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS88_MASK 0x01000000 +#define TMC5160_OFS88_SHIFT 24 +#define TMC5160_OFS88_FIELD ((RegisterField) {TMC5160_OFS88_MASK, TMC5160_OFS88_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS89_MASK 0x02000000 +#define TMC5160_OFS89_SHIFT 25 +#define TMC5160_OFS89_FIELD ((RegisterField) {TMC5160_OFS89_MASK, TMC5160_OFS89_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS90_MASK 0x04000000 +#define TMC5160_OFS90_SHIFT 26 +#define TMC5160_OFS90_FIELD ((RegisterField) {TMC5160_OFS90_MASK, TMC5160_OFS90_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS91_MASK 0x08000000 +#define TMC5160_OFS91_SHIFT 27 +#define TMC5160_OFS91_FIELD ((RegisterField) {TMC5160_OFS91_MASK, TMC5160_OFS91_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS92_MASK 0x10000000 +#define TMC5160_OFS92_SHIFT 28 +#define TMC5160_OFS92_FIELD ((RegisterField) {TMC5160_OFS92_MASK, TMC5160_OFS92_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS93_MASK 0x20000000 +#define TMC5160_OFS93_SHIFT 29 +#define TMC5160_OFS93_FIELD ((RegisterField) {TMC5160_OFS93_MASK, TMC5160_OFS93_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS94_MASK 0x40000000 +#define TMC5160_OFS94_SHIFT 30 +#define TMC5160_OFS94_FIELD ((RegisterField) {TMC5160_OFS94_MASK, TMC5160_OFS94_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS95_MASK 0x80000000 +#define TMC5160_OFS95_SHIFT 31 +#define TMC5160_OFS95_FIELD ((RegisterField) {TMC5160_OFS95_MASK, TMC5160_OFS95_SHIFT, TMC5160_MSLUT2, false}) +#define TMC5160_OFS96_MASK 0x00000001 +#define TMC5160_OFS96_SHIFT 0 +#define TMC5160_OFS96_FIELD ((RegisterField) {TMC5160_OFS96_MASK, TMC5160_OFS96_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS97_MASK 0x00000002 +#define TMC5160_OFS97_SHIFT 1 +#define TMC5160_OFS97_FIELD ((RegisterField) {TMC5160_OFS97_MASK, TMC5160_OFS97_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS98_MASK 0x00000004 +#define TMC5160_OFS98_SHIFT 2 +#define TMC5160_OFS98_FIELD ((RegisterField) {TMC5160_OFS98_MASK, TMC5160_OFS98_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS99_MASK 0x00000008 +#define TMC5160_OFS99_SHIFT 3 +#define TMC5160_OFS99_FIELD ((RegisterField) {TMC5160_OFS99_MASK, TMC5160_OFS99_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS100_MASK 0x00000010 +#define TMC5160_OFS100_SHIFT 4 +#define TMC5160_OFS100_FIELD ((RegisterField) {TMC5160_OFS100_MASK, TMC5160_OFS100_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS101_MASK 0x00000020 +#define TMC5160_OFS101_SHIFT 5 +#define TMC5160_OFS101_FIELD ((RegisterField) {TMC5160_OFS101_MASK, TMC5160_OFS101_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS102_MASK 0x00000040 +#define TMC5160_OFS102_SHIFT 6 +#define TMC5160_OFS102_FIELD ((RegisterField) {TMC5160_OFS102_MASK, TMC5160_OFS102_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS103_MASK 0x00000080 +#define TMC5160_OFS103_SHIFT 7 +#define TMC5160_OFS103_FIELD ((RegisterField) {TMC5160_OFS103_MASK, TMC5160_OFS103_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS104_MASK 0x00000100 +#define TMC5160_OFS104_SHIFT 8 +#define TMC5160_OFS104_FIELD ((RegisterField) {TMC5160_OFS104_MASK, TMC5160_OFS104_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS105_MASK 0x00000200 +#define TMC5160_OFS105_SHIFT 9 +#define TMC5160_OFS105_FIELD ((RegisterField) {TMC5160_OFS105_MASK, TMC5160_OFS105_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS106_MASK 0x00000400 +#define TMC5160_OFS106_SHIFT 10 +#define TMC5160_OFS106_FIELD ((RegisterField) {TMC5160_OFS106_MASK, TMC5160_OFS106_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS107_MASK 0x00000800 +#define TMC5160_OFS107_SHIFT 11 +#define TMC5160_OFS107_FIELD ((RegisterField) {TMC5160_OFS107_MASK, TMC5160_OFS107_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS108_MASK 0x00001000 +#define TMC5160_OFS108_SHIFT 12 +#define TMC5160_OFS108_FIELD ((RegisterField) {TMC5160_OFS108_MASK, TMC5160_OFS108_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS109_MASK 0x00002000 +#define TMC5160_OFS109_SHIFT 13 +#define TMC5160_OFS109_FIELD ((RegisterField) {TMC5160_OFS109_MASK, TMC5160_OFS109_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS110_MASK 0x00004000 +#define TMC5160_OFS110_SHIFT 14 +#define TMC5160_OFS110_FIELD ((RegisterField) {TMC5160_OFS110_MASK, TMC5160_OFS110_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS111_MASK 0x00008000 +#define TMC5160_OFS111_SHIFT 15 +#define TMC5160_OFS111_FIELD ((RegisterField) {TMC5160_OFS111_MASK, TMC5160_OFS111_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS112_MASK 0x00010000 +#define TMC5160_OFS112_SHIFT 16 +#define TMC5160_OFS112_FIELD ((RegisterField) {TMC5160_OFS112_MASK, TMC5160_OFS112_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS113_MASK 0x00020000 +#define TMC5160_OFS113_SHIFT 17 +#define TMC5160_OFS113_FIELD ((RegisterField) {TMC5160_OFS113_MASK, TMC5160_OFS113_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS114_MASK 0x00040000 +#define TMC5160_OFS114_SHIFT 18 +#define TMC5160_OFS114_FIELD ((RegisterField) {TMC5160_OFS114_MASK, TMC5160_OFS114_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS115_MASK 0x00080000 +#define TMC5160_OFS115_SHIFT 19 +#define TMC5160_OFS115_FIELD ((RegisterField) {TMC5160_OFS115_MASK, TMC5160_OFS115_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS116_MASK 0x00100000 +#define TMC5160_OFS116_SHIFT 20 +#define TMC5160_OFS116_FIELD ((RegisterField) {TMC5160_OFS116_MASK, TMC5160_OFS116_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS117_MASK 0x00200000 +#define TMC5160_OFS117_SHIFT 21 +#define TMC5160_OFS117_FIELD ((RegisterField) {TMC5160_OFS117_MASK, TMC5160_OFS117_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS118_MASK 0x00400000 +#define TMC5160_OFS118_SHIFT 22 +#define TMC5160_OFS118_FIELD ((RegisterField) {TMC5160_OFS118_MASK, TMC5160_OFS118_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS119_MASK 0x00800000 +#define TMC5160_OFS119_SHIFT 23 +#define TMC5160_OFS119_FIELD ((RegisterField) {TMC5160_OFS119_MASK, TMC5160_OFS119_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS120_MASK 0x01000000 +#define TMC5160_OFS120_SHIFT 24 +#define TMC5160_OFS120_FIELD ((RegisterField) {TMC5160_OFS120_MASK, TMC5160_OFS120_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS121_MASK 0x02000000 +#define TMC5160_OFS121_SHIFT 25 +#define TMC5160_OFS121_FIELD ((RegisterField) {TMC5160_OFS121_MASK, TMC5160_OFS121_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS122_MASK 0x04000000 +#define TMC5160_OFS122_SHIFT 26 +#define TMC5160_OFS122_FIELD ((RegisterField) {TMC5160_OFS122_MASK, TMC5160_OFS122_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS123_MASK 0x08000000 +#define TMC5160_OFS123_SHIFT 27 +#define TMC5160_OFS123_FIELD ((RegisterField) {TMC5160_OFS123_MASK, TMC5160_OFS123_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS124_MASK 0x10000000 +#define TMC5160_OFS124_SHIFT 28 +#define TMC5160_OFS124_FIELD ((RegisterField) {TMC5160_OFS124_MASK, TMC5160_OFS124_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS125_MASK 0x20000000 +#define TMC5160_OFS125_SHIFT 29 +#define TMC5160_OFS125_FIELD ((RegisterField) {TMC5160_OFS125_MASK, TMC5160_OFS125_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS126_MASK 0x40000000 +#define TMC5160_OFS126_SHIFT 30 +#define TMC5160_OFS126_FIELD ((RegisterField) {TMC5160_OFS126_MASK, TMC5160_OFS126_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS127_MASK 0x80000000 +#define TMC5160_OFS127_SHIFT 31 +#define TMC5160_OFS127_FIELD ((RegisterField) {TMC5160_OFS127_MASK, TMC5160_OFS127_SHIFT, TMC5160_MSLUT3, false}) +#define TMC5160_OFS128_MASK 0x00000001 +#define TMC5160_OFS128_SHIFT 0 +#define TMC5160_OFS128_FIELD ((RegisterField) {TMC5160_OFS128_MASK, TMC5160_OFS128_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS129_MASK 0x00000002 +#define TMC5160_OFS129_SHIFT 1 +#define TMC5160_OFS129_FIELD ((RegisterField) {TMC5160_OFS129_MASK, TMC5160_OFS129_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS130_MASK 0x00000004 +#define TMC5160_OFS130_SHIFT 2 +#define TMC5160_OFS130_FIELD ((RegisterField) {TMC5160_OFS130_MASK, TMC5160_OFS130_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS131_MASK 0x00000008 +#define TMC5160_OFS131_SHIFT 3 +#define TMC5160_OFS131_FIELD ((RegisterField) {TMC5160_OFS131_MASK, TMC5160_OFS131_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS132_MASK 0x00000010 +#define TMC5160_OFS132_SHIFT 4 +#define TMC5160_OFS132_FIELD ((RegisterField) {TMC5160_OFS132_MASK, TMC5160_OFS132_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS133_MASK 0x00000020 +#define TMC5160_OFS133_SHIFT 5 +#define TMC5160_OFS133_FIELD ((RegisterField) {TMC5160_OFS133_MASK, TMC5160_OFS133_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS134_MASK 0x00000040 +#define TMC5160_OFS134_SHIFT 6 +#define TMC5160_OFS134_FIELD ((RegisterField) {TMC5160_OFS134_MASK, TMC5160_OFS134_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS135_MASK 0x00000080 +#define TMC5160_OFS135_SHIFT 7 +#define TMC5160_OFS135_FIELD ((RegisterField) {TMC5160_OFS135_MASK, TMC5160_OFS135_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS136_MASK 0x00000100 +#define TMC5160_OFS136_SHIFT 8 +#define TMC5160_OFS136_FIELD ((RegisterField) {TMC5160_OFS136_MASK, TMC5160_OFS136_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS137_MASK 0x00000200 +#define TMC5160_OFS137_SHIFT 9 +#define TMC5160_OFS137_FIELD ((RegisterField) {TMC5160_OFS137_MASK, TMC5160_OFS137_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS138_MASK 0x00000400 +#define TMC5160_OFS138_SHIFT 10 +#define TMC5160_OFS138_FIELD ((RegisterField) {TMC5160_OFS138_MASK, TMC5160_OFS138_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS139_MASK 0x00000800 +#define TMC5160_OFS139_SHIFT 11 +#define TMC5160_OFS139_FIELD ((RegisterField) {TMC5160_OFS139_MASK, TMC5160_OFS139_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS140_MASK 0x00001000 +#define TMC5160_OFS140_SHIFT 12 +#define TMC5160_OFS140_FIELD ((RegisterField) {TMC5160_OFS140_MASK, TMC5160_OFS140_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS141_MASK 0x00002000 +#define TMC5160_OFS141_SHIFT 13 +#define TMC5160_OFS141_FIELD ((RegisterField) {TMC5160_OFS141_MASK, TMC5160_OFS141_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS142_MASK 0x00004000 +#define TMC5160_OFS142_SHIFT 14 +#define TMC5160_OFS142_FIELD ((RegisterField) {TMC5160_OFS142_MASK, TMC5160_OFS142_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS143_MASK 0x00008000 +#define TMC5160_OFS143_SHIFT 15 +#define TMC5160_OFS143_FIELD ((RegisterField) {TMC5160_OFS143_MASK, TMC5160_OFS143_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS144_MASK 0x00010000 +#define TMC5160_OFS144_SHIFT 16 +#define TMC5160_OFS144_FIELD ((RegisterField) {TMC5160_OFS144_MASK, TMC5160_OFS144_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS145_MASK 0x00020000 +#define TMC5160_OFS145_SHIFT 17 +#define TMC5160_OFS145_FIELD ((RegisterField) {TMC5160_OFS145_MASK, TMC5160_OFS145_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS146_MASK 0x00040000 +#define TMC5160_OFS146_SHIFT 18 +#define TMC5160_OFS146_FIELD ((RegisterField) {TMC5160_OFS146_MASK, TMC5160_OFS146_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS147_MASK 0x00080000 +#define TMC5160_OFS147_SHIFT 19 +#define TMC5160_OFS147_FIELD ((RegisterField) {TMC5160_OFS147_MASK, TMC5160_OFS147_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS148_MASK 0x00100000 +#define TMC5160_OFS148_SHIFT 20 +#define TMC5160_OFS148_FIELD ((RegisterField) {TMC5160_OFS148_MASK, TMC5160_OFS148_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS149_MASK 0x00200000 +#define TMC5160_OFS149_SHIFT 21 +#define TMC5160_OFS149_FIELD ((RegisterField) {TMC5160_OFS149_MASK, TMC5160_OFS149_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS150_MASK 0x00400000 +#define TMC5160_OFS150_SHIFT 22 +#define TMC5160_OFS150_FIELD ((RegisterField) {TMC5160_OFS150_MASK, TMC5160_OFS150_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS151_MASK 0x00800000 +#define TMC5160_OFS151_SHIFT 23 +#define TMC5160_OFS151_FIELD ((RegisterField) {TMC5160_OFS151_MASK, TMC5160_OFS151_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS152_MASK 0x01000000 +#define TMC5160_OFS152_SHIFT 24 +#define TMC5160_OFS152_FIELD ((RegisterField) {TMC5160_OFS152_MASK, TMC5160_OFS152_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS153_MASK 0x02000000 +#define TMC5160_OFS153_SHIFT 25 +#define TMC5160_OFS153_FIELD ((RegisterField) {TMC5160_OFS153_MASK, TMC5160_OFS153_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS154_MASK 0x04000000 +#define TMC5160_OFS154_SHIFT 26 +#define TMC5160_OFS154_FIELD ((RegisterField) {TMC5160_OFS154_MASK, TMC5160_OFS154_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS155_MASK 0x08000000 +#define TMC5160_OFS155_SHIFT 27 +#define TMC5160_OFS155_FIELD ((RegisterField) {TMC5160_OFS155_MASK, TMC5160_OFS155_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS156_MASK 0x10000000 +#define TMC5160_OFS156_SHIFT 28 +#define TMC5160_OFS156_FIELD ((RegisterField) {TMC5160_OFS156_MASK, TMC5160_OFS156_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS157_MASK 0x20000000 +#define TMC5160_OFS157_SHIFT 29 +#define TMC5160_OFS157_FIELD ((RegisterField) {TMC5160_OFS157_MASK, TMC5160_OFS157_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS158_MASK 0x40000000 +#define TMC5160_OFS158_SHIFT 30 +#define TMC5160_OFS158_FIELD ((RegisterField) {TMC5160_OFS158_MASK, TMC5160_OFS158_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS159_MASK 0x80000000 +#define TMC5160_OFS159_SHIFT 31 +#define TMC5160_OFS159_FIELD ((RegisterField) {TMC5160_OFS159_MASK, TMC5160_OFS159_SHIFT, TMC5160_MSLUT4, false}) +#define TMC5160_OFS160_MASK 0x00000001 +#define TMC5160_OFS160_SHIFT 0 +#define TMC5160_OFS160_FIELD ((RegisterField) {TMC5160_OFS160_MASK, TMC5160_OFS160_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS161_MASK 0x00000002 +#define TMC5160_OFS161_SHIFT 1 +#define TMC5160_OFS161_FIELD ((RegisterField) {TMC5160_OFS161_MASK, TMC5160_OFS161_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS162_MASK 0x00000004 +#define TMC5160_OFS162_SHIFT 2 +#define TMC5160_OFS162_FIELD ((RegisterField) {TMC5160_OFS162_MASK, TMC5160_OFS162_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS163_MASK 0x00000008 +#define TMC5160_OFS163_SHIFT 3 +#define TMC5160_OFS163_FIELD ((RegisterField) {TMC5160_OFS163_MASK, TMC5160_OFS163_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS164_MASK 0x00000010 +#define TMC5160_OFS164_SHIFT 4 +#define TMC5160_OFS164_FIELD ((RegisterField) {TMC5160_OFS164_MASK, TMC5160_OFS164_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS165_MASK 0x00000020 +#define TMC5160_OFS165_SHIFT 5 +#define TMC5160_OFS165_FIELD ((RegisterField) {TMC5160_OFS165_MASK, TMC5160_OFS165_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS166_MASK 0x00000040 +#define TMC5160_OFS166_SHIFT 6 +#define TMC5160_OFS166_FIELD ((RegisterField) {TMC5160_OFS166_MASK, TMC5160_OFS166_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS167_MASK 0x00000080 +#define TMC5160_OFS167_SHIFT 7 +#define TMC5160_OFS167_FIELD ((RegisterField) {TMC5160_OFS167_MASK, TMC5160_OFS167_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS168_MASK 0x00000100 +#define TMC5160_OFS168_SHIFT 8 +#define TMC5160_OFS168_FIELD ((RegisterField) {TMC5160_OFS168_MASK, TMC5160_OFS168_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS169_MASK 0x00000200 +#define TMC5160_OFS169_SHIFT 9 +#define TMC5160_OFS169_FIELD ((RegisterField) {TMC5160_OFS169_MASK, TMC5160_OFS169_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS170_MASK 0x00000400 +#define TMC5160_OFS170_SHIFT 10 +#define TMC5160_OFS170_FIELD ((RegisterField) {TMC5160_OFS170_MASK, TMC5160_OFS170_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS171_MASK 0x00000800 +#define TMC5160_OFS171_SHIFT 11 +#define TMC5160_OFS171_FIELD ((RegisterField) {TMC5160_OFS171_MASK, TMC5160_OFS171_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS172_MASK 0x00001000 +#define TMC5160_OFS172_SHIFT 12 +#define TMC5160_OFS172_FIELD ((RegisterField) {TMC5160_OFS172_MASK, TMC5160_OFS172_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS173_MASK 0x00002000 +#define TMC5160_OFS173_SHIFT 13 +#define TMC5160_OFS173_FIELD ((RegisterField) {TMC5160_OFS173_MASK, TMC5160_OFS173_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS174_MASK 0x00004000 +#define TMC5160_OFS174_SHIFT 14 +#define TMC5160_OFS174_FIELD ((RegisterField) {TMC5160_OFS174_MASK, TMC5160_OFS174_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS175_MASK 0x00008000 +#define TMC5160_OFS175_SHIFT 15 +#define TMC5160_OFS175_FIELD ((RegisterField) {TMC5160_OFS175_MASK, TMC5160_OFS175_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS176_MASK 0x00010000 +#define TMC5160_OFS176_SHIFT 16 +#define TMC5160_OFS176_FIELD ((RegisterField) {TMC5160_OFS176_MASK, TMC5160_OFS176_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS177_MASK 0x00020000 +#define TMC5160_OFS177_SHIFT 17 +#define TMC5160_OFS177_FIELD ((RegisterField) {TMC5160_OFS177_MASK, TMC5160_OFS177_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS178_MASK 0x00040000 +#define TMC5160_OFS178_SHIFT 18 +#define TMC5160_OFS178_FIELD ((RegisterField) {TMC5160_OFS178_MASK, TMC5160_OFS178_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS179_MASK 0x00080000 +#define TMC5160_OFS179_SHIFT 19 +#define TMC5160_OFS179_FIELD ((RegisterField) {TMC5160_OFS179_MASK, TMC5160_OFS179_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS180_MASK 0x00100000 +#define TMC5160_OFS180_SHIFT 20 +#define TMC5160_OFS180_FIELD ((RegisterField) {TMC5160_OFS180_MASK, TMC5160_OFS180_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS181_MASK 0x00200000 +#define TMC5160_OFS181_SHIFT 21 +#define TMC5160_OFS181_FIELD ((RegisterField) {TMC5160_OFS181_MASK, TMC5160_OFS181_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS182_MASK 0x00400000 +#define TMC5160_OFS182_SHIFT 22 +#define TMC5160_OFS182_FIELD ((RegisterField) {TMC5160_OFS182_MASK, TMC5160_OFS182_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS183_MASK 0x00800000 +#define TMC5160_OFS183_SHIFT 23 +#define TMC5160_OFS183_FIELD ((RegisterField) {TMC5160_OFS183_MASK, TMC5160_OFS183_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS184_MASK 0x01000000 +#define TMC5160_OFS184_SHIFT 24 +#define TMC5160_OFS184_FIELD ((RegisterField) {TMC5160_OFS184_MASK, TMC5160_OFS184_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS185_MASK 0x02000000 +#define TMC5160_OFS185_SHIFT 25 +#define TMC5160_OFS185_FIELD ((RegisterField) {TMC5160_OFS185_MASK, TMC5160_OFS185_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS186_MASK 0x04000000 +#define TMC5160_OFS186_SHIFT 26 +#define TMC5160_OFS186_FIELD ((RegisterField) {TMC5160_OFS186_MASK, TMC5160_OFS186_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS187_MASK 0x08000000 +#define TMC5160_OFS187_SHIFT 27 +#define TMC5160_OFS187_FIELD ((RegisterField) {TMC5160_OFS187_MASK, TMC5160_OFS187_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS188_MASK 0x10000000 +#define TMC5160_OFS188_SHIFT 28 +#define TMC5160_OFS188_FIELD ((RegisterField) {TMC5160_OFS188_MASK, TMC5160_OFS188_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS189_MASK 0x20000000 +#define TMC5160_OFS189_SHIFT 29 +#define TMC5160_OFS189_FIELD ((RegisterField) {TMC5160_OFS189_MASK, TMC5160_OFS189_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS190_MASK 0x40000000 +#define TMC5160_OFS190_SHIFT 30 +#define TMC5160_OFS190_FIELD ((RegisterField) {TMC5160_OFS190_MASK, TMC5160_OFS190_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS191_MASK 0x80000000 +#define TMC5160_OFS191_SHIFT 31 +#define TMC5160_OFS191_FIELD ((RegisterField) {TMC5160_OFS191_MASK, TMC5160_OFS191_SHIFT, TMC5160_MSLUT5, false}) +#define TMC5160_OFS192_MASK 0x00000001 +#define TMC5160_OFS192_SHIFT 0 +#define TMC5160_OFS192_FIELD ((RegisterField) {TMC5160_OFS192_MASK, TMC5160_OFS192_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS193_MASK 0x00000002 +#define TMC5160_OFS193_SHIFT 1 +#define TMC5160_OFS193_FIELD ((RegisterField) {TMC5160_OFS193_MASK, TMC5160_OFS193_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS194_MASK 0x00000004 +#define TMC5160_OFS194_SHIFT 2 +#define TMC5160_OFS194_FIELD ((RegisterField) {TMC5160_OFS194_MASK, TMC5160_OFS194_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS195_MASK 0x00000008 +#define TMC5160_OFS195_SHIFT 3 +#define TMC5160_OFS195_FIELD ((RegisterField) {TMC5160_OFS195_MASK, TMC5160_OFS195_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS196_MASK 0x00000010 +#define TMC5160_OFS196_SHIFT 4 +#define TMC5160_OFS196_FIELD ((RegisterField) {TMC5160_OFS196_MASK, TMC5160_OFS196_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS197_MASK 0x00000020 +#define TMC5160_OFS197_SHIFT 5 +#define TMC5160_OFS197_FIELD ((RegisterField) {TMC5160_OFS197_MASK, TMC5160_OFS197_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS198_MASK 0x00000040 +#define TMC5160_OFS198_SHIFT 6 +#define TMC5160_OFS198_FIELD ((RegisterField) {TMC5160_OFS198_MASK, TMC5160_OFS198_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS199_MASK 0x00000080 +#define TMC5160_OFS199_SHIFT 7 +#define TMC5160_OFS199_FIELD ((RegisterField) {TMC5160_OFS199_MASK, TMC5160_OFS199_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS200_MASK 0x00000100 +#define TMC5160_OFS200_SHIFT 8 +#define TMC5160_OFS200_FIELD ((RegisterField) {TMC5160_OFS200_MASK, TMC5160_OFS200_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS201_MASK 0x00000200 +#define TMC5160_OFS201_SHIFT 9 +#define TMC5160_OFS201_FIELD ((RegisterField) {TMC5160_OFS201_MASK, TMC5160_OFS201_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS202_MASK 0x00000400 +#define TMC5160_OFS202_SHIFT 10 +#define TMC5160_OFS202_FIELD ((RegisterField) {TMC5160_OFS202_MASK, TMC5160_OFS202_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS203_MASK 0x00000800 +#define TMC5160_OFS203_SHIFT 11 +#define TMC5160_OFS203_FIELD ((RegisterField) {TMC5160_OFS203_MASK, TMC5160_OFS203_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS204_MASK 0x00001000 +#define TMC5160_OFS204_SHIFT 12 +#define TMC5160_OFS204_FIELD ((RegisterField) {TMC5160_OFS204_MASK, TMC5160_OFS204_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS205_MASK 0x00002000 +#define TMC5160_OFS205_SHIFT 13 +#define TMC5160_OFS205_FIELD ((RegisterField) {TMC5160_OFS205_MASK, TMC5160_OFS205_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS206_MASK 0x00004000 +#define TMC5160_OFS206_SHIFT 14 +#define TMC5160_OFS206_FIELD ((RegisterField) {TMC5160_OFS206_MASK, TMC5160_OFS206_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS207_MASK 0x00008000 +#define TMC5160_OFS207_SHIFT 15 +#define TMC5160_OFS207_FIELD ((RegisterField) {TMC5160_OFS207_MASK, TMC5160_OFS207_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS208_MASK 0x00010000 +#define TMC5160_OFS208_SHIFT 16 +#define TMC5160_OFS208_FIELD ((RegisterField) {TMC5160_OFS208_MASK, TMC5160_OFS208_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS209_MASK 0x00020000 +#define TMC5160_OFS209_SHIFT 17 +#define TMC5160_OFS209_FIELD ((RegisterField) {TMC5160_OFS209_MASK, TMC5160_OFS209_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS210_MASK 0x00040000 +#define TMC5160_OFS210_SHIFT 18 +#define TMC5160_OFS210_FIELD ((RegisterField) {TMC5160_OFS210_MASK, TMC5160_OFS210_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS211_MASK 0x00080000 +#define TMC5160_OFS211_SHIFT 19 +#define TMC5160_OFS211_FIELD ((RegisterField) {TMC5160_OFS211_MASK, TMC5160_OFS211_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS212_MASK 0x00100000 +#define TMC5160_OFS212_SHIFT 20 +#define TMC5160_OFS212_FIELD ((RegisterField) {TMC5160_OFS212_MASK, TMC5160_OFS212_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS213_MASK 0x00200000 +#define TMC5160_OFS213_SHIFT 21 +#define TMC5160_OFS213_FIELD ((RegisterField) {TMC5160_OFS213_MASK, TMC5160_OFS213_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS214_MASK 0x00400000 +#define TMC5160_OFS214_SHIFT 22 +#define TMC5160_OFS214_FIELD ((RegisterField) {TMC5160_OFS214_MASK, TMC5160_OFS214_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS215_MASK 0x00800000 +#define TMC5160_OFS215_SHIFT 23 +#define TMC5160_OFS215_FIELD ((RegisterField) {TMC5160_OFS215_MASK, TMC5160_OFS215_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS216_MASK 0x01000000 +#define TMC5160_OFS216_SHIFT 24 +#define TMC5160_OFS216_FIELD ((RegisterField) {TMC5160_OFS216_MASK, TMC5160_OFS216_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS217_MASK 0x02000000 +#define TMC5160_OFS217_SHIFT 25 +#define TMC5160_OFS217_FIELD ((RegisterField) {TMC5160_OFS217_MASK, TMC5160_OFS217_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS218_MASK 0x04000000 +#define TMC5160_OFS218_SHIFT 26 +#define TMC5160_OFS218_FIELD ((RegisterField) {TMC5160_OFS218_MASK, TMC5160_OFS218_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS219_MASK 0x08000000 +#define TMC5160_OFS219_SHIFT 27 +#define TMC5160_OFS219_FIELD ((RegisterField) {TMC5160_OFS219_MASK, TMC5160_OFS219_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS220_MASK 0x10000000 +#define TMC5160_OFS220_SHIFT 28 +#define TMC5160_OFS220_FIELD ((RegisterField) {TMC5160_OFS220_MASK, TMC5160_OFS220_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS221_MASK 0x20000000 +#define TMC5160_OFS221_SHIFT 29 +#define TMC5160_OFS221_FIELD ((RegisterField) {TMC5160_OFS221_MASK, TMC5160_OFS221_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS222_MASK 0x40000000 +#define TMC5160_OFS222_SHIFT 30 +#define TMC5160_OFS222_FIELD ((RegisterField) {TMC5160_OFS222_MASK, TMC5160_OFS222_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS223_MASK 0x80000000 +#define TMC5160_OFS223_SHIFT 31 +#define TMC5160_OFS223_FIELD ((RegisterField) {TMC5160_OFS223_MASK, TMC5160_OFS223_SHIFT, TMC5160_MSLUT6, false}) +#define TMC5160_OFS224_MASK 0x00000001 +#define TMC5160_OFS224_SHIFT 0 +#define TMC5160_OFS224_FIELD ((RegisterField) {TMC5160_OFS224_MASK, TMC5160_OFS224_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS225_MASK 0x00000002 +#define TMC5160_OFS225_SHIFT 1 +#define TMC5160_OFS225_FIELD ((RegisterField) {TMC5160_OFS225_MASK, TMC5160_OFS225_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS226_MASK 0x00000004 +#define TMC5160_OFS226_SHIFT 2 +#define TMC5160_OFS226_FIELD ((RegisterField) {TMC5160_OFS226_MASK, TMC5160_OFS226_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS227_MASK 0x00000008 +#define TMC5160_OFS227_SHIFT 3 +#define TMC5160_OFS227_FIELD ((RegisterField) {TMC5160_OFS227_MASK, TMC5160_OFS227_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS228_MASK 0x00000010 +#define TMC5160_OFS228_SHIFT 4 +#define TMC5160_OFS228_FIELD ((RegisterField) {TMC5160_OFS228_MASK, TMC5160_OFS228_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS229_MASK 0x00000020 +#define TMC5160_OFS229_SHIFT 5 +#define TMC5160_OFS229_FIELD ((RegisterField) {TMC5160_OFS229_MASK, TMC5160_OFS229_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS230_MASK 0x00000040 +#define TMC5160_OFS230_SHIFT 6 +#define TMC5160_OFS230_FIELD ((RegisterField) {TMC5160_OFS230_MASK, TMC5160_OFS230_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS231_MASK 0x00000080 +#define TMC5160_OFS231_SHIFT 7 +#define TMC5160_OFS231_FIELD ((RegisterField) {TMC5160_OFS231_MASK, TMC5160_OFS231_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS232_MASK 0x00000100 +#define TMC5160_OFS232_SHIFT 8 +#define TMC5160_OFS232_FIELD ((RegisterField) {TMC5160_OFS232_MASK, TMC5160_OFS232_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS233_MASK 0x00000200 +#define TMC5160_OFS233_SHIFT 9 +#define TMC5160_OFS233_FIELD ((RegisterField) {TMC5160_OFS233_MASK, TMC5160_OFS233_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS234_MASK 0x00000400 +#define TMC5160_OFS234_SHIFT 10 +#define TMC5160_OFS234_FIELD ((RegisterField) {TMC5160_OFS234_MASK, TMC5160_OFS234_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS235_MASK 0x00000800 +#define TMC5160_OFS235_SHIFT 11 +#define TMC5160_OFS235_FIELD ((RegisterField) {TMC5160_OFS235_MASK, TMC5160_OFS235_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS236_MASK 0x00001000 +#define TMC5160_OFS236_SHIFT 12 +#define TMC5160_OFS236_FIELD ((RegisterField) {TMC5160_OFS236_MASK, TMC5160_OFS236_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS237_MASK 0x00002000 +#define TMC5160_OFS237_SHIFT 13 +#define TMC5160_OFS237_FIELD ((RegisterField) {TMC5160_OFS237_MASK, TMC5160_OFS237_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS238_MASK 0x00004000 +#define TMC5160_OFS238_SHIFT 14 +#define TMC5160_OFS238_FIELD ((RegisterField) {TMC5160_OFS238_MASK, TMC5160_OFS238_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS239_MASK 0x00008000 +#define TMC5160_OFS239_SHIFT 15 +#define TMC5160_OFS239_FIELD ((RegisterField) {TMC5160_OFS239_MASK, TMC5160_OFS239_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS240_MASK 0x00010000 +#define TMC5160_OFS240_SHIFT 16 +#define TMC5160_OFS240_FIELD ((RegisterField) {TMC5160_OFS240_MASK, TMC5160_OFS240_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS241_MASK 0x00020000 +#define TMC5160_OFS241_SHIFT 17 +#define TMC5160_OFS241_FIELD ((RegisterField) {TMC5160_OFS241_MASK, TMC5160_OFS241_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS242_MASK 0x00040000 +#define TMC5160_OFS242_SHIFT 18 +#define TMC5160_OFS242_FIELD ((RegisterField) {TMC5160_OFS242_MASK, TMC5160_OFS242_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS243_MASK 0x00080000 +#define TMC5160_OFS243_SHIFT 19 +#define TMC5160_OFS243_FIELD ((RegisterField) {TMC5160_OFS243_MASK, TMC5160_OFS243_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS244_MASK 0x00100000 +#define TMC5160_OFS244_SHIFT 20 +#define TMC5160_OFS244_FIELD ((RegisterField) {TMC5160_OFS244_MASK, TMC5160_OFS244_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS245_MASK 0x00200000 +#define TMC5160_OFS245_SHIFT 21 +#define TMC5160_OFS245_FIELD ((RegisterField) {TMC5160_OFS245_MASK, TMC5160_OFS245_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS246_MASK 0x00400000 +#define TMC5160_OFS246_SHIFT 22 +#define TMC5160_OFS246_FIELD ((RegisterField) {TMC5160_OFS246_MASK, TMC5160_OFS246_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS247_MASK 0x00800000 +#define TMC5160_OFS247_SHIFT 23 +#define TMC5160_OFS247_FIELD ((RegisterField) {TMC5160_OFS247_MASK, TMC5160_OFS247_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS248_MASK 0x01000000 +#define TMC5160_OFS248_SHIFT 24 +#define TMC5160_OFS248_FIELD ((RegisterField) {TMC5160_OFS248_MASK, TMC5160_OFS248_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS249_MASK 0x02000000 +#define TMC5160_OFS249_SHIFT 25 +#define TMC5160_OFS249_FIELD ((RegisterField) {TMC5160_OFS249_MASK, TMC5160_OFS249_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS250_MASK 0x04000000 +#define TMC5160_OFS250_SHIFT 26 +#define TMC5160_OFS250_FIELD ((RegisterField) {TMC5160_OFS250_MASK, TMC5160_OFS250_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS251_MASK 0x08000000 +#define TMC5160_OFS251_SHIFT 27 +#define TMC5160_OFS251_FIELD ((RegisterField) {TMC5160_OFS251_MASK, TMC5160_OFS251_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS252_MASK 0x10000000 +#define TMC5160_OFS252_SHIFT 28 +#define TMC5160_OFS252_FIELD ((RegisterField) {TMC5160_OFS252_MASK, TMC5160_OFS252_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS253_MASK 0x20000000 +#define TMC5160_OFS253_SHIFT 29 +#define TMC5160_OFS253_FIELD ((RegisterField) {TMC5160_OFS253_MASK, TMC5160_OFS253_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS254_MASK 0x40000000 +#define TMC5160_OFS254_SHIFT 30 +#define TMC5160_OFS254_FIELD ((RegisterField) {TMC5160_OFS254_MASK, TMC5160_OFS254_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_OFS255_MASK 0x80000000 +#define TMC5160_OFS255_SHIFT 31 +#define TMC5160_OFS255_FIELD ((RegisterField) {TMC5160_OFS255_MASK, TMC5160_OFS255_SHIFT, TMC5160_MSLUT7, false}) +#define TMC5160_W0_MASK 0x00000003 +#define TMC5160_W0_SHIFT 0 +#define TMC5160_W0_FIELD ((RegisterField) {TMC5160_W0_MASK, TMC5160_W0_SHIFT, TMC5160_MSLUTSEL, false}) +#define TMC5160_W1_MASK 0x0000000C +#define TMC5160_W1_SHIFT 2 +#define TMC5160_W1_FIELD ((RegisterField) {TMC5160_W1_MASK, TMC5160_W1_SHIFT, TMC5160_MSLUTSEL, false}) +#define TMC5160_W2_MASK 0x00000030 +#define TMC5160_W2_SHIFT 4 +#define TMC5160_W2_FIELD ((RegisterField) {TMC5160_W2_MASK, TMC5160_W2_SHIFT, TMC5160_MSLUTSEL, false}) +#define TMC5160_W3_MASK 0x000000C0 +#define TMC5160_W3_SHIFT 6 +#define TMC5160_W3_FIELD ((RegisterField) {TMC5160_W3_MASK, TMC5160_W3_SHIFT, TMC5160_MSLUTSEL, false}) +#define TMC5160_X1_MASK 0x0000FF00 +#define TMC5160_X1_SHIFT 8 +#define TMC5160_X1_FIELD ((RegisterField) {TMC5160_X1_MASK, TMC5160_X1_SHIFT, TMC5160_MSLUTSEL, false}) +#define TMC5160_X2_MASK 0x00FF0000 +#define TMC5160_X2_SHIFT 16 +#define TMC5160_X2_FIELD ((RegisterField) {TMC5160_X2_MASK, TMC5160_X2_SHIFT, TMC5160_MSLUTSEL, false}) +#define TMC5160_X3_MASK 0xFF000000 +#define TMC5160_X3_SHIFT 24 +#define TMC5160_X3_FIELD ((RegisterField) {TMC5160_X3_MASK, TMC5160_X3_SHIFT, TMC5160_MSLUTSEL, false}) +#define TMC5160_START_SIN_MASK 0x000000FF +#define TMC5160_START_SIN_SHIFT 0 +#define TMC5160_START_SIN_FIELD ((RegisterField) {TMC5160_START_SIN_MASK, TMC5160_START_SIN_SHIFT, TMC5160_MSLUTSTART, false}) +#define TMC5160_START_SIN90_MASK 0x00FF0000 +#define TMC5160_START_SIN90_SHIFT 16 +#define TMC5160_START_SIN90_FIELD ((RegisterField) {TMC5160_START_SIN90_MASK, TMC5160_START_SIN90_SHIFT, TMC5160_MSLUTSTART, false}) +#define TMC5160_MSCNT_MASK 0x000003FF +#define TMC5160_MSCNT_SHIFT 0 +#define TMC5160_MSCNT_FIELD ((RegisterField) {TMC5160_MSCNT_MASK, TMC5160_MSCNT_SHIFT, TMC5160_MSCNT, false}) +#define TMC5160_CUR_A_MASK 0x000001FF +#define TMC5160_CUR_A_SHIFT 0 +#define TMC5160_CUR_A_FIELD ((RegisterField) {TMC5160_CUR_A_MASK, TMC5160_CUR_A_SHIFT, TMC5160_MSCURACT, true}) +#define TMC5160_CUR_B_MASK 0x01FF0000 +#define TMC5160_CUR_B_SHIFT 16 +#define TMC5160_CUR_B_FIELD ((RegisterField) {TMC5160_CUR_B_MASK, TMC5160_CUR_B_SHIFT, TMC5160_MSCURACT, true}) +#define TMC5160_TOFF_MASK 0x0000000F +#define TMC5160_TOFF_SHIFT 0 +#define TMC5160_TOFF_FIELD ((RegisterField) {TMC5160_TOFF_MASK, TMC5160_TOFF_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_TFD_2__0__MASK 0x00000070 +#define TMC5160_TFD_2__0__SHIFT 4 +#define TMC5160_TFD_2__0__FIELD ((RegisterField) {TMC5160_TFD_2__0__MASK, TMC5160_TFD_2__0__SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_OFFSET_MASK 0x00000780 +#define TMC5160_OFFSET_SHIFT 7 +#define TMC5160_OFFSET_FIELD ((RegisterField) {TMC5160_OFFSET_MASK, TMC5160_OFFSET_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_TFD___MASK 0x00000800 +#define TMC5160_TFD___SHIFT 11 +#define TMC5160_TFD___FIELD ((RegisterField) {TMC5160_TFD___MASK, TMC5160_TFD___SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_DISFDCC_MASK 0x00001000 +#define TMC5160_DISFDCC_SHIFT 12 +#define TMC5160_DISFDCC_FIELD ((RegisterField) {TMC5160_DISFDCC_MASK, TMC5160_DISFDCC_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_CHM_MASK 0x00004000 +#define TMC5160_CHM_SHIFT 14 +#define TMC5160_CHM_FIELD ((RegisterField) {TMC5160_CHM_MASK, TMC5160_CHM_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_TBL_MASK 0x00018000 +#define TMC5160_TBL_SHIFT 15 +#define TMC5160_TBL_FIELD ((RegisterField) {TMC5160_TBL_MASK, TMC5160_TBL_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_VHIGHFS_MASK 0x00040000 +#define TMC5160_VHIGHFS_SHIFT 18 +#define TMC5160_VHIGHFS_FIELD ((RegisterField) {TMC5160_VHIGHFS_MASK, TMC5160_VHIGHFS_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_VHIGHCHM_MASK 0x00080000 +#define TMC5160_VHIGHCHM_SHIFT 19 +#define TMC5160_VHIGHCHM_FIELD ((RegisterField) {TMC5160_VHIGHCHM_MASK, TMC5160_VHIGHCHM_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_TPFD_MASK 0x00F00000 +#define TMC5160_TPFD_SHIFT 20 +#define TMC5160_TPFD_FIELD ((RegisterField) {TMC5160_TPFD_MASK, TMC5160_TPFD_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_MRES_MASK 0x0F000000 +#define TMC5160_MRES_SHIFT 24 +#define TMC5160_MRES_FIELD ((RegisterField) {TMC5160_MRES_MASK, TMC5160_MRES_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_INTPOL_MASK 0x10000000 +#define TMC5160_INTPOL_SHIFT 28 +#define TMC5160_INTPOL_FIELD ((RegisterField) {TMC5160_INTPOL_MASK, TMC5160_INTPOL_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_DEDGE_MASK 0x20000000 +#define TMC5160_DEDGE_SHIFT 29 +#define TMC5160_DEDGE_FIELD ((RegisterField) {TMC5160_DEDGE_MASK, TMC5160_DEDGE_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_DISS2G_MASK 0x40000000 +#define TMC5160_DISS2G_SHIFT 30 +#define TMC5160_DISS2G_FIELD ((RegisterField) {TMC5160_DISS2G_MASK, TMC5160_DISS2G_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_DISS2VS_MASK 0x80000000 +#define TMC5160_DISS2VS_SHIFT 31 +#define TMC5160_DISS2VS_FIELD ((RegisterField) {TMC5160_DISS2VS_MASK, TMC5160_DISS2VS_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_TOFF_MASK 0x0000000F +#define TMC5160_TOFF_SHIFT 0 +#define TMC5160_TOFF_FIELD ((RegisterField) {TMC5160_TOFF_MASK, TMC5160_TOFF_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_TFD_ALL_MASK 0x00000070 +#define TMC5160_TFD_ALL_SHIFT 4 +#define TMC5160_TFD_ALL_FIELD ((RegisterField) {TMC5160_TFD_2__0__MASK, TMC5160_TFD_2__0__SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_OFFSET_MASK 0x00000780 +#define TMC5160_OFFSET_SHIFT 7 +#define TMC5160_OFFSET_FIELD ((RegisterField) {TMC5160_OFFSET_MASK, TMC5160_OFFSET_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_TFD_3_MASK 0x00000800 +#define TMC5160_TFD_3_SHIFT 11 +#define TMC5160_TFD_3_FIELD ((RegisterField) {TMC5160_TFD___MASK, TMC5160_TFD___SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_DISFDCC_MASK 0x00001000 +#define TMC5160_DISFDCC_SHIFT 12 +#define TMC5160_DISFDCC_FIELD ((RegisterField) {TMC5160_DISFDCC_MASK, TMC5160_DISFDCC_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_RNDTF_MASK 0x00002000 +#define TMC5160_RNDTF_SHIFT 13 +#define TMC5160_RNDTF_FIELD ((RegisterField) {TMC5160_RNDTF_MASK, TMC5160_RNDTF_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_CHM_MASK 0x00004000 +#define TMC5160_CHM_SHIFT 14 +#define TMC5160_CHM_FIELD ((RegisterField) {TMC5160_CHM_MASK, TMC5160_CHM_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_TBL_MASK 0x00018000 +#define TMC5160_TBL_SHIFT 15 +#define TMC5160_TBL_FIELD ((RegisterField) {TMC5160_TBL_MASK, TMC5160_TBL_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_VSENSE_MASK 0x00020000 +#define TMC5160_VSENSE_SHIFT 17 +#define TMC5160_VSENSE_FIELD ((RegisterField) {TMC5160_VSENSE_MASK, TMC5160_VSENSE_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_VHIGHFS_MASK 0x00040000 +#define TMC5160_VHIGHFS_SHIFT 18 +#define TMC5160_VHIGHFS_FIELD ((RegisterField) {TMC5160_VHIGHFS_MASK, TMC5160_VHIGHFS_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_VHIGHCHM_MASK 0x00080000 +#define TMC5160_VHIGHCHM_SHIFT 19 +#define TMC5160_VHIGHCHM_FIELD ((RegisterField) {TMC5160_VHIGHCHM_MASK, TMC5160_VHIGHCHM_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_TPFD_MASK 0x00F00000 +#define TMC5160_TPFD_SHIFT 20 +#define TMC5160_TPFD_FIELD ((RegisterField) {TMC5160_TPFD_MASK, TMC5160_TPFD_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_MRES_MASK 0x0F000000 +#define TMC5160_MRES_SHIFT 24 +#define TMC5160_MRES_FIELD ((RegisterField) {TMC5160_MRES_MASK, TMC5160_MRES_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_INTPOL_MASK 0x10000000 +#define TMC5160_INTPOL_SHIFT 28 +#define TMC5160_INTPOL_FIELD ((RegisterField) {TMC5160_INTPOL_MASK, TMC5160_INTPOL_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_DEDGE_MASK 0x20000000 +#define TMC5160_DEDGE_SHIFT 29 +#define TMC5160_DEDGE_FIELD ((RegisterField) {TMC5160_DEDGE_MASK, TMC5160_DEDGE_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_DISS2G_MASK 0x40000000 +#define TMC5160_DISS2G_SHIFT 30 +#define TMC5160_DISS2G_FIELD ((RegisterField) {TMC5160_DISS2G_MASK, TMC5160_DISS2G_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_DISS2VS_MASK 0x80000000 +#define TMC5160_DISS2VS_SHIFT 31 +#define TMC5160_DISS2VS_FIELD ((RegisterField) {TMC5160_DISS2VS_MASK, TMC5160_DISS2VS_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_TOFF_MASK 0x0000000F +#define TMC5160_TOFF_SHIFT 0 +#define TMC5160_TOFF_FIELD ((RegisterField) {TMC5160_TOFF_MASK, TMC5160_TOFF_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_HSTRT_MASK 0x00000070 +#define TMC5160_HSTRT_SHIFT 4 +#define TMC5160_HSTRT_FIELD ((RegisterField) {TMC5160_HSTRT_MASK, TMC5160_HSTRT_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_HEND_MASK 0x00000780 +#define TMC5160_HEND_SHIFT 7 +#define TMC5160_HEND_FIELD ((RegisterField) {TMC5160_HEND_MASK, TMC5160_HEND_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_CHM_MASK 0x00004000 +#define TMC5160_CHM_SHIFT 14 +#define TMC5160_CHM_FIELD ((RegisterField) {TMC5160_CHM_MASK, TMC5160_CHM_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_TBL_MASK 0x00018000 +#define TMC5160_TBL_SHIFT 15 +#define TMC5160_TBL_FIELD ((RegisterField) {TMC5160_TBL_MASK, TMC5160_TBL_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_VHIGHFS_MASK 0x00040000 +#define TMC5160_VHIGHFS_SHIFT 18 +#define TMC5160_VHIGHFS_FIELD ((RegisterField) {TMC5160_VHIGHFS_MASK, TMC5160_VHIGHFS_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_VHIGHCHM_MASK 0x00080000 +#define TMC5160_VHIGHCHM_SHIFT 19 +#define TMC5160_VHIGHCHM_FIELD ((RegisterField) {TMC5160_VHIGHCHM_MASK, TMC5160_VHIGHCHM_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_TPFD_MASK 0x00F00000 +#define TMC5160_TPFD_SHIFT 20 +#define TMC5160_TPFD_FIELD ((RegisterField) {TMC5160_TPFD_MASK, TMC5160_TPFD_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_MRES_MASK 0x0F000000 +#define TMC5160_MRES_SHIFT 24 +#define TMC5160_MRES_FIELD ((RegisterField) {TMC5160_MRES_MASK, TMC5160_MRES_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_INTPOL_MASK 0x10000000 +#define TMC5160_INTPOL_SHIFT 28 +#define TMC5160_INTPOL_FIELD ((RegisterField) {TMC5160_INTPOL_MASK, TMC5160_INTPOL_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_DEDGE_MASK 0x20000000 +#define TMC5160_DEDGE_SHIFT 29 +#define TMC5160_DEDGE_FIELD ((RegisterField) {TMC5160_DEDGE_MASK, TMC5160_DEDGE_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_DISS2G_MASK 0x40000000 +#define TMC5160_DISS2G_SHIFT 30 +#define TMC5160_DISS2G_FIELD ((RegisterField) {TMC5160_DISS2G_MASK, TMC5160_DISS2G_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_DISS2VS_MASK 0x80000000 +#define TMC5160_DISS2VS_SHIFT 31 +#define TMC5160_DISS2VS_FIELD ((RegisterField) {TMC5160_DISS2VS_MASK, TMC5160_DISS2VS_SHIFT, TMC5160_CHOPCONF, false}) +#define TMC5160_SEMIN_MASK 0x0000000F +#define TMC5160_SEMIN_SHIFT 0 +#define TMC5160_SEMIN_FIELD ((RegisterField) {TMC5160_SEMIN_MASK, TMC5160_SEMIN_SHIFT, TMC5160_COOLCONF, false}) +#define TMC5160_SEUP_MASK 0x00000060 +#define TMC5160_SEUP_SHIFT 5 +#define TMC5160_SEUP_FIELD ((RegisterField) {TMC5160_SEUP_MASK, TMC5160_SEUP_SHIFT, TMC5160_COOLCONF, false}) +#define TMC5160_SEMAX_MASK 0x00000F00 +#define TMC5160_SEMAX_SHIFT 8 +#define TMC5160_SEMAX_FIELD ((RegisterField) {TMC5160_SEMAX_MASK, TMC5160_SEMAX_SHIFT, TMC5160_COOLCONF, false}) +#define TMC5160_SEDN_MASK 0x00006000 +#define TMC5160_SEDN_SHIFT 13 +#define TMC5160_SEDN_FIELD ((RegisterField) {TMC5160_SEDN_MASK, TMC5160_SEDN_SHIFT, TMC5160_COOLCONF, false}) +#define TMC5160_SEIMIN_MASK 0x00008000 +#define TMC5160_SEIMIN_SHIFT 15 +#define TMC5160_SEIMIN_FIELD ((RegisterField) {TMC5160_SEIMIN_MASK, TMC5160_SEIMIN_SHIFT, TMC5160_COOLCONF, false}) +#define TMC5160_SGT_MASK 0x007F0000 +#define TMC5160_SGT_SHIFT 16 +#define TMC5160_SGT_FIELD ((RegisterField) {TMC5160_SGT_MASK, TMC5160_SGT_SHIFT, TMC5160_COOLCONF, true}) +#define TMC5160_SFILT_MASK 0x01000000 +#define TMC5160_SFILT_SHIFT 24 +#define TMC5160_SFILT_FIELD ((RegisterField) {TMC5160_SFILT_MASK, TMC5160_SFILT_SHIFT, TMC5160_COOLCONF, false}) +#define TMC5160_DC_TIME_MASK 0x000003FF +#define TMC5160_DC_TIME_SHIFT 0 +#define TMC5160_DC_TIME_FIELD ((RegisterField) {TMC5160_DC_TIME_MASK, TMC5160_DC_TIME_SHIFT, TMC5160_DCCTRL, false}) +#define TMC5160_DC_SG_MASK 0x00FF0000 +#define TMC5160_DC_SG_SHIFT 16 +#define TMC5160_DC_SG_FIELD ((RegisterField) {TMC5160_DC_SG_MASK, TMC5160_DC_SG_SHIFT, TMC5160_DCCTRL, false}) +#define TMC5160_SG_RESULT_MASK 0x000003FF +#define TMC5160_SG_RESULT_SHIFT 0 +#define TMC5160_SG_RESULT_FIELD ((RegisterField) {TMC5160_SG_RESULT_MASK, TMC5160_SG_RESULT_SHIFT, TMC5160_DRV_STATUS, false}) +#define TMC5160_S2VSA_MASK 0x00001000 +#define TMC5160_S2VSA_SHIFT 12 +#define TMC5160_S2VSA_FIELD ((RegisterField) {TMC5160_S2VSA_MASK, TMC5160_S2VSA_SHIFT, TMC5160_DRV_STATUS, false}) +#define TMC5160_S2VSB_MASK 0x00002000 +#define TMC5160_S2VSB_SHIFT 13 +#define TMC5160_S2VSB_FIELD ((RegisterField) {TMC5160_S2VSB_MASK, TMC5160_S2VSB_SHIFT, TMC5160_DRV_STATUS, false}) +#define TMC5160_STEALTH_MASK 0x00004000 +#define TMC5160_STEALTH_SHIFT 14 +#define TMC5160_STEALTH_FIELD ((RegisterField) {TMC5160_STEALTH_MASK, TMC5160_STEALTH_SHIFT, TMC5160_DRV_STATUS, false}) +#define TMC5160_FSACTIVE_MASK 0x00008000 +#define TMC5160_FSACTIVE_SHIFT 15 +#define TMC5160_FSACTIVE_FIELD ((RegisterField) {TMC5160_FSACTIVE_MASK, TMC5160_FSACTIVE_SHIFT, TMC5160_DRV_STATUS, false}) +#define TMC5160_CS_ACTUAL_MASK 0x001F0000 +#define TMC5160_CS_ACTUAL_SHIFT 16 +#define TMC5160_CS_ACTUAL_FIELD ((RegisterField) {TMC5160_CS_ACTUAL_MASK, TMC5160_CS_ACTUAL_SHIFT, TMC5160_DRV_STATUS, false}) +#define TMC5160_STALLGUARD_MASK 0x01000000 +#define TMC5160_STALLGUARD_SHIFT 24 +#define TMC5160_STALLGUARD_FIELD ((RegisterField) {TMC5160_STALLGUARD_MASK, TMC5160_STALLGUARD_SHIFT, TMC5160_DRV_STATUS, false}) +#define TMC5160_OT_MASK 0x02000000 +#define TMC5160_OT_SHIFT 25 +#define TMC5160_OT_FIELD ((RegisterField) {TMC5160_OT_MASK, TMC5160_OT_SHIFT, TMC5160_DRV_STATUS, false}) +#define TMC5160_OTPW_MASK 0x04000000 +#define TMC5160_OTPW_SHIFT 26 +#define TMC5160_OTPW_FIELD ((RegisterField) {TMC5160_OTPW_MASK, TMC5160_OTPW_SHIFT, TMC5160_DRV_STATUS, false}) +#define TMC5160_S2GA_MASK 0x08000000 +#define TMC5160_S2GA_SHIFT 27 +#define TMC5160_S2GA_FIELD ((RegisterField) {TMC5160_S2GA_MASK, TMC5160_S2GA_SHIFT, TMC5160_DRV_STATUS, false}) +#define TMC5160_S2GB_MASK 0x10000000 +#define TMC5160_S2GB_SHIFT 28 +#define TMC5160_S2GB_FIELD ((RegisterField) {TMC5160_S2GB_MASK, TMC5160_S2GB_SHIFT, TMC5160_DRV_STATUS, false}) +#define TMC5160_OLA_MASK 0x20000000 +#define TMC5160_OLA_SHIFT 29 +#define TMC5160_OLA_FIELD ((RegisterField) {TMC5160_OLA_MASK, TMC5160_OLA_SHIFT, TMC5160_DRV_STATUS, false}) +#define TMC5160_OLB_MASK 0x40000000 +#define TMC5160_OLB_SHIFT 30 +#define TMC5160_OLB_FIELD ((RegisterField) {TMC5160_OLB_MASK, TMC5160_OLB_SHIFT, TMC5160_DRV_STATUS, false}) +#define TMC5160_STST_MASK 0x80000000 +#define TMC5160_STST_SHIFT 31 +#define TMC5160_STST_FIELD ((RegisterField) {TMC5160_STST_MASK, TMC5160_STST_SHIFT, TMC5160_DRV_STATUS, false}) +#define TMC5160_PWM_OFS_MASK 0x000000FF +#define TMC5160_PWM_OFS_SHIFT 0 +#define TMC5160_PWM_OFS_FIELD ((RegisterField) {TMC5160_PWM_OFS_MASK, TMC5160_PWM_OFS_SHIFT, TMC5160_PWMCONF, false}) +#define TMC5160_PWM_GRAD_MASK 0x0000FF00 +#define TMC5160_PWM_GRAD_SHIFT 8 +#define TMC5160_PWM_GRAD_FIELD ((RegisterField) {TMC5160_PWM_GRAD_MASK, TMC5160_PWM_GRAD_SHIFT, TMC5160_PWMCONF, false}) +#define TMC5160_PWM_FREQ_MASK 0x00030000 +#define TMC5160_PWM_FREQ_SHIFT 16 +#define TMC5160_PWM_FREQ_FIELD ((RegisterField) {TMC5160_PWM_FREQ_MASK, TMC5160_PWM_FREQ_SHIFT, TMC5160_PWMCONF, false}) +#define TMC5160_PWM_AUTOSCALE_MASK 0x00040000 +#define TMC5160_PWM_AUTOSCALE_SHIFT 18 +#define TMC5160_PWM_AUTOSCALE_FIELD ((RegisterField) {TMC5160_PWM_AUTOSCALE_MASK, TMC5160_PWM_AUTOSCALE_SHIFT, TMC5160_PWMCONF, false}) +#define TMC5160_PWM_AUTOGRAD_MASK 0x00080000 +#define TMC5160_PWM_AUTOGRAD_SHIFT 19 +#define TMC5160_PWM_AUTOGRAD_FIELD ((RegisterField) {TMC5160_PWM_AUTOGRAD_MASK, TMC5160_PWM_AUTOGRAD_SHIFT, TMC5160_PWMCONF, false}) +#define TMC5160_FREEWHEEL_MASK 0x00300000 +#define TMC5160_FREEWHEEL_SHIFT 20 +#define TMC5160_FREEWHEEL_FIELD ((RegisterField) {TMC5160_FREEWHEEL_MASK, TMC5160_FREEWHEEL_SHIFT, TMC5160_PWMCONF, false}) +#define TMC5160_PWM_REG_MASK 0x0F000000 +#define TMC5160_PWM_REG_SHIFT 24 +#define TMC5160_PWM_REG_FIELD ((RegisterField) {TMC5160_PWM_REG_MASK, TMC5160_PWM_REG_SHIFT, TMC5160_PWMCONF, false}) +#define TMC5160_PWM_LIM_MASK 0xF0000000 +#define TMC5160_PWM_LIM_SHIFT 28 +#define TMC5160_PWM_LIM_FIELD ((RegisterField) {TMC5160_PWM_LIM_MASK, TMC5160_PWM_LIM_SHIFT, TMC5160_PWMCONF, false}) +#define TMC5160_PWM_SCALE_SUM_MASK 0x000000FF +#define TMC5160_PWM_SCALE_SUM_SHIFT 0 +#define TMC5160_PWM_SCALE_SUM_FIELD ((RegisterField) {TMC5160_PWM_SCALE_SUM_MASK, TMC5160_PWM_SCALE_SUM_SHIFT, TMC5160_PWM_SCALE, false}) +#define TMC5160_PWM_SCALE_AUTO_MASK 0x01FF0000 +#define TMC5160_PWM_SCALE_AUTO_SHIFT 16 +#define TMC5160_PWM_SCALE_AUTO_FIELD ((RegisterField) {TMC5160_PWM_SCALE_AUTO_MASK, TMC5160_PWM_SCALE_AUTO_SHIFT, TMC5160_PWM_SCALE, true}) +#define TMC5160_PWM_OFS_AUTO_MASK 0x000000FF +#define TMC5160_PWM_OFS_AUTO_SHIFT 0 +#define TMC5160_PWM_OFS_AUTO_FIELD ((RegisterField) {TMC5160_PWM_OFS_AUTO_MASK, TMC5160_PWM_OFS_AUTO_SHIFT, TMC5160_PWM_AUTO, false}) +#define TMC5160_PWM_GRAD_AUTO_MASK 0x00FF0000 +#define TMC5160_PWM_GRAD_AUTO_SHIFT 16 +#define TMC5160_PWM_GRAD_AUTO_FIELD ((RegisterField) {TMC5160_PWM_GRAD_AUTO_MASK, TMC5160_PWM_GRAD_AUTO_SHIFT, TMC5160_PWM_AUTO, false}) +#define TMC5160_LOST_STEPS_MASK 0x000FFFFF +#define TMC5160_LOST_STEPS_SHIFT 0 +#define TMC5160_LOST_STEPS_FIELD ((RegisterField) {TMC5160_LOST_STEPS_MASK, TMC5160_LOST_STEPS_SHIFT, TMC5160_LOST_STEPS, false}) + +#endif diff --git a/firmware/lib/tmc/src/Types.h b/firmware/lib/tmc/src/Types.h new file mode 100755 index 0000000..aeedde1 --- /dev/null +++ b/firmware/lib/tmc/src/Types.h @@ -0,0 +1,107 @@ +/******************************************************************************* +* Copyright © 2016 TRINAMIC Motion Control GmbH & Co. KG +* (now owned by Analog Devices Inc.), +* +* Copyright © 2023 Analog Devices Inc. All Rights Reserved. +* This software is proprietary to Analog Devices, Inc. and its licensors. +*******************************************************************************/ + + +// Turn off the integer typedefs by uncommenting the following two defines. +// If your IDE (e.g. Arduino IDE) already defines these types, deactivating +// these typedefs will fix errors and/or warnings. +//#define TMC_SKIP_UINT_TYPEDEFS // Disable u8, u16, u32, uint8, uint16 and uint32 typedefs +//#define TMC_SKIP_INT_TYPEDEFS // Disable s8, s16, s32, int8, int16 and int32 typedefs + +#ifndef TMC_TYPES_H_ +#define TMC_TYPES_H_ + +#include +#include +#include + +#ifndef TMC_TYPES_INTEGERS +#define TMC_TYPES_INTEGERS + +// todo: change to standard ISO C99 types (ED) + +// www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf +// ISO C99: 7.18 Integer types 8, 16, 32, or 64 bits +// intN_t = two’s complement signed integer type with width N, no padding bits. +// uintN_t = an unsigned integer type with width N. +// floatN_t = N bit IEE 754 float. +// INT8_MIN, INT8_MAX, INT16_MIN, INT16_MAX, INT32_MIN, INT32_MAX, .... UINT32_MAX + +typedef float float32_t; +typedef double float64_t; + +#ifndef TMC_TYPES_INTEGERS_UNSIGNED +#define TMC_TYPES_INTEGERS_UNSIGNED + +#ifndef TMC_SKIP_UINT_TYPEDEFS +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; + +typedef uint8_t uint8; +typedef uint16_t uint16; +typedef uint32_t uint32; +#endif /* TMC_SKIP_UINT_TYPEDEFS */ + +#define u8_MAX (uint8_t) 255 +#define u10_MAX (uint16_t) 1023 +#define u12_MAX (uint16_t) 4095 +#define u15_MAX (uint16_t) 32767 +#define u16_MAX (uint16_t) 65535 +#define u18_MAX (uint32_t) 262143uL +#define u20_MAX (uint32_t) 1048575uL +#define u22_MAX (uint32_t) 4194303uL +#define u24_MAX (uint32_t) 16777215uL +#define u32_MAX (uint32_t) 4294967295uL + +#endif /* TMC_TYPES_INTEGERS_UNSIGNED */ + +#ifndef TMC_TYPES_INTEGERS_SIGNED +#define TMC_TYPES_INTEGERS_SIGNED + +#ifndef TMC_SKIP_INT_TYPEDEFS +typedef int8_t s8; +typedef int16_t s16; +typedef int32_t s32; + +typedef int8_t int8; +typedef int16_t int16; +typedef int32_t int32; +#endif /* TMC_SKIP_INT_TYPEDEFS */ + +#define s8_MAX (int8_t) 127 +#define s8_MIN (int8_t) -128 +#define s16_MAX (int16_t) 32767 +#define s16_MIN (int16_t) -32768 +#define s24_MAX (int32_t) 8388607 +#define s24_MIN (int32_t) -8388608 +#define s32_MAX (int32_t) 2147483647 +#define s32_MIN (int32_t) -2147483648 + +#endif /* TMC_TYPES_INTEGERS_SIGNED */ + +#endif /* TMC_TYPES_INTEGERS */ + +#ifndef TMC_TYPES_NULL +#define TMC_TYPES_NULL + +#ifndef NULL +#define NULL ((void *) 0) +#endif /* NULL */ + +#ifndef FALSE +#define FALSE false +#endif + +#ifndef TRUE +#define TRUE true +#endif + +#endif /* TMC_TYPES_NULL */ + +#endif /* TMC_TYPES_H_ */ diff --git a/firmware/lib/tmc/src/logger.cpp b/firmware/lib/tmc/src/logger.cpp new file mode 100755 index 0000000..4cfeb36 --- /dev/null +++ b/firmware/lib/tmc/src/logger.cpp @@ -0,0 +1,12 @@ +#include +extern "C" { + #include "logger.h" +} + +void log_char(const char *msg) { + Serial.println(msg); +} + +void log_int(int msg) { + Serial.println(msg); +} \ No newline at end of file diff --git a/firmware/lib/tmc/src/logger.h b/firmware/lib/tmc/src/logger.h new file mode 100755 index 0000000..c9c7fd9 --- /dev/null +++ b/firmware/lib/tmc/src/logger.h @@ -0,0 +1,2 @@ +void log_char(const char *msg); +void log_int(int msg); \ No newline at end of file diff --git a/firmware/lib/tmc/src/registercall_hierarchy_flowchart_SPI.svg b/firmware/lib/tmc/src/registercall_hierarchy_flowchart_SPI.svg new file mode 100755 index 0000000..cbad58f --- /dev/null +++ b/firmware/lib/tmc/src/registercall_hierarchy_flowchart_SPI.svg @@ -0,0 +1,3 @@ + + +

HAL

HAL

APP (Eval)

APP (Eval)

API

API
Read a register
  •  Call tmcXXXX_readRegister function
Read a register...
Returns the register read value
Returns the register read value
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
tmcXXXX.c
tmcXXXX.c
SPI.c
SPI.c
tmcXXXX_eval.c
tmcXXXX_eval.c

 Implementation of SPI_readWrite
  • Sends and receives bytes on the SPI bus
Implementation of SPI_readWrite...
Returns the raw reply data
Returns the raw reply data

Implementation of tmcXXXX_readWriteSPI
  • Sets the CSN pin to LOW
  • Takes the array of data to write
  • Calls hardware function SPI_readWrite
  • Upon completion of data transfer,
    sets CSN to 
    HIGH
Implementation of tmcXXXX_readWriteSPI...
Passes on the raw reply data to the API
Passes on the raw reply data to the API
Implementation of readRegisterSPI
  • Constructs the datagram
  • Calls HAL wrapper function 
Implementation of readRegisterSPI...
tmcXXXX_readWriteSPI
tmcXXXX_readWriteSPI
Parses the reply and returns the register value
Parses the reply and returns the register value
Implementation of tmcXXXX_readRegister 
  • Check which bus is active SPI/UART. (e.g. SPI)
  • Calls bus-specific function (e.g. readRegisterSPI)
 
Implementation of tmcXXXX_readRegister...
Returns the register read value
Returns the register read value
\ No newline at end of file diff --git a/firmware/lib/tmc/src/registercall_hierarchy_flowchart_UART.svg b/firmware/lib/tmc/src/registercall_hierarchy_flowchart_UART.svg new file mode 100755 index 0000000..425f60a --- /dev/null +++ b/firmware/lib/tmc/src/registercall_hierarchy_flowchart_UART.svg @@ -0,0 +1,3 @@ + + +

HAL

HAL

APP (Eval)

APP (Eval)

API

API
Read a register
  •  Call tmcXXXX_readRegister function
Read a register...
Returns the register read value
Returns the register read value
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
tmcXXXX.c
tmcXXXX.c
UART.c
UART.c
tmcXXXX_eval.c
tmcXXXX_eval.c

 Implementation of UART_readWrite
  • Sends and receives bytes on the UART bus
Implementation of UART_readWrite...
Returns the raw reply data
Returns the raw reply data

Implementation of tmcXXXX_readWriteUART
  • Takes the array of data to write
  • Calls hardware function UART_readWrite
Implementation of tmcXXXX_readWriteUART...
Passes on the raw reply data to the API
Passes on the raw reply data to the API
Implementation of readRegisterUART
  • Constructs the datagram
  • Calls HAL wrapper function 
Implementation of readRegisterUART...
tmcXXXX_readWriteUART
tmcXXXX_readWriteUART
Parses the reply and returns the register value
Parses the reply and returns the register value
Implementation of tmcXXXX_readRegister 
  • Check which bus is active SPI/UART. (e.g. UART)
  • Calls bus-specific function (e.g. readRegisterUART)
 
Implementation of tmcXXXX_readRegister...
Returns the register read value
Returns the register read value
\ No newline at end of file diff --git a/firmware/lib/tmc/src/uml-tmc-api.svg b/firmware/lib/tmc/src/uml-tmc-api.svg new file mode 100755 index 0000000..5a5f8dd --- /dev/null +++ b/firmware/lib/tmc/src/uml-tmc-api.svg @@ -0,0 +1,3 @@ + + +

TMCXXXX_HW_Abstraction.h



TMCXXXX_HW_Abstraction.h...
// Constants
#define TMCXXXX_MOTORS              
                          
// Register definitions
#define TMCXXXX_GCONF        
                          ⋮
// Register fields definitions
#define TMCXXXX_GCONF_OTPW_FIELD
                     
// Constants...

TMCXXXX.h



TMCXXXX.h...
extern void tmcXXXX_readWriteSPI();
extern void tmcXXXX_readWriteUART();
extern TMCXXXXBusType tmcXXXX_getBusType();
extern uint8_t tmcXXXX_getNodeAddress();
                                  ⋮
tmcXXXX_readRegister();
tmcXXXX_writeRegister();
                                  ⋮
extern void tmcXXXX_readWriteSPI();...

TMCXXXX.c



TMCXXXX.c...
const uint8_t tmcCRCTable_Poly7Reflected[256] = {...};
int32_t tmcXXXX_readRegister(){
/* Call tmcXXXX_getBusType();
 * Based on bus type, call readRegisterSPI/UART() that
 * further calls tmcXXXX_readWriteSPI/UART();
 * For UART it also calls tmcXXXX_getNodeAddress();
                                           ⋮
}
                                           ⋮
const uint8_t tmcCRCTable_Poly7Reflected[256] = {.....
TMC-API
TMC-API

TMCXXXX_Simple_Rotation.h


TMCXXXX_Simple_Rotation.h...
void initAllMotors();
             ⋮
  
void initAllMotors()...

TMCXXXX_Simple_Rotation.c


TMCXXXX_Simple_Rotation.c...
void initAllMotors(){

// Configuring registers to enable motor drivers etc..
tmcXXXX_writeRegister();
                    ⋮
}
                    ⋮
void initAllMotors(){...
Examples
Examples
User Project
User Project

User_Project.h


User_Project.h

User_Project.c








User_Project.c...

void tmcXXXX_readWriteSPI(){
                           ⋮
}
void tmcXXXX_readWriteUART(){
                           ⋮
}
TMCXXXXBusType tmcXXXX_getBusType(){
                           ⋮
}
uint8_t tmcXXXX_getNodeAddress(){
                           ⋮
}

// User Code
                           ⋮
void tmcXXXX_readWriteSPI(){...
#include "TMCXXXX_HW_Abstraction.h"
#include "TMCXXXX.h"
#include "TMCXXXX_Simple_Rotation.h"
                                ⋮
TMCXXXXBusType bus = IC_BUS_SPI/UART;
uint8_t nodeAddress = <nodeAddress>;
                                ⋮
#include "TMCXXXX_HW_Abstraction.h"...
\ No newline at end of file diff --git a/firmware/platformio.ini b/firmware/platformio.ini new file mode 100755 index 0000000..7fb6f7e --- /dev/null +++ b/firmware/platformio.ini @@ -0,0 +1,19 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:megaatmega2560] +platform = atmelavr +board = leonardo +framework = arduino +monitor_speed = 115200 +build_flags = -Isrc -Ilib/tmc/src +lib_deps = + adafruit/DHT sensor library@^1.4.4 + adafruit/Adafruit Unified Sensor@^1.1.4 \ No newline at end of file diff --git a/firmware/src/config/Constants.h b/firmware/src/config/Constants.h new file mode 100644 index 0000000..ce82b05 --- /dev/null +++ b/firmware/src/config/Constants.h @@ -0,0 +1,50 @@ +#ifndef FTW_CONSTANTS_H +#define FTW_CONSTANTS_H + +/* Serial */ +#define BAUD_RATE 115200 + +/* SPI */ +#define SPI_CLOCK_DIV SPI_CLOCK_DIV4 + +/* Motor driver */ +#define ACCELERATION 20000 +#define ENC_DEVIATION_LIMIT 1500 +#define ENC_CONST 0x000C1F40 +#define ENCMODE_DECIMAL 0x400 + +/* Yaw axis */ +#define YAW_STEPS_PER_ROUND 177000 +#define YAW_GEAR_RATIO 739.5555f +#define YAW_GLOBAL_SCALER 80 +#define YAW_DEFAULT_XACTUAL 0x0007A120 +#define YAW_ENDSTOP_SPEED 25000 +#define YAW_DEFAULT_VMAX 50000 + +/* Pitch axis */ +#define PITCH_STEPS_PER_ROUND 500000 +#define PITCH_GEAR_RATIO 739.5555f +#define PITCH_GLOBAL_SCALER 50 +#define PITCH_DEFAULT_XACTUAL 500000 +#define PITCH_ENDSTOP_SPEED 150000 +#define PITCH_DEFAULT_VMAX 250000 + +/* Homing */ +#define HOMING_MIN_ROUND_DIFF_OFFSET 6000 +#define HOMING_XENC_MARGIN 1000 +#define HOMING_DELAY_MS 10 +#define HOMING_PITCH_INITIAL_DELAY 1000 +#define HOMING_YAW_TIMEOUT_MS 2000 + +/* Thermal */ +#define THERMAL_FAN_ON_TEMP 25 +#define THERMAL_FAN_GAIN 20 +#define THERMAL_FAN_MAX_PWM 255 +#define THERMAL_FAN_PULSE_US 100000 +#define THERMAL_FAN_FREQ_DIV 0.004 +#define THERMAL_LOOP_INTERVAL 250 + +/* Info print interval */ +#define INFO_PRINT_INTERVAL_MS 250 + +#endif diff --git a/firmware/src/config/Pins.h b/firmware/src/config/Pins.h new file mode 100644 index 0000000..9bd76b3 --- /dev/null +++ b/firmware/src/config/Pins.h @@ -0,0 +1,15 @@ +#ifndef FTW_PINS_H +#define FTW_PINS_H + +/* TMC5160 driver pins */ +#define PIN_TMC_CS_YAW 8 +#define PIN_TMC_CS_PITCH 1 +#define PIN_TMC_EN_YAW 7 +#define PIN_TMC_EN_PITCH 0 + +/* Thermal */ +#define PIN_DHT_DATA 9 +#define PIN_FAN_PWM 10 +#define PIN_FAN_SENS 11 + +#endif diff --git a/firmware/src/hal/README.md b/firmware/src/hal/README.md new file mode 100644 index 0000000..fd563cb --- /dev/null +++ b/firmware/src/hal/README.md @@ -0,0 +1,25 @@ +# HAL — Hardware Abstraction Layer + +This folder contains the callbacks that bridge the **TMC-API** vendor library to the **Arduino SPI** peripheral. + +## Why it exists + +The TMC5160 library is hardware-agnostic. It doesn't know about Arduino, SPI, or chip-select pins. Instead, it expects the project to implement two callback functions: + +| Callback | Purpose | +|---|---| +| `tmc5160_readWriteSPI(icID, data, len)` | Select the correct CS pin, perform SPI transfer, deselect | +| `tmc5160_getBusType(icID)` | Tell the library which bus to use (always `IC_BUS_SPI`) | + +## Call chain + +``` +tmc5160_readRegister(icID, addr) + → readRegisterSPI(icID, addr) [vendor, TMC5160.c] + → tmc5160_readWriteSPI(...) [this file] + → SPI.transfer(data[i]) [Arduino HAL] +``` + +## Chip select + +Each motor has its own CS pin (defined in `config/Pins.h`). The callback selects the correct one based on `icID` (`MotorYaw` or `MotorPitch`). diff --git a/firmware/src/hal/SPI_HAL.cpp b/firmware/src/hal/SPI_HAL.cpp new file mode 100644 index 0000000..661af8f --- /dev/null +++ b/firmware/src/hal/SPI_HAL.cpp @@ -0,0 +1,32 @@ +#include +#include +#include "config/Pins.h" +#include "motor/MotorConfig.h" + +#include "TMC5160.h" + +void tmc5160_readWriteSPI(uint16_t icID, uint8_t *data, size_t dataLength) { + uint8_t input[dataLength]; + + if (icID == MotorYaw) + digitalWrite(PIN_TMC_CS_YAW, LOW); + if (icID == MotorPitch) + digitalWrite(PIN_TMC_CS_PITCH, LOW); + delayMicroseconds(1); + + for (size_t i = 0; i < dataLength; i++) { + input[i] = SPI.transfer(data[i]); + data[i] = input[i]; + } + delayMicroseconds(1); + + if (icID == MotorYaw) + digitalWrite(PIN_TMC_CS_YAW, HIGH); + if (icID == MotorPitch) + digitalWrite(PIN_TMC_CS_PITCH, HIGH); +} + +TMC5160BusType tmc5160_getBusType(uint16_t icID) { + (void)icID; + return IC_BUS_SPI; +} diff --git a/firmware/src/main.cpp b/firmware/src/main.cpp new file mode 100644 index 0000000..a85bee9 --- /dev/null +++ b/firmware/src/main.cpp @@ -0,0 +1,38 @@ +#include +#include "config/Constants.h" +#include "motor/MotorDriver.h" +#include "motor/Homing.h" +#include "serial/CommandParser.h" +#include "thermal/ThermalManager.h" + +static unsigned long s_last_loop = 0; + +void setup() { + Serial.begin(BAUD_RATE); + delay(50); + Serial.println(F("Starting...")); + + init_motor_hardware(); + init_motor_params(); + thermal_init(); + + s_last_loop = millis(); +} + +void loop() { + motor_periodic_job(MotorYaw); + motor_periodic_job(MotorPitch); + endstop_routine(); + + if (Serial.available()) { + char in = Serial.read(); + parser(in); + } + + if (millis() - s_last_loop > INFO_PRINT_INTERVAL_MS) { + s_last_loop = millis(); + print_motor_info(MotorPitch); + print_motor_info(MotorYaw); + thermal_loop(); + } +} diff --git a/firmware/src/motor/Homing.cpp b/firmware/src/motor/Homing.cpp new file mode 100644 index 0000000..9085263 --- /dev/null +++ b/firmware/src/motor/Homing.cpp @@ -0,0 +1,133 @@ +#include "motor/Homing.h" +#include "motor/MotorAxis.h" +#include "motor/MotorDriver.h" +#include "config/Constants.h" + +#include "TMC5160.h" + +static unsigned long s_tick_move_yaw = 0; + +void do_endstop(uint16_t axis) { + if (axis == MotorYaw) { + ax_yaw.set_xenc_to_xact(); + ax_yaw.reset_enc_dev_warn(); + ax_yaw.driver_status = GIMBAL_STATUS_ENC_INIT; + ax_yaw.set_speed(30000); + ax_yaw.set_SGT(60); + ax_yaw.move_endstop_right = true; + tmc5160_rotateMotor(MotorYaw, YAW_ENDSTOP_SPEED); + } + else if (axis == MotorPitch) { + if (ax_pitch.get_status_endswitch_l()) { + tmc5160_rotateMotor(MotorPitch, PITCH_ENDSTOP_SPEED); + delay(HOMING_PITCH_INITIAL_DELAY); + } + else if (ax_pitch.get_status_endswitch_r()) { + tmc5160_rotateMotor(MotorPitch, -PITCH_ENDSTOP_SPEED); + delay(HOMING_PITCH_INITIAL_DELAY); + } + ax_pitch.set_xenc_to_xact(); + ax_pitch.reset_enc_dev_warn(); + ax_pitch.driver_status = GIMBAL_STATUS_ENC_INIT; + ax_pitch.set_speed(30000); + ax_pitch.set_SGT(60); + ax_pitch.move_endstop_right = true; + tmc5160_rotateMotor(MotorPitch, PITCH_ENDSTOP_SPEED); + } +} + +static void yaw_homing(void) { + if (ax_yaw.driver_status == GIMBAL_STATUS_ENC_INIT + && millis() - s_tick_move_yaw > HOMING_YAW_TIMEOUT_MS + && !ax_yaw.move_endstop_right) { + s_tick_move_yaw = millis(); + tmc5160_rotateMotor(MotorYaw, -YAW_ENDSTOP_SPEED); + } + + if (ax_yaw.driver_status == GIMBAL_STATUS_ENC_INIT && ax_yaw.move_endstop_right) { + if (ax_yaw.get_dev_warn_status()) { + tmc5160_rotateMotor(MotorYaw, 0); + ax_yaw.update(); + Serial.println(ax_yaw.X_enc); + Serial.println(ax_yaw.X_act); + Serial.println(ax_yaw.X_err); + ax_yaw.encoderpos_r = ax_yaw.X_enc; + ax_yaw.set_xenc_to_xact(); + ax_yaw.reset_enc_dev_warn(); + ax_yaw.move_endstop_right = false; + s_tick_move_yaw = millis(); + } + } + else if (ax_yaw.driver_status == GIMBAL_STATUS_ENC_INIT && !ax_yaw.move_endstop_right) { + if (ax_yaw.get_dev_warn_status()) { + tmc5160_rotateMotor(MotorYaw, 0); + ax_yaw.update(); + ax_yaw.encoderpos_l = ax_yaw.X_enc; + ax_yaw.set_xenc_to_xact(); + ax_yaw.reset_enc_dev_warn(); + ax_yaw.move_endstop_right = true; + + if (abs(ax_yaw.encoderpos_l - ax_yaw.encoderpos_r) + < (ax_yaw.one_round_in_steps - HOMING_MIN_ROUND_DIFF_OFFSET)) { + Serial.println(F("Endstop drive failed")); + ax_yaw.driver_status = GIMBAL_STATUS_ERROR; + } + else { + ax_yaw.driver_status = GIMBAL_STATUS_INITIALIZED; + ax_yaw.act_steps_per_round = ax_yaw.encoderpos_r - ax_yaw.encoderpos_l; + Serial.println(F("YAW ENDs L/R/Diff")); + Serial.println(ax_yaw.encoderpos_l); + Serial.println(ax_yaw.encoderpos_r); + Serial.println(abs(ax_yaw.encoderpos_l - ax_yaw.encoderpos_r)); + tmc5160_moveTo(MotorYaw, + (ax_yaw.encoderpos_l + ax_yaw.encoderpos_r) / 2, 35000); + } + } + } +} + +static void pitch_homing(void) { + if (ax_pitch.driver_status == GIMBAL_STATUS_ENC_INIT && ax_pitch.move_endstop_right) { + if (ax_pitch.get_status_endswitch_r()) { + ax_pitch.update(); + Serial.println(ax_pitch.X_enc); + Serial.println(ax_pitch.X_act); + Serial.println(ax_pitch.X_err); + delay(HOMING_DELAY_MS); + ax_pitch.encoderpos_r = ax_pitch.get_X_Latch(); + ax_pitch.reset_enc_dev_warn(); + ax_pitch.move_endstop_right = false; + tmc5160_rotateMotor(MotorPitch, -PITCH_ENDSTOP_SPEED); + } + } + else if (ax_pitch.driver_status == GIMBAL_STATUS_ENC_INIT && !ax_pitch.move_endstop_right) { + if (ax_pitch.get_status_endswitch_l()) { + ax_pitch.update(); + delay(HOMING_DELAY_MS); + ax_pitch.encoderpos_l = ax_pitch.get_X_Latch(); + ax_pitch.reset_enc_dev_warn(); + ax_pitch.move_endstop_right = true; + + if (abs(ax_pitch.encoderpos_l - ax_pitch.encoderpos_r) + < (ax_pitch.one_round_in_steps - HOMING_MIN_ROUND_DIFF_OFFSET)) { + Serial.println(F("Endstop drive failed")); + ax_pitch.driver_status = GIMBAL_STATUS_ERROR; + } + else { + ax_pitch.driver_status = GIMBAL_STATUS_INITIALIZED; + ax_pitch.act_steps_per_round = ax_pitch.encoderpos_r - ax_pitch.encoderpos_l; + Serial.println(F("Pitch ENDs L/R/Diff")); + Serial.println(ax_pitch.encoderpos_l); + Serial.println(ax_pitch.encoderpos_r); + Serial.println(abs(ax_pitch.encoderpos_l - ax_pitch.encoderpos_r)); + tmc5160_moveTo(MotorPitch, + (ax_pitch.encoderpos_l + ax_pitch.encoderpos_r) / 2, 150000); + } + } + } +} + +void endstop_routine(void) { + yaw_homing(); + pitch_homing(); +} diff --git a/firmware/src/motor/Homing.h b/firmware/src/motor/Homing.h new file mode 100644 index 0000000..a9803f5 --- /dev/null +++ b/firmware/src/motor/Homing.h @@ -0,0 +1,10 @@ +#ifndef FTW_HOMING_H +#define FTW_HOMING_H + +#include +#include "motor/MotorConfig.h" + +void do_endstop(uint16_t axis); +void endstop_routine(void); + +#endif diff --git a/firmware/src/motor/MotorAxis.cpp b/firmware/src/motor/MotorAxis.cpp new file mode 100644 index 0000000..5b004c8 --- /dev/null +++ b/firmware/src/motor/MotorAxis.cpp @@ -0,0 +1,68 @@ +#include "motor/MotorAxis.h" +#include "config/Constants.h" + +MotorAxisParam ax_yaw(MotorYaw, YAW_STEPS_PER_ROUND, YAW_GEAR_RATIO, YAW_DEFAULT_VMAX); +MotorAxisParam ax_pitch(MotorPitch, PITCH_STEPS_PER_ROUND, PITCH_GEAR_RATIO, PITCH_DEFAULT_VMAX); + +uint32_t MotorAxisParam::get_standstill_status() { + return tmc5160_fieldRead(MOTOR_ID, TMC5160_STST_FIELD); +} + +bool MotorAxisParam::get_status_endswitch_l() { + return tmc5160_fieldRead(MOTOR_ID, TMC5160_STATUS_STOP_L_FIELD); +} + +bool MotorAxisParam::get_status_endswitch_r() { + return tmc5160_fieldRead(MOTOR_ID, TMC5160_STATUS_STOP_R_FIELD); +} + +uint32_t MotorAxisParam::get_X_Latch() { + return tmc5160_readRegister(MOTOR_ID, TMC5160_XLATCH); +} + +uint32_t MotorAxisParam::get_SGT_Status() { + return tmc5160_fieldRead(MOTOR_ID, TMC5160_EVENT_STOP_SG_FIELD); +} + +uint32_t MotorAxisParam::get_dev_warn_status() { + return tmc5160_fieldRead(MOTOR_ID, TMC5160_DEVIATION_WARN_FIELD); +} + +int32_t MotorAxisParam::get_dev_value() { + return tmc5160_readRegister(MOTOR_ID, TMC5160_ENC_DEVIATION); +} + +void MotorAxisParam::set_SGT(uint8_t sgt) { + tmc5160_fieldWrite(MOTOR_ID, TMC5160_SGT_FIELD, sgt); +} + +void MotorAxisParam::reset_SGT() { + tmc5160_fieldWrite(MOTOR_ID, TMC5160_EVENT_STOP_SG_FIELD, 1); +} + +void MotorAxisParam::reset_enc_dev_warn() { + tmc5160_fieldWrite(MOTOR_ID, TMC5160_DEVIATION_WARN_FIELD, 1); +} + +void MotorAxisParam::set_enc_dev_warn_limit(int32_t limit) { + tmc5160_fieldWrite(MOTOR_ID, TMC5160_ENC_DEVIATION_FIELD, limit); +} + +void MotorAxisParam::set_xenc_to_xact() { + tmc5160_writeRegister(MOTOR_ID, TMC5160_XACTUAL, X_enc); +} + +void MotorAxisParam::set_speed(int32_t speed) { + tmc5160_writeRegister(MOTOR_ID, TMC5160_VMAX, speed); +} + +void MotorAxisParam::set_step_len(int32_t s) { + int32_t turn_len = (encoderpos_r - HOMING_XENC_MARGIN) - (encoderpos_l + HOMING_XENC_MARGIN); + steps = turn_len / (s - 1); +} + +void MotorAxisParam::update() { + X_enc = tmc5160_readRegister(MOTOR_ID, TMC5160_XENC); + X_act = tmc5160_readRegister(MOTOR_ID, TMC5160_XACTUAL); + X_err = X_act - X_enc; +} diff --git a/firmware/src/motor/MotorAxis.h b/firmware/src/motor/MotorAxis.h new file mode 100644 index 0000000..2484411 --- /dev/null +++ b/firmware/src/motor/MotorAxis.h @@ -0,0 +1,68 @@ +#ifndef FTW_MOTOR_AXIS_H +#define FTW_MOTOR_AXIS_H + +#include +#include "motor/MotorConfig.h" + +#include "TMC5160.h" + +struct MotorAxisParam { + const uint16_t MOTOR_ID; + const int32_t one_round_in_steps; + const float gear_red_var; + int32_t act_steps_per_round; + int32_t encoderpos_l; + int32_t encoderpos_r; + int32_t steps; + float c_hdg; + int32_t hdg_constant; + int32_t target; + int32_t X_act; + int32_t X_enc; + int32_t X_err; + int32_t v_max; + gimbal_status driver_status; + bool move_endstop_right; + bool new_pos; + + MotorAxisParam(uint16_t id, int32_t steps, float ratio, int32_t vmax) + : MOTOR_ID(id), + one_round_in_steps(steps), + gear_red_var(ratio), + act_steps_per_round(0), + encoderpos_l(0), + encoderpos_r(0), + steps(0), + c_hdg(0.0f), + hdg_constant(0), + target(0), + X_act(0), + X_enc(0), + X_err(0), + v_max(vmax), + driver_status(GIMBAL_STATUS_BOOT), + move_endstop_right(false), + new_pos(false) + {} + + uint32_t get_standstill_status(); + bool get_status_endswitch_l(); + bool get_status_endswitch_r(); + uint32_t get_X_Latch(); + uint32_t get_SGT_Status(); + uint32_t get_dev_warn_status(); + int32_t get_dev_value(); + void set_SGT(uint8_t sgt); + void reset_SGT(); + void reset_enc_dev_warn(); + void set_enc_dev_warn_limit(int32_t limit); + void set_xenc_to_xact(); + void set_speed(int32_t speed); + void set_step_len(int32_t s); + void update(); +}; + +extern MotorAxisParam ax_yaw; +extern MotorAxisParam ax_pitch; + +#endif diff --git a/firmware/src/motor/MotorConfig.h b/firmware/src/motor/MotorConfig.h new file mode 100644 index 0000000..217ae47 --- /dev/null +++ b/firmware/src/motor/MotorConfig.h @@ -0,0 +1,19 @@ +#ifndef FTW_MOTOR_CONFIG_H +#define FTW_MOTOR_CONFIG_H + +#include + +#define MotorYaw 0x00 +#define MotorPitch 0x01 + +typedef enum { + GIMBAL_STATUS_ERROR = -2, + GIMBAL_STATUS_BOOT = -1, + GIMBAL_STATUS_RESET = 0, + GIMBAL_STATUS_ENC_INIT = 1, + GIMBAL_STATUS_INITIALIZED= 2, + GIMBAL_STATUS_AUTO = 3, + GIMBAL_STATUS_MANUAL = 4 +} gimbal_status; + +#endif diff --git a/firmware/src/motor/MotorDriver.cpp b/firmware/src/motor/MotorDriver.cpp new file mode 100644 index 0000000..835d47d --- /dev/null +++ b/firmware/src/motor/MotorDriver.cpp @@ -0,0 +1,156 @@ +#include "motor/MotorDriver.h" +#include "motor/MotorAxis.h" +#include "config/Pins.h" +#include "config/Constants.h" + +#include +#include "TMC5160.h" + +static void write_regs_yaw(void) { + tmc5160_writeRegister(MotorYaw, 0x00, 0x0000000C); + tmc5160_writeRegister(MotorYaw, 0x09, 0x00010606); + tmc5160_writeRegister(MotorYaw, 0x0A, 0x00080400); + tmc5160_writeRegister(MotorYaw, 0x0B, YAW_GLOBAL_SCALER); + tmc5160_writeRegister(MotorYaw, 0x10, 0x00071F08); + tmc5160_writeRegister(MotorYaw, 0x11, 0x00000008); + tmc5160_writeRegister(MotorYaw, 0x13, 0); + tmc5160_writeRegister(MotorYaw, 0x14, 0); + tmc5160_writeRegister(MotorYaw, 0x15, 0); + tmc5160_writeRegister(MotorYaw, 0x21, YAW_DEFAULT_XACTUAL); + tmc5160_writeRegister(MotorYaw, 0x24, ACCELERATION); + tmc5160_writeRegister(MotorYaw, 0x26, ACCELERATION); + tmc5160_writeRegister(MotorYaw, 0x25, 0x00000000); + tmc5160_writeRegister(MotorYaw, 0x27, 0); + tmc5160_writeRegister(MotorYaw, 0x28, ACCELERATION); + tmc5160_writeRegister(MotorYaw, 0x2A, ACCELERATION); + tmc5160_writeRegister(MotorYaw, 0x2B, 0x00000100); + tmc5160_writeRegister(MotorYaw, 0x2D, 500000); + tmc5160_writeRegister(MotorYaw, 0x34, 0x08A3); + tmc5160_writeRegister(MotorYaw, 0x35, 0xFFFF); + tmc5160_writeRegister(MotorYaw, 0x38, ENCMODE_DECIMAL); + tmc5160_writeRegister(MotorYaw, 0x39, 500000); + tmc5160_writeRegister(MotorYaw, 0x3A, ENC_CONST); + tmc5160_writeRegister(MotorYaw, 0x3D, ENC_DEVIATION_LIMIT); + tmc5160_writeRegister(MotorYaw, 0x6C, 0x00410043); + tmc5160_writeRegister(MotorYaw, 0x6D, 0x00000000); + tmc5160_writeRegister(MotorYaw, 0x70, 0x010C1E3C); + tmc5160_writeRegister(MotorYaw, TMC5160_RAMPMODE, TMC5160_MODE_HOLD); +} + +static void write_regs_pitch(void) { + tmc5160_writeRegister(MotorPitch, 0x00, 0x0000000C); + tmc5160_writeRegister(MotorPitch, 0x09, 0x00010606); + tmc5160_writeRegister(MotorPitch, 0x0A, 0x00080400); + tmc5160_writeRegister(MotorPitch, 0x0B, PITCH_GLOBAL_SCALER); + tmc5160_writeRegister(MotorPitch, 0x10, 0x00071F08); + tmc5160_writeRegister(MotorPitch, 0x11, 0x00000008); + tmc5160_writeRegister(MotorPitch, 0x13, 0); + tmc5160_writeRegister(MotorPitch, 0x14, 0); + tmc5160_writeRegister(MotorPitch, 0x15, 0); + tmc5160_writeRegister(MotorPitch, 0x21, PITCH_DEFAULT_XACTUAL); + tmc5160_writeRegister(MotorPitch, 0x24, ACCELERATION); + tmc5160_writeRegister(MotorPitch, 0x26, ACCELERATION); + tmc5160_writeRegister(MotorPitch, 0x25, 0x00000000); + tmc5160_writeRegister(MotorPitch, 0x27, 0); + tmc5160_writeRegister(MotorPitch, 0x28, ACCELERATION); + tmc5160_writeRegister(MotorPitch, 0x2A, ACCELERATION); + tmc5160_writeRegister(MotorPitch, 0x2B, 0x00000100); + tmc5160_writeRegister(MotorPitch, 0x2D, 500000); + tmc5160_writeRegister(MotorPitch, 0x34, 0x08A3); + tmc5160_writeRegister(MotorPitch, 0x35, 0xFFFF); + tmc5160_writeRegister(MotorPitch, 0x38, ENCMODE_DECIMAL); + tmc5160_writeRegister(MotorPitch, 0x39, 500000); + tmc5160_writeRegister(MotorPitch, 0x3A, ENC_CONST); + tmc5160_writeRegister(MotorPitch, 0x3D, ENC_DEVIATION_LIMIT); + tmc5160_writeRegister(MotorPitch, 0x6C, 0x00410043); + tmc5160_writeRegister(MotorPitch, 0x6D, 0x00000000); + tmc5160_writeRegister(MotorPitch, 0x70, 0x010C1E3C); + tmc5160_writeRegister(MotorPitch, TMC5160_RAMPMODE, TMC5160_MODE_HOLD); +} + +void init_motor_hardware(void) { + pinMode(PIN_TMC_CS_YAW, OUTPUT); + digitalWrite(PIN_TMC_CS_YAW, HIGH); + pinMode(PIN_TMC_EN_YAW, OUTPUT); + digitalWrite(PIN_TMC_EN_YAW, HIGH); + pinMode(PIN_TMC_CS_PITCH, OUTPUT); + digitalWrite(PIN_TMC_CS_PITCH, HIGH); + pinMode(PIN_TMC_EN_PITCH, OUTPUT); + digitalWrite(PIN_TMC_EN_PITCH, HIGH); + + SPI.setBitOrder(MSBFIRST); + SPI.setClockDivider(SPI_CLOCK_DIV); + SPI.setDataMode(SPI_MODE3); + SPI.begin(); + delay(50); + + tmc5160_initCache(); +} + +void init_motor_params(void) { + write_regs_yaw(); + write_regs_pitch(); +} + +void motor_power_on(uint16_t axis) { + if (axis == MotorPitch) { + digitalWrite(PIN_TMC_EN_PITCH, LOW); + } else if (axis == MotorYaw) { + digitalWrite(PIN_TMC_EN_YAW, LOW); + } +} + +void motor_power_off(uint16_t axis) { + if (axis == MotorPitch) { + digitalWrite(PIN_TMC_EN_PITCH, HIGH); + } else if (axis == MotorYaw) { + digitalWrite(PIN_TMC_EN_YAW, HIGH); + } +} + +void motor_periodic_job(uint16_t axis) { + if (axis == MotorYaw) { + ax_yaw.update(); + } else if (axis == MotorPitch) { + ax_pitch.update(); + } +} + +void print_motor_info(uint16_t axis) { + const char *spacer = ", "; + if (axis == MotorPitch) { + Serial.print(F("PITCH: ")); + Serial.print(ax_pitch.X_enc); + Serial.print(spacer); + Serial.print(ax_pitch.X_act); + Serial.print(spacer); + Serial.print(ax_pitch.X_err); + Serial.print(spacer); + Serial.print(tmc5160_fieldRead(MotorPitch, TMC5160_DEVIATION_WARN_FIELD)); + Serial.print(spacer); + Serial.print(tmc5160_fieldRead(MotorPitch, TMC5160_DEVIATION_WARN_FIELD)); + Serial.print(spacer); + Serial.print(tmc5160_fieldRead(MotorPitch, TMC5160_STATUS_SG_FIELD)); + Serial.print(spacer); + Serial.print(tmc5160_fieldRead(MotorPitch, TMC5160_SG_STOP_FIELD)); + Serial.print(spacer); + Serial.print(tmc5160_fieldRead(MotorPitch, TMC5160_STATUS_STOP_L_FIELD)); + Serial.print(spacer); + Serial.println(tmc5160_fieldRead(MotorPitch, TMC5160_STATUS_STOP_R_FIELD)); + } else if (axis == MotorYaw) { + Serial.print(F("YAW: ")); + Serial.print(ax_yaw.X_enc); + Serial.print(spacer); + Serial.print(ax_yaw.X_act); + Serial.print(spacer); + Serial.print(ax_yaw.X_err); + Serial.print(spacer); + Serial.print(tmc5160_fieldRead(MotorYaw, TMC5160_DEVIATION_WARN_FIELD)); + Serial.print(spacer); + Serial.print(tmc5160_fieldRead(MotorYaw, TMC5160_DEVIATION_WARN_FIELD)); + Serial.print(spacer); + Serial.print(tmc5160_fieldRead(MotorYaw, TMC5160_STATUS_SG_FIELD)); + Serial.print(spacer); + Serial.println(tmc5160_fieldRead(MotorYaw, TMC5160_SG_STOP_FIELD)); + } +} diff --git a/firmware/src/motor/MotorDriver.h b/firmware/src/motor/MotorDriver.h new file mode 100644 index 0000000..c9ff316 --- /dev/null +++ b/firmware/src/motor/MotorDriver.h @@ -0,0 +1,14 @@ +#ifndef FTW_MOTOR_DRIVER_H +#define FTW_MOTOR_DRIVER_H + +#include +#include "motor/MotorConfig.h" + +void init_motor_hardware(void); +void init_motor_params(void); +void motor_power_on(uint16_t axis); +void motor_power_off(uint16_t axis); +void motor_periodic_job(uint16_t axis); +void print_motor_info(uint16_t axis); + +#endif diff --git a/firmware/src/serial/CommandParser.cpp b/firmware/src/serial/CommandParser.cpp new file mode 100644 index 0000000..4bfcd67 --- /dev/null +++ b/firmware/src/serial/CommandParser.cpp @@ -0,0 +1,170 @@ +#include +#include +#include "serial/CommandParser.h" +#include "motor/MotorAxis.h" +#include "motor/MotorDriver.h" +#include "motor/Homing.h" +#include "config/Constants.h" + +#include "TMC5160.h" + +void parser(char &c) { + int base = 16; + if (Serial.peek() == 'd') { + Serial.read(); + base = 10; + } + + static char buffer[32]; + size_t len = Serial.readBytesUntil('\n', buffer, sizeof(buffer) - 1); + buffer[len] = '\0'; + + int32_t args[4] = {0}; + uint8_t argc = 0; + + char *token = strtok(buffer, ","); + while (token && argc < 4) { + args[argc++] = strtol(token, nullptr, base); + token = strtok(nullptr, ","); + } + + switch (c) { + + case 'r': + init_motor_params(); + motor_power_on(MotorPitch); + motor_power_on(MotorYaw); + ax_pitch.driver_status = GIMBAL_STATUS_RESET; + ax_yaw.driver_status = GIMBAL_STATUS_RESET; + Serial.println(F("Reset")); + break; + + case 'q': + do_endstop(MotorYaw); + do_endstop(MotorPitch); + break; + + case '!': + motor_power_off(MotorPitch); + motor_power_off(MotorYaw); + break; + + case '*': + motor_power_on(MotorPitch); + motor_power_on(MotorYaw); + break; + + case 'm': + Serial.print(F("Move ")); + Serial.print(args[0]); + Serial.print(F(" with ")); + Serial.println(args[1]); + tmc5160_moveTo(MotorYaw, args[0], args[1]); + break; + + case ';': + tmc5160_writeRegister(MotorYaw, 0x21, args[0]); + break; + + case 's': + tmc5160_rotateMotor(MotorPitch, 0); + tmc5160_rotateMotor(MotorYaw, 0); + Serial.println(F("Stop")); + break; + + case 'b': + ax_yaw.reset_enc_dev_warn(); + ax_pitch.reset_enc_dev_warn(); + break; + + case 't': + ax_yaw.set_xenc_to_xact(); + ax_pitch.set_xenc_to_xact(); + break; + + case 'e': + ax_yaw.reset_SGT(); + ax_pitch.reset_SGT(); + break; + + case 'w': + ax_yaw.set_SGT(args[0]); + ax_pitch.set_SGT(args[0]); + break; + + case 'u': + if (args[0] > 2) { + ax_yaw.set_step_len(args[0]); + ax_yaw.target = ax_yaw.encoderpos_l + 2000; + ax_yaw.driver_status = GIMBAL_STATUS_AUTO; + } + break; + + case 'h': { + if (args[0] == MotorYaw) { + ax_yaw.c_hdg = (float)args[1]; + ax_yaw.hdg_constant = ax_yaw.X_enc; + + int ee = 0; + int32_t dist = ax_yaw.hdg_constant - ax_yaw.encoderpos_l; + EEPROM.put(ee, ax_yaw.c_hdg); + ee += sizeof(float); + EEPROM.put(ee, dist); + } + break; + } + + case 'y': { + if (args[0] == MotorYaw) { + int ee = 0; + int32_t dist = 0; + EEPROM.get(ee, ax_yaw.c_hdg); + ee += sizeof(float); + EEPROM.get(ee, dist); + ax_yaw.hdg_constant = ax_yaw.encoderpos_l + dist; + Serial.println(ax_yaw.c_hdg); + Serial.println(ax_yaw.hdg_constant); + } + break; + } + + case 'd': + ax_yaw.driver_status = GIMBAL_STATUS_MANUAL; + break; + + case 'p': + ax_yaw.set_xenc_to_xact(); + ax_yaw.target += ax_yaw.steps; + ax_yaw.new_pos = true; + break; + + case 'v': + ax_yaw.v_max = args[0]; + break; + + case '+': + ax_yaw.encoderpos_r = ax_yaw.X_enc; + break; + + case '-': + ax_yaw.encoderpos_l = ax_yaw.X_enc; + break; + + case '/': + ax_yaw.encoderpos_r = args[0]; + ax_yaw.encoderpos_l = args[1]; + Serial.println(ax_yaw.encoderpos_r); + Serial.println(ax_yaw.encoderpos_l); + break; + + case '?': + Serial.println(ax_yaw.encoderpos_r); + Serial.println(ax_yaw.encoderpos_l); + Serial.println(ax_yaw.encoderpos_l - ax_yaw.encoderpos_r); + break; + + default: + Serial.println(F("Unknown command")); + break; + } +} diff --git a/firmware/src/serial/CommandParser.h b/firmware/src/serial/CommandParser.h new file mode 100644 index 0000000..73ba0e4 --- /dev/null +++ b/firmware/src/serial/CommandParser.h @@ -0,0 +1,8 @@ +#ifndef FTW_COMMAND_PARSER_H +#define FTW_COMMAND_PARSER_H + +#include + +void parser(char &c); + +#endif diff --git a/firmware/src/thermal/ThermalManager.cpp b/firmware/src/thermal/ThermalManager.cpp new file mode 100644 index 0000000..0b3d122 --- /dev/null +++ b/firmware/src/thermal/ThermalManager.cpp @@ -0,0 +1,36 @@ +#include "thermal/ThermalManager.h" +#include "config/Pins.h" +#include "config/Constants.h" + +#include "DHT.h" + +static DHT s_dht(PIN_DHT_DATA, DHT11); +static int16_t s_temperature = 0; +static int8_t s_humidity = 0; + +void thermal_init(void) { + s_dht.begin(); +} + +void thermal_loop(void) { + s_humidity = s_dht.readHumidity(); + s_temperature = s_dht.readTemperature(); + + if (s_temperature > THERMAL_FAN_ON_TEMP) { + int16_t pwm = (s_temperature - THERMAL_FAN_ON_TEMP) * THERMAL_FAN_GAIN; + if (pwm > THERMAL_FAN_MAX_PWM) pwm = THERMAL_FAN_MAX_PWM; + analogWrite(PIN_FAN_PWM, pwm); + } else { + analogWrite(PIN_FAN_PWM, 0); + } + + (void)pulseIn(PIN_FAN_SENS, HIGH, THERMAL_FAN_PULSE_US); +} + +inline int16_t thermal_get_temperature(void) { + return s_temperature; +} + +inline int8_t thermal_get_humidity(void) { + return s_humidity; +} diff --git a/firmware/src/thermal/ThermalManager.h b/firmware/src/thermal/ThermalManager.h new file mode 100644 index 0000000..cc0f768 --- /dev/null +++ b/firmware/src/thermal/ThermalManager.h @@ -0,0 +1,12 @@ +#ifndef FTW_THERMAL_MANAGER_H +#define FTW_THERMAL_MANAGER_H + +#include + +void thermal_init(void); +void thermal_loop(void); + +inline int16_t thermal_get_temperature(void); +inline int8_t thermal_get_humidity(void); + +#endif diff --git a/firmware/test/README b/firmware/test/README new file mode 100755 index 0000000..b0416ad --- /dev/null +++ b/firmware/test/README @@ -0,0 +1,11 @@ + +This directory is intended for PlatformIO Test Runner and project tests. + +Unit Testing is a software testing method by which individual units of +source code, sets of one or more MCU program modules together with associated +control data, usage procedures, and operating procedures, are tested to +determine whether they are fit for use. Unit testing finds problems early +in the development cycle. + +More information about PlatformIO Unit Testing: +- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html diff --git a/host/CMakeLists.txt b/host/CMakeLists.txt new file mode 100755 index 0000000..900787a --- /dev/null +++ b/host/CMakeLists.txt @@ -0,0 +1,84 @@ +cmake_minimum_required(VERSION 3.10) +project(FireWatchTower_2axis) + +set(CMAKE_CXX_STANDARD 17) + +# Source files +add_executable(FireWatchTower_2axis + FWT_host.cpp + Camera.cpp + MQTT.cpp +) + +# Include directories +target_include_directories(FireWatchTower_2axis PRIVATE + /usr/local/include/mqtt + /usr/local/include + /usr/local/include/opencv4 + /usr/include/jxl/ + /opt/VimbaX/api/include/ + /usr/local/include/boost/ +) + +# Library search paths +target_link_directories(FireWatchTower_2axis PRIVATE + /usr/lib/x86_64-linux-gnu + /usr/local/lib + /opt/VimbaX/api/lib +) + +# Libraries +target_link_libraries(FireWatchTower_2axis PRIVATE + paho-mqttpp3 + paho-mqtt3a + opencv_core + opencv_imgproc + opencv_highgui + opencv_imgcodecs + jxl + jxl_threads + VmbC + VmbCPP + VmbImageTransform + boost_filesystem + boost_thread + boost_log + boost_log_setup + boost_system + boost_chrono + boost_regex + boost_program_options + boost_serialization + boost_iostreams + boost_date_time + boost_json + boost_locale + boost_coroutine + boost_context + boost_fiber + boost_random + boost_atomic + boost_url + boost_charconv + boost_container + boost_graph + boost_wave + boost_type_erasure + boost_contract + boost_timer + boost_nowide + boost_wserialization + boost_math_tr1 + boost_math_tr1f + boost_math_tr1l + boost_math_c99 + boost_math_c99f + boost_math_c99l + boost_stacktrace_basic + boost_stacktrace_noop + boost_stacktrace_addr2line + boost_stacktrace_backtrace + boost_stacktrace_from_exception + boost_prg_exec_monitor + boost_unit_test_framework +) diff --git a/host/Camera.cpp b/host/Camera.cpp new file mode 100755 index 0000000..ab89655 --- /dev/null +++ b/host/Camera.cpp @@ -0,0 +1,343 @@ +#include "Camera.h" +#include "JPEG_XL.h" +#include "timing.h" +#include +#include +#include +#include + + +class FrameObserver : public IFrameObserver +{ +public: + typedef std::function Callback; + Callback call; + + void registerCallback(Callback f) { + call = f; + } + + FrameObserver(CameraPtr camera) : IFrameObserver(camera) {}; + + void FrameReceived(const FramePtr pFrame) + { + bool bQueueDirectly = true; + VmbFrameStatusType eReceiveStatus; + + if (VmbErrorSuccess == pFrame->GetReceiveStatus(eReceiveStatus)) + { + /* ignore any incompletely frame */ + if (VmbFrameStatusComplete != eReceiveStatus) + { + VmbUint64_t id; + std::string name; + std::string serial; + pFrame->GetFrameID(id); + m_pCamera->GetModel(name); + m_pCamera->GetSerialNumber(serial); + std::cout << "!!!incomplete frame, rcvd error: " << eReceiveStatus << " id: " << id << " camera: " << name << " + " << serial << std::endl; + m_pCamera->QueueFrame(pFrame); + return; + } + // Lock the frame queue + m_FramesMutex.lock(); + // Add frame to queue + m_Frames.push(pFrame); + // Unlock frame queue + m_FramesMutex.unlock(); + // Emit the frame received signal + call(); + // callback! + bQueueDirectly = false; + } + else { + std::cout << "frame rcvd error" << std::endl; + } + + // If any error occurred we queue the frame without notification + if (true == bQueueDirectly) + { + m_pCamera->QueueFrame(pFrame); + } + }; + + FramePtr GetFrame() { + FramePtr res; + // Lock the frame queue + m_FramesMutex.lock(); + // Pop frame from queue + if (!m_Frames.empty()) + { + res = m_Frames.front(); + m_Frames.pop(); + } + // Unlock frame queue + m_FramesMutex.unlock(); + return res; + } + + void QueueF(FramePtr& frame) { + m_pCamera->QueueFrame(frame); + } + + void ClearFrameQueue() { + // Lock the frame queue + m_FramesMutex.lock(); + std::queue empty; + std::swap(m_Frames, empty); + m_FramesMutex.unlock(); + } +private: + std::queue m_Frames; + std::mutex m_FramesMutex; +}; + +VimbaHandler::VimbaHandler(const char* cameraId, MQTTClient* mqttc, motor_info* motor_i) : + m_vmbSystem(VmbSystem::GetInstance()), mqtt_client(mqttc), gimbal_data(motor_i) +{ + VmbErrorType err = m_vmbSystem.Startup(); + + if (err != VmbErrorSuccess) + { + throw std::runtime_error("Could not start API, err=" + std::to_string(err)); + } + + CameraPtrVector cameras; + err = m_vmbSystem.GetCameras(cameras); + if (err != VmbErrorSuccess) + { + m_vmbSystem.Shutdown(); + throw std::runtime_error("Could not get cameras, err=" + std::to_string(err)); + } + + if (cameras.empty()) + { + m_vmbSystem.Shutdown(); + throw std::runtime_error("No cameras found."); + } + + if (cameraId != nullptr) + { + err = m_vmbSystem.GetCameraByID(cameraId, m_camera); + if (err != VmbErrorSuccess) + { + m_vmbSystem.Shutdown(); + throw std::runtime_error("No camera found with ID=" + std::string(cameraId) + ", err = " + std::to_string(err)); + } + } + else + { + m_camera = cameras[0]; + } + + err = m_camera->Open(VmbAccessModeFull); + if (err != VmbErrorSuccess) + { + m_vmbSystem.Shutdown(); + throw std::runtime_error("Could not open camera, err=" + std::to_string(err)); + } + + std::string name; + if (m_camera->GetName(name) == VmbErrorSuccess) + { + std::cout << "Opened Camera " << name << std::endl; + } +} + +VimbaHandler::~VimbaHandler() +{ + try + { + Stop(); + } + catch (std::runtime_error& e) + { + std::cout << e.what() << std::endl; + } + + m_vmbSystem.Shutdown(); +} + +void VimbaHandler::Open() +{ +} + +void VimbaHandler::Close() +{ +} + +void VimbaHandler::Start() +{ + save_thread_running = true; + std::cout << "starting Camera thread" << std::endl; + image_saver_thread = std::thread(&VimbaHandler::SaveImage, this); + SP_SET(FO_ptr, new FrameObserver(m_camera)); + VmbErrorType err = m_camera->StartContinuousImageAcquisition(5, FO_ptr); + if (err != VmbErrorSuccess) + { + throw std::runtime_error("Could not start acquisition, err=" + std::to_string(err)); + } + else { + cam_started = true; + SP_DYN_CAST(FO_ptr)->registerCallback(std::bind(&VimbaHandler::EnqueueToStoreStruct,this)); + } +} + +void VimbaHandler::Stop() +{ + VmbErrorType err = m_camera->StopContinuousImageAcquisition(); + if (err != VmbErrorSuccess) + { + throw std::runtime_error("Could not stop acquisition, err=" + std::to_string(err)); + } + cam_started = false; + save_thread_running = false; + if (image_saver_thread.joinable()) { + image_saver_thread.join(); + } +} + +void VimbaHandler::evaluateCommand(std::string cmd, double val) +{ + if (cmd == "fps" && val > 0) + ChangeFramerate(val); + else if (cmd == "jxlq" && val > 0) + jxlq = val; + else if (cmd == "jxle" && val > 0) + jxle = val; + else if (cmd == "display" && val >=0) + display_image=int(val); +} + +void VimbaHandler::EnqueueToStoreStruct() +{ + FramePtr frame = SP_DYN_CAST(FO_ptr)->GetFrame(); + + VmbUint32_t Width; + VmbUint32_t Height; + VmbUint32_t BufferSize; + VmbPixelFormatType PixelFormat; + const VmbUchar_t* pBuffer(NULL); + + if (VmbErrorSuccess == frame->GetPixelFormat(PixelFormat) + && VmbErrorSuccess == frame->GetWidth(Width) + && VmbErrorSuccess == frame->GetHeight(Height) + && VmbErrorSuccess == frame->GetBufferSize(BufferSize) + && VmbErrorSuccess == frame->GetBuffer(pBuffer)) + { + NanoUnixTimer time; + long long tstamp = time.Stamp_longlong(); + std::lock_guard lg(queue_mut); + ImageStore8Ptr pFrame; + // in case we reached the maximum number of queued frames + // take of the oldest and reuse it to store the newly arriving frame + + std::vector data_in = std::vector(pBuffer, pBuffer + BufferSize); + if (m_ImageQueueRGB8.size() >= 100) + { + pFrame = m_ImageQueueRGB8.front(); + m_ImageQueueRGB8.pop(); + if (!pFrame->equal(Width, Height, PixelFormat)) + { + pFrame.reset(); + } + } + if (pFrame == NULL) + { + pFrame = ImageStore8Ptr(new image_store_8bit(data_in.data(), data_in.size(), Width, Height, PixelFormat, tstamp)); + } + else + { + pFrame->setData(data_in.data(), data_in.size(), tstamp); + } + m_ImageQueueRGB8.push(pFrame); + + SP_DYN_CAST(FO_ptr)->QueueF(frame); + cv_proc.notify_one(); + } +} + +void VimbaHandler::SaveImage() +{ + while (save_thread_running) { + std::unique_lock lock(proc_wait_mut); + cv_proc.wait(lock); + ImageStore8Ptr pFrame; + while (m_ImageQueueRGB8.size() > 0 && save_jxl) + { + std::cout << "RGB SaveQueue size: " << m_ImageQueueRGB8.size() << std::endl; + Timer time; + queue_mut.lock(); + pFrame = m_ImageQueueRGB8.front(); + m_ImageQueueRGB8.pop(); + queue_count_rgb = m_ImageQueueRGB8.size(); + queue_mut.unlock(); + cv::Mat img_to_rotate = cv::Mat(pFrame->height(), pFrame->width(), CV_8UC3, pFrame->data()); + cv::Mat img; + cv::rotate(img_to_rotate, img, cv::ROTATE_90_COUNTERCLOCKWISE); + if (display_image) { + cv::namedWindow("Display Image", cv::WINDOW_NORMAL); + cv::resizeWindow("Display Image", img.cols/4,img.rows/4); + cv::imshow("Display Image", img); + cv::waitKey(10); + } + std::string homedir = getenv("HOME"); + std::string filename = homedir+ "/projects/Fire_Gimbal_Control/bin/x64/Release/RGB/" + std::to_string(pFrame->getTimestamp()) + ".jxl"; + JPEGXL jxl_writer(img.cols, img.rows, img.data, 3, (float)jxlq, (int)jxle); + jxl_writer.WriteFile(filename.c_str()); + std::cout << "RGB Compress TIME:" << std::to_string(time.ElapsedMillis()) << std::endl; + time.Reset(); + //cv::imwrite(filename, img, compression_params); + std::string net_path = "/mnt/ggs-smb/FirewatchTowers/FWT_Podrosche/"; + std::string backup_net_path = "/home/ggs/fwt_image_backup/"; + //try { + // std::filesystem::copy_file(filename, net_path + filename); + // std::cout << "RGB Upload TIME:" << std::to_string(time.ElapsedMillis()) << std::endl; + //} + //catch (std::filesystem::filesystem_error& e) + //{ + // std::cout << "Could not copy image to zkms: " << e.what() << '\n'; + // std::cout << "Copy Backup to LattePanda Sigma" << '\n'; + // try { + // std::filesystem::copy_file(filename, backup_net_path + filename); + // } + // catch (std::filesystem::filesystem_error& e) + // { + // std::cout << "Could not copy image to LattePanda Sigma: " << e.what() << '\n'; + // } + //} + //std::filesystem::remove(filename); + mqtt_client->publish(mqtt_RGB,std::to_string((int)(gimbal_data->hdg*10)) + "," + std::to_string(pFrame->getTimestamp())); + } + } +} + +bool VimbaHandler::ChangeFramerate(double fr) +{ + VmbErrorType result; + FeaturePtr pFeature; + result = SP_ACCESS(m_camera)->GetFeatureByName("AcquisitionFrameRate", pFeature); + if (result == VmbErrorSuccess) + result = pFeature->SetValue(fr); + if (result == VmbErrorSuccess) { + std::cout << "camera fps changed: " << fr<< std::endl; + return true; + } + std::cout << "camera fps change failed with error:"<< result << std::endl; + return false; +} + +bool VimbaHandler::TriggerCamera() +{ + VmbErrorType result; + FeaturePtr pFeature; + result = SP_ACCESS(m_camera)->GetFeatureByName("TriggerSoftware", pFeature); + if (result == VmbErrorSuccess) + result = pFeature->RunCommand(); + if (result == VmbErrorSuccess) { + std::cout << "camera triggerd " << std::endl; + return true; + } + std::cout << "camera trigger failed with error:" << result << std::endl; + return false; +} diff --git a/host/Camera.h b/host/Camera.h new file mode 100755 index 0000000..1672dc4 --- /dev/null +++ b/host/Camera.h @@ -0,0 +1,100 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include "MQTT.h" +#include "Serial.h" +using namespace VmbCPP; + +struct image_store_8bit +{ +private: + typedef std::vector data_vec; + data_vec m_Data; + VmbUint32_t m_Width; // frame width + VmbUint32_t m_Height; // frame height + VmbPixelFormat_t m_PixelFormat; // frame pixel format + long long m_timestamp; +public: + image_store_8bit(const VmbUchar_t* pBuffer, VmbUint32_t BufferByteSize, VmbUint32_t Width, VmbUint32_t Height, VmbPixelFormatType PixelFormat, long long stamp) + : m_Data(pBuffer, pBuffer + BufferByteSize) + , m_Width(Width) + , m_Height(Height) + , m_PixelFormat(PixelFormat) + , m_timestamp(stamp) + { + } + + long long getTimestamp() { + return(m_timestamp); + } + + bool equal(VmbUint32_t Width, VmbUint32_t Height, VmbPixelFormat_t PixelFormat) const + { + return m_Width == Width + && m_Height == Height + && m_PixelFormat == PixelFormat; + } + + bool setData(const VmbUchar_t* Buffer, VmbUint32_t BufferSize, long long stamp) + { + if (BufferSize == dataSize()) + { + std::copy(Buffer, Buffer + BufferSize, m_Data.begin()); + m_timestamp = stamp; + return true; + } + return false; + } + VmbPixelFormat_t pixelFormat() const { return m_PixelFormat; } + VmbUint32_t width() const { return m_Width; } + VmbUint32_t height() const { return m_Height; } + VmbUint32_t dataSize() const { return static_cast(m_Data.size()); } + const VmbUchar_t* data() const { return &*m_Data.begin(); } + VmbUchar_t* data() { return &*m_Data.begin(); } +}; + +class VimbaHandler +{ +public: + VimbaHandler(const char* cameraId, MQTTClient* mqtt_c, motor_info* motor_i); + ~VimbaHandler(); + void Open(); + void Close(); + void Start(); + void Stop(); + void evaluateCommand(std::string cmd, double val); + void EnqueueToStoreStruct(); + void SaveImage(); + bool ChangeFramerate(double fr); + bool TriggerCamera(); + + + bool cam_started = false; + int queue_count_rgb=0; +private: + double jxlq = 2.0; + double jxle = 3.0; + const std::string fwt_name = "Dev"; + const std::string mqtt_RGB = "GGS/FWT/" + fwt_name + "/CamEvent/RGB"; + motor_info* gimbal_data; + MQTTClient* mqtt_client; + typedef std::shared_ptr ImageStore8Ptr; + typedef std::queue ImageQueue8; + ImageQueue8 m_ImageQueueRGB8; + std::mutex queue_mut; + std::mutex proc_wait_mut; + std::condition_variable cv_proc; + bool save_thread_running = false; + bool save_jxl = true; + bool display_image = false; + std::thread image_saver_thread; + IFrameObserverPtr FO_ptr; + VmbSystem& m_vmbSystem; + CameraPtr m_camera; +}; + diff --git a/host/FWT_host.cpp b/host/FWT_host.cpp new file mode 100755 index 0000000..1fb2d90 --- /dev/null +++ b/host/FWT_host.cpp @@ -0,0 +1,281 @@ +#include +#include +#include +#include +#include + +#include +#include + +#include "Camera.h" +#include "MQTT.h" +#include "Parser.h" +#include "timing.h" + +namespace po = boost::program_options; + +/* ------------------------------------------------------------------ */ +/* Application State */ +/* ------------------------------------------------------------------ */ + +struct AppState { + std::atomic running{true}; + + bool motorctl_info_out{false}; + bool init_gimbal{false}; + bool start_gimbal{false}; + bool trigger_after_stopping{false}; + + double imagerate{0.1}; + int ctl_code{0}; + std::string mqtt_hdg{"0"}; + + std::string fwt_name{"Dev"}; + Parser parse_cmd; + Timer loop_timer; +}; + +static AppState g_state; + +/* ------------------------------------------------------------------ */ +/* Helpers */ +/* ------------------------------------------------------------------ */ + +static void readInput() { + std::string input; + while (g_state.running) { + std::getline(std::cin, input); + if (input == "exit") { + g_state.running = false; + break; + } + std::cout << "Received input: " << input << "\n"; + g_state.parse_cmd.parse_input(input); + } +} + +static void parseCommandLine(int argc, char* argv[], bool& init, bool& start) { + po::options_description desc("Allowed options"); + desc.add_options() + ("help,h", "produce help message") + ("init,i", po::value(), "find endstops") + ("start,s", po::value(), "start gimbal system automatically"); + + po::variables_map vm; + try { + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + if (vm.count("help")) { + std::cout << desc << "\n"; + std::exit(0); + } + + if (vm.count("init")) { + init = vm["init"].as(); + std::cout << "find endstops: " << init << "\n"; + } else { + std::cout << "init was not set.\n"; + } + + if (vm.count("start")) { + start = vm["start"].as(); + std::cout << "starting gimbal: " << start << "\n"; + } else { + std::cout << "Not starting Gimbal automatically.\n"; + } + } catch (const std::exception& e) { + std::cerr << "ARGS Error: " << e.what() << "\n"; + std::exit(1); + } catch (...) { + std::cerr << "Unknown ARGS error!\n"; + std::exit(1); + } +} + +static void initGimbal(SerialPort& serial) { + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + serial.sendCommand("r"); + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + serial.sendCommand("e"); + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + serial.sendCommand("q"); + std::this_thread::sleep_for(std::chrono::milliseconds(60000)); + serial.get_controller_info(); + serial.sendCommand("y"); + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + serial.sendCommand("ud80"); + std::cout << "Gimbal init finished." << std::endl; +} + +static void printMotorInfo(const motor_info& info) { + std::cout << "_________________________________\n" + << "Encoder act: " << info.Xenc << "\n" + << "HDG: " << info.hdg << "\n" + << "Encoder err: " << info.Xerr << "\n" + << "sgt_stat/sgt_val/not_moving: " << info.sgt_stat + << " / " << info.sgt_val << " / " << info.is_moving << "\n" + << "Driver Status: " << info.control_status << "\n" + << "Deviation Warning: " << info.deviation_warn << "\n" + << "temp/humid/fan_pwm(0-255): " << info.temp + << " / " << info.humid << " / " << info.fan_pwm << "\n"; +} + +static void processCommands(SerialPort& serial, VimbaHandler& cam) { + parser_data cmd_data = g_state.parse_cmd.get_parser_data(); + CMD_eval eval; + InputCommands cmds = eval.eval(g_state.parse_cmd); + + if (cmds == no_cmd) return; + + switch (cmds) { + case startcamera: + std::cout << "starting Camera" << std::endl; + cam.Start(); + break; + case stopcamera: + std::cout << "stopping Camera" << std::endl; + cam.Stop(); + break; + case setcamera: + cam.evaluateCommand(cmd_data.option, cmd_data.command_val); + break; + case setmotorcontrol: + std::cout << "send command: " << cmd_data.option << std::endl; + serial.sendCommand(cmd_data.option); + break; + case setimagerate: + g_state.imagerate = cmd_data.command_val; + std::cout << "imagerate is: " << g_state.imagerate << std::endl; + break; + case setdebug: + g_state.motorctl_info_out = !g_state.motorctl_info_out; + std::cout << "debug is: " << g_state.motorctl_info_out << std::endl; + break; + default: + break; + } +} + +static void handleCameraTrigger( + SerialPort& serial, + const motor_info& act_info, + VimbaHandler& cam) +{ + if (!cam.cam_started) return; + + const double interval_ms = 1000.0 / g_state.imagerate; + + if (g_state.ctl_code == 0) { + if (g_state.loop_timer.ElapsedMillis() > interval_ms && act_info.is_moving == 1) { + g_state.loop_timer.Reset(); + g_state.trigger_after_stopping = true; + serial.sendCommand("p"); + } + if (g_state.trigger_after_stopping && g_state.loop_timer.ElapsedMillis() > 100 && act_info.is_moving == 1) { + if (cam.TriggerCamera()) { + std::cout << "trigger camera" << std::endl; + g_state.trigger_after_stopping = false; + } + } + } else if (g_state.ctl_code == 1) { + if (g_state.loop_timer.ElapsedMillis() > interval_ms && act_info.is_moving == 1) { + g_state.loop_timer.Reset(); + g_state.trigger_after_stopping = true; + serial.sendCommand("kd" + g_state.mqtt_hdg); + std::cout << "ctl " << g_state.ctl_code << std::endl; + std::cout << "hdg " << g_state.mqtt_hdg << std::endl; + } + if (g_state.trigger_after_stopping && g_state.loop_timer.ElapsedMillis() > 100 && act_info.is_moving == 1) { + if (cam.TriggerCamera()) { + std::cout << "trigger camera" << std::endl; + g_state.trigger_after_stopping = false; + } + } + } +} + +/* ------------------------------------------------------------------ */ +/* Main */ +/* ------------------------------------------------------------------ */ + +int main(int argc, char* argv[]) { + /* ---- Parse CLI arguments ---- */ + bool init = false, start = false; + parseCommandLine(argc, argv, init, start); + g_state.init_gimbal = init; + g_state.start_gimbal = start; + + /* ---- Serial communication ---- */ + SerialPort serial("/dev/ttyACM0", 115200); + std::thread io_thread; + try { + serial.startReading(); + io_thread = std::thread([&serial]() { serial.run(); }); + } catch (const std::exception& e) { + std::cerr << "Serial Exception: " << e.what() << std::endl; + } + + /* ---- MQTT connection ---- */ + MQTTClient mqtt_client("172.16.42.1", g_state.fwt_name, g_state.fwt_name); + const std::string mqtt_STATUS = "GGS/FWT/" + g_state.fwt_name + "/StatusCode"; + + mqtt_client.connect_client(); + while (!mqtt_client.connected) { + std::this_thread::sleep_for(std::chrono::milliseconds(50)); + } + mqtt_client.publish(mqtt_STATUS, "0"); + + /* ---- Input thread ---- */ + std::thread inputThread(readInput); + + /* ---- Camera handler ---- */ + motor_info act_info; + VimbaHandler cam_handler(NULL, &mqtt_client, &act_info); + + /* ---- Gimbal initialization ---- */ + if (g_state.init_gimbal) { + initGimbal(serial); + } + + /* ---- Main loop ---- */ + while (g_state.running) { + /* Commands from stdin */ + processCommands(serial, cam_handler); + + /* Auto-start camera if requested */ + if (g_state.start_gimbal) { + std::cout << "starting Camera" << std::endl; + cam_handler.Start(); + g_state.start_gimbal = false; + } + + /* Motor controller info */ + act_info = serial.get_controller_info(); + if (g_state.motorctl_info_out) { + printMotorInfo(act_info); + } + + /* MQTT inbound messages */ + mqtt_sub_data mqtt_in = mqtt_client.callback.get_sub_data(); + if (mqtt_in.ctl_avail) { + g_state.ctl_code = mqtt_in.control_code; + mqtt_client.publish(mqtt_STATUS, std::to_string(g_state.ctl_code)); + } + if (mqtt_in.hdg_avail) { + g_state.mqtt_hdg = mqtt_in.target_heading; + } + + /* Gimbal control and camera trigger */ + handleCameraTrigger(serial, act_info, cam_handler); + + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } + + /* ---- Cleanup ---- */ + serial.stop(); + io_thread.join(); + inputThread.join(); + + return 0; +} diff --git a/host/JPEG_XL.h b/host/JPEG_XL.h new file mode 100755 index 0000000..9b756f1 --- /dev/null +++ b/host/JPEG_XL.h @@ -0,0 +1,110 @@ +#pragma once +#include +#include // for fopen, fclose +#include +#include +#include +#include +#include +#include +#include +#include +class JPEGXL +{ +public: + JPEGXL(int width, int height, const unsigned char* img, int num_channels, float q, int e, int th = 4) :m_width(width), m_height(height), m_num_channels(num_channels), m_quality(q), m_efford(e) + { + auto enc = JxlEncoderMake(/*memory_manager=*/nullptr); + + auto runner = JxlThreadParallelRunnerMake(nullptr, th); + if (JXL_ENC_SUCCESS != JxlEncoderSetParallelRunner(enc.get(), + JxlThreadParallelRunner, + runner.get())) { + fprintf(stderr, "JxlEncoderSetParallelRunner failed\n"); + } + + JxlPixelFormat pixel_format = { m_num_channels, JXL_TYPE_UINT8, JXL_NATIVE_ENDIAN, 0 }; + JxlBasicInfo basic_info; + JxlEncoderInitBasicInfo(&basic_info); + basic_info.xsize = m_width; + basic_info.ysize = m_height; + basic_info.alpha_bits = 0; + basic_info.bits_per_sample = 8; + basic_info.num_color_channels = m_num_channels; + basic_info.uses_original_profile = false; + + if (JXL_ENC_SUCCESS != JxlEncoderSetBasicInfo(enc.get(), &basic_info)) { + fprintf(stderr, "JxlEncoderSetBasicInfo failed\n"); + return; + } + JxlColorEncoding color_encoding = {}; + JxlColorEncodingSetToSRGB(&color_encoding,/*is_gray=*/pixel_format.num_channels < 3); + if (JXL_ENC_SUCCESS != JxlEncoderSetColorEncoding(enc.get(), &color_encoding)) { + fprintf(stderr, "JxlEncoderSetColorEncoding failed\n"); + return; + } + JxlEncoderFrameSettings* frame_settings = JxlEncoderFrameSettingsCreate(enc.get(), nullptr); + JxlEncoderFrameSettingsSetOption(frame_settings, JXL_ENC_FRAME_SETTING_EFFORT, e); + JxlEncoderFrameSettingsSetOption(frame_settings, JXL_ENC_FRAME_SETTING_DECODING_SPEED, 0); + + if (q == 0) {//if lossless + JxlEncoderSetFrameDistance(frame_settings, 0); + JxlEncoderSetFrameLossless(frame_settings, true); + } + else { + JxlEncoderSetFrameLossless(frame_settings, false); + JxlEncoderSetFrameDistance(frame_settings, q); + } + if (JXL_ENC_SUCCESS != JxlEncoderAddImageFrame(frame_settings, &pixel_format, (void*)img, sizeof(uint8_t) * m_width * m_height * m_num_channels)) { + fprintf(stderr, "JxlEncoderAddImageFrame failed\n"); + return; + } + JxlEncoderCloseInput(enc.get()); + std::vector* compressed = &compressed_data; + compressed->resize(64); + uint8_t* next_out = compressed->data(); + size_t avail_out = compressed->size() - (next_out - compressed->data()); + JxlEncoderStatus process_result = JXL_ENC_NEED_MORE_OUTPUT; + while (process_result == JXL_ENC_NEED_MORE_OUTPUT) { + process_result = JxlEncoderProcessOutput(enc.get(), &next_out, &avail_out); + if (process_result == JXL_ENC_NEED_MORE_OUTPUT) { + size_t offset = next_out - compressed->data(); + compressed->resize(compressed->size() * 2); + next_out = compressed->data() + offset; + avail_out = compressed->size() - offset; + } + } + compressed->resize(next_out - compressed->data()); + if (JXL_ENC_SUCCESS != process_result) { + fprintf(stderr, "JxlEncoderProcessOutput failed\n"); + return; + } + } + ~JPEGXL() {} + + bool WriteFile(const char* filename) { + FILE* file = fopen(filename, "wb"); + if (!file) { + fprintf(stderr, "Could not open %s for writing\n", filename); + return false; + } + if (fwrite(compressed_data.data(), sizeof(uint8_t), compressed_data.size(), file) != + compressed_data.size()) { + fprintf(stderr, "Could not write bytes to %s\n", filename); + fclose(file); + return false; + } + if (fclose(file) != 0) { + fprintf(stderr, "Could not close %s\n", filename); + return false; + } + return true; + } +private: + int m_width; + int m_height; + int m_num_channels; + float m_quality; + int m_efford; + std::vector compressed_data; +}; diff --git a/host/Log.h b/host/Log.h new file mode 100755 index 0000000..50e9667 --- /dev/null +++ b/host/Log.h @@ -0,0 +1 @@ +#pragma once diff --git a/host/MQTT.cpp b/host/MQTT.cpp new file mode 100755 index 0000000..296ded7 --- /dev/null +++ b/host/MQTT.cpp @@ -0,0 +1,157 @@ +#include "MQTT.h" + +const int QOS = 1; +const int N_RETRY_ATTEMPTS = 5; +const std::string SERVER_ADDRESS{ "172.16.42.1" };//localhost:1883"); +const std::string CLIENT_ID{ "gimbaltest" }; + + +void MQTTCallback::on_failure(const mqtt::token& tok) +{ + std::cout << "Connection failed" << std::endl; + if (++nretry_ > N_RETRY_ATTEMPTS) + std::cout << "Connection attempt failed already a few times" << std::endl; + reconnect(); +} + + + + +// (Re)connection success +void MQTTCallback::connected(const std::string& cause) { + std::cout << "\nConnection success" << std::endl; + std::cout << "\nSubscribing to topics.." << std::endl; + + cli_.subscribe(tpoic_target_hdg, QOS, nullptr, subListener_); + cli_.subscribe(topic_control_mode, QOS, nullptr, subListener_); +} + +void MQTTCallback::message_arrived(mqtt::const_message_ptr msg) { + std::cout << "Message arrived" << std::endl; + std::cout << "\ttopic: '" << msg->get_topic() << "'" << std::endl; + std::cout << "\tpayload: '" << msg->to_string() << "'\n" << std::endl; + if (msg->get_topic() == "GGS/FWT/" + fwt_name + "/target_HDG") { + try { + int value = static_cast(std::stoi(msg->to_string())); + std::unique_lock ul(mqtt_mut); + sub_data.set_target_heading(msg->to_string()); + } + catch (const std::invalid_argument& e) { + std::cerr << "MQTT type convertion invalid argument: " << e.what() << std::endl; + } + catch (const std::out_of_range& e) { + std::cerr << "MQTT type convertion out of range: " << e.what() << std::endl; + } + } + else if (msg->get_topic() == "GGS/FWT/" + fwt_name + "/ControlCode") { + try { + std::unique_lock ul(mqtt_mut); + sub_data.set_control_code(static_cast(std::stoi(msg->to_string()))); + } + catch (const std::invalid_argument& e) { + std::cerr << "MQTT type convertion invalid argument: " << e.what() << std::endl; + } + catch (const std::out_of_range& e) { + std::cerr << "MQTT type convertion out of range: " << e.what() << std::endl; + } + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////7x + +MQTTClient::MQTTClient(const std::string& serverURI, const std::string& clientId, std::string tower_name) + : client(serverURI, clientId), callback(client, connOpts, tower_name) +{ + connOpts.set_keep_alive_interval(20); + connOpts.set_clean_session(true); + std::cout << "MQTT object created" << std::endl; + client.set_callback(callback); + std::cout << "MQTT callback set" << std::endl; +} + +MQTTClient::~MQTTClient() { + if (client.is_connected()) + disconnect(); +} + +void MQTTClient::connect_client() { + std::cout << "connecting MQTT..." << std::endl; + running = true; + mqtt_thread = std::thread(&MQTTClient::run, this); + +} + +void MQTTClient::run() { + const auto TIMEOUT = std::chrono::seconds(5); + try { + conToken = client.connect(connOpts, nullptr, callback); + conToken->wait_for(TIMEOUT); + connected = true; + } + catch (const mqtt::exception& exc) { + std::cerr << "Error: " << exc.what() << std::endl; + running = false; + connected = false; + return; + } + std::cout << "MQTT connected" << std::endl; + + while (running) + ; +} + +void MQTTClient::disconnect() { + // Disconnect + try { + std::cout << "\nDisconnecting from the MQTT server..." << std::flush; + client.disconnect()->wait(); + std::cout << "OK" << std::endl; + } + catch (const mqtt::exception& exc) { + std::cerr << exc.what() << std::endl; + } + running = false; + mqtt_thread.join(); +} + +void MQTTClient::publish(const std::string& topic, const std::string& payload) { + const auto TIMEOUT = std::chrono::seconds(3); + mqtt::delivery_token_ptr pubtok; + mqtt::message_ptr msg = mqtt::make_message(topic, payload); + msg->set_qos(1); + msg->set_retained(true); + try { + pubtok = client.publish(msg); + pubtok->wait_for(TIMEOUT); + } + catch (const mqtt::exception& exc) { + std::cerr << "Error: " << exc.what() << std::endl; + } +} + +void MQTTClient::subscribe(const std::string& topic) { + try { + subToken = client.subscribe(topic, 1); + subToken->wait(); + } + catch (const mqtt::exception& exc) { + std::cerr << "Error: " << exc.what() << std::endl; + } +} + +void MQTTClient::receiveMessages() { + try { + client.start_consuming(); + } + catch (const mqtt::exception& exc) { + std::cerr << "Error: " << exc.what() << std::endl; + } + while (true) { + + } +} + +bool MQTTClient::is_connected_to_server() +{ + return client.is_connected(); +} diff --git a/host/MQTT.h b/host/MQTT.h new file mode 100755 index 0000000..5a65bc1 --- /dev/null +++ b/host/MQTT.h @@ -0,0 +1,157 @@ +#pragma once + +#include +#include +#include +#include +struct mqtt_sub_data +{ + bool ctl_avail = false; + bool hdg_avail = false; + std::string target_heading=""; + int control_code = 0; + void set_control_code(int c) { + ctl_avail = true; + control_code = c; + } + void set_target_heading(std::string target) { + hdg_avail = true; + target_heading = target; + } +}; + +// Callbacks for the success or failures of requested actions. +// This could be used to initiate further action, but here we just log the +// results to the console. +class action_listener : public virtual mqtt::iaction_listener +{ + std::string name_; + + void on_failure(const mqtt::token& tok) override { + std::cout << name_ << " failure"; + if (tok.get_message_id() != 0) + std::cout << " for token: [" << tok.get_message_id() << "]" << std::endl; + std::cout << std::endl; + } + + void on_success(const mqtt::token& tok) override { + std::cout << name_ << " success"; + if (tok.get_message_id() != 0) + std::cout << " for token: [" << tok.get_message_id() << "]" << std::endl; + auto top = tok.get_topics(); + if (top && !top->empty()) + std::cout << "\ttoken topic: '" << (*top)[0] << "', ..." << std::endl; + std::cout << std::endl; + } + +public: + action_listener(const std::string& name) : name_(name) {} +}; + +///////////////////////////////////////////////////////////////////////////// + +/** + * Local callback & listener class for use with the client connection. + * This is primarily intended to receive messages, but it will also monitor + * the connection to the broker. If the connection is lost, it will attempt + * to restore the connection and re-subscribe to the topic. + */ +class MQTTCallback : public virtual mqtt::callback, + public virtual mqtt::iaction_listener + +{ + const std::string tpoic_target_hdg; + const std::string topic_control_mode; + mqtt_sub_data sub_data; + std::mutex mqtt_mut; + std::string fwt_name; + // Counter for the number of connection retries + int nretry_; + // The MQTT client + mqtt::async_client& cli_; + // Options to use if we need to reconnect + mqtt::connect_options& connOpts_; + // An action listener to display the result of actions. + action_listener subListener_; + + // This deomonstrates manually reconnecting to the broker by calling + // connect() again. This is a possibility for an application that keeps + // a copy of it's original connect_options, or if the app wants to + // reconnect with different options. + // Another way this can be done manually, if using the same options, is + // to just call the async_client::reconnect() method. + void reconnect() { + std::this_thread::sleep_for(std::chrono::milliseconds(2500)); + try { + cli_.connect(connOpts_, nullptr, *this); + } + catch (const mqtt::exception& exc) { + std::cerr << "Error: " << exc.what() << std::endl; + } + } + + + // Re-connection failure + void on_failure(const mqtt::token& tok) override; + + // (Re)connection success + // Either this or connected() can be used for callbacks. + void on_success(const mqtt::token& tok) override {} + // Re-connection success + void connected(const std::string& cause) override; + + // Callback for when the connection is lost. + // This will initiate the attempt to manually reconnect. + void connection_lost(const std::string& cause) override { + std::cout << "\nConnection lost" << std::endl; + if (!cause.empty()) + std::cout << "\tcause: " << cause << std::endl; + + std::cout << "Reconnecting..." << std::endl; + nretry_ = 0; + reconnect(); + } + + // Callback for when a message arrives. + void message_arrived(mqtt::const_message_ptr msg) override; + + void delivery_complete(mqtt::delivery_token_ptr token) override { + std::cout << "Message delivery complete" << std::endl; + } + +public: + MQTTCallback(mqtt::async_client& cli, mqtt::connect_options& connOpts, std::string tower_name) + : nretry_(0), cli_(cli), connOpts_(connOpts), subListener_("Subscription"), fwt_name(tower_name), tpoic_target_hdg("GGS/FWT/" + tower_name + "/target_HDG"), topic_control_mode("GGS/FWT/" + tower_name + "/ControlCode") {} + mqtt_sub_data get_sub_data() { + std::unique_lock ul(mqtt_mut); + mqtt_sub_data tmp = sub_data; + sub_data.hdg_avail = false; + sub_data.ctl_avail = false; + return tmp; + } +}; + +class MQTTClient { +public: + MQTTClient(const std::string& serverURI, const std::string& clientId, std::string tower_name); + ~MQTTClient(); + + void connect_client(); + void run(); + void disconnect(); + void publish(const std::string& topic, const std::string& payload); + void subscribe(const std::string& topic); + void receiveMessages(); + bool is_connected_to_server(); + + bool running = false; + bool connected = false; + MQTTCallback callback; +private: + std::string fwt_name; + mqtt::async_client client; + mqtt::token_ptr subToken; + mqtt::token_ptr conToken; + mqtt::connect_options connOpts; + std::thread mqtt_thread; +}; diff --git a/host/Parser.h b/host/Parser.h new file mode 100755 index 0000000..d2161f0 --- /dev/null +++ b/host/Parser.h @@ -0,0 +1,101 @@ +#pragma once +#include +#include +#include +#include + +namespace qi = boost::spirit::qi; + +enum InputCommands +{ + no_cmd, + startcamera, + stopcamera, + setcamera, + setimagerate, + setgimbal, + setmotorcontrol, + setdebug +}; + +struct parser_data { + std::string command=""; + std::string device = ""; + std::string option = ""; + double command_val=0.0; +}; + +struct Parser +{ + parser_data p_data; + std::mutex mut; + void set_parser_data(parser_data& data) { + std::cout << "parser set data..." << std::endl; + std::lock_guard lg(mut); + p_data = data; + } + + void clear_parser_data() { + //std::cout << "parser clear data..." << std::endl; + std::lock_guard lg(mut); + p_data.command = ""; + } + + parser_data get_parser_data() { + //std::cout << "parser get data..." << std::endl; + std::lock_guard lg(mut); + parser_data temp= p_data; + //clear_parser_data(); + return temp; + } + + void parse_input(std::string input) { + parser_data temp_data; + qi::parse( + input.begin(), input.end(), + (*qi::char_("a-zA-Z") >> ' ' >> *qi::char_("a-zA-Z") >> ' ' >> *qi::char_("a-zA-Z") >> ' ' >> qi::double_), + temp_data.command, temp_data.device, temp_data.option, temp_data.command_val + ); + std::cout << temp_data.command << " ... " << temp_data.device << " ... " << temp_data.option << " ... " << temp_data.command_val << std::endl; + set_parser_data(temp_data); + std::cout << "parser data set" << temp_data.command_val << std::endl; + } +}; + +struct CMD_eval { + InputCommands eval(Parser& parse) { + if (parse.p_data.command == "start") { + std::cout << "starting Camera" << std::endl; + parse.clear_parser_data(); + return startcamera; + } + else if (parse.p_data.command == "stop") { + std::cout << "stopping Camera" << std::endl; + parse.clear_parser_data(); + return stopcamera; + } + else if (parse.p_data.command == "debug") { + parse.clear_parser_data(); + return setdebug; + } + else if (parse.p_data.command == "set") { + //std::cout << "setting" << std::endl; + if (parse.p_data.device == "camera") { + parse.clear_parser_data(); + return setcamera; + } + else if (parse.p_data.device == "fps") { + parse.clear_parser_data(); + return setimagerate; + } + else if (parse.p_data.device == "motorctl") { + parse.clear_parser_data(); + return setmotorcontrol; + } + + } + else { + return no_cmd; + } + } +}; diff --git a/host/README.md b/host/README.md new file mode 100644 index 0000000..5040566 --- /dev/null +++ b/host/README.md @@ -0,0 +1,113 @@ +# Host Application + +C++ application running on the LattePanda's Linux side. Handles camera acquisition, serial communication with the Arduino firmware, and MQTT-based remote control. + +## Dependencies + +| Library | Purpose | +|---------|---------| +| **Vimba SDK** | Camera control (Allied Vision / FLIR) | +| **Eclipse Paho MQTT C/C++** | MQTT client for telemetry and remote commands | +| **OpenCV 4** | Image processing and codecs | +| **libjxl** | JPEG XL image encoding | +| **Boost** | Program options, ASIO (serial), Spirit (parsing), threading | + +Install system packages (Debian/Ubuntu): +```bash +sudo apt install libboost-all-dev libopencv-dev libjxl-dev libpaho-mqttpp3-dev libpaho-mqtt3-dev +``` + +Vimba SDK must be installed separately from Allied Vision. + +## Build + +```bash +mkdir build && cd build +cmake .. +make -j$(nproc) +``` + +## Usage + +```bash +./FireWatchTower_2axis [options] + +Options: + -h, --help Produce help message + -i, --init [bool] Run gimbal endstop initialization sequence + -s, --start [bool] Auto-start camera acquisition on launch +``` + +Example: +```bash +./FireWatchTower_2axis --init true --start true +``` + +## Serial Communication + +The host communicates with the Arduino firmware over `/dev/ttyACM0` at 115200 baud. + +### Incoming Telemetry + +The firmware periodically sends motor status lines prefixed with `$`, semicolon-delimited: +``` +$Xenc;Xerr;sgt_val;sgt_stat;is_moving;control_status;hdg;deviation_warn;humid;temp;fan_pwm +``` + +Parsed into `motor_info` struct in [Serial.h](Serial.h). + +### Outgoing Commands + +Single-character commands sent via `serial.sendCommand()`: +- `r` — Reset motor parameters and power on +- `e` — Reset SGT (step goal threshold) +- `q` — Run endstop homing sequence +- `y` — Load heading calibration from EEPROM +- `ud80` — Set auto-scan step length +- `p` — Step yaw to next position (trigger after stop) +- `kd` — Set target heading (guided mode) + +## MQTT Integration + +Connects to broker at `172.16.42.1` (hardcoded; modify [MQTT.cpp](MQTT.cpp) to change). Subscribes to two control topics and publishes status/camera events. + +### Subscribed Topics + +| Topic | Payload | Effect | +|-------|---------|--------| +| `GGS/FWT//ControlCode` | `0` or `1` | Switch control mode: 0=free scan, 1=guided heading | +| `GGS/FWT//target_HDG` | Float string | Target yaw heading for guided mode | + +### Published Topics + +| Topic | Payload | Description | +|-------|---------|-------------| +| `GGS/FWT//StatusCode` | Integer | Current control mode | +| `GGS/FWT//CamEvent/RGB` | — | Camera event notifications | + +## Interactive Commands (stdin) + +While running, the host accepts commands on stdin parsed by Boost.Spirit: + +| Command | Description | +|---------|-------------| +| `start` | Start camera acquisition | +| `stop` | Stop camera acquisition | +| `set camera