⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dloadarm.c

📁 在高通的手机平台下,一个下载手机.bin文件到手机的flash中的工具,包含PC端的程序代码和运行在基带处理器中的代码.
💻 C
📖 第 1 页 / 共 4 页
字号:
  being built dynamically.

PARAMETERS
  pkt     A pkt_buffer_type struct in which the packet will be built.
  val     The word to be added to the packet.

DEPENDENCIES
  START_BUILDING_PACKET must have been called on pkt before calling
  this macro.

RETURN VALUE
  None.

SIDE EFFECTS
  Each argument is evaluated twice within this macro.
  This macro is not an expression, not is it a single statement.  It
  must be called with a trailing semicolon.

===========================================================================*/

#define  ADD_WORD_TO_PACKET(pkt,val)         \
  /*lint -e778 val or (val >> 8) may evaluate to zero. */                    \
  add_byte_to_packet(&pkt, (const byte)((val >> 8) & 0xFF)); /* high byte */ \
  add_byte_to_packet(&pkt, (const byte)(val & 0xFF))         /* low  byte */ \
  /*lint +e778 */


/*===========================================================================

MACRO ADD_CRC_TO_PACKET

DESCRIPTION
  This macro adds a word (LEAST significant byte first) to a packet
  being built dynamically.  This should only be used for the CRC,
  since other words are supposed to be sent most significant byte
  first.

PARAMETERS
  pkt     A pkt_buffer_type struct in which the packet will be built.
  val     The word to be added to the packet.

DEPENDENCIES
  START_BUILDING_PACKET must have been called on pkt before calling
  this macro.

RETURN VALUE
  None.

SIDE EFFECTS
  Each argument is evaluated twice within this macro.
  This macro is not an expression, not is it a single statement.  It
  must be called with a trailing semicolon.

===========================================================================*/

#define  ADD_CRC_TO_PACKET(pkt,val)         \
  add_byte_to_packet(&pkt, (const byte)(val & 0xFF));        /* low  byte */ \
  add_byte_to_packet(&pkt, (const byte)((val >> 8) & 0xFF))  /* high byte */


/*===========================================================================

MACRO ADD_STUFF_TO_PACKET

DESCRIPTION
  This macro adds an arbitrary buffer of bytes to a packet being built
  dynamically.

PARAMETERS
  pkt     A pkt_buffer_type struct in which the packet will be built.
  data    A pointer to byte (or array of bytes) containing the data to be added
  len     The number of bytes to be added to the packet.

DEPENDENCIES
  START_BUILDING_PACKET must have been called on pkt before calling
  this macro.

RETURN VALUE
  None.

SIDE EFFECTS
  None.

===========================================================================*/

#define  ADD_STUFF_TO_PACKET(pkt,data,len)   \
               /*lint -e717 Yes, this is a do...while(0). */\
               do {                                         \
               int   stuff_i;                               \
                                                            \
               for (stuff_i=0; stuff_i < len; stuff_i++)    \
                 {                                          \
                 add_byte_to_packet(&pkt, data[stuff_i]);   \
                 }                                          \
               } while (0)                                  \
               /*lint +e717 */


/*===========================================================================

MACRO ADD_STRING_TO_PACKET

DESCRIPTION
  This macro adds a text string (null terminated) to a packet being built
  dynamically.  If the string is not null terminated or is longer than 20
  characters, only the first 20 characters are added to the packet.

PARAMETERS
  pkt     A pkt_buffer_type struct in which the packet will be built.
  str     The string to be added to the packet.

DEPENDENCIES
  START_BUILDING_PACKET must have been called on pkt before calling
  this macro.

RETURN VALUE
  None.

SIDE EFFECTS
  None.

===========================================================================*/

#define  ADD_STRING_TO_PACKET(pkt,str)       \
               /*lint -e717 Yes, this is a do...while(0). */ \
               do {                                          \
               byte count = 0;                               \
               byte stopping_point;                          \
                                                             \
               stopping_point = dload_str_len(str);          \
               while (count < stopping_point)                \
                 add_byte_to_packet(&pkt, str[count++]);     \
               } while (0)                                   \
               /*lint -e717 */


/*===========================================================================

MACRO FINISH_BUILDING_PACKET

DESCRIPTION
  This macro completes the process of building a packet dynamically.
  It just calls a function to do the work.

PARAMETERS
  pkt     A pkt_buffer_type struct in which the packet has been built.

DEPENDENCIES
  START_BUILDING_PACKET must have been called on pkt before calling
  this macro.

RETURN VALUE
  None.

SIDE EFFECTS
  None.

===========================================================================*/

#define  FINISH_BUILDING_PACKET(pkt)         \
               finish_building_packet(&pkt)


/*-------------------------------------------------------------------------*/

/* Mask for CRC-16 polynomial:
**
**      x^16 + x^12 + x^5 + 1
**
** This is more commonly referred to as CCITT-16.
** Note:  the x^16 tap is left off, it's implicit.
*/
#define CRC_16_L_POLYNOMIAL     0x8408

/* Seed value for CRC register.  The all ones seed is part of CCITT-16, as
** well as allows detection of an entire data stream of zeroes.
*/
#define CRC_16_L_SEED           0xFFFF

/* Residual CRC value to compare against return value of a CRC_16_L_STEP().
** Use CRC_16_L_STEP() to calculate a 16 bit CRC, complement the result,
** and append it to the buffer.  When CRC_16_L_STEP() is applied to the
** unchanged entire buffer, and complemented, it returns CRC_16_L_OK.
** That is, it returns CRC_16_L_OK_NEG.
*/
#define CRC_16_L_OK             0x0F47
#define CRC_16_L_OK_NEG         0xF0B8

/*===========================================================================

MACRO CRC_16_L_STEP

DESCRIPTION
  This macro calculates one byte step of an LSB-first 16-bit CRC.
  It can be used to produce a CRC and to check a CRC.

PARAMETERS
  xx_crc  Current value of the CRC calculation, 16-bits
  xx_c    New byte to figure into the CRC, 8-bits

DEPENDENCIES
  None

RETURN VALUE
  The new CRC value, 16-bits.  If this macro is being used to check a
  CRC, and is run over a range of bytes, the return value will be equal
  to CRC_16_L_OK_NEG if the CRC checks correctly according to the DMSS
  Async Download Protocol Spec.

SIDE EFFECTS
  xx_crc is evaluated twice within this macro.

===========================================================================*/

//extern word crc_16_l_table[];       /* Extern for macro (global) */
extern const word crc_16_l_table[]; 

#define CRC_16_L_STEP(xx_crc,xx_c) \
  (((xx_crc) >> 8) ^ crc_16_l_table[((xx_crc) ^ (xx_c)) & 0x00ff])



/*===========================================================================

MACRO CRC_16_L_STEP

DESCRIPTION
  This macro calculates one byte step of an LSB-first 16-bit CRC.
  It can be used to produce a CRC and to check a CRC.

PARAMETERS
  xx_crc  Current value of the CRC calculation, 16-bits
  xx_c    New byte to figure into the CRC, 8-bits

DEPENDENCIES
  None

RETURN VALUE
  The new CRC value, 16-bits.  If this macro is being used to check a
  CRC, and is run over a range of bytes, the return value will be equal
  to CRC_16_L_OK_NEG if the CRC checks correctly according to the DMSS
  Async Download Protocol Spec.

SIDE EFFECTS
  xx_crc is evaluated twice within this macro.

===========================================================================*/
/*
const word crc_16_l_table[ 256 ] = {
  0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
  0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
  0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
  0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
  0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
  0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
  0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
  0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
  0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
  0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
  0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
  0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
  0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
  0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
  0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
  0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
  0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
  0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
  0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
  0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
  0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
  0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
  0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
  0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
  0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
  0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
  0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
  0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
  0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
  0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
  0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
  0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
};
*/
#define CRC_16_L_STEP(xx_crc,xx_c) \
  (((xx_crc) >> 8) ^ crc_16_l_table[((xx_crc) ^ (xx_c)) & 0x00ff])


/*===========================================================================

FUNCTION add_byte_to_packet

DESCRIPTION
  This function adds a single byte to a packet that is being built
  dynamically.  It takes care of byte stuffing and checks for buffer
  overflow.

  This function is a helper function for the packet building macros
  and should not be called directly.

DEPENDENCIES
  The START_BUILDING_PACKET() macro should have been called on the
  packet buffer before calling this function.

RETURN VALUE
  None.

SIDE EFFECTS
  None.

===========================================================================*/

static void add_byte_to_packet
(
  pkt_buffer_type  *pkt,
    /* Structure containing the packet being built */

  const byte        val
    /* The byte to be added to the packet */
)
{

  if (pkt->broken != FALSE)   /* If the packet is broken already, */
    {
    return;                  /* Don't do anything. */
    }

           /* Check if the byte needs escaping for transparency. */
  if (val == ASYNC_HDLC_FLAG || val == ASYNC_HDLC_ESC)
    {
                              /* Check for an impending overflow. */
    if (pkt->length+2+ROOM_FOR_CRC+ROOM_FOR_FLAG >= MAX_RESPONSE_LEN)
      {
      pkt->broken = TRUE;     /* Overflow.  Mark this packet broken. */
      return;
      }

           /* No overflow.  Escape the byte into the buffer. */
    pkt->buf[pkt->length++] = ASYNC_HDLC_ESC;
    pkt->buf[pkt->length++] = val ^ (byte)ASYNC_HDLC_ESC_MASK;
    }

  else     /* Byte doesn't need escaping. */
    {
                              /* Check for an impending overflow. */
    if (pkt->length+1+ROOM_FOR_CRC+ROOM_FOR_FLAG >= MAX_RESPONSE_LEN)
      {
      pkt->broken = TRUE;     /* Overflow.  Mark this packet broken. */
      return;
      }

           /* No overflow.  Place the byte into the buffer. */
    pkt->buf[pkt->length++] = val;
    }

}/* add_byte_to_packet() */


/*===========================================================================

FUNCTION finish_building_packet

DESCRIPTION
  This function completes the process of building a packet dynamically.
  If all is well, it adds the CRC and a trailing flag to the buffer.
  If an error has been encountered in building the packet, it substitutes
  a NAK packet for whatever has been built.

  This function is a helper function for the packet building macros
  and should not be called directly.

DEPENDENCIES
  The START_BUILDING_PACKET() macro should have been called on the
  packet buffer before calling this function.

RETURN VALUE
  None.

SIDE EFFECTS
  None.

===========================================================================*/

static void finish_building_packet
(
  pkt_buffer_type  *pkt
    /* Structure containing the packet being built */
)
{
  word  crc;
    /* Cyclic Redundancy Check for the packet we've built. */

  word  i;
    /* Index for scanning through the packet, computing the CRC. */

/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/

  if (pkt->broken == FALSE)
    {
    /* Compute the CRC for all the bytes in the packet. */
    crc = CRC_16_L_SEED;
    for (i=0; i < pkt->length; i++)
       {
       crc = CRC_16_L_STEP(crc, (word) pkt->buf[i]);
       }
    crc ^= CRC_16_L_SEED;

    ADD_CRC_TO_PACKET(*pkt,crc);             /* Add the CRC to the packet */

    pkt->buf[pkt->length] = ASYNC_HDLC_FLAG;  /* Add a flag to the packet.*/
                                              /* This can't use the regular
                                                 add_byte_to_packet() function
                                                 because it's a flag. */
    }
  else
    {
    (void) memcpy((void*)pkt->buf, rsp_nak_invalid_len,
             sizeof(rsp_nak_invalid_len));    /* Substitute a NAK */
    }

}/* finish_building_packet() */


/*===========================================================================

FUNCTION transmit_packet

DESCRIPTION
  This function transmits a packet response through the UART.

DEPENDENCIES
  The packet must end with a flag.

RETURN VALUE
  None.

SIDE EFFECTS
  The watchdog may be reset.

===========================================================================*/

static void transmit_packet
(
  pkt_buffer_type  *pkt
    /* The packet to be transmitted. */
)
{
  const byte *data = (byte*) pkt->buf;
    /* Pointer into the packet being transmitted */

/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/

  uart_transmit_byte(ASYNC_HDLC_FLAG);      /* Supply the leading flag  */

  do
    {
    uart_transmit_byte(*data);        /* Transmit bytes from the buffer */
    }
  while (*data++ != ASYNC_HDLC_FLAG); /* Until we've transmitted a flag */

} /* transmit_packet() */


/*===========================================================================

FUNCTION transmit_response

DESCRIPTION
  This function transmits a packet response through the UART.
  This function supplies the entire packet, based on the type
  code passed in.

DEPENDENCIES
  Uses the response_table[] to find the packet to transmit.  This
  packet must be terminated by a flag.

RETURN VALUE
  None.

SIDE EFFECTS
  The watchdog may be reset.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -