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

📄 hostif_low.c

📁 本程序为ST公司开发的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	if (mode == HOSTIF_TX_MSGCMDEVAL)	{		/* Use a special buffer shared with the hostifReceiveBlock function */		/* with the MsgCmdEval already formatted by the hostifReceiveBlock() */		hostifSendPacket(hostif_msg_cmd_eval_buf, 5);				/* Since this is an error condition, we ignore the eventual Ack sent by the Host */		/* no ACK timer needed */		return TL_inprogress;	}	if (hostif_app_buffer_length < hostifCommProtocolParam.maxI2CFrameSize + 2)	{		/* Application command fits in a single LL frame, do not start a Transport session */		hostifSendPacket(hostif_app_buffer, hostif_app_buffer_length);		/* no ACK timer needed */		return TL_inprogress;	}	else	{		ASSERT(FALSE, "Message longer than I2C frame in SendBlock");	}	return TL_ready;}/******************************************************************************//* Function:  hostifRecvBlock                                                  *//*                                                                            *//*! \brief    Host communication protocol Link Layer Rx function. *  \param[in] packet Pointer to the caller-provided data buffer *  \param[in] len Length of the data contained in the buffer *  \return   void *  \remark   Transport Layer receive function. *            Performs reassembly of the packets into a message Block *            and processes the BlockID and PacketNumber fields from *            the Block header if necessary. *            In the current implementation it is assumed that only *            messages that fit in a LL frame are sent from the Host. *//******************************************************************************/void hostifRecvBlock(char *msgp, uint16 *blockLenp){	switch (hostifRecvPacket(msgp, blockLenp)) {		case LL_checksumError:			/* Create MsgCmdEval with Checksum error */			createMsgCmdEval(&hostif_msg_cmd_eval_buf[0], CMDE_CHECK_SUM_ERROR, *msgp, *(msgp+1));			send_hostif_inevent(HOSTIF_SEND_MSGCMDEVAL);			break;		case LL_badSize:			/* Create MsgCmdEval with Checksum error */			createMsgCmdEval(&hostif_msg_cmd_eval_buf[0], CMDE_LENGTH_ERROR, *msgp, *(msgp+1));			send_hostif_inevent(HOSTIF_SEND_MSGCMDEVAL);			break;		case LL_ok:			/* We received a complete Command/Message, no more processing required */			//JS added MsgCommandEval(NoError)			createMsgCmdEval(&hostif_msg_cmd_eval_buf[0], CMDE_NO_ERROR, *msgp, *(msgp+1));     			send_hostif_inevent(HOSTIF_SEND_MSGCMDEVAL);			break;		}}/******************************************************************************//* Function:  hostifSendPacket                                                 *//*                                                                            *//*! \brief    Host communication protocol Link Layer Tx function. *  \param[in] packet Pointer to the caller-provided data buffer *  \param[in] len Length of the data contained in the buffer *  \return   void *  \remark   Adds the L (length) and CS (checksum) bytes to the *            message and passes it to the low level tx functions. *            Example: *            Original message *              D1 D2 D3 .. Dn *            Message passed to low level driver *              L D1 D2 D3 .. Dn CS *            Details: *            Copies the data from the caller buffer to the I2C IRQ buffer. *            The function also processes the Ack Failure condition by *            retransmitting the errored message after 100ms. During this *            period, all tx to the Host are buffered but not sent. *//******************************************************************************/void hostifSendPacket(char *packet, uint16 len){	char *i2c_buf;	uint16 checksum;		ASSERT((len+2 <= DEFAULT_MAX_I2C_FRAME_SIZE), "Requested transmission longer than I2C frame");	ASSERT((i2c_flags.tx_msg_done == 1), "I2C LinkLayer tx buffer full");	if (len > DEFAULT_MAX_I2C_FRAME_SIZE - 2)	{		/* truncate the message, not nice but preserve sanity over the I2C */		len = DEFAULT_MAX_I2C_FRAME_SIZE - 2;	}	/* Copy the local buffer to the buffer used by the IRQ routine */ 	/* which does the actual transmission */	i2c_buf = &i2c_irq_tx_buffer[0];		/* First transmitted byte is the length, include the CS in the count */	*i2c_buf++ = len + 1; // L byte		/* Calculate the checksum while copying message to IRQ buffer */	/* do not include the L byte in the checksum calculation */	checksum = 0x5a;	while (len-- > 0)	{		checksum += (uint16) *packet;		*i2c_buf++ = *packet++;	}		/* Append the checksum */	*i2c_buf = (char) (checksum & 0xFF);		/* Use this flag to avoid overwriting the tx buffer: */	/* The IRQ will set it to 1 after sending this message */	i2c_flags.tx_msg_done = 0;		/* No need to set the buffer length anywhere, it is the I2C master */	/* that decides when to stop reception. */	/* The I2C master uses the first transmitted byte (L) as packet length. */		/* Bring down the CRQ line to signal to the master that we have a message ready */	/* Will be reset to high in the IRQ after the first byte transmission */	PDB &= I2C_CRQ_AND_MASK;	start_timer(HOSTIF_LL_CRQ_TIMER, HOSTIF_LL_CRQ_TIMER_DURATION);}/******************************************************************************//* Function:  hostifRecvPacket                                                 *//*                                                                            *//*! \brief    Host communication protocol Link Layer receive function. *  \param[in] packet Pointer to the caller-provided data buffer *  \param[in] len Length of the data contained in the buffer *  \return   LLStatusType *  \remark   Removes the L (length) and CS (checksum) bytes to the *            message and passes it to the upper level rx functions. *            Performs che checksum check. *            Example: *            Original message *              L D1 D2 D3 .. Dn CS *            Message passed to the caller *              D1 D2 D3 .. Dn *//******************************************************************/LLStatusType hostifRecvPacket(char *user_packet, uint16 *len){	uint16 irq_len, checksum;	char *irq_packet;		/* If this assertion fails we may have overwritten outside the irq msg buffer */	ASSERT(i2c_irq_rx_buffer_idx < DEFAULT_MAX_I2C_FRAME_SIZE, "Illegal message size in hostifRecvPacket");		/* L byte: add 1 because L does not count the L byte itself */	irq_len = i2c_irq_rx_buffer[0] + 1;	 	/* Sanity check: the L field should be coherent with the */	/* packet length reported by the physical layer */	if (i2c_irq_rx_buffer_idx != irq_len)	{		return LL_badSize;	}		/* Copy message to caller buffer and calculate checksum */	irq_packet = &i2c_irq_rx_buffer[1]; /* Skip the L byte */	/* Do not copy the CS and the L bytes */    irq_len -= 2;    /* Save length for caller */    *len = irq_len;	checksum = 0x5a;	while (irq_len-- > 0)	{		checksum += (uint16) *irq_packet;		*user_packet++ = *irq_packet++;	}		/* Signal to IRQ that the rx buffer is free */	i2c_flags.i2c_new_cmd = 0;		if ((checksum & 0xFF) != *irq_packet)	{		*len = 0;		return LL_checksumError;	}		return LL_ok;		}/******************************************************************************//* Function:  fifo_reset                                                      *//*                                                                            *//*! \brief    Initialize a message FIFO *  \param[in] fifo pointer the message FIFO *  \return   void *  \remark    *//******************************************************************/void fifo_reset(t_hostif_msg_fifo *fifo){	uint16 i;	char *bufp;		fifo->readp = fifo->writep = &(fifo->circular_buffer[0]);	fifo->top = fifo->readp + HOSTIF_MSG_FIFO_LEN;		/* for debug only */	bufp = &(fifo->circular_buffer[0]);	for (i = 0; i < HOSTIF_MSG_FIFO_LEN; i++)	{		*bufp++ = 0;	}		}/******************************************************************************//* Function:  fifo_has_msg                                                    *//*                                                                            *//*! \brief    Check if there are messaged in the FIFO *  \param[in] fifo pointer the message FIFO *  \return   t_bool *  \remark    *//******************************************************************/t_bool fifo_has_msg(t_hostif_msg_fifo *fifo){	if (fifo->readp == fifo->writep)	{		return FALSE;	}	else	{		return TRUE;	}}/******************************************************************************//* Function:  fifo_push_msg                                                   *//*                                                                            *//*! \brief    Push one message into the message FIFO *  \param[in] fifo pointer to the message FIFO *  \param[in] msg pointer to message to push on the FIFO *  \return   t_bool *  \remark   Each message is prepended in the FIFO with its *            length (1 byte). *//******************************************************************/t_bool fifo_push_msg(t_hostif_msg_fifo *fifo, char* msg, uint16 msg_len){	sint16 free_cells; // [RB] was uint16, but some overflow condition goes undetected in that case	sint16 pointer_diff;		semaphore_wait(&sem_hostif_critical);		pointer_diff = fifo->writep - fifo->readp;	if (pointer_diff < 0)	{		free_cells = -pointer_diff - 1;	}  else  {		free_cells = HOSTIF_MSG_FIFO_LEN - pointer_diff - 1;  }	/* Add one to store the length byte also */	if (free_cells < msg_len + 1)	{		semaphore_signal(&sem_hostif_critical);		return FALSE;	}		/* Use only one byte for the length of the message for now */	/* Might extend in the future to two bytes */	ASSERT((msg_len < 256), "Message too long in fifo_push_msg");	*(fifo->writep)++ = (char) msg_len;	while (msg_len-- > 0)	{		if (fifo->writep == fifo->top)		{			fifo->writep = fifo->circular_buffer;		}		*(fifo->writep)++ = *msg++;	}	if (fifo->writep == fifo->top)	{		fifo->writep = fifo->circular_buffer;	}		semaphore_signal(&sem_hostif_critical);	return TRUE;}/******************************************************************************//* Function:  fifo_pop_msg                                                       *//*                                                                            *//*! \brief    Pop one msg from the message FIFO *  \param[in] fifo pointer to the message FIFO *  \param[in] ch charachter popped from the FIFO *  \return   t_bool *  \remark    *//******************************************************************/t_bool fifo_pop_msg(t_hostif_msg_fifo *fifo, char *msg, uint16 *msg_len){	uint16 local_len;		semaphore_wait(&sem_hostif_critical);		if (fifo->writep == fifo->readp)	{		semaphore_signal(&sem_hostif_critical);		return FALSE;	}	local_len = *(fifo->readp)++;	*msg_len = local_len;	while (local_len-- > 0)	{		if (fifo->readp == fifo->top)		{			fifo->readp = fifo->circular_buffer;		}		*msg++ = *(fifo->readp)++;	}			if (fifo->readp == fifo->top)	{		fifo->readp = fifo->circular_buffer;	}	semaphore_signal(&sem_hostif_critical);	return TRUE;}#if (0 != HAVE_POSITION)/******************************************************************************//* Function:  hostif_calculate_checksum                                          *//*                                                                            *//*! \brief    Calculate checksum of the last position memory *  \return   void *  \remark    *//******************************************************************/uint32 hostif_calculate_checksum(void){  uint16 i = sizeof (hostifStoredValueType);  uint32 checksum = 0;  while(i --)  {    checksum += hostifStoredData.f.all[i];  }  return checksum;}/******************************************************************************//* Function:  hostif_verify_checksum                                          *//*                                                                            *//*! \brief    Verify checksum of the last position memory *  \return   void *  \remark    *//******************************************************************/uint8 hostif_verify_checksum(void){  return (hostif_calculate_checksum() == hostifStoredData.Checksum);}/******************************************************************************//* Function:  hostif_update_checksum                                          *//*                                                                            *//*! \brief    Update checksum of the last position memory *  \return   void *  \remark    *//******************************************************************/void hostif_update_checksum(void){  hostifStoredData.Checksum = hostif_calculate_checksum();}#endif /* HAVE_POSITION */

⌨️ 快捷键说明

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