diff --git a/README.md b/README.md index c495a27dafb..e4d5415e9b0 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ Known bugs: Emulation: - [ ] Validate arha's bitmap changes, transition over to it fully +- [ ] Test piezo TX (prelim tests promising) - [ ] General code cleanup - [ ] Reverse track precompute & replay (should be simple with new bitmap approach; just iterate through bytes backwards, bits forwards?) - [ ] Parameter tuning, find best defaults, troubleshoot improperly parsed TX diff --git a/helpers/mag_helpers.c b/helpers/mag_helpers.c index 67a707214fe..5faa96838f5 100644 --- a/helpers/mag_helpers.c +++ b/helpers/mag_helpers.c @@ -23,10 +23,13 @@ void bitbang_raw(bool value, MagSetting* setting) { case MagTxStateRFID: furi_hal_gpio_write(RFID_PIN_OUT, value); break; - case MagTxStateGPIOA6A7: + case MagTxStateGPIO: furi_hal_gpio_write(GPIO_PIN_A, value); furi_hal_gpio_write(GPIO_PIN_B, !value); break; + case MagTxStatePiezo: + furi_hal_gpio_write(&gpio_speaker, value); + break; case MagTxCC1101_434: case MagTxCC1101_868: if(last_value == 2 || value != (bool)last_value) { @@ -90,15 +93,53 @@ void play_bit_gpio(uint8_t send_bit, MagSetting* setting) { furi_delay_us(setting->us_interpacket); } +void play_bit_piezo(uint8_t send_bit, MagSetting* setting) { + // TX testing with parasitic EMF from buzzer + bit_dir ^= 1; + furi_hal_gpio_write(&gpio_speaker, bit_dir); + furi_delay_us(setting->us_clock); + + if(send_bit) { + bit_dir ^= 1; + furi_hal_gpio_write(&gpio_speaker, bit_dir); + } + furi_delay_us(setting->us_clock); + + furi_delay_us(setting->us_interpacket); +} + +void play_bit_lf_p(uint8_t send_bit, MagSetting* setting) { + // TX testing with parasitic EMF from buzzer + bit_dir ^= 1; + furi_hal_gpio_write(&gpio_speaker, bit_dir); + furi_hal_gpio_write(RFID_PIN_OUT, bit_dir); + furi_delay_us(setting->us_clock); + + if(send_bit) { + bit_dir ^= 1; + furi_hal_gpio_write(&gpio_speaker, bit_dir); + furi_hal_gpio_write(RFID_PIN_OUT, bit_dir); + } + furi_delay_us(setting->us_clock); + + furi_delay_us(setting->us_interpacket); +} + bool play_bit(uint8_t send_bit, MagSetting* setting) { // Initialize configured TX method switch(setting->tx) { case MagTxStateRFID: play_bit_rfid(send_bit, setting); break; - case MagTxStateGPIOA6A7: + case MagTxStateGPIO: play_bit_gpio(send_bit, setting); break; + case MagTxStatePiezo: + play_bit_piezo(send_bit, setting); + break; + case MagTxStateLF_P: + play_bit_lf_p(send_bit, setting); + break; case MagTxCC1101_434: case MagTxCC1101_868: play_bit_rf(send_bit & 0x01, setting); @@ -185,15 +226,35 @@ void tx_deinit_rf() { furi_hal_subghz_idle(); } +void tx_init_piezo() { + // TODO: some special mutex acquire procedure? c.f. furi_hal_speaker.c + furi_hal_gpio_init(&gpio_speaker, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); + + // tossing in this delay arbitrarily to make it easier to see light blinking during TX + //furi_delay_ms(100); +} + +void tx_deinit_piezo() { + // TODO: some special mutex release procedure? + furi_hal_gpio_init(&gpio_speaker, GpioModeAnalog, GpioPullNo, GpioSpeedLow); +} + bool tx_init(MagSetting* setting) { // Initialize configured TX method switch(setting->tx) { case MagTxStateRFID: tx_init_rfid(); break; - case MagTxStateGPIOA6A7: + case MagTxStateGPIO: tx_init_gpio(); break; + case MagTxStatePiezo: + tx_init_piezo(); + break; + case MagTxStateLF_P: + tx_init_piezo(); + tx_init_rfid(); + break; case MagTxCC1101_434: tx_init_rf(434000000); break; @@ -213,9 +274,16 @@ bool tx_deinit(MagSetting* setting) { case MagTxStateRFID: tx_deinit_rfid(); break; - case MagTxStateGPIOA6A7: + case MagTxStateGPIO: tx_deinit_gpio(); break; + case MagTxStatePiezo: + tx_deinit_piezo(); + break; + case MagTxStateLF_P: + tx_deinit_piezo(); + tx_deinit_rfid(); + break; case MagTxCC1101_434: case MagTxCC1101_868: tx_deinit_rf(); @@ -345,13 +413,11 @@ void mag_spoof_bitwise(Mag* mag) { for(uint16_t i = 0; i < bits_t1_count; i++) { uint8_t byte = i / 8; uint8_t bitmask = 1 << (7 - (i % 8)); - /* this comment is mostly for zw's convenience: - * - * bits are stored in their arrays like on a card (LSB first). This is not how usually bits are stored in a + /* Bits are stored in their arrays like on a card (LSB first). This is not how usually bits are stored in a * byte, with the MSB first. the var bitmask creates the pattern to iterate through each bit, LSB first, like so * 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x80... masking bits one by one from the current byte * - * i've chosen this LSB approach since bits and bytes are hard enough to visualize with the 5/8 and 7/8 encoding + * I've chosen this LSB approach since bits and bytes are hard enough to visualize with the 5/8 and 7/8 encoding * MSR uses. It's a biiit more complicated to process, but visualizing it with printf or a debugger is * infinitely easier * @@ -362,7 +428,7 @@ void mag_spoof_bitwise(Mag* mag) { * bits backward, jumping 16 more bits ahead. * * I find this much more convenient for debugging, with the tiny incovenience of reading the bits in reverse - * order. THus, the reason for the bitmask above + * order. Thus, the reason for the bitmask above */ bit = !!(bits_t1_manchester[byte] & bitmask); @@ -583,4 +649,4 @@ void debug_msr_string(char* data, uint8_t track_bits, uint8_t track_ascii_offset if(i % 4 == 3) printf(" "); } printf("\r\n\r\n"); -} \ No newline at end of file +} diff --git a/helpers/mag_helpers.h b/helpers/mag_helpers.h index 3d45904ccf6..24eb6afd5fc 100644 --- a/helpers/mag_helpers.h +++ b/helpers/mag_helpers.h @@ -4,6 +4,8 @@ void play_bit_rfid(uint8_t send_bit, MagSetting* setting); void play_bit_gpio(uint8_t send_bit, MagSetting* setting); +void play_bit_piezo(uint8_t send_bit, MagSetting* setting); +void play_bit_lf_p(uint8_t send_bit, MagSetting* setting); bool play_bit(uint8_t send_bit, MagSetting* setting); void tx_init_rfid(); void tx_init_gpio(); diff --git a/helpers/mag_types.h b/helpers/mag_types.h index 523904752f0..d7743b9c4ef 100644 --- a/helpers/mag_types.h +++ b/helpers/mag_types.h @@ -28,7 +28,9 @@ typedef enum { typedef enum { MagTxStateRFID, - MagTxStateGPIOA6A7, + MagTxStateGPIO, + MagTxStatePiezo, + MagTxStateLF_P, // combo of RFID and Piezo MagTxCC1101_434, MagTxCC1101_868, } MagTxState; diff --git a/mag.c b/mag.c index 09cf59bf9d3..853e00e0f69 100644 --- a/mag.c +++ b/mag.c @@ -4,7 +4,7 @@ #define SETTING_DEFAULT_REVERSE MagReverseStateOff #define SETTING_DEFAULT_TRACK MagTrackStateAll -#define SETTING_DEFAULT_TX_RFID MagTxStateRFID +#define SETTING_DEFAULT_TX_RFID MagTxStateGPIO #define SETTING_DEFAULT_US_CLOCK 240 #define SETTING_DEFAULT_US_INTERPACKET 10 diff --git a/scenes/mag_scene_emulate_config.c b/scenes/mag_scene_emulate_config.c index 439b414068a..c0e83f9efbd 100644 --- a/scenes/mag_scene_emulate_config.c +++ b/scenes/mag_scene_emulate_config.c @@ -10,16 +10,20 @@ enum MagSettingIndex { MagSettingIndexInterpacket, }; -#define TX_COUNT 4 +#define TX_COUNT 6 const char* const tx_text[TX_COUNT] = { "RFID", - "A6/A7", + "GPIO", + "Piezo", + "LF+P", "434MHz", "868MHz", }; const uint32_t tx_value[TX_COUNT] = { MagTxStateRFID, - MagTxStateGPIOA6A7, + MagTxStateGPIO, + MagTxStatePiezo, + MagTxStateLF_P, MagTxCC1101_434, MagTxCC1101_868,