Skip to content

Commit

Permalink
nfc: st25tb: add write support
Browse files Browse the repository at this point in the history
  • Loading branch information
augustozanellato committed Nov 21, 2023
1 parent 9d93357 commit 7922e3c
Show file tree
Hide file tree
Showing 8 changed files with 93 additions and 5 deletions.
1 change: 1 addition & 0 deletions lib/nfc/protocols/st25tb/st25tb.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ typedef enum {
St25tbErrorFieldOff,
St25tbErrorWrongCrc,
St25tbErrorTimeout,
St25tbErrorWriteFailed,
} St25tbError;

typedef enum {
Expand Down
5 changes: 3 additions & 2 deletions lib/nfc/protocols/st25tb/st25tb_poller.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
#include "st25tb.h"
#include <lib/nfc/nfc.h>

#include <nfc/nfc_poller.h>

#ifdef __cplusplus
extern "C" {
#endif
Expand Down Expand Up @@ -43,6 +41,9 @@ St25tbError st25tb_poller_get_uid(St25tbPoller* instance, uint8_t* uid);
St25tbError
st25tb_poller_read_block(St25tbPoller* instance, uint32_t* block, uint8_t block_number);

St25tbError
st25tb_poller_write_block(St25tbPoller* instance, uint32_t block, uint8_t block_number);

St25tbError st25tb_poller_halt(St25tbPoller* instance);

#ifdef __cplusplus
Expand Down
45 changes: 45 additions & 0 deletions lib/nfc/protocols/st25tb/st25tb_poller_i.c
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,51 @@ St25tbError
return ret;
}

St25tbError
st25tb_poller_write_block(St25tbPoller* instance, uint32_t block, uint8_t block_number) {
furi_assert(instance);
furi_assert(instance->nfc);
furi_assert(
(block_number <= st25tb_get_block_count(instance->data->type)) ||
block_number == ST25TB_SYSTEM_OTP_BLOCK);
FURI_LOG_T(TAG, "writing block %d", block_number);
bit_buffer_reset(instance->tx_buffer);

// Send Write_block(Addr, Data)
bit_buffer_append_byte(instance->tx_buffer, 0x09);
bit_buffer_append_byte(instance->tx_buffer, block_number);
bit_buffer_append_bytes(instance->tx_buffer, (uint8_t*)&block, ST25TB_BLOCK_SIZE);
St25tbError ret;
do {
ret = st25tb_poller_send_frame(
instance, instance->tx_buffer, instance->rx_buffer, ST25TB_FDT_FC);
if(ret != St25tbErrorTimeout) { // tag doesn't ack writes so timeout are expected.
break;
}

furi_delay_ms(7); // 7ms is the max programming time as per datasheet

uint32_t block_check;
ret = st25tb_poller_read_block(instance, &block_check, block_number);
if(ret != St25tbErrorNone) {
FURI_LOG_E(TAG, "write verification failed: read error");
break;
}
if(block_check != block) {
FURI_LOG_E(
TAG,
"write verification failed: wrote %08lX but read back %08lX",
block,
block_check);
ret = St25tbErrorWriteFailed;
break;
}
FURI_LOG_D(TAG, "wrote %08lX to block %d", block, block_number);
} while(false);

return ret;
}

St25tbError st25tb_poller_halt(St25tbPoller* instance) {
furi_assert(instance);

Expand Down
2 changes: 2 additions & 0 deletions lib/nfc/protocols/st25tb/st25tb_poller_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

#include "st25tb_poller.h"

#include <nfc/nfc_poller.h>

#ifdef __cplusplus
extern "C" {
#endif
Expand Down
29 changes: 29 additions & 0 deletions lib/nfc/protocols/st25tb/st25tb_poller_sync.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ typedef enum {
St25tbPollerCmdTypeDetectType,
St25tbPollerCmdTypeRead,
St25tbPollerCmdTypeReadBlock,
St25tbPollerCmdTypeWriteBlock,

St25tbPollerCmdTypeNum,
} St25tbPollerCmdType;
Expand All @@ -25,10 +26,16 @@ typedef struct {
uint32_t* block;
} St25tbPollerCmdReadBlockData;

typedef struct {
uint8_t block_num;
uint32_t block;
} St25tbPollerCmdWriteBlockData;

typedef union {
St25tbPollerCmdDetectTypeData detect_type;
St25tbPollerCmdReadData read;
St25tbPollerCmdReadBlockData read_block;
St25tbPollerCmdWriteBlockData write_block;
} St25tbPollerCmdData;

typedef struct {
Expand Down Expand Up @@ -59,10 +66,17 @@ static St25tbError
poller, data->read_block.block, data->read_block.block_num);
}

static St25tbError
st25tb_poller_write_block_handler(St25tbPoller* poller, St25tbPollerCmdData* data) {
return st25tb_poller_write_block(
poller, data->write_block.block, data->write_block.block_num);
}

static St25tbPollerCmdHandler st25tb_poller_cmd_handlers[St25tbPollerCmdTypeNum] = {
[St25tbPollerCmdTypeDetectType] = st25tb_poller_detect_handler,
[St25tbPollerCmdTypeRead] = st25tb_poller_read_handler,
[St25tbPollerCmdTypeReadBlock] = st25tb_poller_read_block_handler,
[St25tbPollerCmdTypeWriteBlock] = st25tb_poller_write_block_handler,
};

static NfcCommand st25tb_poller_cmd_callback(NfcGenericEvent event, void* context) {
Expand Down Expand Up @@ -117,6 +131,21 @@ St25tbError st25tb_poller_sync_read_block(Nfc* nfc, uint8_t block_num, uint32_t*
return st25tb_poller_cmd_execute(nfc, &poller_context);
}

St25tbError st25tb_poller_sync_write_block(Nfc* nfc, uint8_t block_num, uint32_t block) {
St25tbPollerContext poller_context = {
.cmd_type = St25tbPollerCmdTypeWriteBlock,
.cmd_data =
{
.write_block =
{
.block = block,
.block_num = block_num,
},
},
};
return st25tb_poller_cmd_execute(nfc, &poller_context);
}

St25tbError st25tb_poller_sync_detect_type(Nfc* nfc, St25tbType* type) {
St25tbPollerContext poller_context = {
.cmd_type = St25tbPollerCmdTypeDetectType,
Expand Down
2 changes: 2 additions & 0 deletions lib/nfc/protocols/st25tb/st25tb_poller_sync.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ extern "C" {

St25tbError st25tb_poller_sync_read_block(Nfc* nfc, uint8_t block_num, uint32_t* block);

St25tbError st25tb_poller_sync_write_block(Nfc* nfc, uint8_t block_num, uint32_t block);

St25tbError st25tb_poller_sync_detect_type(Nfc* nfc, St25tbType* type);

St25tbError st25tb_poller_sync_read(Nfc* nfc, St25tbData* data);
Expand Down
2 changes: 1 addition & 1 deletion targets/f18/api_symbols.csv
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
entry,status,name,type,params
Version,+,46.0,,
Version,+,47.0,,
Header,+,applications/services/bt/bt_service/bt.h,,
Header,+,applications/services/cli/cli.h,,
Header,+,applications/services/cli/cli_vcp.h,,
Expand Down
12 changes: 10 additions & 2 deletions targets/f7/api_symbols.csv
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
entry,status,name,type,params
Version,+,46.0,,
Version,+,47.0,,
Header,+,applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h,,
Header,+,applications/services/bt/bt_service/bt.h,,
Header,+,applications/services/cli/cli.h,,
Expand Down Expand Up @@ -140,6 +140,7 @@ Header,+,lib/nfc/protocols/mf_ultralight/mf_ultralight_poller_sync.h,,
Header,+,lib/nfc/protocols/slix/slix.h,,
Header,+,lib/nfc/protocols/st25tb/st25tb.h,,
Header,+,lib/nfc/protocols/st25tb/st25tb_poller.h,,
Header,+,lib/nfc/protocols/st25tb/st25tb_poller_sync.h,,
Header,+,lib/one_wire/maxim_crc.h,,
Header,+,lib/one_wire/one_wire_host.h,,
Header,+,lib/one_wire/one_wire_slave.h,,
Expand Down Expand Up @@ -2684,15 +2685,22 @@ Function,+,st25tb_free,void,St25tbData*
Function,+,st25tb_get_base_data,St25tbData*,const St25tbData*
Function,+,st25tb_get_block_count,uint8_t,St25tbType
Function,+,st25tb_get_device_name,const char*,"const St25tbData*, NfcDeviceNameType"
Function,+,st25tb_get_type_from_uid,St25tbType,const uint8_t*
Function,+,st25tb_get_uid,const uint8_t*,"const St25tbData*, size_t*"
Function,+,st25tb_is_equal,_Bool,"const St25tbData*, const St25tbData*"
Function,+,st25tb_load,_Bool,"St25tbData*, FlipperFormat*, uint32_t"
Function,+,st25tb_poller_activate,St25tbError,"St25tbPoller*, St25tbData*"
Function,+,st25tb_poller_get_uid,St25tbError,"St25tbPoller*, uint8_t*"
Function,+,st25tb_poller_halt,St25tbError,St25tbPoller*
Function,+,st25tb_poller_initiate,St25tbError,"St25tbPoller*, uint8_t*"
Function,+,st25tb_poller_read,St25tbError,"St25tbPoller*, St25tbData*"
Function,+,st25tb_poller_read_block,St25tbError,"St25tbPoller*, uint32_t*, uint8_t"
Function,+,st25tb_poller_select,St25tbError,"St25tbPoller*, uint8_t*"
Function,+,st25tb_poller_send_frame,St25tbError,"St25tbPoller*, const BitBuffer*, BitBuffer*, uint32_t"
Function,+,st25tb_poller_sync_detect_type,St25tbError,"Nfc*, St25tbType*"
Function,+,st25tb_poller_sync_read,St25tbError,"Nfc*, St25tbData*"
Function,+,st25tb_poller_sync_read_block,St25tbError,"Nfc*, uint8_t, uint32_t*"
Function,+,st25tb_poller_sync_write_block,St25tbError,"Nfc*, uint8_t, uint32_t"
Function,+,st25tb_poller_write_block,St25tbError,"St25tbPoller*, uint32_t, uint8_t"
Function,+,st25tb_reset,void,St25tbData*
Function,+,st25tb_save,_Bool,"const St25tbData*, FlipperFormat*"
Function,+,st25tb_set_uid,_Bool,"St25tbData*, const uint8_t*, size_t"
Expand Down

0 comments on commit 7922e3c

Please # to comment.