Snap for 9115583 from 36896d304ede2125dba1c94eeff9b01b1c882d36 to gki13-boot-release
Change-Id: Ie0d5a0e9633f4db88294ce685ef41113d75e45da
diff --git a/st21nfc/hal/hal_fd.cc b/st21nfc/hal/hal_fd.cc
index 2e8fab0..810aca3 100644
--- a/st21nfc/hal/hal_fd.cc
+++ b/st21nfc/hal/hal_fd.cc
@@ -55,6 +55,51 @@
static const uint8_t ApduExitLoadMode[] = {0x2F, 0x04, 0x06, 0x80, 0xA0,
0x00, 0x00, 0x01, 0x01};
+
+// APDUs for ST54L
+const int UK_NB = 2;
+const int UK_SIZE = 12;
+static uint8_t UserKeys[UK_NB][UK_SIZE] = {
+ {0x00, 0x00, 0xFD, 0x0F, 0x87, 0x7D, 0x31, 0xE3, 0xCF, 0x0C, 0xD3,
+ 0x68}, // Test
+ {0x00, 0x00, 0xFD, 0x00, 0x87, 0x7D, 0x31, 0xE3, 0xCF, 0x0C, 0xD3,
+ 0x68}}; // Production
+
+static uint8_t ApduPutKeyUser1[UK_NB][50] = {
+ {0x2F, 0x04, 0x2F, 0x84, 0x11, 0x00, 0x00, 0x2A, 0x01, 0xB3,
+ 0x56, 0x01, // Test
+ 0x00, 0x00, 0xFD, 0x20, 0x20, 0xEC, 0x7D, 0x47, 0xAE, 0xF3,
+ 0x23, 0x2E, 0x00, 0x00, 0x34, 0x78, 0x82, 0xEC, 0x6b, 0xA5,
+ 0x83, 0xAF, 0x68, 0xC7, 0x1F, 0x9F, 0xB0, 0xD7, 0x9D, 0x33,
+ 0xB0, 0xDA, 0xC6, 0x2C, 0xAB, 0x8A, 0x10, 0xEA},
+ {0x2F, 0x04, 0x2F, 0x84, 0x11, 0x00, 0x00, 0x2A, 0x01, 0xB3,
+ 0x56, 0x01, // Production
+ 0x00, 0x00, 0xFD, 0x20, 0x20, 0xEC, 0x7D, 0x47, 0xAE, 0xF3,
+ 0x23, 0x2E, 0x00, 0x00, 0xE1, 0xA2, 0x78, 0xA9, 0x71, 0x14,
+ 0x46, 0x6D, 0x73, 0x86, 0x4C, 0x3B, 0x0F, 0x51, 0x71, 0x8E,
+ 0xE4, 0x1D, 0x54, 0x02, 0x3A, 0xE3, 0x18, 0x55}};
+
+static uint8_t ApduEraseUpgradeStart[] = {
+ 0x2F, 0x04, 0x12, 0x84, 0x35, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00,
+ 0x00, 0x01, 0xB2, 0x51, 0x42, 0xB0, 0x27, 0x92, 0xAA, 0xAB};
+
+static uint8_t ApduEraseNfcArea[] = {0x2F, 0x04, 0x17, 0x84, 0x36, 0x00, 0x00,
+ 0x12, 0x00, 0x01, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x04, 0x5E, 0x00, 0x4D, 0x83, 0xE1,
+ 0x59, 0x62, 0xDC, 0x14, 0x64};
+
+static uint8_t ApduEraseUpgradeStop[] = {0x2F, 0x04, 0x0F, 0x80, 0x33, 0x00,
+ 0x00, 0x0A, 0x00, 0x02, 0x97, 0x22,
+ 0xC2, 0x5A, 0x2D, 0xA4, 0x09, 0x1A};
+
+static uint8_t ApduSetVariousConfig[] = {
+ 0x2F, 0x04, 0x11, 0x84, 0x74, 0x00, 0x00, 0x0C, 0x06, 0x02,
+ 0x80, 0x80, 0xD4, 0x29, 0xEC, 0x9A, 0xFB, 0xC8, 0x4B, 0x2A};
+
+static uint8_t ApduSwitchToUser[] = {0x2F, 0x04, 0x0F, 0x84, 0xA0, 0x00,
+ 0x00, 0x0A, 0x20, 0x01, 0xFC, 0x63,
+ 0x2A, 0xE1, 0xFD, 0xAA, 0xD1, 0x9B};
+
static const uint8_t nciHeaderPropSetUwbConfig[9] = {
0x2F, 0x02, 0x00, 0x04, 0x00, 0x16, 0x01, 0x00, 0x00};
static const uint8_t nciGetPropConfig[8] = {0x2F, 0x02, 0x05, 0x03,
@@ -64,12 +109,44 @@
static uint8_t nciPropSetUwbConfig[128];
static uint8_t nciPropSetConfig_CustomField[64];
hal_fd_state_e mHalFDState = HAL_FD_STATE_AUTHENTICATE;
+hal_fd_st54l_state_e mHalFD54LState = HAL_FD_ST54L_STATE_PUY_KEYUSER;
void SendExitLoadMode(HALHANDLE mmHalHandle);
+void SendSwitchToUserMode(HALHANDLE mmHalHandle);
extern void hal_wrapper_update_complete();
typedef size_t (*STLoadUwbParams)(void *out_buff,
size_t buf_size);
+/***********************************************************************
+ * Determine UserKey
+ *
+ * @return mode: -1 : not supported
+ * 0 : Test sample
+ * 1 : Product sample
+ ***********************************************************************/
+static int GetProdType(uint8_t* UserKey) {
+ int i, j;
+ int status;
+
+ for (i = 0; i < UK_NB; i++) {
+ status = 1;
+ for (j = 0; j < UK_SIZE; j++) {
+ if (UserKey[j] != UserKeys[i][j]) {
+ STLOG_HAL_D(
+ " No match between UserKey[%d]=0x%02X and \
+ UserKeys[%d][%d]=0x%02X",
+ j, UserKey[j], i, j, UserKeys[i][j]);
+ status = 0;
+ break;
+ }
+ }
+ if (1 == status) {
+ return i;
+ }
+ }
+ return (-1);
+}
+
/**
* Send a HW reset and decode NCI_CORE_RESET_NTF information
* @param pHwVersion is used to return HW version, part of NCI_CORE_RESET_NTF
@@ -90,6 +167,7 @@
char ConfPath[256];
char fwBinName[256];
char fwConfName[256];
+ int ret;
STLOG_HAL_D(" %s - enter", __func__);
@@ -142,19 +220,56 @@
STLOG_HAL_D("%s - %s not detected", __func__, fwBinName);
} else {
STLOG_HAL_D("%s - %s file detected\n", __func__, fwBinName);
-
result |= FW_PATCH_AVAILABLE;
- fread(mBinData, sizeof(uint8_t), 4, mFwFileBin);
- mFWInfo->patchVersion =
+
+ ret = fread(mBinData, sizeof(uint8_t), 4, mFwFileBin);
+ if (ret != 4) {
+ STLOG_HAL_E("%s did not read 4 bytes \n", __func__);
+ }
+ mFWInfo->fileFwVersion =
mBinData[0] << 24 | mBinData[1] << 16 | mBinData[2] << 8 | mBinData[3];
- fread(mApduAuthent, sizeof(uint8_t), 24, mFwFileBin);
-
fgetpos(mFwFileBin, &mPosInit);
+ ret = fread(mBinData, sizeof(uint8_t), 5, mFwFileBin);
+ if (ret != 5) {
+ STLOG_HAL_E("%s did not read 5 bytes \n", __func__);
+ }
+ fsetpos(mFwFileBin, &mPosInit); // reset pos in stream
- STLOG_HAL_D(
- "%s --> st21nfc_fw integrates patch NFC FW version 0x%08X (%s)\n",
- __func__, mFWInfo->patchVersion, FwType);
+ if (mBinData[4] == 0x35) {
+ mFWInfo->fileHwVersion = HW_ST54L;
+ } else {
+ ret = fread(mApduAuthent, sizeof(uint8_t), 24, mFwFileBin);
+ if (ret != 24) {
+ STLOG_HAL_E("%s Wrong read nb \n", __func__);
+ }
+
+ // We use the last byte of the auth command to discriminate at the moment.
+ // it can be extended in case of conflict later.
+ switch (mApduAuthent[23]) {
+ case 0x43:
+ case 0xC7:
+ mFWInfo->fileHwVersion = HW_NFCD;
+ break;
+
+ case 0xE9:
+ mFWInfo->fileHwVersion = HW_ST54J;
+ break;
+ }
+ }
+
+ if (mFWInfo->fileHwVersion == 0) {
+ STLOG_HAL_E("%s --> %s integrates unknown patch NFC FW -- rejected\n",
+ __func__, FwPath);
+ fclose(mFwFileBin);
+ mFwFileBin = NULL;
+ } else {
+ fgetpos(mFwFileBin, &mPosInit);
+
+ STLOG_HAL_D("%s --> %s integrates patch NFC FW version 0x%08X (r:%d)\n",
+ __func__, FwPath, mFWInfo->fileFwVersion,
+ mFWInfo->fileHwVersion);
+ }
}
if ((mCustomFileBin = fopen((char *)ConfPath, "r")) == NULL) {
@@ -162,9 +277,9 @@
} else {
STLOG_HAL_D("%s - %s file detected\n", __func__, ConfPath);
fread(mBinData, sizeof(uint8_t), 2, mCustomFileBin);
- mFWInfo->confVersion = mBinData[0] << 8 | mBinData[1];
+ mFWInfo->fileCustVersion = mBinData[0] << 8 | mBinData[1];
STLOG_HAL_D("%s --> st21nfc_custom configuration version 0x%04X \n",
- __func__, mFWInfo->confVersion);
+ __func__, mFWInfo->fileCustVersion);
result |= FW_CUSTOM_PARAM_AVAILABLE;
}
@@ -215,25 +330,26 @@
STLOG_HAL_D("-> Router Mode NCI_CORE_RESET_NTF received after HW Reset");
/* retrieve HW Version from NCI_CORE_RESET_NTF */
- mFWInfo->hwVersion = pdata[8];
- STLOG_HAL_D(" HwVersion = 0x%02X", mFWInfo->hwVersion);
+ mFWInfo->chipHwVersion = pdata[8];
+ STLOG_HAL_D(" HwVersion = 0x%02X", mFWInfo->chipHwVersion);
/* retrieve FW Version from NCI_CORE_RESET_NTF */
- mFWInfo->fwVersion =
+ mFWInfo->chipFwVersion =
(pdata[10] << 24) | (pdata[11] << 16) | (pdata[12] << 8) | pdata[13];
- STLOG_HAL_D(" FwVersion = 0x%08X", mFWInfo->fwVersion);
+ STLOG_HAL_D(" FwVersion = 0x%08X", mFWInfo->chipFwVersion);
/* retrieve Loader Version from NCI_CORE_RESET_NTF */
- mFWInfo->loaderVersion = (pdata[14] << 16) | (pdata[15] << 8) | pdata[16];
- STLOG_HAL_D(" LoaderVersion = 0x%06X", mFWInfo->loaderVersion);
+ mFWInfo->chipLoaderVersion =
+ (pdata[14] << 16) | (pdata[15] << 8) | pdata[16];
+ STLOG_HAL_D(" LoaderVersion = 0x%06X", mFWInfo->chipLoaderVersion);
/* retrieve Customer Version from NCI_CORE_RESET_NTF */
- mFWInfo->custVersion = (pdata[31] << 8) | pdata[32];
- STLOG_HAL_D(" CustomerVersion = 0x%04X", mFWInfo->custVersion);
+ mFWInfo->chipCustVersion = (pdata[31] << 8) | pdata[32];
+ STLOG_HAL_D(" CustomerVersion = 0x%04X", mFWInfo->chipCustVersion);
/* retrieve Uwb param Version from NCI_CORE_RESET_NTF */
- mFWInfo->uwbFwVersion = (pdata[29] << 8) | pdata[30];
- STLOG_HAL_D(" uwbVersion = 0x%04X", mFWInfo->uwbFwVersion);
+ mFWInfo->chipUwbVersion = (pdata[29] << 8) | pdata[30];
+ STLOG_HAL_D(" uwbVersion = 0x%04X", mFWInfo->chipUwbVersion);
*clf_mode = FT_CLF_MODE_ROUTER;
} else if ((pdata[2] == 0x39) && (pdata[3] == 0xA1)) {
@@ -241,32 +357,43 @@
/* deduce HW Version from Factory Loader version */
if (pdata[16] == 0x01) {
- mFWInfo->hwVersion = 0x05; // ST54J
+ mFWInfo->chipHwVersion = 0x05; // ST54J
} else if (pdata[16] == 0x02) {
- mFWInfo->hwVersion = 0x04; // ST21NFCD
+ mFWInfo->chipHwVersion = 0x04; // ST21NFCD
} else {
- mFWInfo->hwVersion = 0x03; // ST21NFCD
+ mFWInfo->chipHwVersion = 0x03; // ST21NFCD
}
- STLOG_HAL_D(" HwVersion = 0x%02X", mFWInfo->hwVersion);
+ STLOG_HAL_D(" HwVersion = 0x%02X", mFWInfo->chipHwVersion);
/* Identify the Active loader. Normally only one should be detected*/
if (pdata[11] == 0xA0) {
- mFWInfo->loaderVersion = (pdata[8] << 16) | (pdata[9] << 8) | pdata[10];
+ mFWInfo->chipLoaderVersion =
+ (pdata[8] << 16) | (pdata[9] << 8) | pdata[10];
STLOG_HAL_D(" - Most recent loader activated, revision 0x%06X",
- mFWInfo->loaderVersion);
+ mFWInfo->chipLoaderVersion);
}
if (pdata[15] == 0xA0) {
- mFWInfo->loaderVersion = (pdata[12] << 16) | (pdata[13] << 8) | pdata[14];
+ mFWInfo->chipLoaderVersion =
+ (pdata[12] << 16) | (pdata[13] << 8) | pdata[14];
STLOG_HAL_D(" - Least recent loader activated, revision 0x%06X",
- mFWInfo->loaderVersion);
+ mFWInfo->chipLoaderVersion);
}
if (pdata[19] == 0xA0) {
- mFWInfo->loaderVersion = (pdata[16] << 16) | (pdata[17] << 8) | pdata[18];
+ mFWInfo->chipLoaderVersion =
+ (pdata[16] << 16) | (pdata[17] << 8) | pdata[18];
STLOG_HAL_D(" - Factory loader activated, revision 0x%06X",
- mFWInfo->loaderVersion);
+ mFWInfo->chipLoaderVersion);
}
*clf_mode = FT_CLF_MODE_LOADER;
+ } else if ((pdata[2] == 0x41) && (pdata[3] == 0xA2)) {
+ STLOG_HAL_D("-> Loader V3 Mode NCI_CORE_RESET_NTF received after HW Reset");
+ mFWInfo->chipHwVersion = HW_ST54L;
+ STLOG_HAL_D(" HwVersion = 0x%02X", mFWInfo->chipHwVersion);
+ mFWInfo->chipFwVersion = 0; // make sure FW will be updated.
+ /* retrieve Production type* from NCI_CORE_RESET_NTF */
+ mFWInfo->chipProdType = GetProdType(&pdata[44]);
+ *clf_mode = FT_CLF_MODE_LOADER;
} else {
STLOG_HAL_E(
"%s --> ERROR: wrong NCI_CORE_RESET_NTF received after HW Reset",
@@ -274,17 +401,18 @@
*clf_mode = FT_CLF_MODE_ERROR;
}
- // Allow update only for ST54J
- if (mFWInfo->hwVersion == 0x05) {
- if ((mFwFileBin != NULL) && (mFWInfo->patchVersion != mFWInfo->fwVersion)) {
+ if ((mFWInfo->chipHwVersion == HW_ST54J) ||
+ (mFWInfo->chipHwVersion == HW_ST54L)) {
+ if ((mFwFileBin != NULL) &&
+ (mFWInfo->fileFwVersion != mFWInfo->chipFwVersion)) {
STLOG_HAL_D("---> Firmware update needed\n");
result |= FW_UPDATE_NEEDED;
} else {
STLOG_HAL_D("---> No Firmware update needed\n");
}
- if ((mFWInfo->confVersion != 0) &&
- (mFWInfo->custVersion != mFWInfo->confVersion)) {
+ if ((mFWInfo->fileCustVersion != 0) &&
+ (mFWInfo->chipCustVersion != mFWInfo->fileCustVersion)) {
STLOG_HAL_D(
"%s - Need to apply new st21nfc custom configuration settings\n",
__func__);
@@ -294,8 +422,8 @@
__func__);
}
}
- if ((mFWInfo->uwbVersion != 0) &&
- (mFWInfo->uwbVersion != mFWInfo->uwbFwVersion)) {
+ if ((mFWInfo->fileUwbVersion != 0) &&
+ (mFWInfo->fileUwbVersion != mFWInfo->chipUwbVersion)) {
result |= UWB_CONF_UPDATE_NEEDED;
STLOG_HAL_D("%s - Need to apply new uwb param configuration \n", __func__);
mUwbConfigNeeded = true;
@@ -401,10 +529,10 @@
memcpy(nciPropSetUwbConfig, nciHeaderPropSetUwbConfig, 9);
nciPropSetUwbConfig[2] = lengthOutput + 6;
nciPropSetUwbConfig[8] = lengthOutput;
- mFWInfo->uwbVersion =
+ mFWInfo->fileUwbVersion =
nciPropSetUwbConfig[9] << 8 | nciPropSetUwbConfig[10];
STLOG_HAL_D("%s --> uwb configuration version 0x%04X \n", __func__,
- mFWInfo->uwbVersion);
+ mFWInfo->fileUwbVersion);
return true;
} else {
STLOG_HAL_D("%s: lengthOutput null", __func__);
@@ -415,11 +543,34 @@
}
return false;
}
+/*******************************************************************************
+**
+** Function resetHandlerState
+**
+** Description Reset FW update state.
+**
+** Parameters void
+**
+**
+*******************************************************************************/
void resetHandlerState() {
STLOG_HAL_D("%s", __func__);
mHalFDState = HAL_FD_STATE_AUTHENTICATE;
+ mHalFD54LState = HAL_FD_ST54L_STATE_PUY_KEYUSER;
}
+/*******************************************************************************
+**
+** Function UpdateHandler
+**
+** Description Handler to update ST54J NFCC FW.
+**
+** Parameters mHalHandle - HAL handle
+** data_len - Buffer length
+** p_data - Data buffer from NFCC
+**
+**
+*******************************************************************************/
void UpdateHandler(HALHANDLE mHalHandle, uint16_t data_len, uint8_t *p_data) {
HalSendDownstreamStopTimer(mHalHandle);
@@ -512,8 +663,9 @@
STLOG_HAL_D("%s - mHalFDState = HAL_FD_STATE_EXIT_APDU", __func__);
if ((p_data[data_len - 2] != 0x90) || (p_data[data_len - 1] != 0x00)) {
STLOG_HAL_D(
- "%s - Error exiting loader mode, i.e. a problem occured during FW "
- "update", __func__);
+ "%s - Error exiting loader mode, i.e. a problem occurred"
+ "during FW update",
+ __func__);
}
I2cResetPulse();
@@ -529,6 +681,176 @@
}
}
+/*******************************************************************************
+**
+** Function UpdateHandlerST54L
+**
+** Description Handler to update ST54L NFCC FW.
+**
+** Parameters mHalHandle - HAL handle
+** data_len - Buffer length
+** p_data - Data buffer from NFCC
+**
+**
+*******************************************************************************/
+static void UpdateHandlerST54L(HALHANDLE mHalHandle, uint16_t data_len,
+ uint8_t* p_data) {
+ STLOG_HAL_D("%s : Enter state = %d", __func__, mHalFD54LState);
+
+ switch (mHalFD54LState) {
+ case HAL_FD_ST54L_STATE_PUY_KEYUSER:
+ if (!HalSendDownstreamTimer(
+ mHalHandle, (uint8_t*)ApduPutKeyUser1[mFWInfo->chipProdType],
+ sizeof(ApduPutKeyUser1[mFWInfo->chipProdType]),
+ FW_TIMER_DURATION)) {
+ STLOG_HAL_E("%s - SendDownstream failed", __func__);
+ }
+ mHalFD54LState = HAL_FD_ST54L_STATE_ERASE_UPGRADE_START;
+ break;
+
+ case HAL_FD_ST54L_STATE_ERASE_UPGRADE_START:
+ if ((p_data[data_len - 2] == 0x90) && (p_data[data_len - 1] == 0x00)) {
+ if (!HalSendDownstreamTimer(mHalHandle, (uint8_t*)ApduEraseUpgradeStart,
+ sizeof(ApduEraseUpgradeStart),
+ FW_TIMER_DURATION)) {
+ STLOG_HAL_E("%s - SendDownstream failed", __func__);
+ }
+ mHalFD54LState = HAL_FD_ST54L_STATE_ERASE_NFC_AREA;
+ } else {
+ STLOG_HAL_D("%s - FW flash not succeeded", __func__);
+ SendSwitchToUserMode(mHalHandle);
+ }
+ break;
+
+ case HAL_FD_ST54L_STATE_ERASE_NFC_AREA:
+ if ((p_data[data_len - 2] == 0x90) && (p_data[data_len - 1] == 0x00)) {
+ if (!HalSendDownstreamTimer(mHalHandle, (uint8_t*)ApduEraseNfcArea,
+ sizeof(ApduEraseNfcArea),
+ FW_TIMER_DURATION)) {
+ STLOG_HAL_E("%s - SendDownstream failed", __func__);
+ }
+ mHalFD54LState = HAL_FD_ST54L_STATE_ERASE_UPGRADE_STOP;
+ } else {
+ STLOG_HAL_D("%s - FW flash not succeeded", __func__);
+ SendSwitchToUserMode(mHalHandle);
+ }
+ break;
+
+ case HAL_FD_ST54L_STATE_ERASE_UPGRADE_STOP:
+ if ((p_data[data_len - 2] == 0x90) && (p_data[data_len - 1] == 0x00)) {
+ if (!HalSendDownstreamTimer(mHalHandle, (uint8_t*)ApduEraseUpgradeStop,
+ sizeof(ApduEraseUpgradeStop),
+ FW_TIMER_DURATION)) {
+ STLOG_HAL_E("%s - SendDownstream failed", __func__);
+ }
+ mHalFD54LState = HAL_FD_ST54L_STATE_SEND_RAW_APDU;
+ } else {
+ STLOG_HAL_D("%s - FW flash not succeeded", __func__);
+ SendSwitchToUserMode(mHalHandle);
+ }
+ break;
+
+ case HAL_FD_ST54L_STATE_SEND_RAW_APDU:
+ STLOG_HAL_D("%s - mHalFDState = HAL_FD_ST54L_STATE_SEND_RAW_APDU",
+ __func__);
+ if ((p_data[0] == 0x4f) && (p_data[1] == 0x04)) {
+ if ((p_data[data_len - 2] == 0x90) && (p_data[data_len - 1] == 0x00)) {
+ mRetry = true;
+
+ fgetpos(mFwFileBin, &mPos); // save current position in stream
+ if ((fread(mBinData, sizeof(uint8_t), 3, mFwFileBin) == 3) &&
+ (fread(mBinData + 3, sizeof(uint8_t), mBinData[2], mFwFileBin) ==
+ mBinData[2])) {
+ if (!HalSendDownstreamTimer(mHalHandle, mBinData, mBinData[2] + 3,
+ FW_TIMER_DURATION)) {
+ STLOG_HAL_E("%s - SendDownstream failed", __func__);
+ }
+ } else {
+ STLOG_HAL_D("%s - EOF of FW binary", __func__);
+ if (!HalSendDownstreamTimer(
+ mHalHandle, (uint8_t*)ApduSetVariousConfig,
+ sizeof(ApduSetVariousConfig), FW_TIMER_DURATION)) {
+ STLOG_HAL_E("%s - SendDownstream failed", __func__);
+ }
+ mHalFD54LState = HAL_FD_ST54L_STATE_SET_CONFIG;
+ }
+ } else if (mRetry == true) {
+ STLOG_HAL_D("%s - Last Tx was NOK. Retry", __func__);
+ mRetry = false;
+ fsetpos(mFwFileBin, &mPos);
+ if ((fread(mBinData, sizeof(uint8_t), 3, mFwFileBin) == 3) &&
+ (fread(mBinData + 3, sizeof(uint8_t), mBinData[2], mFwFileBin) ==
+ mBinData[2])) {
+ if (!HalSendDownstreamTimer(mHalHandle, mBinData, mBinData[2] + 3,
+ FW_TIMER_DURATION)) {
+ STLOG_HAL_E("%s - SendDownstream failed", __func__);
+ }
+ fgetpos(mFwFileBin, &mPos); // save current position in stream
+ } else {
+ STLOG_HAL_D("%s - EOF of FW binary", __func__);
+ if (!HalSendDownstreamTimer(
+ mHalHandle, (uint8_t*)ApduSetVariousConfig,
+ sizeof(ApduSetVariousConfig), FW_TIMER_DURATION)) {
+ STLOG_HAL_E("%s - SendDownstream failed", __func__);
+ }
+ mHalFD54LState = HAL_FD_ST54L_STATE_SET_CONFIG;
+ }
+ } else {
+ STLOG_HAL_D("%s - FW flash not succeeded.", __func__);
+ I2cResetPulse();
+ SendSwitchToUserMode(mHalHandle);
+ }
+ }
+ break;
+
+ case HAL_FD_ST54L_STATE_SET_CONFIG:
+
+ if ((p_data[0] == 0x4f) && (p_data[1] == 0x04)) {
+ SendSwitchToUserMode(mHalHandle);
+ }
+ break;
+
+ case HAL_FD_ST54L_STATE_SWITCH_TO_USER:
+ if ((p_data[data_len - 2] != 0x90) || (p_data[data_len - 1] != 0x00)) {
+ STLOG_HAL_D(
+ "%s - Error exiting loader mode, i.e. a problem occurred during FW "
+ "update",
+ __func__);
+ }
+
+ I2cResetPulse();
+ hal_wrapper_set_state(HAL_WRAPPER_STATE_OPEN);
+ mHalFD54LState = HAL_FD_ST54L_STATE_PUY_KEYUSER;
+ break;
+
+ default:
+ STLOG_HAL_D("%s - mHalFD54LState = unknown", __func__);
+ STLOG_HAL_D("%s - FW flash not succeeded", __func__);
+ SendSwitchToUserMode(mHalHandle);
+ break;
+ }
+}
+
+/*******************************************************************************
+**
+** Function FwUpdateHandler
+**
+** Description Handler to update NFCC FW.
+**
+** Parameters mHalHandle - HAL handle
+** data_len - Buffer length
+** p_data - Data buffer from NFCC
+**
+**
+*******************************************************************************/
+void FwUpdateHandler(HALHANDLE mHalHandle, uint16_t data_len, uint8_t* p_data) {
+ if (mFWInfo->chipHwVersion == HW_ST54L) {
+ UpdateHandlerST54L(mHalHandle, data_len, p_data);
+ } else {
+ UpdateHandler(mHalHandle, data_len, p_data);
+ }
+}
+
void ApplyCustomParamHandler(HALHANDLE mHalHandle, uint16_t data_len,
uint8_t *p_data) {
STLOG_HAL_D("%s - Enter ", __func__);
@@ -595,8 +917,8 @@
nciPropSetConfig_CustomField[8] = p_data[6];
nciPropSetConfig_CustomField[2] = p_data[6] + 6;
memcpy(nciPropSetConfig_CustomField + 9, p_data + 7, p_data[6]);
- nciPropSetConfig_CustomField[13] = mFWInfo->uwbFwVersion >> 8;
- nciPropSetConfig_CustomField[14] = mFWInfo->uwbFwVersion;
+ nciPropSetConfig_CustomField[13] = mFWInfo->chipUwbVersion >> 8;
+ nciPropSetConfig_CustomField[14] = mFWInfo->chipUwbVersion;
if (!HalSendDownstream(mHalHandle, nciPropSetConfig_CustomField,
nciPropSetConfig_CustomField[2] + 3)) {
@@ -697,8 +1019,8 @@
nciPropSetConfig_CustomField[8] = p_data[6];
nciPropSetConfig_CustomField[2] = p_data[6] + 6;
memcpy(nciPropSetConfig_CustomField + 9, p_data + 7, p_data[6]);
- nciPropSetConfig_CustomField[13] = mFWInfo->uwbVersion >> 8;
- nciPropSetConfig_CustomField[14] = mFWInfo->uwbVersion;
+ nciPropSetConfig_CustomField[13] = mFWInfo->fileUwbVersion >> 8;
+ nciPropSetConfig_CustomField[14] = mFWInfo->fileUwbVersion;
if (!HalSendDownstream(mHalHandle, nciPropSetConfig_CustomField,
nciPropSetConfig_CustomField[2] + 3)) {
@@ -739,3 +1061,13 @@
}
mHalFDState = HAL_FD_STATE_EXIT_APDU;
}
+
+void SendSwitchToUserMode(HALHANDLE mmHalHandle) {
+ STLOG_HAL_D("%s: enter", __func__);
+
+ if (!HalSendDownstreamTimer(mmHalHandle, ApduSwitchToUser,
+ sizeof(ApduSwitchToUser), FW_TIMER_DURATION)) {
+ STLOG_HAL_E("%s - SendDownstream failed", __func__);
+ }
+ mHalFD54LState = HAL_FD_ST54L_STATE_SWITCH_TO_USER;
+}
diff --git a/st21nfc/hal/hal_fd.h b/st21nfc/hal/hal_fd.h
index 3ee42e9..44cde09 100644
--- a/st21nfc/hal/hal_fd.h
+++ b/st21nfc/hal/hal_fd.h
@@ -28,14 +28,18 @@
*/
typedef struct FWInfo {
uint32_t patchVersion;
- uint32_t fwVersion;
- uint8_t hwVersion;
- uint32_t loaderVersion;
- uint16_t custVersion;
- uint16_t confVersion;
- uint16_t uwbFwVersion;
- uint16_t uwbVersion;
+ uint32_t chipFwVersion;
+ uint8_t chipHwVersion;
+ uint32_t chipLoaderVersion;
+ uint16_t chipCustVersion;
+ uint16_t chipUwbVersion;
bool hibernate_exited;
+
+ uint16_t fileUwbVersion;
+ uint8_t fileHwVersion; // if 0, no FW patch available.
+ uint32_t fileFwVersion;
+ uint16_t fileCustVersion; // if 0, no custom params available.
+ uint8_t chipProdType;
} FWInfo;
typedef enum {
@@ -46,6 +50,16 @@
HAL_FD_STATE_EXIT_APDU,
} hal_fd_state_e;
+typedef enum {
+ HAL_FD_ST54L_STATE_PUY_KEYUSER,
+ HAL_FD_ST54L_STATE_ERASE_UPGRADE_START,
+ HAL_FD_ST54L_STATE_ERASE_NFC_AREA,
+ HAL_FD_ST54L_STATE_ERASE_UPGRADE_STOP,
+ HAL_FD_ST54L_STATE_SEND_RAW_APDU,
+ HAL_FD_ST54L_STATE_SET_CONFIG,
+ HAL_FD_ST54L_STATE_SWITCH_TO_USER,
+} hal_fd_st54l_state_e;
+
#define FT_CLF_MODE_ERROR 0
#define FT_CLF_MODE_LOADER 1
#define FT_CLF_MODE_ROUTER 2
@@ -62,13 +76,18 @@
#define MAX_BUFFER_SIZE 300
+// HwVersion :
+#define HW_NFCD 0x04
+#define HW_ST54J 0x05
+#define HW_ST54L 0x06
+
/* Function declarations */
int hal_fd_init();
void hal_fd_close();
uint8_t ft_cmd_HwReset(uint8_t* pdata, uint8_t* clf_mode);
void ExitHibernateHandler(HALHANDLE mHalHandle, uint16_t data_len,
uint8_t* p_data);
-void UpdateHandler(HALHANDLE mHalHandle, uint16_t data_len, uint8_t* p_data);
+void FwUpdateHandler(HALHANDLE mHalHandle, uint16_t data_len, uint8_t* p_data);
void ApplyCustomParamHandler(HALHANDLE mHalHandle, uint16_t data_len,
uint8_t* p_data);
void ApplyUwbParamHandler(HALHANDLE mHalHandle, uint16_t data_len,
diff --git a/st21nfc/hal_wrapper.cc b/st21nfc/hal_wrapper.cc
index 5c97179..2b5ecc7 100644
--- a/st21nfc/hal_wrapper.cc
+++ b/st21nfc/hal_wrapper.cc
@@ -240,12 +240,17 @@
mHalWrapperCallback(HAL_NFC_OPEN_CPLT_EVT, HAL_NFC_STATUS_FAILED);
I2cCloseLayer();
} else {
- STLOG_HAL_V("%s - Send APDU_GET_ATR_CMD", __func__);
- mRetryFwDwl--;
- if (!HalSendDownstreamTimer(mHalHandle, ApduGetAtr,
- sizeof(ApduGetAtr),
- FW_TIMER_DURATION)) {
- STLOG_HAL_E("%s - SendDownstream failed", __func__);
+ if (((p_data[3] == 0x01) && (p_data[8] == HW_ST54L)) ||
+ ((p_data[2] == 0x41) && (p_data[3] == 0xA2))) { // ST54L
+ FwUpdateHandler(mHalHandle, data_len, p_data);
+ } else {
+ STLOG_HAL_V("%s - Send APDU_GET_ATR_CMD", __func__);
+ mRetryFwDwl--;
+ if (!HalSendDownstreamTimer(mHalHandle, ApduGetAtr,
+ sizeof(ApduGetAtr),
+ FW_TIMER_DURATION)) {
+ STLOG_HAL_E("%s - SendDownstream failed", __func__);
+ }
}
mHalWrapperState = HAL_WRAPPER_STATE_UPDATE;
}
@@ -556,7 +561,7 @@
case HAL_WRAPPER_STATE_UPDATE: // 7
STLOG_HAL_V("%s - mHalWrapperState = HAL_WRAPPER_STATE_UPDATE", __func__);
- UpdateHandler(mHalHandle, data_len, p_data);
+ FwUpdateHandler(mHalHandle, data_len, p_data);
break;
case HAL_WRAPPER_STATE_APPLY_CUSTOM_PARAM: // 8
STLOG_HAL_V(