Merge branch 'master' into new-keys

Signed-off-by: Iceman <iceman@iuse.se>
This commit is contained in:
Iceman 2025-05-12 19:28:39 +02:00 committed by GitHub
commit 1199710644
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
22 changed files with 189 additions and 75 deletions

View file

@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file.
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
## [unreleased][unreleased]
- Fixed `hf mf ekeyprn` - failed to download emulator memory due to wrong size calculation (@iceman1001)
- Fixed `hf mf fchk --mem` to actually use flash dict (@doegox)
- Fixed `make install` on OSX thanks DaveItsLong (@doegox)
- Added new standalone mode `HF_ST25_TEAROFF` to store/restore ST25TB tags with tearoff for counters (@seclabz)

View file

@ -264,8 +264,11 @@ ifeq ($(PLATFORM_CHANGED),true)
$(Q)$(MAKE) --no-print-directory -C bootrom clean
$(Q)$(MAKE) --no-print-directory -C armsrc clean
$(Q)$(MAKE) --no-print-directory -C recovery clean
$(Q)$(MAKE) --no-print-directory -C client clean
$(Q)$(MAKE) --no-print-directory -C tools/fpga_compress clean
# clean the client only if PLATFORM got changed from or to PM3ICOPYX
ifeq (PM3ICOPYX,$(filter PM3ICOPYX, $(PLATFORM) $(CACHED_PLATFORM)))
$(Q)$(MAKE) --no-print-directory -C client clean
endif
$(Q)$(ECHO) CACHED_PLATFORM=$(PLATFORM) > .Makefile.options.cache
$(Q)$(ECHO) CACHED_PLATFORM_EXTRAS=$(PLATFORM_EXTRAS) >> .Makefile.options.cache
$(Q)$(ECHO) CACHED_PLATFORM_DEFS=$(PLATFORM_DEFS) >> .Makefile.options.cache

View file

@ -27,6 +27,10 @@ PLATFORM=PM3RDV4
# Only available with PLATFORM=PM3GENERIC
#LED_ORDER=PM3EASY
# Uncomment a line below to change default USART baud rate
# defaults to 115200 used by HC-05 in Blueshark
#USART_BAUD_RATE=19200
# Uncomment the lines below in order to make a 256KB image
# and comment out the lines above

View file

@ -1664,13 +1664,13 @@ static void PacketReceived(PacketCommandNG *packet) {
break;
}
case CMD_HF_ISO14443A_GET_CONFIG: {
hf14a_config *hf14aconfig = getHf14aConfig();
reply_ng(CMD_HF_ISO14443A_GET_CONFIG, PM3_SUCCESS, (uint8_t *)hf14aconfig, sizeof(hf14a_config));
hf14a_config_t *c = getHf14aConfig();
reply_ng(CMD_HF_ISO14443A_GET_CONFIG, PM3_SUCCESS, (uint8_t *)c, sizeof(hf14a_config_t));
break;
}
case CMD_HF_ISO14443A_SET_CONFIG: {
hf14a_config c;
memcpy(&c, packet->data.asBytes, sizeof(hf14a_config));
hf14a_config_t c;
memcpy(&c, packet->data.asBytes, sizeof(hf14a_config_t));
setHf14aConfig(&c);
break;
}
@ -1969,7 +1969,7 @@ static void PacketReceived(PacketCommandNG *packet) {
struct p *payload = (struct p *) packet->data.asBytes;
//
size_t size = payload->blockno * payload->blockwidth;
size_t size = payload->blockcnt * payload->blockwidth;
if (size > PM3_CMD_DATA_SIZE) {
reply_ng(CMD_HF_MIFARE_EML_MEMGET, PM3_EMALLOC, NULL, 0);
return;

View file

@ -134,31 +134,29 @@ static uint32_t LastProxToAirDuration;
#define SEC_Z 0xc0
static const iso14a_polling_frame_t WUPA_CMD = {
{ ISO14443A_CMD_WUPA }, 1, 7, 0
static const iso14a_polling_frame_t WUPA_CMD_FRAME = {
.frame = { ISO14443A_CMD_WUPA },
.frame_length = 1,
.last_byte_bits = 7,
.extra_delay = 0
};
static const iso14a_polling_frame_t REQA_CMD = {
{ISO14443A_CMD_REQA }, 1, 7, 0
static const iso14a_polling_frame_t MAGWUPA_CMD_FRAMES[] = {
{{ MAGSAFE_CMD_WUPA_1 }, 1, 7, 0},
{{ MAGSAFE_CMD_WUPA_2 }, 1, 7, 0},
{{ MAGSAFE_CMD_WUPA_3 }, 1, 7, 0},
{{ MAGSAFE_CMD_WUPA_4 }, 1, 7, 0}
};
static const iso14a_polling_frame_t MAGWUPA_COMMANDS[4] = {
{{ 0x7A }, 1, 7, 0},
{{ 0x7B }, 1, 7, 0},
{{ 0x7C }, 1, 7, 0},
{{ 0x7D }, 1, 7, 0}
};
// Polling frames and configurations
iso14a_polling_parameters_t WUPA_POLLING_PARAMETERS = {
.frames = { WUPA_CMD },
.frames = { {{ ISO14443A_CMD_WUPA }, 1, 7, 0 }},
.frame_count = 1,
.extra_timeout = 0,
};
iso14a_polling_parameters_t REQA_POLLING_PARAMETERS = {
.frames = { REQA_CMD },
.frames = { {{ ISO14443A_CMD_REQA }, 1, 7, 0 }},
.frame_count = 1,
.extra_timeout = 0,
};
@ -173,10 +171,10 @@ Default HF 14a config is set to:
magsafe = 0 (disabled)
polling_loop_annotation = {{0}, 0, 0, 0} (disabled)
*/
static hf14a_config hf14aconfig = { 0, 0, 0, 0, 0, 0, {{0}, 0, 0, 0} };
static hf14a_config_t hf14aconfig = { 0, 0, 0, 0, 0, 0, {{0}, 0, 0, 0} };
static iso14a_polling_parameters_t hf14a_polling_parameters = {
.frames = { WUPA_CMD },
.frames = { {{ ISO14443A_CMD_WUPA }, 1, 7, 0 }},
.frame_count = 1,
.extra_timeout = 0
};
@ -236,45 +234,64 @@ void printHf14aConfig(void) {
* @brief setSamplingConfig
* @param sc
*/
void setHf14aConfig(const hf14a_config *hc) {
if ((hc->forceanticol >= 0) && (hc->forceanticol <= 2))
void setHf14aConfig(const hf14a_config_t *hc) {
if ((hc->forceanticol >= 0) && (hc->forceanticol <= 2)) {
hf14aconfig.forceanticol = hc->forceanticol;
if ((hc->forcebcc >= 0) && (hc->forcebcc <= 2))
}
if ((hc->forcebcc >= 0) && (hc->forcebcc <= 2)) {
hf14aconfig.forcebcc = hc->forcebcc;
if ((hc->forcecl2 >= 0) && (hc->forcecl2 <= 2))
}
if ((hc->forcecl2 >= 0) && (hc->forcecl2 <= 2)) {
hf14aconfig.forcecl2 = hc->forcecl2;
if ((hc->forcecl3 >= 0) && (hc->forcecl3 <= 2))
}
if ((hc->forcecl3 >= 0) && (hc->forcecl3 <= 2)) {
hf14aconfig.forcecl3 = hc->forcecl3;
if ((hc->forcerats >= 0) && (hc->forcerats <= 2))
}
if ((hc->forcerats >= 0) && (hc->forcerats <= 2)) {
hf14aconfig.forcerats = hc->forcerats;
if ((hc->magsafe >= 0) && (hc->magsafe <= 1))
}
if ((hc->magsafe >= 0) && (hc->magsafe <= 1)) {
hf14aconfig.magsafe = hc->magsafe;
}
if (hc->polling_loop_annotation.frame_length >= 0) {
memcpy(&hf14aconfig.polling_loop_annotation, &hc->polling_loop_annotation, sizeof(iso14a_polling_frame_t));
}
// iceman: Somehow I think we should memcpy WUPA_CMD and all other hf14a_polling_parameters.frames[xxx] assignments
// right now we are assigning...
// Derive polling loop configuration based on 14a config
hf14a_polling_parameters.frames[0] = WUPA_CMD;
hf14a_polling_parameters.frames[0] = WUPA_CMD_FRAME;
hf14a_polling_parameters.frame_count = 1;
hf14a_polling_parameters.extra_timeout = 0;
if (hf14aconfig.magsafe == 1) {
for (int i = 0; i < ARRAYLEN(MAGWUPA_COMMANDS); i++) {
for (int i = 0; i < ARRAYLEN(MAGWUPA_CMD_FRAMES); i++) {
if (hf14a_polling_parameters.frame_count < ARRAYLEN(hf14a_polling_parameters.frames) - 1) {
hf14a_polling_parameters.frames[hf14a_polling_parameters.frame_count] = MAGWUPA_COMMANDS[i];
hf14a_polling_parameters.frame_count += 1;
hf14a_polling_parameters.frames[hf14a_polling_parameters.frame_count] = MAGWUPA_CMD_FRAMES[i];
hf14a_polling_parameters.frame_count++;
}
}
}
if (hf14aconfig.polling_loop_annotation.frame_length > 0) {
if (hf14a_polling_parameters.frame_count < ARRAYLEN(hf14a_polling_parameters.frames)) {
if (hf14a_polling_parameters.frame_count < ARRAYLEN(hf14a_polling_parameters.frames) - 1) {
hf14a_polling_parameters.frames[hf14a_polling_parameters.frame_count] = hf14aconfig.polling_loop_annotation;
hf14a_polling_parameters.frame_count += 1;
hf14a_polling_parameters.frame_count++;
}
hf14a_polling_parameters.extra_timeout = 250;
}
}
hf14a_config *getHf14aConfig(void) {
hf14a_config_t *getHf14aConfig(void) {
return &hf14aconfig;
}
@ -2759,26 +2776,34 @@ static int GetATQA(uint8_t *resp, uint16_t resp_len, uint8_t *resp_par, const is
uint32_t save_iso14a_timeout = iso14a_get_timeout();
iso14a_set_timeout(1236 / 128 + 1); // response to WUPA is expected at exactly 1236/fc. No need to wait longer.
polling_parameters = polling_parameters != NULL ? polling_parameters : &hf14a_polling_parameters;
// refactored to use local pointer, now no modification of polling_parameters pointer is done
// I don't think the intention was to modify polling_parameters when sending in WUPA_POLLING_PARAMETERS etc.
// Modify polling_params, if null use default values.
iso14a_polling_parameters_t p;
memcpy(&p, (uint8_t*)polling_parameters, sizeof(iso14a_polling_parameters_t));
if (polling_parameters == NULL) {
memcpy(&p, (uint8_t*)&hf14a_polling_parameters, sizeof(iso14a_polling_parameters_t));
}
bool first_try = true;
int len;
uint32_t retry_timeout = RETRY_TIMEOUT * polling_parameters->frame_count + polling_parameters->extra_timeout;
uint32_t retry_timeout = ((RETRY_TIMEOUT * p.frame_count) + p.extra_timeout);
uint32_t start_time = 0;
uint8_t current_frame = 0;
uint8_t curr = 0;
// Use the temporary polling parameters
do {
const iso14a_polling_frame_t *frame_parameters = &polling_parameters->frames[current_frame];
iso14a_polling_frame_t *frp = &p.frames[curr];
if (frame_parameters->last_byte_bits == 8) {
ReaderTransmit(frame_parameters->frame, frame_parameters->frame_length, NULL);
if (frp->last_byte_bits == 8) {
ReaderTransmit(frp->frame, frp->frame_length, NULL);
} else {
ReaderTransmitBitsPar(frame_parameters->frame, frame_parameters->last_byte_bits, NULL, NULL);
ReaderTransmitBitsPar(frp->frame, frp->last_byte_bits, NULL, NULL);
}
if (frame_parameters->extra_delay) {
SpinDelay(frame_parameters->extra_delay);
if (frp->extra_delay) {
SpinDelay(frp->extra_delay);
}
// Receive the ATQA
@ -2791,7 +2816,8 @@ static int GetATQA(uint8_t *resp, uint16_t resp_len, uint8_t *resp_par, const is
}
// Go over frame configurations, loop back when we reach the end
current_frame = current_frame < (polling_parameters->frame_count - 1) ? current_frame + 1 : 0;
curr = (curr < (p.frame_count - 1)) ? curr + 1 : 0;
} while (len == 0 && GetTickCountDelta(start_time) <= retry_timeout);
iso14a_set_timeout(save_iso14a_timeout);

View file

@ -125,8 +125,8 @@ typedef enum {
#endif
void printHf14aConfig(void);
void setHf14aConfig(const hf14a_config *hc);
hf14a_config *getHf14aConfig(void);
void setHf14aConfig(const hf14a_config_t *hc);
hf14a_config_t *getHf14aConfig(void);
void iso14a_set_timeout(uint32_t timeout);
uint32_t iso14a_get_timeout(void);

View file

@ -1905,15 +1905,14 @@ FF16014FEFC7
# Food GEM
6686FADE5566
#
# Samsung Data Systems (SDS) — Electronic Locks
# Gen 1 S10 KA/KB is FFFFFFFFFFFF, incompatible with Gen 2 locks
#
# SDS Gen 2 S10 KB
# Samsung Data Systems (SDS)
# 10-11 A/B (Gen 2)
9B7C25052FC3
C22E04247D9A
6C4F77534170
704153564F6C
#
# Data from Discord, French pool
# SDS Gen 2 S10 KA
9B7C25052FC3
494446555455
#
# Data from Discord, seems to be related to ASSA
@ -3108,7 +3107,7 @@ AB921CF0752C
265A5F32DE73
567D734C403C
2426217B3B3B
#
# German Aral Gas Station Car-Wash cards
080507020706
0100815D8D00
@ -3134,3 +3133,55 @@ C082C0F35CE6
B1BA3E778930
2037627D9260
28C4D7170FCD
#
# Card keys from Andalusian public transport system (Consorcio de Transportes)
1848A8D1E4C5
16EE1FE134E4
5246B8F4ACFC
515A8209843C
0EF7636AA829
E59D0F78C413
5AF68604DD6B
B0BCB22DCBA3
51B3EF60BF56
99100225D83B
63C88F562B97
B30B6A5AD434
D33E4A4A0041
9C0A4CC89D61
5204D83D8CD3
A662F9DC0D3D
#
# Card keys from EMT Malaga (Spain) bus system
41534E354936
454D41343253
4541444C4130
46305234324E
505444505232
5239425A3546
454449434631
414F4544384C
344E4F4E4937
45444E413254
3255534D3033
4F554D523935
3141544D3735
494E47463539
32414F4E3341
41534C473637
534E41395430
41364C38364F
525241414D39
41304532334F
4D4545494F35
4E324C453045
394143494E32
5352554E3245
324553553036
444D414E3539
324745413232
4E4E41455236
394C52493639
4D4941413236
414D504F3243
434C414E3639

View file

@ -90,13 +90,14 @@ def lprint(s='', end='\n', flush=False, prompt="[" + color("=", fg="yellow") +
- logfile (R)
"""
s = f"{prompt}" + f"\n{prompt}".join(s.split('\n'))
print(s, end=end, flush=flush)
safe_s = s.encode('utf-8', errors='ignore').decode('utf-8')
print(safe_s, end=end, flush=flush)
if log is True:
global logbuffer
if logfile is not None:
with open(logfile, 'a', encoding='utf-8') as f:
f.write(s + end)
f.write(safe_s + end)
else:
# buffering
logbuffer += s + end

View file

@ -1303,6 +1303,14 @@
"Description": "Umo Mobility Card",
"Type": "transport"
},
{
"AID": "7A007A",
"Vendor": "Regional Transportation Commission of Southern Nevada (RTC) via Masabi Ltd",
"Country": "US",
"Name": "RTC TAP & GO (LAS)",
"Description": "LAS TAP & GO; Masabi Justride Tap and Ride DESFire Smartcard",
"Type": "transport"
},
{
"AID": "784000",
"Vendor": "Roads & Transport Authority (Government of Dubai)",

View file

@ -250,7 +250,7 @@ static int CmdHF14AList(const char *Cmd) {
return CmdTraceListAlias(Cmd, "hf 14a", "14a -c");
}
int hf14a_getconfig(hf14a_config *config) {
int hf14a_getconfig(hf14a_config_t *config) {
if (!g_session.pm3_present) return PM3_ENOTTY;
if (config == NULL) {
@ -265,16 +265,16 @@ int hf14a_getconfig(hf14a_config *config) {
PrintAndLogEx(WARNING, "command execution time out");
return PM3_ETIMEOUT;
}
memcpy(config, resp.data.asBytes, sizeof(hf14a_config));
memcpy(config, resp.data.asBytes, sizeof(hf14a_config_t));
return PM3_SUCCESS;
}
int hf14a_setconfig(hf14a_config *config, bool verbose) {
int hf14a_setconfig(hf14a_config_t *config, bool verbose) {
if (!g_session.pm3_present) return PM3_ENOTTY;
clearCommandBuffer();
if (config != NULL) {
SendCommandNG(CMD_HF_ISO14443A_SET_CONFIG, (uint8_t *)config, sizeof(hf14a_config));
SendCommandNG(CMD_HF_ISO14443A_SET_CONFIG, (uint8_t *)config, sizeof(hf14a_config_t));
if (verbose) {
SendCommandNG(CMD_HF_ISO14443A_PRINT_CONFIG, NULL, 0);
}
@ -490,7 +490,7 @@ static int CmdHf14AConfig(const char *Cmd) {
}
// Initialize config with all parameters
hf14a_config config = {
hf14a_config_t config = {
.forceanticol = atqa,
.forcebcc = bcc,
.forcecl2 = cl2,

View file

@ -20,7 +20,7 @@
#define CMDHF14A_H__
#include "common.h"
#include "pm3_cmd.h" //hf14a_config
#include "pm3_cmd.h" //hf14a_config_t
#include "mifare.h" // structs
// structure and database for uid -> tagtype lookups
@ -61,8 +61,8 @@ int CmdHF14ANdefWrite(const char *Cmd); // used by cmdnfc.c
int detect_nxp_card(uint8_t sak, uint16_t atqa, uint64_t select_status);
int hf14a_getconfig(hf14a_config *config);
int hf14a_setconfig(hf14a_config *config, bool verbose);
int hf14a_getconfig(hf14a_config_t *config);
int hf14a_setconfig(hf14a_config_t *config, bool verbose);
int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search);
int infoHF14A4Applications(bool verbose);
const char *getTagInfo(uint8_t uid);

View file

@ -5186,7 +5186,7 @@ static int CmdHF14AMfEKeyPrn(const char *Cmd) {
memcpy(uid, data, sizeof(uid));
// download keys from EMUL
for (int i = 0; i < sectors_cnt; i++) {
for (uint8_t i = 0; i < sectors_cnt; i++) {
if (mf_eml_get_mem(data, mfFirstBlockOfSector(i) + mfNumBlocksPerSector(i) - 1, 1) != PM3_SUCCESS) {
PrintAndLogEx(WARNING, "error get block %d", mfFirstBlockOfSector(i) + mfNumBlocksPerSector(i) - 1);

View file

@ -4166,17 +4166,17 @@ static int CmdHF14AMfUCSetUid(const char *Cmd) {
// Enforce bad BCC handling temporarily as BCC will be wrong between
// block 1 write and block2 write
hf14a_config config;
hf14a_config_t config;
SendCommandNG(CMD_HF_ISO14443A_GET_CONFIG, NULL, 0);
if (WaitForResponseTimeout(CMD_HF_ISO14443A_GET_CONFIG, &resp, 2000) == false) {
PrintAndLogEx(WARNING, "command execute timeout");
return PM3_ETIMEOUT;
}
memcpy(&config, resp.data.asBytes, sizeof(hf14a_config));
memcpy(&config, resp.data.asBytes, sizeof(hf14a_config_t));
int8_t oldconfig_bcc = config.forcebcc;
if (oldconfig_bcc != 2) {
config.forcebcc = 2;
SendCommandNG(CMD_HF_ISO14443A_SET_CONFIG, (uint8_t *)&config, sizeof(hf14a_config));
SendCommandNG(CMD_HF_ISO14443A_SET_CONFIG, (uint8_t *)&config, sizeof(hf14a_config_t));
}
// block 0.
@ -4219,7 +4219,7 @@ static int CmdHF14AMfUCSetUid(const char *Cmd) {
// restore BCC config
if (oldconfig_bcc != 2) {
config.forcebcc = oldconfig_bcc;
SendCommandNG(CMD_HF_ISO14443A_SET_CONFIG, (uint8_t *)&config, sizeof(hf14a_config));
SendCommandNG(CMD_HF_ISO14443A_SET_CONFIG, (uint8_t *)&config, sizeof(hf14a_config_t));
}
return PM3_SUCCESS;
}

View file

@ -562,7 +562,7 @@ static int select_DF_verify(uint8_t *response, uint8_t response_length, uint8_t
}
// ----------------- MAC Key Generation -----------------
uint8_t cmac[8];
uint8_t cmac[16];
uint8_t MAC_key[24] = {0x00};
memcpy(MAC_key, keys[key_index].privMacKey, 16);
create_cmac(MAC_key, input, cmac, sizeof(input), encryption_algorithm);
@ -1351,7 +1351,7 @@ static int CmdHfSeosGDF(const char *Cmd) {
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
int key_index = arg_get_int_def(ctx, 1, -1);
int key_index = arg_get_int_def(ctx, 1, 0);
CLIParserFree(ctx);
return seos_global_df(key_index);

View file

@ -252,6 +252,10 @@ endif
# WITH_FPC_USART_* needs WITH_FPC_USART :
ifneq (,$(findstring WITH_FPC_USART_,$(PLATFORM_DEFS)))
PLATFORM_DEFS += -DWITH_FPC_USART
ifeq ($(USART_BAUD_RATE),)
USART_BAUD_RATE=115200
endif
PLATFORM_DEFS += -DUSART_BAUD_RATE=$(USART_BAUD_RATE)
endif
PLATFORM_DEFS_INFO = $(strip $(filter-out STANDALONE%, $(subst -DWITH_,,$(PLATFORM_DEFS))))

View file

@ -24,6 +24,7 @@ This document targets both Proxmark3 and Flipper Zero devices.
- [Simulate a standard keyed iCLASS legacy credential](#simulate-a-standard-keyed-iclass-legacy-credential)
- [Write a downgraded iCLASS legacy credential](#write-a-downgraded-iclass-legacy-credential)
- [Using Omnikey Reader 5427CK Gen2 and Proxmark3](#using-omnikey-reader-5427ck-gen2-and-proxmark3)
- [Using Elatec TWN4 or TWN4 mini (USB front reader)](#using-elatec-twn4-or-twn4-mini-usb-front-reader)
- [Using Flipper Zero with NARD](#using-flipper-zero-with-nard)
- [Using Weaponized HID Reader](#using-weaponized-hid-reader)
- [Write ProxII credential to a T5577](#write-proxii-credential-to-a-t5577)
@ -191,6 +192,20 @@ drop iclass-flipper.picopass file here and simulate on Flipper
7. Launch PM3 client, place iCLASS/Picopass card on HF antenna and read your original card on the Omnikey reader
8. Press enter
## Using Elatec TWN4 or TWN4 mini (USB front reader)
^[Top](#top)
OBS!
The reader must have the `PI` designation on the label for it to have a embedded HID SAM. If you have a reader with a different configuration as per the label, an HID SAM will have to be installed in the SAM slot.
1. Plug in Elatec reader
2. Launch [appblaster.exe](../tools/twn/AppBlaster.exe)
3. Click on "program firmware image"
4. Select [encoder.bix](../tools/twn/encoder.bix) as the reader firmware
5. Click program image
6. Launch PM3 client, place iCLASS/Picopass card on HF antenna and read your original card on the Elatec reader
8. Press enter
## Using Flipper Zero with NARD
^[Top](#top)
@ -222,7 +237,7 @@ Prequisite, you will need the following bill of materials (BOM):
* Some 20-24 AWG wire or ethernet cable
* Your preferred power source (5-9v)
The easiest way is to buy a [ESPKEY](https://www.aliexpress.com/item/32850151497.html)
The easiest way is to buy a [ESPKEY](https://www.aliexpress.com/w/wholesale-esp-rfid-tool.html))
Follow these steps:

View file

@ -161,7 +161,7 @@ typedef struct {
int8_t forcerats; // 0:auto 1:force executing RATS 2:force skipping RATS
int8_t magsafe; // 0:disabled 1:enabled
iso14a_polling_frame_t polling_loop_annotation; // Polling loop annotation
} PACKED hf14a_config;
} PACKED hf14a_config_t;
// Tracelog Header struct
typedef struct {

View file

@ -16,8 +16,9 @@
#ifndef __USART_DEFS_H
#define __USART_DEFS_H
//#define USART_BAUD_RATE 9600
#ifndef USART_BAUD_RATE
#define USART_BAUD_RATE 115200
#endif
// BT HC-06 physical layer runs at 128kbps
// so it's possible to gain a little bit by using 230400
// with some risk to overflow its internal buffers:

BIN
tools/twn/AppBlaster.exe Normal file

Binary file not shown.

BIN
tools/twn/decoder.bix Normal file

Binary file not shown.

BIN
tools/twn/encoder.bix Normal file

Binary file not shown.

BIN
tools/twn/pcsc.bix Normal file

Binary file not shown.