summaryrefslogtreecommitdiffstats
path: root/src/phDnldNfc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/phDnldNfc.c')
-rwxr-xr-xsrc/phDnldNfc.c1387
1 files changed, 1127 insertions, 260 deletions
diff --git a/src/phDnldNfc.c b/src/phDnldNfc.c
index 796653e..3d85144 100755
--- a/src/phDnldNfc.c
+++ b/src/phDnldNfc.c
@@ -58,8 +58,6 @@
#define STATIC static
#endif
-#define SECTION_HDR
-
#if defined (DNLD_SUMMARY) && !defined (DNLD_TRACE)
#define DNLD_TRACE
#endif
@@ -94,15 +92,49 @@ extern char phOsalNfc_DbgTraceBuffer[];
/* delay after SW reset cmd in ms, required on uart for XTAL stability */
#define PHDNLD_DNLD_DELAY 5000
-#define PHDNLD_MAX_PACKET 0x0200U /* Max Total Packet Size is 512 */
+//#define PHDNLD_MAX_PACKET 0x0200U /* Max Total Packet Size is 512 */
+#define PHDNLD_MAX_PACKET 32U /* Max Total Packet Size is 512 */
#define PHDNLD_DATA_SIZE ((PHDNLD_MAX_PACKET)- 8U) /* 0x01F8U */
/* Max Data Size is 504 */
#define PHDNLD_MIN_PACKET 0x03U /* Minimum Packet Size is 3*/
+#define DNLD_DEFAULT_RESPONSE_TIMEOUT 0x4000U
+
+#define NXP_FW_MIN_TX_RX_LEN 0x0AU
+
+
+#if defined( NXP_FW_MAX_TX_RX_LEN ) && \
+ ( NXP_FW_MAX_TX_RX_LEN > NXP_FW_MIN_TX_RX_LEN )
+
+#define PHDNLD_FW_TX_RX_LEN NXP_FW_MAX_TX_RX_LEN
+
+#elif !defined( NXP_FW_MAX_TX_RX_LEN )
+
+/* To specify the Maximum TX/RX Len */
+#define NXP_FW_MAX_TX_RX_LEN 0x200
+#define PHDNLD_FW_TX_RX_LEN NXP_FW_MAX_TX_RX_LEN
+
+#else
+
+#define PHDNLD_FW_TX_RX_LEN NXP_FW_MIN_TX_RX_LEN
+
+#endif
+
#define PHDNLD_FRAME_LEN_SIZE 0x02U
#define PHDNLD_ADDR_SIZE 0x03U
#define PHDNLD_DATA_LEN_SIZE 0x02U
+#define PHDNLD_FRAME_DATA_OFFSET 0x03U
+
+#define DNLD_SM_UNLOCK_MASK 0x01U
+#define DNLD_TRIM_MASK 0x02U
+#define DNLD_RESET_MASK 0x04U
+#define DNLD_VERIFY_MASK 0x08U
+#define DNLD_CRITICAL_MASK 0x10U
+
+#define NXP_NFC_IMAG_FW_MAX 0x05U
+
+#define PHDNLD_FW_PATCH_SEC 0x5FU
#define PHDNLD_PAGE_SIZE 0x80U /* Page Size Configured for 64 Bytes */
@@ -118,6 +150,8 @@ extern char phOsalNfc_DbgTraceBuffer[];
#define DNLD_PATCH_TABLE_ADDR 0x00008200U
+/* Raw Command to pass the Data in Download Mode */
+#define PHDNLD_CMD_RAW 0x00U
/* Command to Reset the Device in Download Mode */
#define PHDNLD_CMD_RESET 0x01U
/* Command to Read from the Address specified in Download Mode */
@@ -125,6 +159,7 @@ extern char phOsalNfc_DbgTraceBuffer[];
#define PHDNLD_CMD_READ_LEN 0x0005U
/* Command to write to the Address specified in Download Mode */
#define PHDNLD_CMD_WRITE 0x08U
+#define PHDNLD_CMD_SEC_WRITE 0x0CU
#define PHDNLD_CMD_WRITE_MIN_LEN 0x0005U
#define PHDNLD_CMD_WRITE_MAX_LEN PHDNLD_DATA_SIZE
/* Command to verify the data written */
@@ -145,6 +180,9 @@ extern char phOsalNfc_DbgTraceBuffer[];
/* Command to verify the Integrity of the data written */
#define PHDNLD_CMD_CHECK_INTEGRITY 0x0BU
+/* Command to verify the Integrity of the data written */
+#define PHDNLD_CMD_ENCAPSULATE 0x0DU
+
#define CHECK_INTEGRITY_RESP_CRC16_LEN 0x03U
#define CHECK_INTEGRITY_RESP_CRC32_LEN 0x05U
#define CHECK_INTEGRITY_RESP_COMP_LEN 0x10U
@@ -162,8 +200,23 @@ extern char phOsalNfc_DbgTraceBuffer[];
#define PHDNLD_RESP_PROTOCOL_ERROR 0x0BU
/* Invalid parameter Response to a Command Sent in the Download Mode */
#define PHDNLD_RESP_INVALID_PARAMETER 0x11U
+/* Command Not Supported Response to a Command Sent in the Download Mode */
+#define PHDNLD_RESP_CMD_NOT_SUPPORTED 0x13U
/* Length parameter error Response to a Command Sent in the Download Mode */
#define PHDNLD_RESP_INVALID_LENGTH 0x18U
+/* Checksum Error Response to a Command Sent in the Download Mode */
+#define PHDNLD_RESP_CHKSUM_ERROR 0x19U
+/* Version already uptodate Response to a Command Sent in the Download Mode */
+#define PHDNLD_RESP_VERSION_UPTODATE 0x1DU
+/* Memory operation error during the processing of
+ the Command Frame in the Download Mode */
+#define PHDNLD_RESP_MEMORY_UPDATE_ERROR 0x20U
+/* The Chaining of the Command Frame was Successful in the Download Mode */
+#define PHDNLD_RESP_CHAINING_SUCCESS 0x21U
+/* The Command is not allowed anymore in the Download Mode */
+#define PHDNLD_RESP_CMD_NOT_ALLOWED 0xE0U
+/* The Error during the Chaining the Command Frame in the Download Mode */
+#define PHDNLD_RESP_CHAINING_ERROR 0xE6U
/* Write Error Response to a Command Sent in the Download Mode */
#define PHDNLD_RESP_WRITE_ERROR 0x74U
@@ -185,6 +238,7 @@ extern char phOsalNfc_DbgTraceBuffer[];
typedef enum phDnldNfc_eSeqType{
DNLD_SEQ_RESET = 0x00U,
DNLD_SEQ_INIT,
+ DNLD_SEQ_RAW,
DNLD_SEQ_LOCK,
DNLD_SEQ_UNLOCK,
DNLD_SEQ_UPDATE,
@@ -216,6 +270,7 @@ typedef enum phDnldNfc_eSeq
phDnld_Verify_Integrity,
phDnld_Verify_Section,
phDnld_Complete_Seq,
+ phDnld_Raw_Upgrade,
phDnld_Invalid_Seq
}phDnldNfc_eSeq_t;
@@ -244,7 +299,7 @@ typedef struct img_data_hdr
uint8_t img_data_offset;
/* Number of fimware images available in the img_data */
uint8_t no_of_fw_img;
- /* Number of fimware images available in the img_data */
+ /* Fimware image Padding in the img_data */
uint8_t fw_img_pad[2];
/* HW Compatiblity table for the set of the Hardwares */
hw_comp_tbl_t comp_tbl;
@@ -273,25 +328,12 @@ typedef struct section_hdr
{
uint8_t section_hdr_len;
uint8_t section_mem_type;
- uint16_t section_data_crc;
+ uint8_t section_checksum;
+ uint8_t section_conf;
uint32_t section_address;
uint32_t section_length;
}section_hdr_t;
-
-typedef struct section_type
-{
- unsigned system_mem_unlock:1;
- unsigned trim_val:1;
- unsigned reset_required:1;
- unsigned verify_mem:1;
- unsigned critical_section:1;
- unsigned section_crc_check:1;
- unsigned section_type_rfu:2;
- unsigned section_type_pad:24;
-
-}section_type_t;
-
typedef struct section_info
{
section_hdr_t *p_sec_hdr;
@@ -300,6 +342,10 @@ typedef struct section_info
* to be loaded to the particular address.
*/
uint8_t *p_sec_data;
+ /* The Section checksum to verify the integrity of the section
+ * data.
+ */
+ uint8_t *p_sec_chksum;
/** \internal Index used to refer and process the
* Firmware Section Data */
volatile uint32_t section_offset;
@@ -325,13 +371,24 @@ typedef struct phDnldNfc_sParam
uint8_t data_packet[PHDNLD_DATA_SIZE];
}phDnldNfc_sParam_t;
-
typedef struct phDnldNfc_sDataHdr
{
uint8_t frame_type;
uint8_t frame_length[PHDNLD_FRAME_LEN_SIZE];
}phDnldNfc_sData_Hdr_t;
+typedef struct phDnldNfc_sRawHdr
+{
+ uint8_t frame_type;
+ uint8_t frame_length[PHDNLD_FRAME_LEN_SIZE];
+}phDnldNfc_sRawHdr_t;
+
+typedef struct phDnldNfc_sRawDataHdr
+{
+ uint8_t data_addr[PHDNLD_ADDR_SIZE];
+ uint8_t data_len[PHDNLD_DATA_LEN_SIZE];
+}phDnldNfc_sRawDataHdr_t;
+
typedef struct phDnldNfc_sChkCrc16_Resp
{
uint8_t Chk_status;
@@ -362,11 +419,59 @@ typedef struct phDnldNfc_sData
union param
{
phDnldNfc_sParam_t data_param;
- uint8_t response_data[PHDNLD_MAX_PACKET + 0];
+ uint8_t response_data[PHDNLD_MAX_PACKET];
uint8_t cmd_param;
}param_info;
}phDnldNfc_sData_t;
+#ifdef NXP_NFC_MULTIPLE_FW
+
+typedef struct phDnldNfc_sFwImageInfo
+{
+ /** \internal Data Pointer to the Firmware header section of the Firmware */
+ fw_data_hdr_t *p_fw_hdr;
+ /** \internal Buffer pointer to store the Firmware Section Data */
+ section_info_t *p_fw_sec;
+ /** \internal Buffer pointer to store the Firmware Raw Data */
+ uint8_t *p_fw_raw;
+}phDnldNfc_sFwImageInfo_t;
+
+#endif /* #ifdef NXP_NFC_MULTIPLE_FW */
+
+
+typedef struct phDnldNfc_TxInfo
+{
+ uint8_t *transmit_frame;
+
+ uint16_t tx_offset;
+
+ /** \internal Remaining amount of data to be sent */
+ uint16_t tx_len;
+
+ uint16_t tx_total;
+
+ /** \internal Chain information for the data to be sent */
+ uint8_t tx_chain;
+
+}phDnldNfc_TxInfo_t;
+
+
+typedef struct phDnldNfc_RxInfo
+{
+ /** \internal Total length of the received buffer */
+ uint16_t rx_total;
+ /** \internal Chain information of the received buffer */
+ uint16_t rx_chain;
+ /** \internal Remaining Data information to be read to complete the
+ * Data Information.
+ */
+ uint16_t rx_remain;
+
+ /** \internal Buffer to Send the Raw Data Frame */
+ uint8_t raw_buffer_data[PHDNLD_MAX_PACKET
+ + PHDNLD_PAGE_SIZE];
+}phDnldNfc_RxInfo_t;
+
typedef struct phDnldNfc_sContext
{
@@ -385,18 +490,29 @@ typedef struct phDnldNfc_sContext
/** \internal Timer ID for the Download Abort */
uint32_t timer_id;
+ /** \internal Internal Download for the Download Abort */
+ uint32_t dnld_timeout;
/** \internal Data Pointer to the Image header section of the Firmware */
img_data_hdr_t *p_img_hdr;
+
+#ifdef NXP_NFC_MULTIPLE_FW
+ /** \internal Data Pointer to the Firmware Image Information */
+ phDnldNfc_sFwImageInfo_t *p_img_info;
+#endif /* #ifdef NXP_NFC_MULTIPLE_FW */
+
/** \internal Data Pointer to the Firmware header section of the Firmware */
fw_data_hdr_t *p_fw_hdr;
/** \internal Buffer pointer to store the Firmware Data */
section_info_t *p_fw_sec;
+ /** \internal Buffer pointer to store the Firmware Raw Data */
+ uint8_t *p_fw_raw;
/** \internal Previous Download Size */
uint32_t prev_dnld_size;
/** \internal Single Data Block to download the Firmware */
- phDnldNfc_sData_t dnld_data;
+ uint8_t dnld_data[PHDNLD_MAX_PACKET
+ + PHDNLD_PAGE_SIZE];
/** \internal Index used to refer and process the Download Data */
volatile uint32_t dnld_index;
@@ -424,11 +540,12 @@ typedef struct phDnldNfc_sContext
#define NXP_FW_VMID_CARD_MODE_ADDR 0x00009931U
#define NXP_FW_VMID_RD_MODE_ADDR 0x00009981U
- unsigned vmid_trim_update:1;
- unsigned trim_bits_rfu:31;
+ uint8_t vmid_trim_update;
#endif /* #ifdef NXP_FW_SW_VMID_TRIM */
- uint8_t *p_system_mem_crc;
+ uint8_t cur_frame_info;
+
+ uint8_t raw_mode_upgrade;
uint8_t *p_patch_table_crc;
@@ -438,18 +555,12 @@ typedef struct phDnldNfc_sContext
uint16_t resp_length;
- /** \internal Total length of the received buffer */
- volatile uint16_t rx_total;
-
/** \internal Current FW Section in Process */
volatile uint8_t section_index;
/** \internal Previous Command sent */
volatile uint8_t prev_cmd;
- /** \internal Download Response pending */
- volatile uint8_t recv_pending;
-
uint8_t dnld_retry;
/** \internal Current Download State */
@@ -462,8 +573,14 @@ typedef struct phDnldNfc_sContext
/** \internal Next step in Download Sequence */
volatile uint8_t next_dnld_seq;
-}phDnldNfc_sContext_t;
+ /* \internal Data Transmit information */
+ phDnldNfc_TxInfo_t tx_info;
+ /* \internal Data Receive information */
+ phDnldNfc_RxInfo_t rx_info;
+
+
+}phDnldNfc_sContext_t;
/*
@@ -472,7 +589,9 @@ typedef struct phDnldNfc_sContext
################################################################################
*/
+#ifndef NFC_TIMER_CONTEXT
static phDnldNfc_sContext_t *gpphDnldContext = NULL;
+#endif
#ifdef NXP_FW_DNLD_CHECK_PHASE
@@ -480,6 +599,7 @@ static phDnldNfc_sContext_t *gpphDnldContext = NULL;
#define NXP_FW_DNLD_SYSTEM_PHASE 0x01U
#define NXP_FW_DNLD_CFG_PHASE 0x02U
#define NXP_FW_DNLD_DATA_PHASE 0x03U
+#define NXP_FW_DNLD_RAW_PHASE 0x04U
#define NXP_FW_DNLD_INVALID_PHASE 0xFFU
static uint8_t gphDnldPhase = NXP_FW_DNLD_COMPLETE_PHASE;
@@ -651,8 +771,10 @@ phDnldNfc_Read(
STATIC
void
phDnldNfc_Abort (
- uint32_t abort_id,
- void *pContext
+ uint32_t abort_id
+#ifdef NFC_TIMER_CONTEXT
+ , void *dnld_cntxt
+#endif
);
@@ -820,6 +942,7 @@ phDnldNfc_Release_Resources (
phDnldNfc_sContext_t **ppsDnldContext
)
{
+
if(NULL != (*ppsDnldContext)->p_resp_buffer)
{
phOsalNfc_FreeMemory((*ppsDnldContext)->p_resp_buffer);
@@ -928,12 +1051,24 @@ phDnldNfc_Set_Seq(
(uint8_t) phDnld_Reset_State;
psDnldContext->next_dnld_state =
(uint8_t)phDnld_Upgrade_State;
- psDnldContext->next_dnld_seq =
+ psDnldContext->cur_dnld_seq =
(uint8_t)phDnld_Upgrade_Section;
psDnldContext->next_dnld_seq =
psDnldContext->cur_dnld_seq;
break;
}
+ case DNLD_SEQ_RAW:
+ {
+ psDnldContext->cur_dnld_state =
+ (uint8_t) phDnld_Reset_State;
+ psDnldContext->next_dnld_state =
+ (uint8_t)phDnld_Upgrade_State;
+ psDnldContext->cur_dnld_seq =
+ (uint8_t)phDnld_Raw_Upgrade;
+ psDnldContext->next_dnld_seq =
+ psDnldContext->cur_dnld_seq;
+ break;
+ }
case DNLD_SEQ_UNLOCK:
{
psDnldContext->cur_dnld_state =
@@ -944,7 +1079,7 @@ phDnldNfc_Set_Seq(
{
psDnldContext->next_dnld_state =
(uint8_t)phDnld_Upgrade_State;
- psDnldContext->next_dnld_seq =
+ psDnldContext->cur_dnld_seq =
(uint8_t)phDnld_Upgrade_Section;
}
else
@@ -955,7 +1090,6 @@ phDnldNfc_Set_Seq(
psDnldContext->cur_dnld_seq =
(uint8_t) phDnld_Activate_Patch;
}
-
psDnldContext->next_dnld_seq =
psDnldContext->cur_dnld_seq;
break;
@@ -1009,26 +1143,6 @@ phDnldNfc_Set_Seq(
psDnldContext->cur_dnld_seq ;
break;
}
-#if 0
- case DNLD_UPDATE_STATE1:
- {
- prev_temp_state = (uint8_t) psDnldContext->cur_dnld_state;
- psDnldContext->cur_dnld_state =
- psDnldContext->next_dnld_state;
- /* psDnldContext->next_dnld_state =
- (uint8_t)phDnld_Invalid_State ; */
- break;
- }
- case DNLD_ROLLBACK_STATE1:
- {
- psDnldContext->cur_dnld_state = (uint8_t) prev_temp_state;
- /* psDnldContext->next_dnld_state =
- (uint8_t)phDnld_Invalid_State ; */
- prev_temp_state = 0;
-
- break;
- }
-#endif
default:
{
break;
@@ -1070,6 +1184,36 @@ phDnldNfc_Set_Seq(
#endif
status = plower_if->send((void *)plower_if->pcontext,
(void *)pHwRef, pdata, length);
+
+#if defined(FW_DOWNLOAD_TIMER) && \
+ (FW_DOWNLOAD_TIMER == 2)
+ if (
+ (NFCSTATUS_PENDING == status)
+ && ( NXP_INVALID_TIMER_ID != psDnldContext->timer_id )
+ )
+ {
+ psDnldContext->dnld_timeout = NXP_DNLD_COMPLETE_TIMEOUT;
+
+ if ( psDnldContext->dnld_timeout
+ < DNLD_DEFAULT_RESPONSE_TIMEOUT)
+ {
+ psDnldContext->dnld_timeout
+ = DNLD_DEFAULT_RESPONSE_TIMEOUT;
+ }
+ /* Start the Download Timer */
+ phOsalNfc_Timer_Start( psDnldContext->timer_id,
+ psDnldContext->dnld_timeout,
+ (ppCallBck_t) phDnldNfc_Abort
+#ifdef NFC_TIMER_CONTEXT
+ , (void *) psDnldContext
+#endif
+ );
+
+ DNLD_DEBUG(" DNLD : Timer %X Started ", psDnldContext->timer_id);
+ DNLD_DEBUG(" \t\t With %U Timeout \n", psDnldContext->dnld_timeout);
+ }
+
+#endif /* (NXP_NFC_DNLD_TIMER == 1) */
}
return status;
@@ -1125,8 +1269,10 @@ phDnldNfc_Read(
)
{
NFCSTATUS status = NFCSTATUS_SUCCESS;
- phDnldNfc_sParam_t *p_dnld_data =
- &psDnldContext->dnld_data.param_info.data_param;
+ phDnldNfc_sData_t *p_dnld_data =
+ (phDnldNfc_sData_t *)psDnldContext->dnld_data;
+ phDnldNfc_sParam_t *p_data_param =
+ &p_dnld_data->param_info.data_param;
uint32_t read_addr = (p_sec_info->p_sec_hdr->section_address
+ p_sec_info->section_offset);
static unsigned sec_type = 0;
@@ -1136,7 +1282,7 @@ phDnldNfc_Read(
sec_type = (unsigned int)p_sec_info->p_sec_hdr->section_mem_type;
if( ( FALSE == p_sec_info->section_read )
- && (TRUE == ((section_type_t *)(&sec_type))->trim_val)
+ && ((sec_type & DNLD_TRIM_MASK))
&& (FALSE == p_sec_info->trim_write) )
{
read_size = (uint16_t) p_sec_info->p_sec_hdr->section_length;
@@ -1145,7 +1291,8 @@ phDnldNfc_Read(
else
{
if (( FALSE == p_sec_info->section_read )
- && (TRUE == ((section_type_t *)(&sec_type))->verify_mem ))
+ && ((sec_type & DNLD_VERIFY_MASK))
+ )
{
read_size = (uint16_t)(psDnldContext->prev_dnld_size );
DNLD_DEBUG(" FW_DNLD: Section Read = %X \n", read_size);
@@ -1172,24 +1319,24 @@ phDnldNfc_Read(
read_size = (uint16_t)((PHDNLD_DATA_SIZE >= read_size)?
read_size: PHDNLD_DATA_SIZE);
- psDnldContext->dnld_data.frame_length[i] = (uint8_t)0;
+ p_dnld_data->frame_length[i] = (uint8_t)0;
/* Update the LSB of the Data and the Address Parameter*/
- p_dnld_data->data_addr[i] = (uint8_t)((read_addr >>
+ p_data_param->data_addr[i] = (uint8_t)((read_addr >>
(BYTE_SIZE + BYTE_SIZE)) & BYTE_MASK);
- p_dnld_data->data_len[i] = (uint8_t)((read_size >>
+ p_data_param->data_len[i] = (uint8_t)((read_size >>
BYTE_SIZE) & BYTE_MASK);
i++;
- psDnldContext->dnld_data.frame_length[i] = (uint8_t)
+ p_dnld_data->frame_length[i] = (uint8_t)
( PHDNLD_CMD_READ_LEN & BYTE_MASK);
/* Update the 2nd byte of the Data and the Address Parameter*/
- p_dnld_data->data_addr[i] = (uint8_t)((read_addr >>
+ p_data_param->data_addr[i] = (uint8_t)((read_addr >>
BYTE_SIZE) & BYTE_MASK);
- p_dnld_data->data_len[i] = (uint8_t) (read_size & BYTE_MASK);
+ p_data_param->data_len[i] = (uint8_t) (read_size & BYTE_MASK);
i++;
/* Update the 3rd byte of the the Address Parameter*/
- p_dnld_data->data_addr[i] = (uint8_t)(read_addr & BYTE_MASK);
+ p_data_param->data_addr[i] = (uint8_t)(read_addr & BYTE_MASK);
status = phDnldNfc_Send_Command( psDnldContext, pHwRef,
PHDNLD_CMD_READ, NULL , 0 );
@@ -1218,8 +1365,10 @@ phDnldNfc_Process_Write(
)
{
NFCSTATUS status = NFCSTATUS_SUCCESS;
+ phDnldNfc_sData_t *p_dnld_data =
+ (phDnldNfc_sData_t *)psDnldContext->dnld_data;
phDnldNfc_sParam_t *dnld_data =
- &psDnldContext->dnld_data.param_info.data_param;
+ &p_dnld_data->param_info.data_param;
uint8_t *p_sm_trim_data = (uint8_t *)psDnldContext->
dnld_resp.param_info.response_data;
uint32_t dnld_addr = 0;
@@ -1239,7 +1388,7 @@ phDnldNfc_Process_Write(
{
if( (TRUE == p_sec_info->trim_write)
&& (TRUE == p_sec_info->section_read)
- && (TRUE == ((section_type_t *)(&sec_type))->verify_mem )
+ && ((sec_type & DNLD_VERIFY_MASK))
)
{
if(NULL != psDnldContext->trim_store.buffer)
@@ -1268,7 +1417,7 @@ phDnldNfc_Process_Write(
else
{
if((NULL != psDnldContext->dnld_store.buffer)
- && (TRUE == ((section_type_t *)(&sec_type))->verify_mem )
+ && ((sec_type & DNLD_VERIFY_MASK))
&& (TRUE == p_sec_info->section_write)
&& (TRUE == p_sec_info->section_read)
)
@@ -1333,7 +1482,6 @@ phDnldNfc_Process_Write(
if (dnld_size != 0)
{
-
dnld_size = (uint16_t)((PHDNLD_DATA_SIZE >= dnld_size)?
dnld_size: PHDNLD_DATA_SIZE);
@@ -1342,7 +1490,7 @@ phDnldNfc_Process_Write(
(BYTE_SIZE + BYTE_SIZE)) & BYTE_MASK);
dnld_data->data_len[i] = (uint8_t)((dnld_size >> BYTE_SIZE)
& BYTE_MASK);
- psDnldContext->dnld_data.frame_length[i] = (uint8_t)
+ p_dnld_data->frame_length[i] = (uint8_t)
(((dnld_size + PHDNLD_CMD_WRITE_MIN_LEN) >> BYTE_SIZE)
& BYTE_MASK);
i++;
@@ -1350,7 +1498,7 @@ phDnldNfc_Process_Write(
dnld_data->data_addr[i] = (uint8_t)((dnld_addr >> BYTE_SIZE)
& BYTE_MASK);
dnld_data->data_len[i] = (uint8_t) (dnld_size & BYTE_MASK);
- psDnldContext->dnld_data.frame_length[i] = (uint8_t) ((dnld_size +
+ p_dnld_data->frame_length[i] = (uint8_t) ((dnld_size +
PHDNLD_CMD_WRITE_MIN_LEN) & BYTE_MASK);
i++;
/* Update the 3rd byte of the the Address Parameter*/
@@ -1359,7 +1507,7 @@ phDnldNfc_Process_Write(
(void)memcpy( dnld_data->data_packet,
(p_sec_info->p_sec_data + *p_sec_offset), dnld_size );
- if((TRUE == ((section_type_t *)(&sec_type))->trim_val )
+ if( ((sec_type & DNLD_TRIM_MASK))
&& (p_sec_info->sec_verify_retry != 0)
&& (NULL != psDnldContext->trim_store.buffer)
)
@@ -1367,7 +1515,7 @@ phDnldNfc_Process_Write(
(void)memcpy( dnld_data->data_packet,
psDnldContext->trim_store.buffer, dnld_size );
}
- else if((TRUE == ((section_type_t *)(&sec_type))->trim_val )
+ else if(((sec_type & DNLD_TRIM_MASK))
&& ( TRUE == p_sec_info->section_read )
)
{
@@ -1417,8 +1565,14 @@ else
psDnldContext->trim_store.buffer = NULL;
psDnldContext->trim_store.length = 0;
}
+#if 1
+ (void)
+ phDnldNfc_Allocate_Resource((void **)
+ &(psDnldContext->trim_store.buffer),dnld_size);
+#else
psDnldContext->trim_store.buffer =
(uint8_t *) phOsalNfc_GetMemory(dnld_size);
+#endif
if(NULL != psDnldContext->trim_store.buffer)
{
@@ -1441,8 +1595,14 @@ else
psDnldContext->dnld_store.buffer = NULL;
psDnldContext->dnld_store.length = 0;
}
+#if 1
+ (void)
+ phDnldNfc_Allocate_Resource((void **)
+ &(psDnldContext->dnld_store.buffer),dnld_size);
+#else
psDnldContext->dnld_store.buffer =
(uint8_t *) phOsalNfc_GetMemory(dnld_size);
+#endif
if(NULL != psDnldContext->dnld_store.buffer)
{
(void )memset((void *)psDnldContext->dnld_store.buffer,0,
@@ -1454,15 +1614,24 @@ else
DNLD_DEBUG(" of Size %X ", dnld_size );
}
}
+
+ if(PHDNLD_FW_PATCH_SEC != psDnldContext->p_fw_hdr->fw_patch)
+ {
status = phDnldNfc_Send_Command( psDnldContext, pHwRef,
PHDNLD_CMD_WRITE, NULL , 0 );
+ }
+ else
+ {
+ status = phDnldNfc_Send_Command( psDnldContext, pHwRef,
+ PHDNLD_CMD_SEC_WRITE, NULL , 0 );
+ }
DNLD_DEBUG(" FW_DNLD: Memory Write Status = %X \n", status);
if ( NFCSTATUS_PENDING == status )
{
psDnldContext->prev_dnld_size = dnld_size;
cmp_val = 0x00;
- if(TRUE == ((section_type_t *)(&sec_type))->trim_val )
+ if((sec_type & DNLD_TRIM_MASK))
{
p_sec_info->trim_write = TRUE;
DNLD_DEBUG(" FW_DNLD: Bytes Downloaded (Trimming Values) = %X Bytes \n",
@@ -1515,7 +1684,7 @@ phDnldNfc_Resume_Write(
p_sec_info->trim_write = FALSE;
DNLD_DEBUG(" FW_DNLD: Section %02X Download Complete\n", sec_index);
- if(TRUE == ((section_type_t *)(&sec_type))->reset_required )
+ if((sec_type & DNLD_RESET_MASK))
{
DNLD_DEBUG(" FW_DNLD: Reset After Section %02X Download \n", sec_index);
status = phDnldNfc_Send_Command( psDnldContext, pHwRef,
@@ -1584,7 +1753,7 @@ phDnldNfc_Resume_Write(
#if (ES_HW_VER <= 30)
#define NXP_DNLD_PATCH_ADDR 0x01AFFFU
#else
-#define NXP_DNLD_PATCH_ADDR 0x01AFE0U
+#define NXP_DNLD_PATCH_ADDR 0x01A1E0U
#endif
#if (ES_HW_VER <= 30)
@@ -1605,14 +1774,16 @@ phDnldNfc_Sequence(
{
NFCSTATUS status = NFCSTATUS_SUCCESS;
uint32_t dnld_addr = 0;
- phDnldNfc_sParam_t *dnld_data = &psDnldContext->dnld_data
- .param_info.data_param;
+ phDnldNfc_sData_t *p_dnld_data =
+ (phDnldNfc_sData_t *)psDnldContext->dnld_data;
+ phDnldNfc_sParam_t *p_data_param =
+ & p_dnld_data->param_info.data_param;
uint8_t *p_data = NULL;
static uint32_t patch_size = 0;
#if (ES_HW_VER == 32)
- static uint8_t patch_table[] = {0xA0, 0xAF, 0xE0, 0x80, 0xA9, 0x6C };
+ static uint8_t patch_table[] = {0xA0, 0xA1, 0xE0, 0x80, 0xA9, 0x6C };
static uint8_t patch_data[] = {0xA5, 0xD0, 0xFE, 0xA5, 0xD0, 0xFD, 0xA5,
0xD0, 0xFC, 0xA5, 0x02, 0x80, 0xA9, 0x75};
@@ -1755,25 +1926,25 @@ phDnldNfc_Sequence(
{
/* Update the LSB of the Data and the Address Parameter*/
- dnld_data->data_addr[i] = (uint8_t)((dnld_addr >>
+ p_data_param->data_addr[i] = (uint8_t)((dnld_addr >>
(BYTE_SIZE + BYTE_SIZE))
& BYTE_MASK);
- dnld_data->data_len[i] = (uint8_t)((patch_size >> BYTE_SIZE)
+ p_data_param->data_len[i] = (uint8_t)((patch_size >> BYTE_SIZE)
& BYTE_MASK);
- psDnldContext->dnld_data.frame_length[i] = (uint8_t)
+ p_dnld_data->frame_length[i] = (uint8_t)
(((patch_size + PHDNLD_CMD_WRITE_MIN_LEN) >> BYTE_SIZE)
& BYTE_MASK);
i++;
/* Update the 2nd byte of the Data and the Address Parameter*/
- dnld_data->data_addr[i] = (uint8_t)((dnld_addr >> BYTE_SIZE)
+ p_data_param->data_addr[i] = (uint8_t)((dnld_addr >> BYTE_SIZE)
& BYTE_MASK);
- dnld_data->data_len[i] = (uint8_t) (patch_size & BYTE_MASK);
- psDnldContext->dnld_data.frame_length[i] = (uint8_t)
+ p_data_param->data_len[i] = (uint8_t) (patch_size & BYTE_MASK);
+ p_dnld_data->frame_length[i] = (uint8_t)
((patch_size + PHDNLD_CMD_WRITE_MIN_LEN)
& BYTE_MASK);
i++;
/* Update the 3rd byte of the the Address Parameter*/
- dnld_data->data_addr[i] = (uint8_t)(dnld_addr & BYTE_MASK);
+ p_data_param->data_addr[i] = (uint8_t)(dnld_addr & BYTE_MASK);
status = phDnldNfc_Send_Command( psDnldContext, pHwRef,
PHDNLD_CMD_WRITE,(void *)p_data , (uint8_t)patch_size );
@@ -1787,6 +1958,384 @@ phDnldNfc_Sequence(
return status;
}
+#define FRAME_HEADER_LEN 0x03U
+
+
+static
+void
+phDnldNfc_Tx_Reset(phDnldNfc_sContext_t *psDnldContext)
+{
+ psDnldContext->tx_info.transmit_frame = NULL;
+ psDnldContext->tx_info.tx_total = 0x00;
+ psDnldContext->tx_info.tx_offset = 0x00;
+ psDnldContext->tx_info.tx_len = 0x00;
+ psDnldContext->tx_info.tx_chain = FALSE;
+}
+
+STATIC
+bool_t
+phDnldNfc_Extract_Chunks(
+ uint8_t *frame_data,
+ uint16_t frame_offset,
+ uint16_t frame_length,
+ uint16_t max_frame ,
+ uint16_t *chunk_length
+ );
+
+
+STATIC
+bool_t
+phDnldNfc_Extract_Chunks(
+ uint8_t *frame_data,
+ uint16_t frame_offset,
+ uint16_t frame_length,
+ uint16_t max_frame ,
+ uint16_t *chunk_length
+ )
+{
+ bool_t chunk_present = FALSE;
+
+ if( 0 == frame_offset)
+ {
+ if( max_frame >= (frame_length
+ - frame_offset))
+ {
+ *chunk_length = (frame_length - frame_offset);
+ }
+ else
+ {
+ *chunk_length = max_frame
+ - FRAME_HEADER_LEN;
+ chunk_present = TRUE;
+ }
+ }
+ else
+ {
+ if( max_frame >= (frame_length
+ - frame_offset))
+ {
+ *chunk_length = (frame_length - frame_offset);
+ }
+ else
+ {
+ *chunk_length = max_frame
+ - FRAME_HEADER_LEN;
+ chunk_present = TRUE;
+ }
+ }
+
+ return chunk_present;
+}
+
+
+STATIC
+NFCSTATUS
+phDnldNfc_Send_Raw(
+ phDnldNfc_sContext_t *psDnldContext,
+ void *pHwRef,
+ uint8_t *raw_frame,
+ uint16_t frame_offset,
+ uint16_t frame_length
+ )
+{
+ NFCSTATUS status = NFCSTATUS_SUCCESS;
+ phDnldNfc_sRawHdr_t *raw_frame_hdr = ( phDnldNfc_sRawHdr_t * ) raw_frame;
+
+ switch(raw_frame_hdr->frame_type)
+ {
+ case PHDNLD_CMD_RESET:
+ {
+ break;
+ }
+ case PHDNLD_CMD_READ:
+ {
+ /* TODO: To Update the length and the buffer to receive data */
+ break;
+ }
+ case PHDNLD_CMD_WRITE:
+ {
+ phDnldNfc_sRawDataHdr_t *raw_data_hdr =
+ ( phDnldNfc_sRawDataHdr_t * ) (raw_frame + FRAME_HEADER_LEN);
+
+ psDnldContext->resp_length = PHDNLD_MIN_PACKET;
+
+ break;
+ }
+ case PHDNLD_CMD_SEC_WRITE:
+ {
+ uint16_t tx_length = 0x00;
+ uint16_t frame_offset =
+ psDnldContext->tx_info.tx_offset;
+ uint16_t chain =
+ psDnldContext->tx_info.tx_chain;
+
+ chain =
+ phDnldNfc_Extract_Chunks(
+ raw_frame,
+ frame_offset,
+ frame_length,
+ PHDNLD_FW_TX_RX_LEN,
+ &tx_length
+ );
+
+ if( TRUE == chain )
+ {
+ status = phDnldNfc_Send_Command( psDnldContext,
+ pHwRef, PHDNLD_CMD_ENCAPSULATE,
+ (raw_frame + frame_offset),
+ tx_length);
+ if(NFCSTATUS_PENDING == status)
+ {
+ psDnldContext->prev_cmd = raw_frame_hdr->frame_type;
+ /* TODO: Update for the Chaining */
+ psDnldContext->tx_info.tx_offset += tx_length;
+ psDnldContext->tx_info.tx_chain = chain;
+ }
+ }
+ else if (0 != frame_offset)
+ {
+ status = phDnldNfc_Send_Command( psDnldContext,
+ pHwRef, PHDNLD_CMD_ENCAPSULATE,
+ (raw_frame + frame_offset),
+ tx_length);
+ if(NFCSTATUS_PENDING == status)
+ {
+ psDnldContext->prev_cmd = raw_frame_hdr->frame_type;
+ /* TODO: Update for the Chaining */
+ psDnldContext->prev_dnld_size = frame_length;
+ phDnldNfc_Tx_Reset(psDnldContext);
+ }
+ }
+ else
+ {
+ phDnldNfc_sRawDataHdr_t *raw_data_hdr =
+ ( phDnldNfc_sRawDataHdr_t * ) (raw_frame + FRAME_HEADER_LEN);
+ psDnldContext->resp_length = PHDNLD_MIN_PACKET;
+ }
+
+ break;
+ }
+ case PHDNLD_CMD_CHECK:
+ {
+ psDnldContext->resp_length = PHDNLD_MIN_PACKET;
+ break;
+ }
+ case PHDNLD_CMD_SET_HIF:
+ {
+ psDnldContext->resp_length = PHDNLD_MIN_PACKET;
+ break;
+ }
+ case PHDNLD_CMD_ACTIVATE_PATCH:
+ {
+ psDnldContext->resp_length = PHDNLD_MIN_PACKET;
+ break;
+ }
+ case PHDNLD_CMD_CHECK_INTEGRITY:
+ {
+ uint8_t integrity_param =
+ *(raw_frame + FRAME_HEADER_LEN);
+ switch(integrity_param)
+ {
+ case CHK_INTEGRITY_CONFIG_PAGE_CRC:
+ case CHK_INTEGRITY_PATCH_TABLE_CRC:
+ {
+ psDnldContext->resp_length = PHDNLD_MIN_PACKET
+ + CHECK_INTEGRITY_RESP_CRC16_LEN;
+ break;
+ }
+ case CHK_INTEGRITY_FLASH_CODE_CRC:
+ case CHK_INTEGRITY_PATCH_CODE_CRC:
+ {
+ psDnldContext->resp_length = PHDNLD_MIN_PACKET
+ + CHECK_INTEGRITY_RESP_CRC32_LEN;
+ break;
+ }
+ case CHK_INTEGRITY_COMPLETE_CRC:
+ default:
+ {
+ psDnldContext->resp_length = PHDNLD_MIN_PACKET
+ + CHECK_INTEGRITY_RESP_COMP_LEN;
+ break;
+ }
+ }
+ break;
+ }
+ default:
+ {
+ status = PHNFCSTVAL(CID_NFC_DNLD, NFCSTATUS_FEATURE_NOT_SUPPORTED);
+ break;
+ }
+ }
+
+ if (NFCSTATUS_SUCCESS == status)
+ {
+ status = phDnldNfc_Send( psDnldContext, pHwRef ,
+ raw_frame, frame_length);
+
+ if(NFCSTATUS_PENDING == status)
+ {
+ psDnldContext->prev_cmd = raw_frame_hdr->frame_type;
+ /* TODO: Update for the Chaining */
+ psDnldContext->prev_dnld_size = frame_length;
+ }
+ }
+
+ return status;
+}
+
+
+static
+NFCSTATUS
+phDnldNfc_Frame_Complete(phDnldNfc_sContext_t *psDnldContext)
+{
+ NFCSTATUS status = NFCSTATUS_SUCCESS;
+ phDnldNfc_sData_Hdr_t *p_dnld_raw = NULL;
+ uint32_t dnld_index = psDnldContext->dnld_index;
+ uint8_t *p_raw_sec_hdr = NULL;
+ uint16_t tx_length = 0x00;
+
+ dnld_index = dnld_index + psDnldContext->prev_dnld_size;
+ p_raw_sec_hdr = psDnldContext->p_fw_raw + dnld_index;
+ dnld_index = dnld_index + *p_raw_sec_hdr;
+
+ p_dnld_raw = (phDnldNfc_sData_Hdr_t *) (psDnldContext->p_fw_raw +
+ psDnldContext->dnld_index);
+
+ tx_length = ((p_dnld_raw->frame_length[0] << BYTE_SIZE) |
+ p_dnld_raw->frame_length[1]);
+
+ tx_length = tx_length + PHDNLD_MIN_PACKET;
+
+ return status;
+}
+
+
+static
+NFCSTATUS
+phDnldNfc_Raw_Write(
+ phDnldNfc_sContext_t *psDnldContext,
+ void *pHwRef
+ )
+{
+ NFCSTATUS status = NFCSTATUS_SUCCESS;
+ uint32_t dnld_index = psDnldContext->dnld_index;
+ uint32_t tx_length = 0;
+ uint8_t *p_raw_sec_hdr = NULL;
+ uint8_t dnld_flag = FALSE;
+ uint8_t skip_frame = FALSE;
+
+ if(NULL != psDnldContext->p_fw_raw)
+ {
+
+ if( (TRUE != psDnldContext->tx_info.tx_chain)
+ && (0x00 == psDnldContext->dnld_retry)
+ )
+ {
+ dnld_index = dnld_index + psDnldContext->prev_dnld_size;
+ p_raw_sec_hdr = psDnldContext->p_fw_raw + dnld_index;
+ dnld_index = dnld_index + *p_raw_sec_hdr;
+ }
+ else
+ {
+ phDnldNfc_sData_Hdr_t *p_dnld_raw = (phDnldNfc_sData_Hdr_t *)
+ (psDnldContext->p_fw_raw +
+ psDnldContext->dnld_index);
+
+ tx_length = ((p_dnld_raw->frame_length[0] << BYTE_SIZE) |
+ p_dnld_raw->frame_length[1]);
+
+ tx_length = tx_length + PHDNLD_MIN_PACKET;
+
+ status = phDnldNfc_Send_Raw( psDnldContext, pHwRef,
+ (uint8_t *)(p_dnld_raw),
+ psDnldContext->tx_info.tx_offset,
+ (uint16_t)tx_length);
+ }
+
+
+#define PHDNLD_MAJOR_OFFSET 0x04U
+#define PHDNLD_MINOR_OFFSET 0x05U
+#define PHDNLD_PHASE_OFFSET 0x06U
+#define PHDNLD_FRAMETYPE_OFFSET 0x07U
+
+#define PHDNLD_NO_OPERATION 0x00U
+#define PHDNLD_NORMAL_OPERATION 0x10U
+#define PHDNLD_ADVANCED_OPERATION 0x20U
+#define PHDNLD_SETUP_OPERATION 0x40U
+#define PHDNLD_RECOVER_OPERATION 0x80U
+#define PHDNLD_COMPLETE_OPERATION 0xF0U
+
+#define PHDNLD_TERMINATE_TYPE 0x0EU
+
+#define PHDNLD_MARKER_MASK 0x0FU
+
+ while((NFCSTATUS_SUCCESS == status )
+ && (FALSE == dnld_flag)
+ )
+ {
+ phDnldNfc_sData_Hdr_t *p_dnld_raw = (phDnldNfc_sData_Hdr_t *)
+ (psDnldContext->p_fw_raw + dnld_index);
+ uint8_t frame_type = *(p_raw_sec_hdr + PHDNLD_FRAMETYPE_OFFSET);
+
+ tx_length = ((p_dnld_raw->frame_length[0] << BYTE_SIZE) |
+ p_dnld_raw->frame_length[1]);
+
+ tx_length = tx_length + PHDNLD_MIN_PACKET;
+
+ skip_frame = FALSE;
+
+ if( (0x00 == *(p_raw_sec_hdr + PHDNLD_PHASE_OFFSET))
+ || (0xFF == *(p_raw_sec_hdr + PHDNLD_PHASE_OFFSET))
+ || !( psDnldContext->raw_mode_upgrade
+ & (frame_type & (~PHDNLD_MARKER_MASK)) )
+ )
+ {
+ dnld_index = dnld_index + tx_length;
+ p_raw_sec_hdr = psDnldContext->p_fw_raw + dnld_index;
+ dnld_index = dnld_index + *p_raw_sec_hdr;
+ skip_frame = TRUE;
+ }
+ if (PHDNLD_TERMINATE_TYPE ==
+ (frame_type & PHDNLD_MARKER_MASK))
+ {
+ if(TRUE != skip_frame)
+ {
+ psDnldContext->raw_mode_upgrade =
+ (psDnldContext->raw_mode_upgrade &
+ ~(frame_type & ~PHDNLD_MARKER_MASK));
+ }
+
+ if(PHDNLD_NO_OPERATION ==
+ psDnldContext->raw_mode_upgrade)
+ {
+ dnld_flag = TRUE;
+ }
+ }
+ else
+ {
+
+ }
+
+ if((FALSE == skip_frame)
+ && (FALSE == dnld_flag)
+ )
+ {
+ status = phDnldNfc_Send_Raw( psDnldContext, pHwRef,
+ (uint8_t *)(p_dnld_raw),
+ psDnldContext->tx_info.tx_offset,
+ (uint16_t)tx_length);
+ }
+
+ if( NFCSTATUS_PENDING == status )
+ {
+ psDnldContext->dnld_index = dnld_index;
+ psDnldContext->cur_frame_info= frame_type;
+ }
+ }
+ }
+
+ return status;
+}
static
NFCSTATUS
@@ -1798,13 +2347,18 @@ phDnldNfc_Upgrade_Sequence(
)
{
NFCSTATUS status = NFCSTATUS_SUCCESS;
- /* section_info_t *p_cur_sec = psDnldContext->p_fw_sec +
- psDnldContext->section_index; */
PHNFC_UNUSED_VARIABLE(pdata);
PHNFC_UNUSED_VARIABLE(length);
- status = phDnldNfc_Resume_Write( psDnldContext, pHwRef );
+ if(phDnld_Raw_Upgrade == psDnldContext->cur_dnld_seq)
+ {
+ status = phDnldNfc_Raw_Write( psDnldContext, pHwRef );
+ }
+ else
+ {
+ status = phDnldNfc_Resume_Write( psDnldContext, pHwRef );
+ }
return status;
}
@@ -2018,12 +2572,14 @@ phDnldNfc_Resume(
psDnldContext->lower_interface.pcontext, pHwRef);
phDnldNfc_Release_Lower(psDnldContext, pHwRef);
phDnldNfc_Release_Resources(&psDnldContext);
+#ifndef NFC_TIMER_CONTEXT
+ gpphDnldContext = psDnldContext;
+#endif
/* Notify the Error/Success Scenario to the upper layer */
phDnldNfc_Notify( p_upper_notify, p_upper_context, pHwRef, (uint8_t)
((NFCSTATUS_SUCCESS == comp_info.status )? NFC_IO_SUCCESS: NFC_IO_ERROR),
&comp_info );
}
-
return status;
}
@@ -2041,20 +2597,19 @@ phDnldNfc_Process_Response(
(phDnldNfc_sData_Hdr_t *) pdata;
PHNFC_UNUSED_VARIABLE(pHwRef);
- /* DNLD_DEBUG(" FW_DNLD: Receive Length = %X \n", length ); */
- if(( psDnldContext->rx_total == 0 )
+ DNLD_DEBUG(" FW_DNLD: Receive Length = %X \n", length );
+ if(( psDnldContext->rx_info.rx_total == 0 )
&& (PHDNLD_MIN_PACKET <= length)
- /* && (FALSE == psDnldContext->recv_pending) */
)
{
- psDnldContext->rx_total =
+ psDnldContext->rx_info.rx_total =
((uint16_t)resp_data->frame_length[0] << BYTE_SIZE)|
resp_data->frame_length[1];
- if( psDnldContext->rx_total + PHDNLD_MIN_PACKET == length )
+ if( psDnldContext->rx_info.rx_total + PHDNLD_MIN_PACKET == length )
{
DNLD_DEBUG(" FW_DNLD: Success Memory Read = %X \n",
- psDnldContext->rx_total);
+ psDnldContext->rx_info.rx_total);
#ifndef DNLD_SUMMARY
/* DNLD_PRINT_BUFFER("Receive Buffer",pdata,length); */
#endif
@@ -2064,13 +2619,11 @@ phDnldNfc_Process_Response(
{
/* status = phDnldNfc_Receive( psDnldContext, pHwRef,
psDnldContext->p_resp_buffer,
- (uint8_t)((psDnldContext->rx_total <= PHDNLD_MAX_PACKET)?
- psDnldContext->rx_total: PHDNLD_MAX_PACKET) );
- psDnldContext->recv_pending =
- (uint8_t)( NFCSTATUS_PENDING == status); */
+ (uint8_t)((psDnldContext->rx_info.rx_total <= PHDNLD_MAX_PACKET)?
+ psDnldContext->rx_info.rx_total: PHDNLD_MAX_PACKET) ); */
DNLD_PRINT(" FW_DNLD: Invalid Receive length ");
DNLD_DEBUG(": Length Expected = %X \n",
- (psDnldContext->rx_total + PHDNLD_MIN_PACKET));
+ (psDnldContext->rx_info.rx_total + PHDNLD_MIN_PACKET));
status = PHNFCSTVAL( CID_NFC_DNLD,
NFCSTATUS_INVALID_RECEIVE_LENGTH );
}
@@ -2078,7 +2631,7 @@ phDnldNfc_Process_Response(
else
{
/*TODO:*/
- psDnldContext->rx_total = 0 ;
+ psDnldContext->rx_info.rx_total = 0 ;
status = PHNFCSTVAL( CID_NFC_DNLD,
NFCSTATUS_INVALID_RECEIVE_LENGTH );
}
@@ -2113,6 +2666,7 @@ phDnldNfc_Receive_Complete (
status = pInfo->status ;
length = pInfo->length ;
pdata = pInfo->buffer;
+
if(status != NFCSTATUS_SUCCESS)
{
DNLD_DEBUG(" Failed. Status = %02X\n",status);
@@ -2124,9 +2678,10 @@ phDnldNfc_Receive_Complete (
/* Handle the Error Scenario */
status = PHNFCSTVAL( CID_NFC_DNLD, NFCSTATUS_FAILED );
}
- else if (0 == length)
+ else if ((0 == length)
+ || (PHDNLD_MIN_PACKET > length ))
{
- DNLD_PRINT(" Receive Response Length = 0 .... \n");
+ DNLD_DEBUG(" Receive Response Length = %u .... \n",length);
/* Handle the Error Scenario */
#ifndef HAL_SW_DNLD_RLEN
status = PHNFCSTVAL( CID_NFC_DNLD,
@@ -2136,6 +2691,15 @@ phDnldNfc_Receive_Complete (
else
{
+#if defined(FW_DOWNLOAD_TIMER) && \
+ (FW_DOWNLOAD_TIMER == 2)
+ if ( NXP_INVALID_TIMER_ID != psDnldContext->timer_id )
+ {
+ phOsalNfc_Timer_Stop( psDnldContext->timer_id );
+ }
+
+#endif
+
#ifndef DNLD_SUMMARY
DNLD_PRINT_BUFFER("Receive Buffer",pdata,length);
#endif
@@ -2154,6 +2718,9 @@ phDnldNfc_Receive_Complete (
{
case PHDNLD_CMD_READ :
{
+ if( PHDNLD_NO_OPERATION
+ == psDnldContext->raw_mode_upgrade)
+ {
status = phDnldNfc_Process_Response(
psDnldContext, pHwRef, pdata , length);
@@ -2163,10 +2730,18 @@ phDnldNfc_Receive_Complete (
psDnldContext->dnld_retry = NXP_MAX_DNLD_RETRY;
/* psDnldContext->dnld_retry < NXP_MAX_DNLD_RETRY */
}
+ }
+ else
+ {
+
+ }
break;
}
case PHDNLD_CMD_CHECK_INTEGRITY :
{
+ if( PHDNLD_NO_OPERATION
+ == psDnldContext->raw_mode_upgrade)
+ {
#if (NXP_FW_INTEGRITY_CHK >= 0x01)
phDnldNfc_sChkCrcComplete_t *p_dnld_crc_all =
&psDnldContext->chk_integrity_crc;
@@ -2211,8 +2786,16 @@ phDnldNfc_Receive_Complete (
break;
}
}
-
#endif /* #if (NXP_FW_INTEGRITY_CHK >= 0x01) */
+ }
+ else
+ {
+ psDnldContext->raw_mode_upgrade =
+ (PHDNLD_SETUP_OPERATION | PHDNLD_ADVANCED_OPERATION);
+ /* psDnldContext->raw_mode_upgrade =
+ (psDnldContext->raw_mode_upgrade &
+ ( psDnldContext->cur_frame_info & ~PHDNLD_MARKER_MASK )); */
+ }
break;
}
case PHDNLD_CMD_WRITE:
@@ -2220,10 +2803,18 @@ phDnldNfc_Receive_Complete (
psDnldContext->dnld_retry = 0;
break;
}
+ case PHDNLD_CMD_SEC_WRITE:
+ {
+ psDnldContext->dnld_retry = 0;
+ break;
+ }
case PHDNLD_CMD_ACTIVATE_PATCH:
case PHDNLD_CMD_CHECK:
default:
{
+ if( PHDNLD_NO_OPERATION
+ == psDnldContext->raw_mode_upgrade)
+ {
if( ( (PHDNLD_MIN_PACKET > length)
|| ( 0 != resp_length) )
)
@@ -2236,14 +2827,20 @@ phDnldNfc_Receive_Complete (
{
psDnldContext->dnld_retry = 0;
}
+ }
+ else
+ {
+ psDnldContext->raw_mode_upgrade =
+ (psDnldContext->raw_mode_upgrade & ~PHDNLD_RECOVER_OPERATION);
+ }
break;
}
} /* End of the Previous Command Switch Case */
break;
}/* Case PHDNLD_RESP_SUCCESS*/
case PHDNLD_RESP_TIMEOUT:
- case PHDNLD_RESP_WRITE_ERROR:
case PHDNLD_RESP_CRC_ERROR:
+ case PHDNLD_RESP_WRITE_ERROR:
{
if(psDnldContext->dnld_retry < NXP_MAX_DNLD_RETRY )
{
@@ -2255,22 +2852,139 @@ phDnldNfc_Receive_Complete (
}
/* fall through */
case PHDNLD_RESP_ACCESS_DENIED:
- case PHDNLD_RESP_PROTOCOL_ERROR:
case PHDNLD_RESP_INVALID_PARAMETER:
case PHDNLD_RESP_INVALID_LENGTH:
+ /* Initial Frame Checksum */
+ case PHDNLD_RESP_CHKSUM_ERROR:
+ case PHDNLD_RESP_MEMORY_UPDATE_ERROR:
{
psDnldContext->dnld_retry = NXP_MAX_DNLD_RETRY;
status = PHNFCSTVAL(CID_NFC_DNLD,
resp_data->frame_type);
break;
}
+ case PHDNLD_RESP_PROTOCOL_ERROR:
+ {
+ if(( PHDNLD_NO_OPERATION
+ == psDnldContext->raw_mode_upgrade)
+ || ( PHDNLD_ADVANCED_OPERATION
+ == psDnldContext->raw_mode_upgrade)
+ )
+ {
+ psDnldContext->dnld_retry = NXP_MAX_DNLD_RETRY;
+ status = PHNFCSTVAL(CID_NFC_DNLD,
+ NFCSTATUS_INVALID_FORMAT);
+ }
+ else if( (PHDNLD_NORMAL_OPERATION
+ & psDnldContext->raw_mode_upgrade)
+ )
+ {
+ psDnldContext->raw_mode_upgrade =
+ (psDnldContext->raw_mode_upgrade & ~PHDNLD_NORMAL_OPERATION);
+ }
+ else if ( PHDNLD_RECOVER_OPERATION
+ & psDnldContext->raw_mode_upgrade )
+ {
+ psDnldContext->dnld_retry = NXP_MAX_DNLD_RETRY;
+ status = PHNFCSTVAL(CID_NFC_DNLD,
+ NFCSTATUS_INVALID_FORMAT);
+ }
+ else
+ {
+ psDnldContext->raw_mode_upgrade =
+ (psDnldContext->raw_mode_upgrade &
+ ~( psDnldContext->cur_frame_info & ~PHDNLD_MARKER_MASK ));
+ }
+ break;
+ }
+ case PHDNLD_RESP_VERSION_UPTODATE:
+ {
+ /* TODO: to make sure that the Advance Frames are sent to get
+ * the updated status */
+ if ( PHDNLD_ADVANCED_OPERATION
+ == psDnldContext->raw_mode_upgrade)
+ {
+ status = ( CID_NFC_DNLD << BYTE_SIZE ) ;
+ }
+ else if ( PHDNLD_NO_OPERATION
+ != psDnldContext->raw_mode_upgrade)
+ {
+
+ psDnldContext->raw_mode_upgrade =
+ (psDnldContext->raw_mode_upgrade &
+ ~( psDnldContext->cur_frame_info & ~PHDNLD_MARKER_MASK ));
+ }
+ else
+ {
+ }
+ break;
+ }
+ case PHDNLD_RESP_CMD_NOT_SUPPORTED:
+ {
+
+ if ( PHDNLD_NO_OPERATION
+ == psDnldContext->raw_mode_upgrade)
+ {
+ status = PHNFCSTVAL(CID_NFC_DNLD,
+ NFCSTATUS_FEATURE_NOT_SUPPORTED);
+ }
+ else if ( PHDNLD_ADVANCED_OPERATION
+ == psDnldContext->raw_mode_upgrade)
+ {
+ status = PHNFCSTVAL(CID_NFC_DNLD,
+ NFCSTATUS_FEATURE_NOT_SUPPORTED);
+ }
+#if 0
+ else if( (PHDNLD_NORMAL_OPERATION
+ & psDnldContext->raw_mode_upgrade)
+ )
+ {
+ psDnldContext->raw_mode_upgrade =
+ (psDnldContext->raw_mode_upgrade & ~PHDNLD_NORMAL_OPERATION);
+ }
+ else if ( PHDNLD_SETUP_OPERATION
+ & psDnldContext->raw_mode_upgrade )
+ {
+ psDnldContext->raw_mode_upgrade =
+ (psDnldContext->raw_mode_upgrade & ~PHDNLD_SETUP_OPERATION);
+ }
+#endif
+ else
+ {
+ psDnldContext->raw_mode_upgrade =
+ (psDnldContext->raw_mode_upgrade &
+ ~( psDnldContext->cur_frame_info & ~PHDNLD_MARKER_MASK ));
+ }
+ break;
+ }
+ /* The Chaining of the Command Frame
+ was Successful in the Download Mode */
+ case PHDNLD_RESP_CHAINING_SUCCESS:
+ {
+ /* TODO: Handle the Corner Case Scenarios
+ * the updated status */
+ psDnldContext->dnld_retry = 0x00;
+ break;
+ }
+/* The Error during the Chaining the Command Frame in the Download Mode */
+ case PHDNLD_RESP_CHAINING_ERROR:
+ {
+ /* TODO: Restart the Chunk in Corner Case
+ * the updated status */
+ psDnldContext->dnld_retry++;
+ phDnldNfc_Tx_Reset(psDnldContext);
+ break;
+ }
+/* The Command is not allowed anymore in the Download Mode */
+ case PHDNLD_RESP_CMD_NOT_ALLOWED:
default:
{
psDnldContext->dnld_retry = NXP_MAX_DNLD_RETRY;
status = PHNFCSTVAL(CID_NFC_DNLD,
- NFCSTATUS_FEATURE_NOT_SUPPORTED);
+ NFCSTATUS_NOT_ALLOWED);
break;
}
+
} /* End of the Response Frame Type Switch */
if (NFCSTATUS_PENDING != status)
@@ -2289,10 +3003,57 @@ phDnldNfc_Receive_Complete (
psDnldContext->lower_interface.pcontext, pHwRef);
phDnldNfc_Release_Lower(psDnldContext, pHwRef);
phDnldNfc_Release_Resources(&psDnldContext);
+#ifndef NFC_TIMER_CONTEXT
+ gpphDnldContext = psDnldContext;
+#endif
/* Notify the Error/Success Scenario to the upper layer */
phDnldNfc_Notify( p_upper_notify, p_upper_context, pHwRef,
(uint8_t) NFC_IO_ERROR, &comp_info );
}
+ else if ( (NFCSTATUS_SUCCESS != status) &&
+ (NFCSTATUS_SUCCESS == PHNFCSTATUS(status))
+ )
+ {
+ pphNfcIF_Notification_CB_t p_upper_notify =
+ psDnldContext->p_upper_notify;
+ void *p_upper_context =
+ psDnldContext->p_upper_context;
+
+ comp_info.status = NFCSTATUS_SUCCESS;
+ DNLD_DEBUG(" FW_DNLD: Termination in Receive, Status = %X \n", status);
+ status = phDal4Nfc_Unregister(
+ psDnldContext->lower_interface.pcontext, pHwRef);
+ phDnldNfc_Release_Lower(psDnldContext, pHwRef);
+ phDnldNfc_Release_Resources(&psDnldContext);
+#ifndef NFC_TIMER_CONTEXT
+ gpphDnldContext = psDnldContext;
+#endif
+ /* Notify the Error/Success Scenario to the upper layer */
+ phDnldNfc_Notify( p_upper_notify, p_upper_context, pHwRef,
+ (uint8_t) NFC_IO_SUCCESS, &comp_info );
+
+ }
+ else if (NFCSTATUS_FEATURE_NOT_SUPPORTED == PHNFCSTATUS(status))
+ {
+ pphNfcIF_Notification_CB_t p_upper_notify =
+ psDnldContext->p_upper_notify;
+ void *p_upper_context =
+ psDnldContext->p_upper_context;
+
+ comp_info.status = status;
+ DNLD_DEBUG(" FW_DNLD: Termination in Receive, Status = %X \n", status);
+ status = phDal4Nfc_Unregister(
+ psDnldContext->lower_interface.pcontext, pHwRef);
+ phDnldNfc_Release_Lower(psDnldContext, pHwRef);
+ phDnldNfc_Release_Resources(&psDnldContext);
+#ifndef NFC_TIMER_CONTEXT
+ gpphDnldContext = psDnldContext;
+#endif
+ /* Notify the Error/Success Scenario to the upper layer */
+ phDnldNfc_Notify( p_upper_notify, p_upper_context, pHwRef,
+ (uint8_t) NFC_IO_SUCCESS, &comp_info );
+
+ }
else
{
/* DNLD_PRINT(" FW_DNLD: Successful.\n"); */
@@ -2342,12 +3103,10 @@ phDnldNfc_Send_Complete (
if ((PHDNLD_CMD_SET_HIF != psDnldContext->prev_cmd)
&& (PHDNLD_CMD_RESET != psDnldContext->prev_cmd))
{
- psDnldContext->rx_total = 0;
+ psDnldContext->rx_info.rx_total = 0;
status = phDnldNfc_Receive( psDnldContext, pHwRef,
(uint8_t *)(&psDnldContext->dnld_resp),
psDnldContext->resp_length);
- /* psDnldContext->recv_pending =
- (uint8_t)( NFCSTATUS_PENDING == status); */
}
else
{
@@ -2357,7 +3116,19 @@ phDnldNfc_Send_Complete (
* platform because of its sensitivity to clock. Experimentally
* we found clock unstable for 750us. Delay for 5ms to be sure.
*/
- usleep(5000);
+ if( PHDNLD_CMD_RESET == psDnldContext->prev_cmd )
+ {
+ DO_DELAY(PHDNLD_DNLD_DELAY);
+ }
+#if defined(FW_DOWNLOAD_TIMER) && \
+ (FW_DOWNLOAD_TIMER == 2)
+
+ if ( NXP_INVALID_TIMER_ID != psDnldContext->timer_id )
+ {
+ phOsalNfc_Timer_Stop( psDnldContext->timer_id );
+ }
+#endif
+
status = phDnldNfc_Set_Seq(psDnldContext,
DNLD_SEQ_UPDATE);
}
@@ -2373,6 +3144,7 @@ phDnldNfc_Send_Complete (
}
+
STATIC
NFCSTATUS
phDnldNfc_Send_Command(
@@ -2387,6 +3159,8 @@ phDnldNfc_Send_Command(
uint16_t tx_length = 0;
uint16_t rx_length = 0;
uint8_t **pp_resp_data = &psDnldContext->p_resp_buffer;
+ phDnldNfc_sData_t *p_dnld_data =
+ (phDnldNfc_sData_t *)psDnldContext->dnld_data;
switch(cmd)
{
@@ -2398,8 +3172,10 @@ phDnldNfc_Send_Command(
}
case PHDNLD_CMD_READ:
{
+ phDnldNfc_sData_t *p_dnld_data =
+ (phDnldNfc_sData_t *)psDnldContext->dnld_data;
phDnldNfc_sParam_t *param_info = /* (phDnldNfc_sParam_t *)params */
- &psDnldContext->dnld_data.param_info.data_param;
+ &p_dnld_data->param_info.data_param;
tx_length = PHDNLD_CMD_READ_LEN;
if (NULL != *pp_resp_data)
{
@@ -2410,21 +3186,18 @@ phDnldNfc_Send_Command(
<< BYTE_SIZE) + param_info->data_len[1]);
psDnldContext->resp_length =
-#if 0
- (((rx_length > PHDNLD_DATA_SIZE)?
- PHDNLD_DATA_SIZE + PHDNLD_MIN_PACKET:
-#else
- ((
-#endif
- rx_length + PHDNLD_MIN_PACKET ));
+ (( rx_length + PHDNLD_MIN_PACKET ));
(void)phDnldNfc_Allocate_Resource( (void **) pp_resp_data,
rx_length);
break;
}
case PHDNLD_CMD_WRITE:
+ case PHDNLD_CMD_SEC_WRITE:
{
+ phDnldNfc_sData_t *p_dnld_data =
+ (phDnldNfc_sData_t *)psDnldContext->dnld_data;
phDnldNfc_sParam_t *param_info = /* (phDnldNfc_sParam_t *)params */
- &psDnldContext->dnld_data.param_info.data_param;
+ &p_dnld_data->param_info.data_param;
tx_length = (uint16_t) (((uint16_t)param_info->data_len[0]
<< BYTE_SIZE) + param_info->data_len[1]
+ PHDNLD_CMD_WRITE_MIN_LEN );
@@ -2442,6 +3215,36 @@ phDnldNfc_Send_Command(
psDnldContext->resp_length = PHDNLD_MIN_PACKET;
break;
}
+ case PHDNLD_CMD_ENCAPSULATE:
+ {
+ uint8_t i = 0x00;
+ if ((0 != param_length) && (NULL != params))
+ {
+ p_dnld_data->frame_type =
+ PHDNLD_CMD_ENCAPSULATE;
+ (void)memcpy((void *)( ((uint8_t *)p_dnld_data)
+ + PHDNLD_FRAME_DATA_OFFSET)
+ , params, param_length);
+ tx_length = param_length;
+
+ p_dnld_data->frame_length[i++] =
+ (uint8_t)(tx_length >> BYTE_SIZE);
+ p_dnld_data->frame_length[i] =
+ (uint8_t)( tx_length & BYTE_MASK );
+ tx_length += PHDNLD_FRAME_DATA_OFFSET;
+
+ psDnldContext->resp_length = PHDNLD_MIN_PACKET;
+
+ status = phDnldNfc_Send( psDnldContext, pHwRef ,
+ (uint8_t *)p_dnld_data, tx_length);
+ }
+ else
+ {
+ status = PHNFCSTVAL(CID_NFC_DNLD,
+ NFCSTATUS_NOT_ALLOWED);
+ }
+ break;
+ }
case PHDNLD_CMD_SET_HIF:
{
tx_length++;
@@ -2453,13 +3256,13 @@ phDnldNfc_Send_Command(
psDnldContext->resp_length = PHDNLD_MIN_PACKET;
if ((NULL != params) && ( param_length > 0 ))
{
- psDnldContext->dnld_data.param_info.cmd_param =
+ p_dnld_data->param_info.cmd_param =
(*(uint8_t *)params);
tx_length = param_length;
}
else
{
- psDnldContext->dnld_data.param_info.cmd_param = FALSE;
+ p_dnld_data->param_info.cmd_param = FALSE;
tx_length++;
}
break;
@@ -2478,7 +3281,7 @@ phDnldNfc_Send_Command(
psDnldContext->chk_integrity_param = CHK_INTEGRITY_COMPLETE_CRC;
tx_length++;
}
- psDnldContext->dnld_data.param_info.cmd_param =
+ p_dnld_data->param_info.cmd_param =
(uint8_t) psDnldContext->chk_integrity_param;
switch(psDnldContext->chk_integrity_param)
{
@@ -2506,7 +3309,7 @@ phDnldNfc_Send_Command(
}
#else
tx_length++;
- psDnldContext->dnld_data.param_info.cmd_param =
+ p_dnld_data->param_info.cmd_param =
(uint8_t) CHK_INTEGRITY_COMPLETE_CRC;
#endif /* #if (NXP_FW_INTEGRITY_CHK >= 0x01) */
@@ -2522,14 +3325,14 @@ phDnldNfc_Send_Command(
{
uint8_t i = 0;
- psDnldContext->dnld_data.frame_type = cmd;
- psDnldContext->dnld_data.frame_length[i++] =
+ p_dnld_data->frame_type = cmd;
+ p_dnld_data->frame_length[i++] =
(uint8_t)(tx_length >> BYTE_SIZE);
- psDnldContext->dnld_data.frame_length[i] =
+ p_dnld_data->frame_length[i] =
(uint8_t)( tx_length & BYTE_MASK );
tx_length = tx_length + PHDNLD_MIN_PACKET;
status = phDnldNfc_Send( psDnldContext, pHwRef ,
- (uint8_t *)(&psDnldContext->dnld_data), tx_length);
+ (uint8_t *)p_dnld_data, tx_length);
if(NFCSTATUS_PENDING == status)
{
psDnldContext->prev_cmd = cmd;
@@ -2537,43 +3340,19 @@ phDnldNfc_Send_Command(
if( PHDNLD_CMD_RESET == cmd )
DO_DELAY(PHDNLD_DNLD_DELAY); //this seems like its on the wrong thread
}
-
}
return status;
}
-
static
NFCSTATUS
-phDnldNfc_Process_FW(
- phDnldNfc_sContext_t *psDnldContext,
- phHal_sHwReference_t *pHwRef
-#ifdef NXP_FW_PARAM
- ,uint8_t *nxp_nfc_fw
-#endif
+phDnldNfc_Check_FW(
+ phHal_sHwReference_t *pHwRef,
+ fw_data_hdr_t *cur_fw_hdr
)
{
NFCSTATUS status = NFCSTATUS_FAILED;
- section_info_t *p_cur_sec = NULL;
- static unsigned sec_type;
- uint32_t fw_index = 0;
- fw_data_hdr_t *cur_fw_hdr = NULL;
- uint8_t sec_index = 0;
- uint8_t i = 0;
-
- psDnldContext->p_img_hdr = (img_data_hdr_t *) nxp_nfc_fw;
-
- fw_index = sizeof (img_data_hdr_t);
-
- for ( i=0; i < psDnldContext->p_img_hdr->no_of_fw_img; i++ )
- {
-
- psDnldContext->p_fw_hdr = (fw_data_hdr_t *) ( nxp_nfc_fw + fw_index );
- /* TODO: Create a memory of pointers to store all the Firmwares */
- cur_fw_hdr = psDnldContext->p_fw_hdr;
-
- fw_index = fw_index + (cur_fw_hdr->fw_hdr_len * PNDNLD_WORD_LEN);
if ( !pHwRef->device_info.fw_version )
{
@@ -2589,9 +3368,6 @@ phDnldNfc_Process_FW(
status = PHNFCSTVAL( CID_NFC_DNLD, NFCSTATUS_NOT_ALLOWED );
}
else if (( pHwRef->device_info.fw_version < cur_fw_hdr->fw_version )
-#ifdef NXP_FW_PATCH_VERIFY
- && (pHwRef->device_info.full_version[NXP_PATCH_VER_INDEX] < cur_fw_hdr->fw_patch )
-#endif
)
{
/* TODO: Firmware Version Check and upgrade*/
@@ -2611,22 +3387,87 @@ phDnldNfc_Process_FW(
DNLD_PRINT(" FW_DNLD: Already Updated .... \n");
status = ( CID_NFC_DNLD << BYTE_SIZE ) ;
}
+
+ return status;
+ }
+
+
+static
+NFCSTATUS
+phDnldNfc_Process_FW(
+ phDnldNfc_sContext_t *psDnldContext,
+ phHal_sHwReference_t *pHwRef
+#ifdef NXP_FW_PARAM
+ ,uint8_t *nxp_nfc_fw
+ ,uint32_t nxp_fw_len
+#endif
+ )
+{
+ NFCSTATUS status = NFCSTATUS_FAILED;
+ section_info_t *p_cur_sec = NULL;
+ static unsigned sec_type;
+ uint32_t fw_index = 0;
+#ifdef NXP_NFC_MULTIPLE_FW
+ phDnldNfc_sFwImageInfo_t *p_cur_fw = NULL;
+#endif /* #ifdef NXP_NFC_MULTIPLE_FW */
+ fw_data_hdr_t *cur_fw_hdr = NULL;
+ uint8_t sec_index = 0;
+ uint8_t i = 0;
+
+ psDnldContext->p_img_hdr = (img_data_hdr_t *) nxp_nfc_fw;
+
+#ifdef NXP_NFC_MULTIPLE_FW
+
+ /* TODO: Create a memory of pointers to store all the Firmwares */
+ if( (NXP_NFC_IMAG_FW_MAX > psDnldContext->p_img_hdr->no_of_fw_img)
+ && (0 != psDnldContext->p_img_hdr->no_of_fw_img)
+ )
+ {
+ ( void )phDnldNfc_Allocate_Resource((void **)&psDnldContext->p_img_info,
+ (psDnldContext->p_img_hdr->no_of_fw_img * sizeof(phDnldNfc_sFwImageInfo_t)));
+
+ if(NULL != psDnldContext->p_img_info)
+ {
+ p_cur_fw = psDnldContext->p_img_info;
+ }
}
+#endif /* #ifdef NXP_NFC_MULTIPLE_FW */
+
+ fw_index = sizeof (img_data_hdr_t);
+
+ for ( i=0; i < psDnldContext->p_img_hdr->no_of_fw_img; i++ )
+ {
+
+ psDnldContext->p_fw_hdr = (fw_data_hdr_t *) ( nxp_nfc_fw + fw_index );
+
+#ifdef NXP_NFC_MULTIPLE_FW
+ if(NULL != p_cur_fw)
+ {
+ ( p_cur_fw + i)->p_fw_hdr = psDnldContext->p_fw_hdr;
+ }
+#endif /* #ifdef NXP_NFC_MULTIPLE_FW */
+ cur_fw_hdr = psDnldContext->p_fw_hdr;
+
+ fw_index = fw_index + (cur_fw_hdr->fw_hdr_len * PNDNLD_WORD_LEN);
+
+ status = phDnldNfc_Check_FW( pHwRef, cur_fw_hdr);
+
+ }
+
if ( ( NFCSTATUS_SUCCESS == status )
#if defined (NXP_FW_INTEGRITY_VERIFY)
|| (NFCSTATUS_SUCCESS == PHNFCSTATUS(status) )
#endif /* !defined (NXP_FW_INTEGRITY_VERIFY) */
)
{
-
+ if( (BYTE_MASK > cur_fw_hdr->no_of_sections)
+ && (0 != cur_fw_hdr->no_of_sections)
+ )
+ {
(void) phDnldNfc_Allocate_Resource((void **)&psDnldContext->p_fw_sec,
(cur_fw_hdr->no_of_sections * sizeof(section_info_t)));
- if(NULL == psDnldContext->p_fw_sec)
- {
- status = PHNFCSTVAL(CID_NFC_DNLD,
- NFCSTATUS_INSUFFICIENT_RESOURCES);
- }
- else
+
+ if(NULL != psDnldContext->p_fw_sec)
{
DNLD_DEBUG(" FW_DNLD: FW Index : %x \n",
fw_index );
@@ -2655,7 +3496,7 @@ phDnldNfc_Process_FW(
sec_type = (unsigned int)p_cur_sec->p_sec_hdr->section_mem_type;
- if(TRUE == ((section_type_t *)(&sec_type))->trim_val )
+ if((sec_type & DNLD_TRIM_MASK))
{
p_cur_sec->p_trim_data = (uint8_t *)
(nxp_nfc_fw + fw_index + sizeof(section_hdr_t));
@@ -2665,25 +3506,42 @@ phDnldNfc_Process_FW(
p_cur_sec->p_trim_data = NULL;
}
+ if (0 == sec_index)
+ {
+ if ((sec_type & DNLD_SM_UNLOCK_MASK))
+ {
+ (void)phDnldNfc_Set_Seq(psDnldContext,
+ DNLD_SEQ_UNLOCK);
+ }
+ else
+ {
+ (void)phDnldNfc_Set_Seq(psDnldContext,
+ DNLD_SEQ_INIT);
+ }
+ }
p_cur_sec->section_read = FALSE;
p_cur_sec->section_offset = 0;
p_cur_sec->p_sec_data = ((uint8_t *) nxp_nfc_fw) + fw_index +
-#ifdef SECTION_HDR
(p_cur_sec->p_sec_hdr->section_hdr_len * PNDNLD_WORD_LEN);
-#else
- sizeof (section_hdr_t) ;
-#endif
fw_index = fw_index +
-#ifdef SECTION_HDR
(p_cur_sec->p_sec_hdr->section_hdr_len * PNDNLD_WORD_LEN)
-#else
- sizeof (section_hdr_t)
-#endif
+ p_cur_sec->p_sec_hdr->section_length;
+
+ if( 0 != p_cur_sec->p_sec_hdr->section_checksum )
+ {
+ DNLD_DEBUG(" FW_DNLD: Section checksum : %x \n",
+ p_cur_sec->p_sec_hdr->section_checksum );
+
+ p_cur_sec->p_sec_chksum = ( uint8_t *)(nxp_nfc_fw + fw_index);
+
+ fw_index = fw_index +
+ p_cur_sec->p_sec_hdr->section_checksum;
+ }
+
DNLD_DEBUG(" FW_DNLD: FW Index : %x \n", fw_index );
#if (NXP_FW_INTEGRITY_CHK >= 0x01)
@@ -2717,13 +3575,37 @@ phDnldNfc_Process_FW(
{
break;
}
- }
+
+ } /* End of Address Switch */
#endif /* #if (NXP_FW_INTEGRITY_CHK >= 0x01) */
+ } /* End of For Loop */
+ } /* End of the Null Check */
+ else
+ {
+ status = PHNFCSTVAL(CID_NFC_DNLD,
+ NFCSTATUS_INSUFFICIENT_RESOURCES);
+ }
}
+ else if (
+ (0 == cur_fw_hdr->no_of_sections)
+ && (PHDNLD_FW_PATCH_SEC == cur_fw_hdr->fw_patch)
+ )
+ {
+ psDnldContext->p_fw_raw = (uint8_t *)(nxp_nfc_fw + fw_index);
- DNLD_PRINT("*******************************************\n\n");
+ psDnldContext->raw_mode_upgrade = PHDNLD_COMPLETE_OPERATION;
+
+ (void)phDnldNfc_Set_Seq(psDnldContext,
+ DNLD_SEQ_RAW);
+ }
+ else
+ {
+ DNLD_PRINT("********* Empty Section and Firmware ******************\n\n");
}
+
+ DNLD_PRINT("*******************************************\n\n");
+
}
return status;
}
@@ -2758,45 +3640,7 @@ phDnldNfc_Run_Check(
fw_index = fw_index + (cur_fw_hdr->fw_hdr_len * PNDNLD_WORD_LEN);
- if ( !pHwRef->device_info.fw_version )
- {
- /* Override the Firmware Version Check and upgrade*/;
- DNLD_PRINT(" FW_DNLD_CHK: Forceful Upgrade of the Firmware .... Required \n");
- status = NFCSTATUS_SUCCESS;
- }
- else if ( (pHwRef->device_info.fw_version >> (BYTE_SIZE * 2))
- != ( cur_fw_hdr->fw_version >> (BYTE_SIZE * 2) ))
- {
- /* Check for the Compatible Romlib Version for the Hardware */
- DNLD_PRINT(" FW_DNLD: IC Hardware Version Mismatch.. \n");
- status = PHNFCSTVAL( CID_NFC_DNLD, NFCSTATUS_NOT_ALLOWED );
- }
- else if (( pHwRef->device_info.fw_version < cur_fw_hdr->fw_version )
-#ifdef NXP_FW_PATCH_VERIFY
- && (pHwRef->device_info.full_version[NXP_PATCH_VER_INDEX] < cur_fw_hdr->fw_patch )
-#endif
- )
- {
- /* TODO: Firmware Version Check and upgrade*/
- DNLD_PRINT(" FW_DNLD_CHK: Older Firmware. Upgrading to newer one.... \n");
- status = NFCSTATUS_SUCCESS;
- }
-#ifdef NXP_FW_CHK_LATEST
- else if (( pHwRef->device_info.fw_version > cur_fw_hdr->fw_version )
- )
- {
- DNLD_PRINT(" FW_DNLD: Newer than the Stored One .... \n");
- status = PHNFCSTVAL( CID_NFC_DNLD, NFCSTATUS_NOT_ALLOWED );
- }
-#endif /* NXP_FW_CHK_LATEST */
- else
- {
- DNLD_PRINT(" FW_DNLD_CHK: Already Updated .... \n");
- status = ( CID_NFC_DNLD << BYTE_SIZE ) ;
- }
- }
- if( NFCSTATUS_SUCCESS == status )
- {
+ status = phDnldNfc_Check_FW( pHwRef, cur_fw_hdr);
}
return status;
}
@@ -2807,26 +3651,39 @@ phDnldNfc_Run_Check(
STATIC
void
phDnldNfc_Abort (
- uint32_t abort_id,
- void *pContext
+ uint32_t abort_id
+#ifdef NFC_TIMER_CONTEXT
+ , void *dnld_cntxt
+#endif
)
{
phNfc_sCompletionInfo_t comp_info = {0,0,0};
- if ( ( NULL != gpphDnldContext)
- && (abort_id == gpphDnldContext->timer_id ))
+ phDnldNfc_sContext_t *p_dnld_context = NULL;
+
+#ifdef NFC_TIMER_CONTEXT
+ p_dnld_context = (phDnldNfc_sContext_t *)dnld_cntxt;
+#else
+ p_dnld_context = gpphDnldContext;
+#endif
+
+ if ( ( NULL != p_dnld_context)
+ && (abort_id == p_dnld_context->timer_id ))
{
pphNfcIF_Notification_CB_t p_upper_notify =
- gpphDnldContext->p_upper_notify;
+ p_dnld_context->p_upper_notify;
void *p_upper_context =
- gpphDnldContext->p_upper_context;
- phHal_sHwReference_t *pHwRef = gpphDnldContext->p_hw_ref;
+ p_dnld_context->p_upper_context;
+ phHal_sHwReference_t *pHwRef = p_dnld_context->p_hw_ref;
(void)phDal4Nfc_Unregister(
- gpphDnldContext->lower_interface.pcontext, pHwRef );
- phDnldNfc_Release_Lower(gpphDnldContext, pHwRef);
- phDnldNfc_Release_Resources(&gpphDnldContext);
+ p_dnld_context->lower_interface.pcontext, pHwRef );
+ phDnldNfc_Release_Lower(p_dnld_context, pHwRef);
+ phDnldNfc_Release_Resources(&p_dnld_context);
+#ifndef NFC_TIMER_CONTEXT
+ gpphDnldContext = p_dnld_context;
+#endif
/* Notify the Error/Success Scenario to the upper layer */
DNLD_DEBUG(" FW_DNLD: FW_DNLD Aborted with %x Timer Timeout \n",
@@ -2845,6 +3702,7 @@ NFCSTATUS
phDnldNfc_Upgrade (
phHal_sHwReference_t *pHwRef,
#ifdef NXP_FW_PARAM
+ uint8_t type,
uint8_t *nxp_nfc_fw,
uint32_t fw_length,
#endif
@@ -2868,16 +3726,15 @@ phDnldNfc_Upgrade (
else
{
DNLD_PRINT(" FW_DNLD: Starting the FW Upgrade Sequence .... \n");
- /* Create the memory for Download Mgmt Context */
- psDnldContext = (phDnldNfc_sContext_t *)
- phOsalNfc_GetMemory(sizeof(phDnldNfc_sContext_t));
+ (void)
+ phDnldNfc_Allocate_Resource((void **)
+ &psDnldContext,sizeof(phDnldNfc_sContext_t));
if(psDnldContext != NULL)
{
- (void ) memset((void *)psDnldContext,0,
- sizeof(phDnldNfc_sContext_t));
-
+#ifndef NFC_TIMER_CONTEXT
gpphDnldContext = psDnldContext;
+#endif
psDnldContext->p_hw_ref = pHwRef;
psDnldContext->timer_id = NXP_INVALID_TIMER_ID;
@@ -2911,7 +3768,7 @@ phDnldNfc_Upgrade (
status = phDnldNfc_Process_FW( psDnldContext, pHwRef
#ifdef NXP_FW_PARAM
- ,*nxp_nfc_fw /*, fw_length */
+ ,*nxp_nfc_fw , fw_length
#endif
);
@@ -2922,27 +3779,24 @@ phDnldNfc_Upgrade (
if (NFCSTATUS_PENDING == status)
{
DNLD_PRINT("\n FW_DNLD: Initial Reset .... \n");
- p_cur_sec = ((section_info_t *)
- (psDnldContext->p_fw_sec ));
- sec_type = (unsigned )
- (p_cur_sec->p_sec_hdr->section_mem_type);
- if(TRUE == ((section_type_t *)
- (&sec_type))->system_mem_unlock )
- {
- (void)phDnldNfc_Set_Seq(psDnldContext,
- DNLD_SEQ_UNLOCK);
- }
- else
- {
- (void)phDnldNfc_Set_Seq(psDnldContext,
- DNLD_SEQ_INIT);
- }
-#ifdef FW_DOWNLOAD_TIMER
+#if defined(FW_DOWNLOAD_TIMER)
+
psDnldContext->timer_id = phOsalNfc_Timer_Create( );
+
+#if (FW_DOWNLOAD_TIMER < 2)
phOsalNfc_Timer_Start( psDnldContext->timer_id,
- NXP_DNLD_COMPLETE_TIMEOUT, phDnldNfc_Abort, NULL );
+ NXP_DNLD_COMPLETE_TIMEOUT,
+ (ppCallBck_t) phDnldNfc_Abort
+#ifdef NFC_TIMER_CONTEXT
+ , (void *) psDnldContext
#endif
+ );
+
+#endif /* #if (FW_DOWNLOAD_TIMER < 2) */
+
+#endif /* #if defined(FW_DOWNLOAD_TIMER) */
+
}
}
else if (NFCSTATUS_SUCCESS == PHNFCSTATUS(status))
@@ -2954,23 +3808,33 @@ phDnldNfc_Upgrade (
*/
status = phDnldNfc_Send_Command( psDnldContext, pHwRef,
PHDNLD_CMD_RESET , NULL , 0 );
-
if (NFCSTATUS_PENDING == status)
{
DNLD_PRINT("\n FW_DNLD: Integrity Reset .... \n");
(void)phDnldNfc_Set_Seq(psDnldContext, DNLD_SEQ_COMPLETE);
status = PHNFCSTVAL( CID_NFC_DNLD,
NFCSTATUS_PENDING );
-#ifdef FW_DOWNLOAD_TIMER
+#if defined(FW_DOWNLOAD_TIMER)
psDnldContext->timer_id = phOsalNfc_Timer_Create( );
+#if (FW_DOWNLOAD_TIMER < 2)
phOsalNfc_Timer_Start( psDnldContext->timer_id,
- NXP_DNLD_COMPLETE_TIMEOUT, phDnldNfc_Abort, NULL );
+ NXP_DNLD_COMPLETE_TIMEOUT,
+ (ppCallBck_t) phDnldNfc_Abort
+#ifdef NFC_TIMER_CONTEXT
+ , (void *) psDnldContext
#endif
+ );
+
+#endif /* #if (FW_DOWNLOAD_TIMER < 2) */
+
+#endif /* #if defined(FW_DOWNLOAD_TIMER) */
}
#else
status = NFCSTATUS_SUCCESS;
-#endif
+
+#endif /* #if defined (NXP_FW_INTEGRITY_VERIFY) */
+
}
else
{
@@ -2981,9 +3845,12 @@ phDnldNfc_Upgrade (
if (NFCSTATUS_PENDING != PHNFCSTATUS(status))
{
(void)phDal4Nfc_Unregister(
- gpphDnldContext->lower_interface.pcontext, pHwRef);
- phDnldNfc_Release_Lower(gpphDnldContext, pHwRef);
- phDnldNfc_Release_Resources(&gpphDnldContext);
+ psDnldContext->lower_interface.pcontext, pHwRef);
+ phDnldNfc_Release_Lower(psDnldContext, pHwRef);
+ phDnldNfc_Release_Resources(&psDnldContext);
+#ifndef NFC_TIMER_CONTEXT
+ gpphDnldContext = psDnldContext;
+#endif
}
} /* End of Status Check for Memory */
else