repo refactoring
65
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 (`<tower>` is the instance name, default `Dev`):
|
||||
|
||||
| Topic | Direction | Description |
|
||||
|-------|-----------|-------------|
|
||||
| `GGS/FWT/<tower>/StatusCode` | Publish | Current control mode (0=free scan, 1=guided) |
|
||||
| `GGS/FWT/<tower>/CamEvent/RGB` | Publish | Camera event notifications |
|
||||
| `GGS/FWT/<tower>/ControlCode` | Subscribe | Set control mode remotely |
|
||||
| `GGS/FWT/<tower>/target_HDG` | Subscribe | Set target heading for guided mode |
|
||||
|
||||
## License
|
||||
|
||||
[Add your license here]
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
.pio
|
||||
.vscode/.browse.c_cpp.db*
|
||||
.vscode/c_cpp_properties.json
|
||||
.vscode/launch.json
|
||||
.vscode/ipch
|
||||
|
|
@ -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"
|
||||
]
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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"
|
||||
}
|
||||
]
|
||||
|
|
@ -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
|
||||
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 0a9127a1e886ff1adb4c1b6f5958b24108d55aa6
|
||||
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 2295fe471c38d5e649a7b68cecccc42193c8e41c
|
||||
|
|
@ -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 <Foo.h>
|
||||
#include <Bar.h>
|
||||
|
||||
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
|
||||
|
|
@ -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 <stdlib.h>
|
||||
#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_ */
|
||||
|
|
@ -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_ */
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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_ */
|
||||
|
|
@ -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_ */
|
||||
|
|
@ -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_ */
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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_ */
|
||||
|
|
@ -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_ */
|
||||
|
|
@ -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 */
|
||||
|
|
@ -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 <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#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_ */
|
||||
|
|
@ -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 <tmc/ic/MAX22200/MAX22200.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 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);
|
||||
}
|
||||
|
|
@ -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 <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#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);
|
||||
|
|
@ -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
|
||||
|
After Width: | Height: | Size: 142 KiB |
|
|
@ -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.
|
||||
|
||||

|
||||
|
||||
The following diagram depicts how to access the MAX22200 via SPI using the TMC-API.
|
||||
|
||||

|
||||
|
||||
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.
|
||||
|
||||

|
||||
|
||||
### 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).
|
||||
|
After Width: | Height: | Size: 39 KiB |
|
After Width: | Height: | Size: 31 KiB |
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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 <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#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 */
|
||||
|
|
@ -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
|
||||
|
|
@ -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.
|
||||
|
||||

|
||||
|
||||
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.
|
||||
|
||||

|
||||
|
||||
### 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).
|
||||
|
||||
|
||||
|
After Width: | Height: | Size: 39 KiB |
|
After Width: | Height: | Size: 31 KiB |
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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 <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#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 */
|
||||
|
|
@ -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
|
||||
|
|
@ -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.
|
||||
|
||||

|
||||
|
||||
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.
|
||||
|
||||

|
||||
|
||||
### 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).
|
||||
|
||||
|
||||
|
After Width: | Height: | Size: 39 KiB |
|
After Width: | Height: | Size: 31 KiB |
|
|
@ -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.
|
||||
|
||||

|
||||
|
||||
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.
|
||||
|
||||

|
||||
|
||||
### 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).
|
||||
|
||||
|
||||
|
|
@ -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);
|
||||
}
|
||||
/***************************************************************************************************************************************************************/
|
||||
|
|
@ -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 <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#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_ */
|
||||
|
After Width: | Height: | Size: 39 KiB |
|
After Width: | Height: | Size: 31 KiB |
|
|
@ -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.
|
||||
|
||||

|
||||
|
||||
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.
|
||||
|
||||

|
||||
|
||||
### 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).
|
||||
|
||||
|
||||
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
@ -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 <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#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_ */
|
||||
|
After Width: | Height: | Size: 39 KiB |
|
After Width: | Height: | Size: 31 KiB |
|
|
@ -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.
|
||||
|
||||

|
||||
|
||||
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.
|
||||
|
||||

|
||||
|
||||
### 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).
|
||||
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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 <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#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_ */
|
||||
|
|
@ -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
|
||||
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 31 KiB |
|
|
@ -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.
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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.
|
||||
|
||||

|
||||
|
||||
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.
|
||||
|
||||

|
||||
|
||||
### 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).
|
||||
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -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 <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#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_ */
|
||||
|
|
@ -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
|
||||
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 31 KiB |
|
|
@ -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.
|
||||
|
||||

|
||||
|
||||
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.
|
||||
|
||||

|
||||
|
||||
### 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).
|
||||
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -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 <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#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_ */
|
||||
|
|
@ -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 */
|
||||
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 31 KiB |
|
|
@ -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.
|
||||
|
||||

|
||||
|
||||
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.
|
||||
|
||||

|
||||
|
||||
### 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).
|
||||
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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 <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#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_ */
|
||||
|
|
@ -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
|
||||
|
||||
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 31 KiB |
|
|
@ -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.
|
||||
|
||||

|
||||
|
||||
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.
|
||||
|
||||

|
||||
|
||||
### 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).
|
||||
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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 <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#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_ */
|
||||
|
|
@ -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
|
||||
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 31 KiB |
|
|
@ -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.
|
||||
|
||||

|
||||
|
||||
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.
|
||||
|
||||

|
||||
|
||||
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.
|
||||
|
||||

|
||||
|
||||
### 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).
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
/***************************************************************************************************************************************************************/
|
||||
|
|
@ -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 <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#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_ */
|
||||
|
|
@ -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
|
||||
|
After Width: | Height: | Size: 39 KiB |
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 31 KiB |
|
|
@ -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.
|
||||
|
||||

|
||||
|
||||
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.
|
||||
|
||||

|
||||
|
||||
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.
|
||||
|
||||

|
||||
|
||||
### 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).
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
/***************************************************************************************************************************************************************/
|
||||
|
|
@ -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 <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#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_ */
|
||||
|
|
@ -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
|
||||
|
After Width: | Height: | Size: 39 KiB |
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 31 KiB |
|
|
@ -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.
|
||||
|
||||

|
||||
|
||||
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.
|
||||
|
||||

|
||||
|
||||
### 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).
|
||||
|
||||
|
||||
|
|
@ -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));
|
||||
}
|
||||
|
|
@ -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 <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#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_ */
|
||||