/** * \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]; }
/** * \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++) */ }