🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
215 lines
6.1 KiB
Markdown
215 lines
6.1 KiB
Markdown
# Proxmark3 LED PWM Implementation - Complete
|
|
|
|
**Status:** ✅ Implemented, Flashed, and Tested
|
|
**Date:** 2025-12-02
|
|
**Hardware:** Proxmark3 Easy
|
|
**Firmware:** Iceman/master/4fa8f27-dirty
|
|
|
|
## Summary
|
|
|
|
Successfully implemented two-channel hardware PWM brightness control for LED A and LED B on Proxmark3 Easy, along with basic on/off/toggle control for all LEDs.
|
|
|
|
## Hardware Configuration
|
|
|
|
### Proxmark3 Easy LED Mappings
|
|
|
|
| LED | Color | GPIO Pin | PWM Channel | Brightness Control | Position |
|
|
|-----|--------|----------|-------------|--------------------|----------|
|
|
| A | Green | PA0 | PWM0 | ✅ 0-100% | 1st (left) |
|
|
| B | Blue | PA2 | PWM2 | ✅ 0-100% | 4th (right) |
|
|
| C | Orange | PA9 | None | On/Off only | 2nd |
|
|
| D | Red | PA8 | None | On/Off only | 3rd |
|
|
|
|
**Physical LED order (left to right):** Green, Orange, Red, Blue
|
|
|
|
### PWM Channel Allocation
|
|
|
|
- **PWM0** → LED A brightness control (PA0)
|
|
- **PWM1** → System timing functions (moved from PWM0)
|
|
- **PWM2** → LED B brightness control (PA2)
|
|
- **PWM3** → Unused
|
|
|
|
## Command Interface
|
|
|
|
### Basic LED Control (All LEDs)
|
|
|
|
```bash
|
|
hw led --led a --on # Turn on LED A
|
|
hw led --led b --off # Turn off LED B
|
|
hw led --led c,d --toggle # Toggle LEDs C and D
|
|
hw led --led all --off # Turn off all LEDs
|
|
```
|
|
|
|
### PWM Brightness Control (LED A and B only)
|
|
|
|
```bash
|
|
hw led --led a --brightness 50 # LED A at 50% brightness
|
|
hw led --led b --brightness 75 # LED B at 75% brightness
|
|
hw led --led a,b --brightness 25 # Both LEDs at 25% brightness
|
|
hw led --led a --brightness 0 # LED A off via PWM
|
|
hw led --led b --brightness 100 # LED B at full brightness
|
|
```
|
|
|
|
### Multi-Device Identification Examples
|
|
|
|
```bash
|
|
# Device 1 - Dim green
|
|
hw led --led a --brightness 20
|
|
|
|
# Device 2 - Medium blue
|
|
hw led --led b --brightness 50
|
|
|
|
# Device 3 - Bright green
|
|
hw led --led a --brightness 80
|
|
|
|
# Device 4 - Mixed (40% green + 60% blue)
|
|
hw led --led a --brightness 40
|
|
hw led --led b --brightness 60
|
|
```
|
|
|
|
## Implementation Details
|
|
|
|
### Files Modified (7 files)
|
|
|
|
**Firmware:**
|
|
1. `common_arm/ticks.c` - Moved SpinDelay timing from PWM0 → PWM1
|
|
2. `common_arm/usb_cdc.c` - Moved USB timing from PWM0 → PWM1
|
|
3. `armsrc/util.c` - Moved button timing PWM0 → PWM1, added PWM LED functions
|
|
4. `armsrc/util.h` - Added function declarations
|
|
5. `armsrc/appmain.c` - Added CMD_LED_CONTROL handler
|
|
|
|
**Protocol:**
|
|
6. `include/pm3_cmd.h` - Added CMD_LED_CONTROL (0x011A) and payload structure
|
|
|
|
**Client:**
|
|
7. `client/src/cmdhw.c` - Added `hw led` command with CLIParser
|
|
|
|
### Protocol Definition
|
|
|
|
```c
|
|
// Command ID
|
|
#define CMD_LED_CONTROL 0x011A
|
|
|
|
// Payload structure
|
|
typedef struct {
|
|
uint8_t led; // LED bitmask: LED_A=1, LED_B=2, LED_C=4, LED_D=8
|
|
uint8_t action; // 0=off, 1=on, 2=toggle, 3=pwm
|
|
uint8_t brightness; // 0-100 (for action=3 PWM mode only)
|
|
} PACKED payload_led_control_t;
|
|
```
|
|
|
|
### PWM Functions (armsrc/util.c)
|
|
|
|
```c
|
|
void led_set_pwm_brightness(uint8_t led, uint8_t brightness);
|
|
void led_pwm_disable(uint8_t led);
|
|
```
|
|
|
|
**PWM Configuration:**
|
|
- Frequency: 48 kHz (MCK / 1000)
|
|
- Resolution: 1000 steps (0.1% precision, exposed as 0-100%)
|
|
- Duty cycle: Inverted for active-low LEDs
|
|
- CPU overhead: Zero (hardware-controlled)
|
|
|
|
### Action Modes
|
|
|
|
| Action | Value | Description |
|
|
|--------|-------|-------------|
|
|
| Off | 0 | Turn LED off (disables PWM if active) |
|
|
| On | 1 | Turn LED on at full brightness (disables PWM) |
|
|
| Toggle | 2 | Toggle LED state (disables PWM) |
|
|
| PWM | 3 | Set PWM brightness (0-100%, LED A/B only) |
|
|
|
|
## Build Configuration
|
|
|
|
### Required Makefile.platform Settings
|
|
|
|
```makefile
|
|
PLATFORM=PM3GENERIC
|
|
LED_ORDER=PM3EASY
|
|
```
|
|
|
|
**IMPORTANT:** The `LED_ORDER=PM3EASY` flag is **required** for PM3 Easy hardware. Without it, LED B will be mapped to PA8 (no PWM) instead of PA2 (PWM2).
|
|
|
|
### Build Commands
|
|
|
|
```bash
|
|
cd .pm3-test/proxmark3
|
|
|
|
# Ensure correct platform settings
|
|
cat > Makefile.platform << EOF
|
|
PLATFORM=PM3GENERIC
|
|
LED_ORDER=PM3EASY
|
|
EOF
|
|
|
|
# Build
|
|
SKIPQT=1 CFLAGS="-Wno-error=bad-function-cast" make all
|
|
|
|
# Flash
|
|
./pm3-flash-all
|
|
```
|
|
|
|
## Testing Results
|
|
|
|
✅ **All Tests Passed:**
|
|
- Firmware compiled: 359,015 bytes (68% of 512KB)
|
|
- Flashed successfully to Proxmark3 Easy
|
|
- PWM LED commands working correctly
|
|
- Timing functions verified (`hw status` passed)
|
|
- No interference with RF operations
|
|
- Button functionality intact
|
|
|
|
## Technical Notes
|
|
|
|
### PWM Channel Reallocation
|
|
|
|
The original Proxmark3 firmware used PWM0 for timing functions. To enable LED A brightness control, all timing functions were moved from PWM0 to PWM1:
|
|
|
|
- `SpinDelayUsPrecision()` - High precision delays
|
|
- `SpinDelayUs()` - Standard delays
|
|
- `BUTTON_CLICKED()` / `BUTTON_HELD()` - Button debouncing
|
|
- USB timing functions
|
|
|
|
This change has **zero performance impact** and frees PWM0 for LED control.
|
|
|
|
### Compatibility
|
|
|
|
**Hardware Compatibility:**
|
|
- ✅ PM3 Easy (PA0=PWM0, PA2=PWM2)
|
|
- ⚠️ Other PM3 variants - PWM support depends on LED pin mapping
|
|
- Without `LED_ORDER=PM3EASY`, LED B may not support PWM
|
|
|
|
**Backward Compatibility:**
|
|
- ✅ Fully backward compatible with existing firmware
|
|
- ✅ New `hw led` command co-exists with other hw commands
|
|
- ✅ No changes to existing command behavior
|
|
|
|
### Performance Impact
|
|
|
|
**Expected impact: ZERO**
|
|
- PWM channels operate independently in hardware
|
|
- No CPU overhead once configured
|
|
- No timer interrupts needed
|
|
- No interference with RF operations
|
|
- Timing functions work identically on PWM1
|
|
|
|
## Future Enhancements
|
|
|
|
Potential improvements if needed:
|
|
1. Software PWM for LED C/D (more complex, CPU overhead)
|
|
2. Fade in/out effects using gradual brightness changes
|
|
3. Brightness presets (low, medium, high)
|
|
4. Auto-dim after inactivity for power saving
|
|
|
|
## References
|
|
|
|
- [LED_MAPPINGS.md](LED_MAPPINGS.md) - LED color and pin reference
|
|
- PM3_EASY_PWM_FINAL.md - Original design document (archived)
|
|
- PWM_ENHANCEMENT_COMPLETE.md - Development notes (archived)
|
|
|
|
---
|
|
|
|
**Implementation by:** Claude Code
|
|
**Hardware Tested:** Proxmark3 Easy
|
|
**Firmware Version:** Iceman/master/4fa8f27-dirty
|