Пример #1
0
static uint16_t PIOS_COM_RxInCallback(uint32_t context, uint8_t *buf, uint16_t buf_len, uint16_t *headroom, bool *need_yield)
{
    struct pios_com_dev *com_dev = (struct pios_com_dev *)context;

    bool valid = PIOS_COM_validate(com_dev);

    PIOS_Assert(valid);
    PIOS_Assert(com_dev->has_rx);

    uint16_t bytes_into_fifo = fifoBuf_putData(&com_dev->rx, buf, buf_len);

    if (bytes_into_fifo > 0) {
        /* Data has been added to the buffer */
        PIOS_COM_UnblockRx(com_dev, need_yield);
    }

    if (headroom) {
        *headroom = fifoBuf_getFree(&com_dev->rx);
    }

    return bytes_into_fifo;
}
Пример #2
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 = (struct pios_com_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);

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

	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);
}
Пример #3
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 -2 if mutex can't be taken;
 * \return -3 if data cannot be sent in the max allotted time of 5000msec
 * \return number of bytes transmitted on success
 */
int32_t PIOS_COM_SendBuffer(uint32_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);
#if defined(PIOS_INCLUDE_FREERTOS)
    if (xSemaphoreTake(com_dev->sendbuffer_sem, 5) != pdTRUE) {
        return -2;
    }
#endif /* PIOS_INCLUDE_FREERTOS */
    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_SendBufferNonBlockingInternal(com_dev, buffer, frag_size);
        if (rc >= 0) {
            bytes_to_send -= rc;
            buffer += rc;
        } else {
            switch (rc) {
            case -1:
#if defined(PIOS_INCLUDE_FREERTOS)
                xSemaphoreGive(com_dev->sendbuffer_sem);
#endif /* PIOS_INCLUDE_FREERTOS */
                /* 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) {
                    xSemaphoreGive(com_dev->sendbuffer_sem);
                    return -3;
                }
#endif
                continue;
            default:
                /* Unhandled return code */
#if defined(PIOS_INCLUDE_FREERTOS)
                xSemaphoreGive(com_dev->sendbuffer_sem);
#endif /* PIOS_INCLUDE_FREERTOS */
                return rc;
            }
        }
    }
#if defined(PIOS_INCLUDE_FREERTOS)
    xSemaphoreGive(com_dev->sendbuffer_sem);
#endif /* PIOS_INCLUDE_FREERTOS */
    return len;
}