Ejemplo n.º 1
0
// The function returns false to signal that no more bytes can be passed to be
// sent (put into the TX buffer) until UART transmission is done.
static bool tx_buf_put(uint8_t data_byte)
{
    ASSERT(m_tx_bytes < SER_PHY_HCI_SLIP_TX_BUF_SIZE);
    mp_tx_buf[m_tx_bytes] = data_byte;
    ++m_tx_bytes;

    bool flush = false;
    ser_phy_hci_slip_evt_type_t slip_evt_type = NO_EVENT;
    if (m_tx_phase == PHASE_ACK_END)
    {
        // Send buffer, then signal that an acknowledge packet has been sent.
        flush = true;
        slip_evt_type = SER_PHY_HCI_SLIP_EVT_ACK_SENT;
    }
    else if (m_tx_phase == PHASE_PACKET_END)
    {
        // Send buffer, then signal that a packet with payload has been sent.
        flush = true;
        slip_evt_type = SER_PHY_HCI_SLIP_EVT_PKT_SENT;
    }
    else if (m_tx_bytes >= SER_PHY_HCI_SLIP_TX_BUF_SIZE)
    {
        // Send buffer (because it is filled up), but don't signal anything,
        // since the packet sending is not complete yet.
        flush = true;
    }

    if (flush)
    {
        // If some TX transfer is being done at the moment, a new one cannot be
        // started, it must be scheduled to be performed later.
        if (m_tx_in_progress)
        {
            m_tx_pending_evt_type = slip_evt_type;
            m_tx_pending = true;
            // No more buffers available, can't continue filling.
            return false;
        }

        if (m_port_open)
        {
            m_tx_in_progress = true;
            m_tx_evt_type = slip_evt_type;
            APP_ERROR_CHECK(app_usbd_cdc_acm_write(&m_app_cdc_acm,
                mp_tx_buf, m_tx_bytes));
        }

        // Switch to the second buffer.
        mp_tx_buf = (mp_tx_buf == m_tx_buf0) ? m_tx_buf1 : m_tx_buf0;
        m_tx_bytes = 0;
    }

    return true;
}
Ejemplo n.º 2
0
static ret_code_t cli_cdc_acm_write(const void * p_data,
                                    size_t length,
                                    size_t * p_cnt)
{
    ret_code_t ret;
    do {

        ret = app_usbd_cdc_acm_write(&nrf_cli_cdc_acm, p_data, length);
        if (ret == NRF_SUCCESS && p_cnt)
        {
            *p_cnt = length;
        }

    } while(ret == NRF_ERROR_BUSY);

    return ret;
}
Ejemplo n.º 3
0
static void processTransmit(void)
{
    // If some data was requested to send while port was closed, send it now.
    if ((sUsbState.mTxBuffer != NULL) && isPortOpened())
    {
        if (app_usbd_cdc_acm_write(&sAppCdcAcm, sUsbState.mTxBuffer, sUsbState.mTxSize) == NRF_SUCCESS)
        {
            sUsbState.mTransferInProgress = true;
            sUsbState.mTxBuffer           = NULL;
            sUsbState.mTxSize             = 0;
        }
    }
    else if (sUsbState.mTransferDone)
    {
        otPlatLog(OT_LOG_LEVEL_DEBG, OT_LOG_REGION_PLATFORM, "otPlatUartSendDone");

        sUsbState.mTransferDone       = false;
        sUsbState.mTransferInProgress = false;

        otPlatUartSendDone();
    }
}
Ejemplo n.º 4
0
otError otPlatUartSend(const uint8_t *aBuf, uint16_t aBufLength)
{
    otError error = OT_ERROR_NONE;

    otEXPECT_ACTION(sUsbState.mTransferInProgress == false, error = OT_ERROR_BUSY);
    otEXPECT_ACTION(sUsbState.mTxBuffer == NULL, error = OT_ERROR_BUSY);

    if (!isPortOpened())
    {
        // If port is closed, queue the message until it can be sent.
        sUsbState.mTxBuffer = aBuf;
        sUsbState.mTxSize   = aBufLength;
    }
    else
    {
        otEXPECT_ACTION(app_usbd_cdc_acm_write(&sAppCdcAcm, aBuf, aBufLength) == NRF_SUCCESS, error = OT_ERROR_FAILED);
        sUsbState.mTransferInProgress = true;
    }

exit:

    return error;
}
Ejemplo n.º 5
0
static void cdc_acm_user_ev_handler(app_usbd_class_inst_t const * p_inst,
                                    app_usbd_cdc_acm_user_event_t event)
{
    app_usbd_cdc_acm_t const * p_cdc_acm = app_usbd_cdc_acm_class_get(p_inst);

    switch (event)
    {
    case APP_USBD_CDC_ACM_USER_EVT_PORT_OPEN:
        NRF_LOG_DEBUG("EVT_PORT_OPEN");
        if (!m_port_open)
        {
            ret_code_t ret_code;

            m_port_open = true;

            do {
                ret_code = app_usbd_cdc_acm_read(p_cdc_acm, &m_rx_byte, 1);
                if (ret_code == NRF_SUCCESS)
                {
                    ser_phi_hci_rx_byte(m_rx_byte);
                }
                else if (ret_code != NRF_ERROR_IO_PENDING)
                {
                    APP_ERROR_CHECK(ret_code);
                }
            } while (ret_code == NRF_SUCCESS);
        }
        break;

    case APP_USBD_CDC_ACM_USER_EVT_PORT_CLOSE:
        NRF_LOG_DEBUG("EVT_PORT_CLOSE");
        if (m_tx_in_progress)
        {
            m_ser_phy_hci_slip_event.evt_type = SER_PHY_HCI_SLIP_EVT_PKT_SENT;
            m_ser_phy_hci_slip_event_handler(&m_ser_phy_hci_slip_event);
            m_tx_in_progress = false;
        }
        m_port_open = false;
        break;

    case APP_USBD_CDC_ACM_USER_EVT_TX_DONE:
        // If there is a pending transfer (the second buffer is ready to
        // be sent), start it immediately.
        if (m_tx_pending)
        {
            APP_ERROR_CHECK(app_usbd_cdc_acm_write(p_cdc_acm,
                mp_tx_buf, m_tx_bytes));

            // Switch to the buffer that has just been sent completely
            // and now can be filled again.
            mp_tx_buf = (mp_tx_buf == m_tx_buf0) ? m_tx_buf1 : m_tx_buf0;
            m_tx_bytes = 0;

            m_ser_phy_hci_slip_event.evt_type = m_tx_evt_type;
            m_tx_evt_type = m_tx_pending_evt_type;

            m_tx_pending = false;
        }
        else
        {
            m_tx_in_progress = false;
            m_ser_phy_hci_slip_event.evt_type = m_tx_evt_type;
        }
        // If needed, notify the upper layer that the packet transfer is
        // complete (note that this notification may result in another
        // packet send request, so everything must be cleaned up above).
        if (m_ser_phy_hci_slip_event.evt_type != NO_EVENT)
        {
            m_ser_phy_hci_slip_event_handler(&m_ser_phy_hci_slip_event);
        }
        // And if the sending process is not yet finished, look what is
        // to be done next.
        if (m_tx_phase != PHASE_IDLE)
        {
            tx_buf_fill();
        }
        break;

    case APP_USBD_CDC_ACM_USER_EVT_RX_DONE:
        {
            ret_code_t ret_code;
            do
            {
                ser_phi_hci_rx_byte(m_rx_byte);

                ret_code = app_usbd_cdc_acm_read(p_cdc_acm, &m_rx_byte, 1);
            } while (ret_code == NRF_SUCCESS);
        }
        break;

    default:
        break;
    }
}