Example #1
0
static int32_t PIOS_COM_SendBufferNonBlockingInternal(struct pios_com_dev *com_dev, const uint8_t *buffer, uint16_t len)
{
    PIOS_Assert(com_dev);
    PIOS_Assert(com_dev->has_tx);
    if (com_dev->driver->available && !com_dev->driver->available(com_dev->lower_id)) {
        /*
         * Underlying device is down/unconnected.
         * Dump our fifo contents and act like an infinite data sink.
         * Failure to do this results in stale data in the fifo as well as
         * possibly having the caller block trying to send to a device that's
         * no longer accepting data.
         */
        fifoBuf_clearData(&com_dev->tx);
        return len;
    }

    if (len > fifoBuf_getFree(&com_dev->tx)) {
        /* Buffer cannot accept all requested bytes (retry) */
        return -2;
    }

    uint16_t bytes_into_fifo = fifoBuf_putData(&com_dev->tx, buffer, len);

    if (bytes_into_fifo > 0) {
        /* More data has been put in the tx buffer, make sure the tx is started */
        if (com_dev->driver->tx_start) {
            com_dev->driver->tx_start(com_dev->lower_id,
                                      fifoBuf_getUsed(&com_dev->tx));
        }
    }
    return bytes_into_fifo;
}
Example #2
0
/**
* Sends a package over given port
* (blocking function)
* \param[in] port COM port
* \param[in] buffer character buffer
* \param[in] len buffer length
* \return -1 if port not available
* \return 0 on success
*/
int32_t PIOS_COM_SendBuffer(uint32_t com_id, const uint8_t *buffer, uint16_t len)
{
	struct pios_com_dev * com_dev = PIOS_COM_find_dev(com_id);

	if (!PIOS_COM_validate(com_dev)) {
		/* Undefined COM port for this board (see pios_board.c) */
		return -1;
	}

	PIOS_Assert(com_dev->has_tx);

	int32_t rc;
	do {
	  rc = PIOS_COM_SendBufferNonBlocking(com_id, buffer, len);

#if defined(PIOS_INCLUDE_FREERTOS)
	  if (rc == -2) {
	    /* Make sure the transmitter is running while we wait */
	    if (com_dev->driver->tx_start) {
	      (com_dev->driver->tx_start)(com_dev->lower_id,
					  fifoBuf_getUsed(&com_dev->tx));
	    }
	    if (xSemaphoreTake(com_dev->tx_sem, portMAX_DELAY) != pdTRUE) {
	      return -3;
	    }
	  }
#endif
	} while (rc == -2);

	return len;
}
data_type fifoBuf_getDataPeek(t_fifo_buffer *buf, void *data, data_type len)
{       // get data from the buffer without removing it

    data_type rd = buf->rd;
    data_type buf_size = buf->buf_size;
    uint8_t *buff = buf->buf_ptr;

    // get number of bytes available
    data_type num_bytes = fifoBuf_getUsed(buf);

    if (num_bytes > len)
        num_bytes = len;

    if (num_bytes < 1)
        return 0;       // return number of bytes copied

    uint8_t *p = (uint8_t *)data;
    data_type i = 0;

    while (num_bytes > 0)
    {
        data_type j = buf_size - rd;
        if (j > num_bytes)
            j = num_bytes;
        memcpy(p + i, buff + rd, j);
        i += j;
        num_bytes -= j;
        rd += j;
        if (rd >= buf_size)
            rd = 0;
    }

    return i;                   // return number of bytes copied
}
/**
* puts more than one byte onto the transmit buffer (used for atomic sends)
* \param[in] USART USART name
* \param[in] *buffer pointer to buffer to be sent
* \param[in] len number of bytes to be sent
* \return 0 if no error
* \return -1 if buffer full or cannot get all requested bytes (retry)
*/
static int32_t PIOS_USART_TxBufferPutMoreNonBlocking(uint32_t usart_id, const uint8_t *buffer, uint16_t len)
{
	struct pios_usart_dev * usart_dev = (struct pios_usart_dev *)usart_id;

	bool valid = PIOS_USART_validate(usart_dev);
	PIOS_Assert(valid)

	if (len >= fifoBuf_getFree(&usart_dev->tx)) {
		/* Buffer cannot accept all requested bytes (retry) */
		return -1;
	}

	/* Copy bytes to be transmitted into transmit buffer */
	/* This operation should be atomic! */
	PIOS_IRQ_Disable();

	uint16_t used = fifoBuf_getUsed(&usart_dev->tx);
	fifoBuf_putData(&usart_dev->tx,buffer,len);
	
	if (used == 0) {
		/* enable sending when buffer was previously empty */
		USART_ITConfig(usart_dev->cfg->regs, USART_IT_TXE, ENABLE);
	}

	PIOS_IRQ_Enable();

	/* No error */
	return 0;
}
void fifoBuf_removeData(t_fifo_buffer *buf, data_type len)
{
    // remove a number of bytes from the buffer
    data_type rd = buf->rd;
    data_type buf_size = buf->buf_size;

    // get number of bytes available
    data_type num_bytes = fifoBuf_getUsed(buf);

    if(num_bytes > len)
    {
        num_bytes = len;
    }

    if(num_bytes < 1)
    {
        return;             // nothing to remove
    }

    rd += num_bytes;
    if(rd >= buf_size)
    {
        rd -= buf_size;
    }

    buf->rd = rd;
}
Example #6
0
/**
* Sends a package over given port
* \param[in] port COM port
* \param[in] buffer character buffer
* \param[in] len buffer length
* \return -1 if port not available
* \return -2 if non-blocking mode activated: buffer is full
*            caller should retry until buffer is free again
* \return 0 on success
*/
int32_t PIOS_COM_SendBufferNonBlocking(uint32_t com_id, const uint8_t *buffer, uint16_t len)
{
	struct pios_com_dev * com_dev = PIOS_COM_find_dev(com_id);

	if (!PIOS_COM_validate(com_dev)) {
		/* Undefined COM port for this board (see pios_board.c) */
		return -1;
	}

	PIOS_Assert(com_dev->has_tx);

	if (len >= fifoBuf_getFree(&com_dev->tx)) {
		/* Buffer cannot accept all requested bytes (retry) */
		return -2;
	}

	PIOS_IRQ_Disable();
	uint16_t bytes_into_fifo = fifoBuf_putData(&com_dev->tx, buffer, len);
	PIOS_IRQ_Enable();

	if (bytes_into_fifo > 0) {
		/* More data has been put in the tx buffer, make sure the tx is started */
		if (com_dev->driver->tx_start) {
			com_dev->driver->tx_start(com_dev->lower_id,
						  fifoBuf_getUsed(&com_dev->tx));
		}
	}

	return (bytes_into_fifo);
}
Example #7
0
static uint16_t PIOS_COM_TxOutCallback(uint32_t context, uint8_t * buf, uint16_t buf_len, uint16_t * headroom, bool * need_yield)
{
	struct pios_com_dev * com_dev = PIOS_COM_find_dev(context);

	bool valid = PIOS_COM_validate(com_dev);
	PIOS_Assert(valid);
	PIOS_Assert(buf);
	PIOS_Assert(buf_len);
	PIOS_Assert(com_dev->has_tx);

	PIOS_IRQ_Disable();
	uint16_t bytes_from_fifo = fifoBuf_getData(&com_dev->tx, buf, buf_len);
	PIOS_IRQ_Enable();

	if (bytes_from_fifo > 0) {
		/* More space has been made in the buffer */
		PIOS_COM_UnblockTx(com_dev, need_yield);
	}

	if (headroom) {
		*headroom = fifoBuf_getUsed(&com_dev->tx);
	}

	return (bytes_from_fifo);
}
/**
* returns number of used bytes in transmit buffer
* \param[in] USART USART name
* \return number of used bytes
* \return 0 if USART not available
*/
static int32_t PIOS_USART_TxBufferUsed(uint32_t usart_id)
{
	struct pios_usart_dev * usart_dev = (struct pios_usart_dev *)usart_id;

	bool valid = PIOS_USART_validate(usart_dev);
	PIOS_Assert(valid)

	return (fifoBuf_getUsed(&usart_dev->tx));
}
data_type fifoBuf_getFree(t_fifo_buffer *buf)
{
    // return the free space size in the buffer
    data_type buf_size = buf->buf_size;

    data_type num_bytes = fifoBuf_getUsed(buf);

    return ((buf_size - num_bytes) - 1);
}
Example #10
0
uint16_t fifoBuf_getFree(t_fifo_buffer *buf)
{       // return the free space size in the buffer

    uint16_t buf_size = buf->buf_size;

    uint16_t num_bytes = fifoBuf_getUsed(buf);

    return ((buf_size - num_bytes) - 1);
}
Example #11
0
/**
 * @brief Get data from fifo
 * @param [out] buffer pointer to a @ref pios_bma180_data structure to receive data
 * @return 0 for success, -1 for failure (no data available)
 */
int32_t PIOS_BMA180_ReadFifo(struct pios_bma180_data * buffer)
{
	if(PIOS_BMA180_Validate(dev) != 0)
		return -1;

	if(fifoBuf_getUsed(&dev->fifo) < sizeof(*buffer))
		return -1;
	
	fifoBuf_getData(&dev->fifo, (uint8_t *) buffer, sizeof(*buffer));
	
	return 0;
}
Example #12
0
/**
* Get the number of bytes waiting in the buffer
* \param[in] port COM port
* \return Number of bytes used in buffer
*/
int32_t PIOS_COM_ReceiveBufferUsed(uint32_t com_id)
{
	struct pios_com_dev * com_dev = PIOS_COM_find_dev(com_id);

	if (!PIOS_COM_validate(com_dev)) {
		/* Undefined COM port for this board (see pios_board.c) */
		PIOS_Assert(0);
	}

	PIOS_Assert(com_dev->has_rx);
	return (fifoBuf_getUsed(&com_dev->rx));
}
Example #13
0
/**
* Sends a package over given port
* (blocking function)
* \param[in] port COM port
* \param[in] buffer character buffer
* \param[in] len buffer length
* \return -1 if port not available
* \return number of bytes transmitted on success
*/
int32_t PIOS_COM_SendBuffer(uintptr_t com_id, const uint8_t *buffer, uint16_t len)
{
	struct pios_com_dev * com_dev = (struct pios_com_dev *)com_id;

	if (!PIOS_COM_validate(com_dev)) {
		/* Undefined COM port for this board (see pios_board.c) */
		return -1;
	}

	PIOS_Assert(com_dev->has_tx);

	uint32_t max_frag_len = fifoBuf_getSize(&com_dev->tx);
	uint32_t bytes_to_send = len;
	while (bytes_to_send) {
		uint32_t frag_size;

		if (bytes_to_send > max_frag_len) {
			frag_size = max_frag_len;
		} else {
			frag_size = bytes_to_send;
		}
		int32_t rc = PIOS_COM_SendBufferNonBlocking(com_id, buffer, frag_size);
		if (rc >= 0) {
			bytes_to_send -= rc;
			buffer += rc;
		} else {
			switch (rc) {
			case -1:
				/* Device is invalid, this will never work */
				return -1;
			case -2:
				/* Device is busy, wait for the underlying device to free some space and retry */
				/* Make sure the transmitter is running while we wait */
				if (com_dev->driver->tx_start) {
					(com_dev->driver->tx_start)(com_dev->lower_id,
								fifoBuf_getUsed(&com_dev->tx));
				}
#if defined(PIOS_INCLUDE_FREERTOS)
				if (xSemaphoreTake(com_dev->tx_sem, 5000) != pdTRUE) {
					return -3;
				}
#endif
				continue;
			default:
				/* Unhandled return code */
				return rc;
			}
		}
	}

	return len;
}
Example #14
0
int16_t fifoBuf_getBytePeek(t_fifo_buffer *buf)
{	// get a data byte from the buffer without removing it

    uint16_t rd = buf->rd;

    // get number of bytes available
    uint16_t num_bytes = fifoBuf_getUsed(buf);

    if (num_bytes < 1)
        return -1;                      // no byte returned

    return buf->buf_ptr[rd];            // return the byte
}
int8_t fifoBuf_getBytePeek(t_fifo_buffer *buf)
{
    // get a data byte from the buffer without removing it
    data_type rd = buf->rd;

    // get number of bytes available
    data_type num_bytes = fifoBuf_getUsed(buf);

    if(num_bytes < 1)
    {
        return -1;
    }

    return buf->buf_ptr[rd];
}
Example #16
0
/**
* Gets a byte from the receive buffer
* \param[in] USART USART name
* \return -1 if no new byte available
* \return >= 0: actual byte received
*/
static int32_t PIOS_USART_RxBufferGet(uint32_t usart_id)
{
	struct pios_usart_dev * usart_dev = (struct pios_usart_dev *)usart_id;

	bool valid = PIOS_USART_validate(usart_dev);
	PIOS_Assert(valid)

	if (fifoBuf_getUsed(&usart_dev->rx) == 0) {
		/* Nothing new in the buffer */
		return -1;
	}

	/* get byte - this operation should be atomic! */
	uint8_t b = fifoBuf_getByte(&usart_dev->rx);

	/* Return received byte */
	return b;
}
Example #17
0
uint8_t processRX() {
	if (ProgPort == Usb) {
		while (PIOS_COM_ReceiveBufferUsed(PIOS_COM_TELEM_USB) >= 63) {
			for (int32_t x = 0; x < 63; ++x) {
				mReceive_Buffer[x] = PIOS_COM_ReceiveBuffer(PIOS_COM_TELEM_USB);
			}
			processComand(mReceive_Buffer);
		}
	} else if (ProgPort == Serial) {

		if (fifoBuf_getUsed(&ssp_buffer) >= 63) {
			for (int32_t x = 0; x < 63; ++x) {
				mReceive_Buffer[x] = fifoBuf_getByte(&ssp_buffer);
			}
			processComand(mReceive_Buffer);
		}
	}
	return TRUE;
}
Example #18
0
void fifoBuf_removeData(t_fifo_buffer *buf, uint16_t len)
{       // remove a number of bytes from the buffer

    uint16_t rd = buf->rd;
    uint16_t buf_size = buf->buf_size;

    // get number of bytes available
    uint16_t num_bytes = fifoBuf_getUsed(buf);

    if (num_bytes > len)
        num_bytes = len;

    if (num_bytes < 1)
        return;                         // nothing to remove

    rd += num_bytes;
    if (rd >= buf_size)
        rd -= buf_size;

    buf->rd = rd;
}
Example #19
0
int16_t fifoBuf_getByte(t_fifo_buffer *buf)
{       // get a data byte from the buffer

    uint16_t rd = buf->rd;
    uint16_t buf_size = buf->buf_size;
    uint8_t *buff = buf->buf_ptr;

    // get number of bytes available
    uint16_t num_bytes = fifoBuf_getUsed(buf);

    if (num_bytes < 1)
        return -1;                      // no byte returned

    uint8_t b = buff[rd];
    if (++rd >= buf_size)
        rd = 0;

    buf->rd = rd;

    return b;                           // return the byte
}
Example #20
0
uint16_t fifoBuf_getData(t_fifo_buffer *buf, void *data, uint16_t len)
{       // get data from our rx buffer

    uint16_t rd = buf->rd;
    uint16_t buf_size = buf->buf_size;
    uint8_t *buff = buf->buf_ptr;

    // get number of bytes available
    uint16_t num_bytes = fifoBuf_getUsed(buf);

    if (num_bytes > len)
        num_bytes = len;

    if (num_bytes < 1)
        return 0;               // return number of bytes copied

    uint8_t *p = (uint8_t *)data;
    uint16_t i = 0;

    while (num_bytes > 0)
    {
        uint16_t j = buf_size - rd;
        if (j > num_bytes)
            j = num_bytes;
        memcpy(p + i, buff + rd, j);
        i += j;
        num_bytes -= j;
        rd += j;
        if (rd >= buf_size)
            rd = 0;
    }

    buf->rd = rd;

    return i;                   // return number of bytes copied
}
int8_t fifoBuf_getByte(t_fifo_buffer *buf)
{
    // get data byte from buffer

    data_type rd = buf->rd;
    data_type buf_size = buf->buf_size;
    uint8_t *buff = buf->buf_ptr;
    // get number of bytes available
    data_type num_bytes = fifoBuf_getUsed(buf);

    if(num_bytes < 1)
    {
        return -1;
    }

    uint8_t b = buff[rd];
    if(++rd >= buf_size)
    {
        rd = 0;
    }
    buf->rd = rd;

    return b;
}