Пример #1
0
/**
 * \brief Get byte from UART.
 *
 * \param  chn  Communication channel [0, 1]
 *
 * \retval Byte received
 * \retval -1 in case of no reception
 */
int buart_if_rx_char(uint8_t chn)
{
	uint8_t buf[4] = {0, 0, 0, 0};

	if (buart_if_read(chn, buf, 1) <= 0) {
		return (-1);
	}

	return buf[0];
}
Пример #2
0
/**
 * \brief Function to perform the USI RX process.
 */
void usi_process(void)
{
	uint8_t i;
	int nr_ch = 0;
	uint8_t uc_delimiter = MSGMARK;
	uint8_t *puc_next_token;
	uint8_t *puc_rx_aux;
	uint16_t us_token_size;

	/* Check reception on every port */
	for (i = 0; i < NUM_PORTS; i++) {
		puc_rx_aux = &usi_cfg_aux_rx_buf[i].puc_buf[0];

		/* Read all the data in the respective buffer (UART or USART) */
		if (usi_cfg_map_ports[i].uc_s_type == UART_TYPE) {
			nr_ch = buart_if_read(usi_cfg_map_ports[i].uc_chn, puc_rx_aux,
					usi_cfg_map_ports[i].us_rx_size);
		} else if (usi_cfg_map_ports[i].uc_s_type == USART_TYPE) {
			nr_ch = busart_if_read(usi_cfg_map_ports[i].uc_chn, puc_rx_aux,
					usi_cfg_map_ports[i].us_rx_size);
		}

		/* Go through the received data */
		while (nr_ch > 0) {
			/* Process received data */
			puc_next_token = memchr(puc_rx_aux, uc_delimiter, nr_ch);

			/* If token found */
			if (puc_next_token != NULL) {
				/* Update token size */
				us_token_size = (puc_next_token - puc_rx_aux);

				/* Skip the MSGMARK(s) */
				if (us_token_size == 0) {
					puc_rx_aux++;
					nr_ch--;
					uc_message_status = 1 - uc_message_status;

					/* Corner case: the data starts with two MSGMARKs: one to close
					 * the previously received incomplete message, and the following
					 * to start a new one. */
					if ((uc_message_status == MSG_END) && (usi_cfg_rx_buf[i].us_size > 0)) {
						if (puc_rx_aux[0] == MSGMARK) {
							if (_doEoMsg(i)) {
								/* CRC is OK: process the message */
								if (_process_msg(i)) {
									if (usi_cfg_param[i].us_rx_block_timer != 0) {
										/* Send internal command CMD_UNLOCK_PORT */
										internal_command.puc_buf = &uc_int_cmd_unlock;
										if (_usi_encode_and_send(i, &internal_command)) {
											usi_cfg_param[i].us_rx_block_timer = 0;
										}
									}
								} else {
									if (usi_cfg_param[i].us_rx_block_timer == 0) {
										/* Send internal command CMD_LOCK_PORT */
										internal_command.puc_buf = &uc_int_cmd_lock;
										if (_usi_encode_and_send(i, &internal_command)) {
											usi_cfg_param[i].us_rx_block_timer = RX_BLOCK_TIMEOUT;
										}
									}
								}
							}
						} else { 
							/* The next byte is not a MSGMARK: the incomplete data in 
							 * puc_rx_buf is discarded */
							uc_message_status = 1 - uc_message_status;
						}

						/* Update the buffer pointers and sizes */
						usi_cfg_rx_buf[i].us_size = 0;
						puc_rx_aux += us_token_size;
						nr_ch -= us_token_size;
					}
				} else {
					/* If a message or part of an incomplete message is expected */
					if (uc_message_status == MSG_START) {
						/* Compose the whole message */
						usi_cfg_rx_buf[i].us_size += _decode_copy(&usi_cfg_rx_buf[i].puc_buf[0] + usi_cfg_rx_buf[i].us_size,
								puc_rx_aux, us_token_size);

						/* Calculate CRC */
						if (_doEoMsg(i)) {
							/* CRC is OK: process the message */
							if (_process_msg(i)) {
								/* If port was previously blocked, send message to indicate 
								 * that now it is open. */
								if (usi_cfg_param[i].us_rx_block_timer != 0) {
									/* Send  internal command CMD_UNLOCK_PORT */
									internal_command.puc_buf = &uc_int_cmd_unlock;
									if (_usi_encode_and_send(i, &internal_command)) {
										/* If sent, change block status so message is not
										 * sent again. */
										usi_cfg_param[i].us_rx_block_timer = 0;
									}
								}
							} else {
								/* Message could not be processed. Send Flow Control message
								 * to block port. */
								if (usi_cfg_param[i].us_rx_block_timer == 0) {
									/* Send internal command CMD_LOCK_PORT */
									internal_command.puc_buf = &uc_int_cmd_lock;
									if (_usi_encode_and_send(i, &internal_command)) {
										/* If sent, change block status so message is not
										 * sent again. */
										usi_cfg_param[i].us_rx_block_timer = RX_BLOCK_TIMEOUT;
									}
								}
							}
						}
					} else {
						/* USI protocol error: discard */
					}

					/* Update the buffer pointers and sizes */
					usi_cfg_rx_buf[i].us_size = 0;
					puc_rx_aux += us_token_size;
					nr_ch -= us_token_size;
				}
			} /* end if (puc_next_token != NULL) */
			else { /* No token found */
				if (uc_message_status == MSG_START) {
					usi_cfg_rx_buf[i].us_size
						+= _decode_copy(&usi_cfg_rx_buf[i].puc_buf[0] + usi_cfg_rx_buf[i].us_size,
							puc_rx_aux, nr_ch);
				} else {
					/* USI protocol error: discard */
				}

				nr_ch = 0;
			}
		} /* end while (nr_ch > 0) */
	} /* end for (i = 0; i < NUM_PORTS; i++) */
}