Implement WriteBack cache (Fixes Issue 155)
This commit is contained in:
parent
95914345e1
commit
009d851771
2 changed files with 107 additions and 9 deletions
|
@ -53,7 +53,9 @@ static const byte_t pn53x_nack_frame[] = { 0x00, 0x00, 0xff, 0xff, 0x00, 0x00 };
|
||||||
static const byte_t pn53x_error_frame[] = { 0x00, 0x00, 0xff, 0x01, 0xff, 0x7f, 0x81, 0x00 };
|
static const byte_t pn53x_error_frame[] = { 0x00, 0x00, 0xff, 0x01, 0xff, 0x7f, 0x81, 0x00 };
|
||||||
|
|
||||||
/* prototypes */
|
/* prototypes */
|
||||||
bool pn53x_reset_settings(nfc_device_t * pnd);
|
bool pn53x_reset_settings (nfc_device_t * pnd);
|
||||||
|
bool pn53x_writeback_register (nfc_device_t * pnd);
|
||||||
|
|
||||||
nfc_modulation_t pn53x_ptt_to_nm (const pn53x_target_type_t ptt);
|
nfc_modulation_t pn53x_ptt_to_nm (const pn53x_target_type_t ptt);
|
||||||
pn53x_modulation_t pn53x_nm_to_pm (const nfc_modulation_t nm);
|
pn53x_modulation_t pn53x_nm_to_pm (const nfc_modulation_t nm);
|
||||||
pn53x_target_type_t pn53x_nm_to_ptt (const nfc_modulation_t nm);
|
pn53x_target_type_t pn53x_nm_to_ptt (const nfc_modulation_t nm);
|
||||||
|
@ -102,6 +104,12 @@ pn53x_reset_settings(nfc_device_t * pnd)
|
||||||
bool
|
bool
|
||||||
pn53x_transceive (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTx, byte_t * pbtRx, size_t *pszRx)
|
pn53x_transceive (nfc_device_t * pnd, const byte_t * pbtTx, const size_t szTx, byte_t * pbtRx, size_t *pszRx)
|
||||||
{
|
{
|
||||||
|
if (CHIP_DATA (pnd)->wb_trigged) {
|
||||||
|
if (!pn53x_writeback_register (pnd)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
PNCMD_DBG (pbtTx[0]);
|
PNCMD_DBG (pbtTx[0]);
|
||||||
byte_t abtRx[PN53x_EXTENDED_FRAME__DATA_MAX_LEN];
|
byte_t abtRx[PN53x_EXTENDED_FRAME__DATA_MAX_LEN];
|
||||||
size_t szRx = sizeof(abtRx);
|
size_t szRx = sizeof(abtRx);
|
||||||
|
@ -473,6 +481,8 @@ pn53x_WriteRegister (nfc_device_t * pnd, const uint16_t ui16RegisterAddress, con
|
||||||
bool
|
bool
|
||||||
pn53x_write_register (nfc_device_t * pnd, const uint16_t ui16RegisterAddress, const uint8_t ui8SymbolMask, const uint8_t ui8Value)
|
pn53x_write_register (nfc_device_t * pnd, const uint16_t ui16RegisterAddress, const uint8_t ui8SymbolMask, const uint8_t ui8Value)
|
||||||
{
|
{
|
||||||
|
if ((ui16RegisterAddress < PN53X_CACHE_REGISTER_MIN_ADDRESS) || (ui16RegisterAddress > PN53X_CACHE_REGISTER_MAX_ADDRESS)) {
|
||||||
|
// Direct write
|
||||||
if (ui8SymbolMask != 0xff) {
|
if (ui8SymbolMask != 0xff) {
|
||||||
uint8_t ui8CurrentValue;
|
uint8_t ui8CurrentValue;
|
||||||
if (!pn53x_read_register (pnd, ui16RegisterAddress, &ui8CurrentValue))
|
if (!pn53x_read_register (pnd, ui16RegisterAddress, &ui8CurrentValue))
|
||||||
|
@ -484,6 +494,82 @@ pn53x_write_register (nfc_device_t * pnd, const uint16_t ui16RegisterAddress, co
|
||||||
} else {
|
} else {
|
||||||
return pn53x_WriteRegister (pnd, ui16RegisterAddress, ui8Value);
|
return pn53x_WriteRegister (pnd, ui16RegisterAddress, ui8Value);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// Write-back cache area
|
||||||
|
const int internal_address = ui16RegisterAddress - PN53X_CACHE_REGISTER_MIN_ADDRESS;
|
||||||
|
CHIP_DATA (pnd)->wb_data[internal_address] = (CHIP_DATA (pnd)->wb_data[internal_address] & CHIP_DATA (pnd)->wb_mask[internal_address]) | (ui8Value & ui8SymbolMask);
|
||||||
|
CHIP_DATA (pnd)->wb_mask[internal_address] = CHIP_DATA (pnd)->wb_mask[internal_address] | ui8SymbolMask;
|
||||||
|
CHIP_DATA (pnd)->wb_trigged = true;
|
||||||
|
DBG ("WriteBackRegister (%04x, %02x, %02x)", ui16RegisterAddress, CHIP_DATA (pnd)->wb_data[internal_address], CHIP_DATA (pnd)->wb_mask[internal_address]);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
pn53x_writeback_register (nfc_device_t * pnd)
|
||||||
|
{
|
||||||
|
// TODO Check at each step (ReadRegister, WriteRegister) if we don't exceeded max supported frame lenght
|
||||||
|
uint8_t abtCmd[PN53x_EXTENDED_FRAME__DATA_MAX_LEN] = { ReadRegister };
|
||||||
|
size_t szCmd = 1;
|
||||||
|
|
||||||
|
// First step, it look for registers which need to be readed before applying the requested mask
|
||||||
|
CHIP_DATA (pnd)->wb_trigged = false;
|
||||||
|
for (size_t n = 0; n < PN53X_CACHE_REGISTER_MAX_ADDRESS - PN53X_CACHE_REGISTER_MIN_ADDRESS; n++) {
|
||||||
|
if ((CHIP_DATA (pnd)->wb_mask[n]) && (CHIP_DATA (pnd)->wb_mask[n] != 0xff)) {
|
||||||
|
// This register need to be readed: mask is present but does not cover full data width (ie. mask != 0xff)
|
||||||
|
const uint16_t pn53x_register_address = PN53X_CACHE_REGISTER_MIN_ADDRESS + n;
|
||||||
|
abtCmd[szCmd++] = pn53x_register_address >> 8;
|
||||||
|
abtCmd[szCmd++] = pn53x_register_address & 0xff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (szCmd > 1) {
|
||||||
|
// It need to read some registers
|
||||||
|
uint8_t abtRes[PN53x_EXTENDED_FRAME__DATA_MAX_LEN];
|
||||||
|
size_t szRes = sizeof(abtRes);
|
||||||
|
// Transceive the previously constructed ReadRegister command
|
||||||
|
if (!pn53x_transceive (pnd, abtCmd, szCmd, abtRes, &szRes)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
size_t i = 0;
|
||||||
|
if (CHIP_DATA(pnd)->type == PN533) {
|
||||||
|
// PN533 prepends its answer by a status byte
|
||||||
|
i = 1;
|
||||||
|
}
|
||||||
|
for (size_t n = 0; n < PN53X_CACHE_REGISTER_MAX_ADDRESS - PN53X_CACHE_REGISTER_MIN_ADDRESS; n++) {
|
||||||
|
if ((CHIP_DATA (pnd)->wb_mask[n]) && (CHIP_DATA (pnd)->wb_mask[n] != 0xff)) {
|
||||||
|
CHIP_DATA (pnd)->wb_data[n] = ((CHIP_DATA (pnd)->wb_data[n] & CHIP_DATA (pnd)->wb_mask[n]) | (abtRes[i] & (~CHIP_DATA (pnd)->wb_mask[n])));
|
||||||
|
if (CHIP_DATA (pnd)->wb_data[n] != abtRes[i]) {
|
||||||
|
// Requested value is different from readed one
|
||||||
|
CHIP_DATA (pnd)->wb_mask[n] = 0xff; // We can now apply whole data bits
|
||||||
|
} else {
|
||||||
|
CHIP_DATA (pnd)->wb_mask[n] = 0x00; // We already have the right value
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Now, the writeback-cache only have masks with 0xff, we can start to WriteRegister
|
||||||
|
szCmd = 1;
|
||||||
|
abtCmd[0] = WriteRegister;
|
||||||
|
for (size_t n = 0; n < PN53X_CACHE_REGISTER_MAX_ADDRESS - PN53X_CACHE_REGISTER_MIN_ADDRESS; n++) {
|
||||||
|
if (CHIP_DATA (pnd)->wb_mask[n] == 0xff) {
|
||||||
|
const uint16_t pn53x_register_address = PN53X_CACHE_REGISTER_MIN_ADDRESS + n;
|
||||||
|
abtCmd[szCmd++] = pn53x_register_address >> 8;
|
||||||
|
abtCmd[szCmd++] = pn53x_register_address & 0xff;
|
||||||
|
abtCmd[szCmd++] = CHIP_DATA (pnd)->wb_data[n];
|
||||||
|
DBG ("WriteBackRegister will write (%04x, %02x)", pn53x_register_address, CHIP_DATA (pnd)->wb_data[n]);
|
||||||
|
// This register is handled, we reset the mask to prevent
|
||||||
|
CHIP_DATA (pnd)->wb_mask[n] = 0x00;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (szCmd > 1) {
|
||||||
|
// We need to write some registers
|
||||||
|
if (!pn53x_transceive (pnd, abtCmd, szCmd, NULL, NULL)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2247,4 +2333,8 @@ pn53x_data_new (nfc_device_t * pnd, const struct pn53x_io* io)
|
||||||
|
|
||||||
// Set current target to NULL
|
// Set current target to NULL
|
||||||
CHIP_DATA (pnd)->current_target = NULL;
|
CHIP_DATA (pnd)->current_target = NULL;
|
||||||
|
|
||||||
|
// WriteBack cache is clean
|
||||||
|
CHIP_DATA (pnd)->wb_trigged = false;
|
||||||
|
memset (CHIP_DATA (pnd)->wb_mask, 0x00, PN53X_CACHE_REGISTER_MAX_ADDRESS-PN53X_CACHE_REGISTER_MIN_ADDRESS);
|
||||||
}
|
}
|
||||||
|
|
|
@ -151,6 +151,10 @@ struct pn53x_io {
|
||||||
int (*receive)(nfc_device_t * pnd, byte_t * pbtData, const size_t szDataLen);
|
int (*receive)(nfc_device_t * pnd, byte_t * pbtData, const size_t szDataLen);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* defines */
|
||||||
|
#define PN53X_CACHE_REGISTER_MIN_ADDRESS PN53X_REG_CIU_Mode
|
||||||
|
#define PN53X_CACHE_REGISTER_MAX_ADDRESS PN53X_REG_CIUColl
|
||||||
|
|
||||||
struct pn53x_data {
|
struct pn53x_data {
|
||||||
/** Chip type (PN531, PN532 or PN533)*/
|
/** Chip type (PN531, PN532 or PN533)*/
|
||||||
pn53x_type type;
|
pn53x_type type;
|
||||||
|
@ -170,6 +174,10 @@ struct pn53x_data {
|
||||||
uint8_t ui8LastCommand;
|
uint8_t ui8LastCommand;
|
||||||
/** Interframe timer correction */
|
/** Interframe timer correction */
|
||||||
int16_t timer_correction;
|
int16_t timer_correction;
|
||||||
|
/** WriteBack cache */
|
||||||
|
uint8_t wb_data[PN53X_CACHE_REGISTER_MAX_ADDRESS-PN53X_CACHE_REGISTER_MIN_ADDRESS];
|
||||||
|
uint8_t wb_mask[PN53X_CACHE_REGISTER_MAX_ADDRESS-PN53X_CACHE_REGISTER_MIN_ADDRESS];
|
||||||
|
bool wb_trigged;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define CHIP_DATA(pnd) ((struct pn53x_data*)(pnd->chip_data))
|
#define CHIP_DATA(pnd) ((struct pn53x_data*)(pnd->chip_data))
|
||||||
|
|
Loading…
Reference in a new issue