dl_proc.c

来自「在高通的手机平台下,一个下载手机.bin文件到手机的flash中的工具,包含PC」· C语言 代码 · 共 1,215 行 · 第 1/3 页

C
1,215
字号
  mask  Mask of bits in the port to write
  val   Value to write to the masked bits in the port

DEPENDENCIES
  If the port needs to be tri-stated to allow output, it must be
  tri-stated before the output will be effected by this macro call.

RETURN VALUE
  None

SIDE EFFECTS
  None

===========================================================================*/
#define BIO_OUT(io, mask, val) \
  bio_gpio[io].out_buf = (bio_gpio[io].out_buf & ~(mask)) | ((mask) & (val)); \
  outpw(bio_gpio[io].out_addr, bio_gpio[io].out_buf);


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

MACRO BIO_TRISTATE

DESCRIPTION
  This macro tri-states specified bits in a port, qualified by a specified
  mask, of a specified port.  Only the bits corresponding to the mask are
  actually affected; other bits retain their previous values.  To do this,
  an image is maintained of the previous value written to the port which is
  combined with the new value prior to writing.  Writing a bit to 1 enables
  it as an output, writing a 0 enables it as an input.

PARAMETERS
  io    Basic I/O port defined by this header
  mask  Mask of bits in the port to tri-state enable
  val   Value to write to the masked bits in the port to tri-state enable

DEPENDENCIES
  None

RETURN VALUE
  None

SIDE EFFECTS
  None

===========================================================================*/
#define BIO_TRISTATE(io, mask, val) \
  bio_gpio[io].ts_buf = (bio_gpio[io].ts_buf & ~(mask)) | ((mask) & (val)); \
  outpw(bio_gpio[io].tsen_addr, bio_gpio[io].ts_buf); \

/* Enable/Disable a GPIO as an output.  GPIO's can always be read as inputs.
*/
#define BIO_OUTPUT_ENA_V    0xffff


#define GPIO_INT_OUT_0_WH                             0x03000660
#define GPIO_INT_OUT_0_WH_MASK                            0xffff
#define GPIO_INT_OUT_0_WH__GPIO_INT_15_0_MASK             0xffff
#define GPIO_INT_OUT_1_WH                             0x03000664
#define GPIO_INT_OUT_1_WH_MASK                            0xffff
#define GPIO_INT_OUT_1_WH__GPIO_INT_31_16_MASK            0xffff
#define GPIO_INT_OUT_2_WH                             0x03000668
#define GPIO_INT_OUT_2_WH_MASK                            0xffff
#define GPIO_INT_OUT_2_WH__GPIO_INT_47_32_MASK            0xffff
#define GPIO_INT_OUT_3_WB                             0x0300066c
#define GPIO_INT_OUT_3_WB_MASK                               0x7
#define GPIO_INT_OUT_3_WB__GPIO_INT_50_48_MASK               0x7
#define GPIO_INT_IN_0_RH                              0x03000660
#define GPIO_INT_IN_0_RH_MASK                             0xffff
#define GPIO_INT_IN_0_RH__GPIO_INT_15_0_MASK              0xffff
#define GPIO_INT_IN_1_RH                              0x03000664
#define GPIO_INT_IN_1_RH_MASK                             0xffff
#define GPIO_INT_IN_1_RH__GPIO_INT_31_16_MASK             0xffff
#define GPIO_INT_IN_2_RH                              0x03000668
#define GPIO_INT_IN_2_RH_MASK                             0xffff
#define GPIO_INT_IN_2_RH__GPIO_INT_47_32_MASK             0xffff
#define GPIO_INT_IN_3_RB                              0x0300066c
#define GPIO_INT_IN_3_RB_MASK                                0x7
#define GPIO_INT_IN_3_RB__GPIO_INT_50_48_MASK             0xffff
#define GPIO_INT_TSEN_0_WH                            0x03000670
#define GPIO_INT_TSEN_0_WH_MASK                           0xffff
#define GPIO_INT_TSEN_0_WH__GPIO_INT_15_0_MASK            0xffff
#define GPIO_INT_TSEN_1_WH                            0x03000674
#define GPIO_INT_TSEN_1_WH_MASK                           0xffff
#define GPIO_INT_TSEN_1_WH__GPIO_INT_31_16_MASK           0xffff
#define GPIO_INT_TSEN_2_WH                            0x03000678
#define GPIO_INT_TSEN_2_WH_MASK                           0xffff
#define GPIO_INT_TSEN_2_WH__GPIO_INT_47_32_MASK           0xffff
#define GPIO_INT_TSEN_3_WB                            0x0300067c
#define GPIO_INT_TSEN_3_WB_MASK                              0x7
#define GPIO_INT_TSEN_3_WB__GPIO_INT_50_48_MASK              0x7

#define KEYSENSE_RD_RB                                0x03000670
#define DMOD_KEY_READ_IN      KEYSENSE_RD_RB

/* GPIO types. Use these names to define registers in bio?.h files. */
typedef enum {
  GPIO_REG_0,           /* Formerly ENC_GPIO_0, ENC_GPIO_1, DMOD_GPIO_INT  */
  GPIO_REG_1,           /* Formerly DEC_GPIO_0, DEC_GPIO_1 */
  GPIO_REG_2,           /* Formerly DMOD_GPIO */
  GPIO_REG_3,           /* New in MSM6000 */
  DMOD_KEY_READ,        /* GPIO keysense read register */
  NUM_GPIO,             /* # GPIOs registers in enum */
  ENC_GPIO_0    = 0,
  ENC_GPIO_1    = 0,
  DMOD_GPIO_INT = 0,
  DEC_GPIO_0    = 1,
  DEC_GPIO_1    = 1,
  DMOD_GPIO     = 2
} bio_gpio_type;

/* --------------------------------------------------------------------------
   GPIO port addresses and shadow buffers
-------------------------------------------------------------------------- */
#define BIO_GPIO_44_REG       GPIO_REG_2  
#define BIO_GPIO_44_M         0x1000  /* GPIO 44: None                     */
#define BIO_GPIO_44_HI_V      0x1000  /*  */
#define BIO_GPIO_44_LO_V      0x0000

#define BIO_GPIO_46_REG       GPIO_REG_2  
#define BIO_GPIO_46_M         0x4000  /* GPIO 46: None                     */
#define BIO_GPIO_46_HI_V      0x4000  /* */
#define BIO_GPIO_46_LO_V      0x0000  /* */

#define BIO_GPIO_47_REG       GPIO_REG_2  
#define BIO_GPIO_47_M         0x8000  /* GPIO 47: None                     */
#define BIO_GPIO_47_HI_V      0x8000  /* */
#define BIO_GPIO_47_LO_V      0x0000  /* */
 
#define BIO_PS_HOLD_REG       GPIO_REG_1
#define BIO_PS_HOLD_M         0x0002  /* GPIO 17: Power supply hold ctrl   */
#define BIO_PS_HOLD_ON_V      0x0002
#define BIO_PS_HOLD_OFF_V     0x0000

#define BIO_GPIO46_TRISTATE_INIT_VAL    BIO_PS_HOLD_M

#define PS_HOLD_GPIO_R GPIO_INT_OUT_1_WH         //GPIO output register
#define PS_HOLD_TSEN_R GPIO_INT_TSEN_1_WH        //GPIO tri-state enable register

#define PS_HOLD_BIT_V               0x0002          //GPIO Bit mask
#define PS_HOLD_OFF_V               0x0000          //GPIO PS_HOLD "off" value

/* --------------------------------------------------------------------------
   Determine Initial GPIO Output values
-------------------------------------------------------------------------- */
#define BIO_GPIO46_OUTPUT_INIT_VAL    BIO_PS_HOLD_ON_V

#define BIO_GPIO_REG_2_TRISTATE_INIT_VAL             \
                     BIO_GPIO46_TRISTATE_INIT_VAL 


#define BIO_GPIO_REG_2_OUTPUT_INIT_VAL             \
                     BIO_GPIO46_OUTPUT_INIT_VAL 


bio_gpio_info_type  bio_gpio[NUM_GPIO] = {
  { GPIO_INT_OUT_0_WH, GPIO_INT_IN_0_RH, GPIO_INT_TSEN_0_WH, 0, 0 },
  { GPIO_INT_OUT_1_WH, GPIO_INT_IN_1_RH, GPIO_INT_TSEN_1_WH,
                                  BIO_PS_HOLD_ON_V, BIO_PS_HOLD_M },
  { GPIO_INT_OUT_2_WH, GPIO_INT_IN_2_RH, GPIO_INT_TSEN_2_WH, 0, 0 },
  { GPIO_INT_OUT_3_WB, GPIO_INT_IN_3_RB, GPIO_INT_TSEN_3_WB, 0, 0 },
  { 0, DMOD_KEY_READ_IN, 0, 0, 0 }
};



typedef enum {
  Blue=0,  
  Green,  
  Red,  
  Black  
} color_state_type;

byte pkt_buf[MAX_PACKET_LEN];

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

  FUNCTION  disp_state()

  DESCRIPTION
    This function indicate the state of uart download program.

  PARAMETERS
    None.

  DEPENDENCIES
    None.
    
  RETURN VALUE
    None.

  SIDE EFFECTS
    None.

===========================================================================*/
void
disp_state(color_state_type state)
{

  BIO_TRISTATE( BIO_GPIO_44_REG, BIO_GPIO_44_M, BIO_OUTPUT_ENA_V);
  BIO_TRISTATE( BIO_GPIO_46_REG, BIO_GPIO_46_M, BIO_OUTPUT_ENA_V);
  BIO_TRISTATE( BIO_GPIO_47_REG, BIO_GPIO_47_M, BIO_OUTPUT_ENA_V);
  switch(state)
  {
    case Blue:
      BIO_OUT( BIO_GPIO_44_REG, BIO_GPIO_44_M, BIO_GPIO_44_HI_V);
      BIO_OUT( BIO_GPIO_46_REG, BIO_GPIO_46_M, BIO_GPIO_46_LO_V);
      BIO_OUT( BIO_GPIO_47_REG, BIO_GPIO_47_M, BIO_GPIO_47_LO_V);
    break;
    case Green:  
      BIO_OUT( BIO_GPIO_44_REG, BIO_GPIO_44_M, BIO_GPIO_44_LO_V);
      BIO_OUT( BIO_GPIO_46_REG, BIO_GPIO_46_M, BIO_GPIO_46_HI_V);
      BIO_OUT( BIO_GPIO_47_REG, BIO_GPIO_47_M, BIO_GPIO_47_LO_V);
      break;
    case Red:  
      BIO_OUT( BIO_GPIO_44_REG, BIO_GPIO_44_M, BIO_GPIO_44_LO_V);
      BIO_OUT( BIO_GPIO_46_REG, BIO_GPIO_46_M, BIO_GPIO_46_LO_V);
      BIO_OUT( BIO_GPIO_47_REG, BIO_GPIO_47_M, BIO_GPIO_47_HI_V);
      break;

    case Black:
      BIO_OUT( BIO_GPIO_44_REG, BIO_GPIO_44_M, BIO_GPIO_44_LO_V);
      BIO_OUT( BIO_GPIO_46_REG, BIO_GPIO_46_M, BIO_GPIO_46_LO_V);
      BIO_OUT( BIO_GPIO_47_REG, BIO_GPIO_47_M, BIO_GPIO_47_LO_V);
    break;

      default:
      BIO_OUT( BIO_GPIO_44_REG, BIO_GPIO_44_M, BIO_GPIO_44_LO_V);
      BIO_OUT( BIO_GPIO_46_REG, BIO_GPIO_46_M, BIO_GPIO_46_LO_V);
      BIO_OUT( BIO_GPIO_47_REG, BIO_GPIO_47_M, BIO_GPIO_47_LO_V);
      break;
      
   }
  
}

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

  FUNCTION boot_hw_powerdown()

  DESCRIPTION
    This function clears the PS hold bits to allow phone power off.

  PARAMETERS
    None.

  DEPENDENCIES
    None.
    
  RETURN VALUE
    None.

  SIDE EFFECTS
    None.

===========================================================================*/
void
boot_hw_powerdown()
{

  /* Now clear the GPIO that's attached to the power supply hold-on
     control line.  This allows the phone to power off.  Unfortunately
     this line is in different places for various phone designs.  We
     just clear them all, ignoring any side effects. */
   outpw( PS_HOLD_TSEN_R, PS_HOLD_BIT_V );
   outpw( PS_HOLD_GPIO_R, PS_HOLD_OFF_V );

  for (;;)
     {
      /*---------------------------------------------------------------------
      ** Do nothing until the phone powers off. Make certain the watchdog
      ** does not expire and reset us before the power off.
      **--------------------------------------------------------------------*/
      BOOTHW_KICK_WATCHDOG();

     }
}

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

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.

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

static void transmit_response
(
response_code_type rsp
/* Type of response to transmit */
)

{
	const byte *pkt;
	/* Pointer into the packet being transmitted */

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

	pkt = response_table[rsp];			   /* Find the packet to transmit */

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

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

} /* transmit_response() */


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

FUNCTION rcv_packet

DESCRIPTION
  This function receives a complete packet using the generic UART
  service uart_receive_byte.  It takes care of the async-HDLC state
  machine, enforces a minimum packet length of 1 byte plus CRC, and
  checks the CRC on the fly.

DEPENDENCIES
  Uses the crc table.

RETURN VALUE
  Once a good packet is received, returns its length including
  but not including flags or byte stuffing escapes.

SIDE EFFECTS
  If a NAK-able packet error is detected, this function generates a
  suitable NAK response and does not return until a good packet is
  received.

  The watchdog is reset.
===========================================================================*/

static word rcv_packet
(
  byte *buf
    /* Pointer to the packet buffer for receiving the packet */
)

{

  enum
    {
    HDLC_HUNT_FOR_FLAG,     /* Waiting for a flag to start a packet       */
    HDLC_GOT_FLAG,          /* Have a flag, expecting the packet to start */
    HDLC_GATHER,            /* In the middle of a packet                  */
    HDLC_PACKET_RCVD        /* Now have received a complete packet        */
    } state;
    /* State variable for decoding async HDLC */

  int   chr;
    /* Current character being received */

  word  len;
    /* Length of packet collected so far */

  word  crc=0;
    /* Cyclic Redundancy Check, computed as we go. */

    /*lint -esym(644,len,crc) */
    /* Lint can't tell that the state machine guarantees that
       we initialize len and crc before use */

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

  /* Look at characters and try to find a valid async-HDLC packet of
     length at least MIN_PACKET_LEN with a valid CRC.
     Keep looking until we find one. */
  len=0;
  for (state = HDLC_HUNT_FOR_FLAG; state != HDLC_PACKET_RCVD; /* nil */)
    {
    BOOTHW_KICK_WATCHDOG();                 /* Don't let the watchdog expire */

    chr = uart_receive_byte();       /* Get next character (wait for it) */

    if (chr == UART_RX_ERR)          /* If it's an error ... */
      {
      state = HDLC_HUNT_FOR_FLAG;             /* Start over. */
      continue;
      }

    /* initial communication timed out */
    if (chr == UART_TIMEOUT)
      {
        boot_hw_powerdown();
      }

⌨️ 快捷键说明

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