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 + -
显示快捷键?