I am writing and Android app to communicate with RF430FRL152H devices via ISO15693. This app attempts to duplicate an existing Qt C++ executable that uses a TRF7970A to communicate with the devices. I am consistently unable to write a single block if the option flag is set, resulting in an android.nfc.TagLostException.
The TRF7970A executable follows the TRF7960 Evaluation Mode document, which states that Write Single Block (0x21) must have the Option flag set (0x40) and the data must be LSByte first.
http://www.ti.com/lit/an/sloa141/sloa141.pdf
I have observed this behavior in my own app as well as the examples Android app from the TI forums:
https://e2e.ti.com/support/wireless_connectivity/nfc_rfid/f/667/p/469938/1688321#1688321
https://e2e.ti.com/support/wireless_connectivity/nfc_rfid/f/667/p/432715/1689969#1689969
A 2011 post in the Android Issue Tracker mentions some problems with Android's nfcV and write blocks on common chips, including TI
https://code.google.com/p/android/issues/detail?id=15608
In my app, pasted below, this does prevent the android.nfc.TagLostException and no error flag is returned. However I am not observing the expected behavior later when enabling and setting the interrupt field in the Firmware General Control Register, so I am not sure this is a complete solution.
To complicate matters further, removing the option flag from the write commands in the TRF7970A executable continues to work correctly.
What is the accepted method for writing a single block? Are there known problems between Android and the RF430FRL152H?
Thank you.
public class MainActivity extends AppCompatActivity {
static final String LOG_TAG = MainActivity.class.getSimpleName();
NfcAdapter mNfcAdapter;
NfcV mNfcV;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
}
private void enableForegroundDispatch() {
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
final IntentFilter intentFilter = new IntentFilter(NfcAdapter.ACTION_TECH_DISCOVERED);
IntentFilter[] intentFilters = new IntentFilter[] { intentFilter };
String[][] techListArray = new String[][] { new String[] { NfcV.class.getName() }};
mNfcAdapter.enableForegroundDispatch(this, pendingIntent, intentFilters, techListArray);
}
@Override
public void onPause() {
super.onPause();
mNfcAdapter.disableForegroundDispatch(this);
}
@Override
public void onResume() {
super.onResume();
enableForegroundDispatch();
}
@Override
protected void onNewIntent(Intent intent) {
switch(intent.getAction())
{
case NfcAdapter.ACTION_TECH_DISCOVERED:
onNfcTagDiscoveredAction(intent);
break;
default:
break;
}
}
private void onNfcTagDiscoveredAction(Intent intent) {
if(mNfcV != null) {
return;
}
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
mNfcV = NfcV.get(tag);
AsyncTask<Void, Void, Void> asyncTask = new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
try {
mNfcV.connect();
// TRF7970A "010C00030410002101000000" Register Write Request
// TRF7970A "0109000304F0000000" AGC Toggle
// TRF7970A "0109000304F1FF0000" AM PM Toggle
// TRF7970A "010B000304142401000000" ISO 15693 Inventory request
final byte[] INVENTORY = new byte[] { (byte) 0x24, (byte) 0x01, (byte) 0x00 };
byte[] inventoryResult = mNfcV.transceive(INVENTORY);
Log.d(LOG_TAG, "Inventory complete");
// TRF7970A "010C00030418002312010000"
final byte[] READ_MULTIPLE_BLOCK = new byte[] { (byte)0x00, (byte)0x23, (byte)0x12, (byte)0x01 };
byte[] readResult = mNfcV.transceive(READ_MULTIPLE_BLOCK);
Log.d(LOG_TAG, "Read multiple block complete, result length: " + readResult.length);
// TRF7970A "010F000304180221ff95fe00000000" Request mode
final byte[] WRITE_SINGLE_BLOCK_NO_OPTION = new byte[] { (byte)0x02, (byte)0x21, (byte)0xff, (byte)0x95, (byte)0xfe, (byte)0x00, (byte)0x00 };
byte[] noOptionResult = mNfcV.transceive(WRITE_SINGLE_BLOCK_NO_OPTION);
Log.d(LOG_TAG, "Wrote no option, result length: " + noOptionResult.length);
// TRF7970 "010F00030418402101010100000000" Request Mode
final byte[] WRITE_SINGLE_BLOCK_OPTION = new byte[] { (byte)0x40, (byte)0x21, (byte)0x01, (byte)0x01, (byte)0x01, (byte)0x00, (byte)0x00 };
byte[] optionResult = mNfcV.transceive(WRITE_SINGLE_BLOCK_OPTION);
Log.d(LOG_TAG, "Wrote with option, result length: " + optionResult.length);
}
catch(Exception e) {
Log.d(LOG_TAG, "Exception: " + e.toString());
}
return null;
}
@Override
protected void onPostExecute(Void result)
{
mNfcV = null;
}
};
asyncTask.execute();
}
}
I am writing and Android app to communicate with RF430FRL152H devices via ISO15693. This app attempts to duplicate an existing Qt C++ executable that uses a TRF7970A to communicate with the devices.
I am consistently unable to write a single block if the option flag is set, resulting in an android.nfc.TagLostException.
The TRF7970A executable follows the TRF7960 Evaluation Mode document, which states that Write Single Block (0x21) must have the Option flag set (0x40) and the data must be LSByte first.
http://www.ti.com/lit/an/sloa141/sloa141.pdf
I have observed this behavior in my own app as well as the examples Android app from the TI forums:
https://e2e.ti.com/support/wireless_connectivity/nfc_rfid/f/667/p/469938/1688321#1688321
https://e2e.ti.com/support/wireless_connectivity/nfc_rfid/f/667/p/432715/1689969#1689969
A 2011 post in the Android Issue Tracker mentions some problems with Android's nfcV and write blocks on common chips, including TI
https://code.google.com/p/android/issues/detail?id=15608
In my app this does prevent the android.nfc.TagLostException and no error flag is returned. However I am not observing the expected behavior later when enabling and setting the interrupt field in the Firmware General Control Register, so I am not sure this is a complete solution.
To complicate matters further, removing the option flag from the write commands in the TRF7970A executable continues to work correctly.
What is the accepted method for writing a single block? Are there known problems between Android and the RF430FRL152H?
Thank you.