dl_uart.c

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

C
491
字号
  (void) MSMU_OUT(UART_IMR, 0);                  /* Mask all interrupts off */

  /* Receive watermark at zero.  This means an interrupt would be generated 
   * whenever any (more than zero) characters are in the Rx FIFO.  Since we 
   * don't use Rx interrupts, this doesn't really matter.
   */
  (void) MSMU_RXWAT_OUT(0);
  
  /* Transmit watermark.  We DO use this, to determine if there is
   * room for one more character in the Tx FIFO.
   */
  (void) MSMU_TXWAT_OUT(UART_TXWAT_VAL);  
  
  /* Do not enable hardware flow control.  It works, but it causes
   * more trouble than it's worth with improperly-wired cables.
   * There's really no need for it anyway, since the main data flow
   * is from the host to the phone, and the phone (having nothing
   * better to do than service the UART) will always keep up.
   */

  (void) MSMU_MR1_OUT(0);
  
  (void) MSMU_OUT(UART_MR2, UART_MR2_8BPC | UART_MR2_1SB); /* 8N1 */

switch(baud_rate)
{
    case UART_1152K_BPS:
        (void) MSMU_OUT(UART_CSR, UART_CSR_1152K_BPS); /* 115,200 baud rate   */
        break;
    case UART_2304K_BPS:
        (void) MSMU_OUT(UART_CSR, UART_CSR_2304K_BPS); /* 230,400 baud rate   */
        break;
    case UART_4608K_BPS:
        (void) MSMU_OUT(UART_CSR, UART_CSR_4608K_BPS); /* 460,800 baud rate   */
        break;
    default:
        (void) MSMU_OUT(UART_CSR, UART_CSR_1152K_BPS); /* 115,200 baud rate   */
 }



  (void) MSMU_OUT(UART_CR, UART_CR_RESET_ERR);   /* Reset error status     */
  (void) MSMU_OUT(UART_CR, UART_CR_RESET_RX);    /* Reset the receiver     */
  (void) MSMU_OUT(UART_CR, UART_CR_RESET_RX);    /* Reset the receiver     */
  (void) MSMU_OUT(UART_CR, UART_CR_RESET_TX);    /* Reset the transmitter  */
  (void) MSMU_OUT(UART_CR, UART_CR_RESET_TX);    /* Reset the transmitter  */
  (void) MSMU_OUT(UART_CR, UART_CR_RX_ENA);      /* Enable the receiver    */
  (void) MSMU_OUT(UART_CR, UART_CR_TX_ENA);      /* Enable the transmitter */

   /* Wait while the UART's reciever drains.  After resetting the UART, we
    * may have a couple of spurrious characters in the RX FIFO.  This can
    * happen especially when the phone is not plugged into a DIP, thus 
    * causing the UART to re-recognize the start of break condtion.
    */
   while ( ( inp(UART_SR) & UART_SR_RXRDY ) != 0)
      {
    chr = inp(UART_RFIFO);    /* Get the received character */  
        BOOTHW_KICK_WATCHDOG();    /* Don't let the watchdog expire while we wait  */
      }
} /* dload_uart_init() */



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

FUNCTION dload_uart_poll

DESCRIPTION
  This function polls the UART for the presence of recieved data

DEPENDENCIES
  The UART must be initialized and enabled, or else this routine will
  wait forever.

RETURN VALUE
  If the RXRDY bit goes high (indicating the presence of data), we return
  the entire status register.  If timeout_enabled is true, we only wait for
  a few seconds.  Otherwise, we will wait forever for data to arrive

SIDE EFFECTS
  The watchdog timer will be kicked _very_ often.

===========================================================================*/
int dload_uart_poll(boolean timeout_enabled)
{
  int status;
  int countdown;

  /* if we're going to have a timeout */
  if (timeout_enabled)
    { 
      /* only loop a limited number of times */
      for (countdown = 1000000; countdown > 0; countdown--)
    {
      /* for each loop, get the status, and return it if data is present */
      status = inp(UART_SR);
      if ( (status & UART_SR_RXRDY) != 0)
        return status;

      /* kick the watchdog periodically */
      BOOTHW_KICK_WATCHDOG();
    }
      return UART_TIMEOUT;
    }
  else
    /* loop forever waiting for data */
    for (;;)
      {
    /* for each loop, get the status, and return it if data is present */
    status = inp(UART_SR);
    if ( (status & UART_SR_RXRDY) != 0)
      return status;

    /* kick the watchdog periodically */
    BOOTHW_KICK_WATCHDOG();
      }
} /* dload_uart_poll() */


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

FUNCTION uart_receive_byte

DESCRIPTION
  This function receives a single byte from the UART by polling.

DEPENDENCIES
  The UART must be initialized and enabled, or else this routine will
  wait forever.

RETURN VALUE
  If a character is received without error, returns the value of the
  character received.  If an error occurs, returns UART_RX_ERR.  If a
  timeout occurs, returns UART_TIMEOUT.

SIDE EFFECTS

===========================================================================*/
int uart_receive_byte(void)
{
  int   status;
    /* Return value from the UART's status register */

  int   chr;
    /* The character received from the UART */

  static boolean init_boot = TRUE;
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/

  /* poll the UART to receive a character if it is the initial 
   * communication with the PST we need to enable a timeout of 3 seconds.
   * otherwise, simply poll the UART indefinitely 
   */
  if (init_boot)
  {
    status = dload_uart_poll(TIMEOUT_ENABLED);
  }
  else
  {
    status = dload_uart_poll(TIMEOUT_DISABLED);
  }
      
  /* a timeout has occurred, return error */
  if ( (status == UART_TIMEOUT) && init_boot)
    return UART_TIMEOUT;
  
  /* There are three types of errors we can detect here:  Parity/Framing,
   * Break, and Overrun.  For a overrun, we just clear the error.  For 
   * parity/framing errors, we throw away that character.  For a break, we
   * ignore it.  We basically ignore conditions we can't do anything about.
   */
  if ((status & UART_SR_BREAK_RXD) != 0)
    {
      chr = inp(UART_RFIFO);           
      return UART_RX_ERR;
    }

  /* Check for an overrun error -- if one occurs, there isn't anything
   * we can do about it.  So, we'll just clear the error condition.  Since
   * this is character mode, the only other error we could be clearing is 
   * the hunt character, which we should never get.
   */
  /*  if ((status & UART_SR_OVR_ERR) != 0)
    (void) MSMU_OUT(UART_CR, UART_CR_RESET_ERR);*/

  /* Check for parity framing error -- if one occurs, discard the character
   * and return an error.  We can't trust that this character is valid.  It
   * might even be because of a break, so we leave init_boot true (or it's
   * current state, at least).
   */
  if ((status & UART_SR_PF_ERR) != 0)
    {
      chr = inp(UART_RFIFO);           
      return UART_RX_ERR;
    }

  /* Get the received character */
  chr = inp(UART_RFIFO);           
  init_boot = FALSE;
  return chr;                 /* All OK, return the received character */
} /* uart_receive_byte() */

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

FUNCTION uart_transmit_byte

DESCRIPTION
  This function transmits a single byte through the UART.

DEPENDENCIES
  The UART transmitter must be initialized and enabled, or this routine
  will wait forever.

RETURN VALUE
  None.

SIDE EFFECTS
  The watchdog may be reset.

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

void uart_transmit_byte
(
  byte  chr
    /* Character to be transmitted */
)

{
  
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  
  /* Wait until the transmit FIFO is not too full */
  while ((inp(UART_ISR) & UART_ISR_TXLEV) == 0)
  {
    /* Don't let the watchdog expire while we wait */
    BOOTHW_KICK_WATCHDOG();
  }

  /* Put the byte into the Tx FIFO  */
  (void) MSMU_OUT(UART_TFIFO, (int) chr);    

} /* uart_transmit_byte() */

⌨️ 快捷键说明

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