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

📄 uart.cpp

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

FUNCTION rcv_packet

DESCRIPTION
  This function receives a complete packet. 
  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.
===========================================================================*/

int
CUART::RcvPacket (BYTE *buf, BOOL bCheckHeadFlag, BYTE cWait)
{

  enum e_state
    {
    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 variable for decoding async HDLC */

  enum e_state state, eStartState;

  int   chr;
    /* Current character being received */

  WORD  len=0;
    /* 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 */

  DWORD	dwErr;
  ClearCommError(m_hCom, &dwErr, &m_cs);

/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
  if(bCheckHeadFlag)
      eStartState = HDLC_HUNT_FOR_FLAG;
  else 
      eStartState = HDLC_GOT_FLAG;

 /* 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. */

  for (state = eStartState; state != HDLC_PACKET_RCVD; /* nil */)
  {
    chr = get_next_char(cWait);       /* Get next character (wait for it) */
    
    if (chr == UART_RX_ERR && m_bErrByte)          /* If it's an error ... */
    {
	  m_bErrByte = FALSE;
      state = HDLC_HUNT_FOR_FLAG;             /* Start over. */
      continue;
    }

    if ( chr == UART_RX_OVERTIME )
	{
		return 0;
	}

	if( state == eStartState && chr == 0)
		continue;

    switch(state)                  /* Process according to which state */
    {
      /*lint -esym(788,HDLC_PACKET_RCVD)  No need to deal with HDLC_PACKET_RCVD
      since we're in a loop that guarantees we're not in that state. */
      case HDLC_HUNT_FOR_FLAG:         /* We're looking for a flag ... */
        if (chr == ASYNC_HDLC_FLAG)    /*   and we got one ...         */
        {
          state = HDLC_GOT_FLAG;       /*   so go on to the next step. */
        }
        break;

      case HDLC_GOT_FLAG:              /* Had a flag, now expect a packet */
        if (chr == ASYNC_HDLC_FLAG)    /* Oops, another flag.  No change. */
        {
          break;
        }
        else
        {                            /* Ah, we can really begin a packet */
          len = 0;                     /* The packet starts out empty      */
          crc = CRC_16_L_SEED;         /* and the CRC in its initial state */
          state = HDLC_GATHER;         /* and we begin to gather a packet  */
          /* Fall through */           /*   (starting with this byte)      */
        }

      case HDLC_GATHER:                   /* We're gathering a packet      */
        if (chr == ASYNC_HDLC_FLAG)       /* We've reached the end         */
        {
          if (len < MIN_PACKET_LEN)       /* Reject any too-short packets  */
          {
            state = HDLC_HUNT_FOR_FLAG;                  /* Start over     */
          }
          else if (crc != CRC_16_L_OK_NEG)      /* Reject any with bad CRC */
          {
            state = HDLC_HUNT_FOR_FLAG;                  /* Start over     */
          }
          else                                 /* Yay, it's a good packet! */
          {
            state = HDLC_PACKET_RCVD;                    /* Done for now   */
            init_boot = FALSE;
          }
          break;           /* However it turned out, this packet is over.  */
        }

        /* It wasn't a flag, so we're still inside the packet. */
        if (chr == ASYNC_HDLC_ESC)               /* If it was an ESC       */
        {
          chr = get_next_char(cWait);       /* Get next character (wait for it) */

          if (chr == UART_RX_ERR)                /* If there was an error, */
          {
          state = HDLC_HUNT_FOR_FLAG;          /* Start over             */
          break;
          }

          chr ^= ASYNC_HDLC_ESC_MASK;            /* Otherwise, de-mask it  */
          /* No break; process the de-masked byte normally */
        }

        if (len >= MAX_PACKET_LEN)               /* Make sure there's room */
        {
          state = HDLC_HUNT_FOR_FLAG;            /* Start over             */
        }
        else
        {
          buf[len++] = (BYTE) chr;                   /* Add byte to buffer */
          crc = CRC_16_L_STEP(crc, (WORD) chr);      /* Update the CRC     */
        }
        break;

      default:       /* Shouldn't happen with an enum, but for safety ...  */
        state = HDLC_HUNT_FOR_FLAG;                  /* Start over         */
        break;
    }/* switch on state */

  }/* for (packet not found) */

  return len;
} /* rcv_packet() */

//--------------------------------------------------------------------------------------------------
// FUNCTION: 
//		CUART::TransmitPacket
// DESCRIPTION: 
//		This function transmits a packet data.
// ARGUMENTS PASSED:
//		pBuf	the buffer stored the transmitting data.
// RETURN VALUE:
//		None	
// PRE-CONDITIONS:
//	  The CUART::InitComm function must be called.
// POST-CONDITIONS:
//    None
// IMPORTANT NOTES:
//    None
//--------------------------------------------------------------------------------------------------
void 
CUART::TransmitPacket(BYTE *pBuf)
{
	
	const BYTE *data;
	data = (BYTE*)(((pkt_buffer_type*)pBuf)->buf);

	theComm.TransmitByte(ASYNC_HDLC_FLAG);	  //Supply the leading flag  

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

BOOL 
CUART::SetBaudRateTo38400()
{
	COMMCONFIG CC;
	
	GetCommState(m_hCom, &(CC.dcb));
	CC.dcb.BaudRate = 38400;
	if(!SetCommState(m_hCom, &CC.dcb))
		return false;

	return true;
}

BOOL 
CUART::SetBaudRateTo115200()
{
	COMMCONFIG CC;

	GetCommState(m_hCom, &(CC.dcb));
	CC.dcb.BaudRate = 115200;
	if(!SetCommState(m_hCom, &CC.dcb))
		return false;
	
	return true;
}
BOOL 
CUART::SetBaudRate(enum baud_rate_type bt)
{
	COMMCONFIG CC;

	GetCommState(m_hCom, &(CC.dcb));
    switch(bt)
    {
        case 0:
			CC.dcb.BaudRate = 57600;	
			break;
		case 1:
			CC.dcb.BaudRate = 115200;
			break;
        case 2:
    		CC.dcb.BaudRate = 230400;
			break;
        case 4:
    		CC.dcb.BaudRate = 460800;
			break;
        default:
    		CC.dcb.BaudRate = 115200;
			break;
	}		
			
	if(!SetCommState(m_hCom, &CC.dcb))
		return false;
	
	return true;
}

BYTE 
CUART::GetCurrentPort()
{
	return m_cPort;
}
BOOL 

CUART::SetCurrentPort(BYTE cPort)
{
	if(m_hCom == INVALID_HANDLE_VALUE)
		return false;
	
	CloseComm();
	
	return InitComm(cPort);
}
//--------------------------------------------------------------------------------------------------
//Internal Member Fucntions
//--------------------------------------------------------------------------------------------------
int  
CUART::ReceiveByte(BYTE cWait)
{
	if(m_hCom == INVALID_HANDLE_VALUE) 
	{
		TRACE0("com init Err!");
		return UART_RX_ERR;
	}

	DWORD dwErr = 0;
   	DWORD dwBytesRead = 0;

	time_t t1, t2;
	time(&t1);

	do{
		time(&t2);
		ClearCommError(m_hCom, &dwErr, &m_cs);
	}while( (m_cs.cbInQue == 0) && (t2 < (t1 + cWait)) );

	
	if(m_cs.cbInQue == 0)
		return UART_RX_OVERTIME;
	
	if(!ReadFile(m_hCom, m_rbuf, 1, &dwBytesRead, NULL))
	{
		dwErr = GetLastError();
		switch(dwErr)
		{
		case ERROR_IO_PENDING:
				TRACE("\n\nRead IO_PENDING Err!");
			    break; 
		default:
				TRACE("\n\nErrCode:%d\n",dwErr);
				break;
		}
		
		ClearCommError(m_hCom, &dwErr, &m_cs);
		m_bErrByte = TRUE;
		return UART_RX_ERR;
	}
	else
	{
		static int cout = 1; 
		BYTE tmp = m_rbuf[0];
		TRACE("\ncou: %d Bytes:%X \n", cout++, tmp);
		return m_rbuf[0];
	}
}

void 
CUART::TransmitByte(BYTE cByte)
{
	if(m_hCom == INVALID_HANDLE_VALUE) 
	{
		TRACE0("com init Err!");
		return;
	}

	m_sbuf[0] = cByte;

	DWORD dwBytesWrite = 0;
	DWORD dwErr;

	if(!WriteFile(m_hCom, (LPCVOID)m_sbuf, 1, &dwBytesWrite, NULL))
	{
		dwErr = GetLastError();  
		switch(dwErr)
  		{
			case ERROR_IO_PENDING:
				TRACE("\n\nWrite IO_PENDING Err!\n");
				break; 
			default:
				TRACE("\n\nErrCode:%d\n",dwErr);
				break;
		}

		ClearCommError(m_hCom, &dwErr, &m_cs);
	}
}

⌨️ 快捷键说明

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