aboutsummaryrefslogtreecommitdiff
path: root/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc')
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm.c1190
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm.h362
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm_internal.h268
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc/app_usbd_cdc_desc.h208
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc/app_usbd_cdc_types.h360
5 files changed, 2388 insertions, 0 deletions
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm.c
new file mode 100644
index 0000000..3df941c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm.c
@@ -0,0 +1,1190 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(APP_USBD_CDC_ACM)
+
+#include "app_usbd_cdc_acm.h"
+#include <inttypes.h>
+
+/**
+ * @defgroup app_usbd_cdc_acm_internal CDC ACM internals
+ * @{
+ * @ingroup app_usbd_cdc
+ * @internal
+ */
+
+
+#define NRF_LOG_MODULE_NAME cdc_acm
+
+#if APP_USBD_CDC_ACM_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL APP_USBD_CDC_ACM_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR APP_USBD_CDC_ACM_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR APP_USBD_CDC_ACM_CONFIG_DEBUG_COLOR
+#else //APP_USBD_CDC_ACM_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif //APP_USBD_CDC_ACM_CONFIG_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define APP_USBD_CDC_ACM_COMM_IFACE_IDX 0 /**< CDC ACM class comm interface index. */
+#define APP_USBD_CDC_ACM_DATA_IFACE_IDX 1 /**< CDC ACM class data interface index. */
+
+#define APP_USBD_CDC_ACM_COMM_EPIN_IDX 0 /**< CDC ACM comm class endpoint IN index. */
+#define APP_USBD_CDC_ACM_DATA_EPIN_IDX 0 /**< CDC ACM data class endpoint IN index. */
+#define APP_USBD_CDC_ACM_DATA_EPOUT_IDX 1 /**< CDC ACM data class endpoint OUT index. */
+
+/**
+ * @brief Auxiliary function to access cdc_acm class instance data.
+ *
+ * @param[in] p_inst Class instance data.
+ *
+ * @return CDC ACM class instance.
+ */
+static inline app_usbd_cdc_acm_t const * cdc_acm_get(app_usbd_class_inst_t const * p_inst)
+{
+ ASSERT(p_inst != NULL);
+ return (app_usbd_cdc_acm_t const *)p_inst;
+}
+
+/**
+ * @brief Auxiliary function to access cdc_acm class context data.
+ *
+ * @param[in] p_cdc_acm CDC ACM class instance data.
+ *
+ * @return CDC ACM class instance context.
+ */
+static inline app_usbd_cdc_acm_ctx_t * cdc_acm_ctx_get(app_usbd_cdc_acm_t const * p_cdc_acm)
+{
+ ASSERT(p_cdc_acm != NULL);
+ ASSERT(p_cdc_acm->specific.p_data != NULL);
+ return &p_cdc_acm->specific.p_data->ctx;
+}
+
+/**
+ * @brief User event handler.
+ *
+ * @param[in] p_inst Class instance.
+ * @param[in] event user Event type.
+ */
+static inline void user_event_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 = cdc_acm_get(p_inst);
+ if (p_cdc_acm->specific.inst.user_ev_handler != NULL)
+ {
+ p_cdc_acm->specific.inst.user_ev_handler(p_inst, event);
+ }
+}
+
+/**
+ * @brief Auxiliary function to access CDC ACM COMM IN endpoint address.
+ *
+ * @param[in] p_inst Class instance data.
+ *
+ * @return IN endpoint address.
+ */
+static inline nrf_drv_usbd_ep_t comm_ep_in_addr_get(app_usbd_class_inst_t const * p_inst)
+{
+ app_usbd_class_iface_conf_t const * class_iface;
+ class_iface = app_usbd_class_iface_get(p_inst, APP_USBD_CDC_ACM_COMM_IFACE_IDX);
+
+ app_usbd_class_ep_conf_t const * ep_cfg;
+ ep_cfg = app_usbd_class_iface_ep_get(class_iface, APP_USBD_CDC_ACM_COMM_EPIN_IDX);
+
+ return app_usbd_class_ep_address_get(ep_cfg);
+}
+
+/**
+ * @brief Auxiliary function to access CDC ACM DATA IN endpoint address.
+ *
+ * @param[in] p_inst Class instance data.
+ *
+ * @return IN endpoint address.
+ */
+static inline nrf_drv_usbd_ep_t data_ep_in_addr_get(app_usbd_class_inst_t const * p_inst)
+{
+ app_usbd_class_iface_conf_t const * class_iface;
+ class_iface = app_usbd_class_iface_get(p_inst, APP_USBD_CDC_ACM_DATA_IFACE_IDX);
+
+ app_usbd_class_ep_conf_t const * ep_cfg;
+ ep_cfg = app_usbd_class_iface_ep_get(class_iface, APP_USBD_CDC_ACM_DATA_EPIN_IDX);
+
+ return app_usbd_class_ep_address_get(ep_cfg);
+}
+
+/**
+ * @brief Auxiliary function to access CDC ACM DATA OUT endpoint address.
+ *
+ * @param[in] p_inst Class instance data.
+ *
+ * @return OUT endpoint address.
+ */
+static inline nrf_drv_usbd_ep_t data_ep_out_addr_get(app_usbd_class_inst_t const * p_inst)
+{
+ app_usbd_class_iface_conf_t const * class_iface;
+ class_iface = app_usbd_class_iface_get(p_inst, APP_USBD_CDC_ACM_DATA_IFACE_IDX);
+
+ app_usbd_class_ep_conf_t const * ep_cfg;
+ ep_cfg = app_usbd_class_iface_ep_get(class_iface, APP_USBD_CDC_ACM_DATA_EPOUT_IDX);
+
+ return app_usbd_class_ep_address_get(ep_cfg);
+}
+
+/**
+ * @brief Internal SETUP standard IN request handler.
+ *
+ * @param[in] p_inst Generic class instance.
+ * @param[in] p_setup_ev Setup event.
+ *
+ * @return Standard error code.
+ */
+static ret_code_t setup_req_std_in(app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ /* Only Get Descriptor standard IN request is supported by CDC class */
+ if ((app_usbd_setup_req_rec(p_setup_ev->setup.bmRequestType) == APP_USBD_SETUP_REQREC_INTERFACE)
+ &&
+ (p_setup_ev->setup.bmRequest == APP_USBD_SETUP_STDREQ_GET_DESCRIPTOR))
+ {
+ size_t dsc_len = 0;
+ size_t max_size;
+
+ uint8_t * p_trans_buff = app_usbd_core_setup_transfer_buff_get(&max_size);
+
+ /* Try to find descriptor in class internals*/
+ ret_code_t ret = app_usbd_class_descriptor_find(
+ p_inst,
+ p_setup_ev->setup.wValue.hb,
+ p_setup_ev->setup.wValue.lb,
+ p_trans_buff,
+ &dsc_len);
+
+ if (ret != NRF_ERROR_NOT_FOUND)
+ {
+ ASSERT(dsc_len < NRF_DRV_USBD_EPSIZE);
+ return app_usbd_core_setup_rsp(&(p_setup_ev->setup), p_trans_buff, dsc_len);
+ }
+ }
+
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+/**
+ * @brief Internal SETUP standard OUT request handler
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_setup_ev Setup event
+ *
+ * @return Standard error code.
+ */
+static ret_code_t setup_req_std_out(app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+
+ switch (p_setup_ev->setup.bmRequest)
+ {
+ default:
+ break;
+ }
+
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+/**
+ * @brief Internal SETUP class IN request handler.
+ *
+ * @param[in] p_inst Generic class instance.
+ * @param[in] p_setup_ev Setup event.
+ *
+ * @return Standard error code.
+ */
+static ret_code_t setup_req_class_in(app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ app_usbd_cdc_acm_t const * p_cdc_acm = cdc_acm_get(p_inst);
+ app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm);
+
+ switch (p_setup_ev->setup.bmRequest)
+ {
+ case APP_USBD_CDC_REQ_GET_LINE_CODING:
+ {
+ if (p_setup_ev->setup.wLength.w != sizeof(app_usbd_cdc_line_coding_t))
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ return app_usbd_core_setup_rsp(&p_setup_ev->setup,
+ &p_cdc_acm_ctx->line_coding,
+ sizeof(app_usbd_cdc_line_coding_t));
+ }
+ default:
+ break;
+ }
+
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+/**
+ * @brief Class specific OUT request data callback.
+ *
+ * @param status Endpoint status.
+ * @param p_context Context of transfer (set by @ref app_usbd_core_setup_data_handler_set).
+ *
+ * @return Standard error code.
+ */
+static ret_code_t cdc_acm_req_out_data_cb(nrf_drv_usbd_ep_status_t status, void * p_context)
+{
+ if (status != NRF_USBD_EP_OK)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ app_usbd_cdc_acm_t const * p_cdc_acm = p_context;
+ app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm);
+
+ switch (p_cdc_acm_ctx->request.type)
+ {
+ case APP_USBD_CDC_REQ_SET_LINE_CODING:
+ {
+ memcpy(&p_cdc_acm_ctx->line_coding,
+ &p_cdc_acm_ctx->request.payload.line_coding,
+ sizeof(app_usbd_cdc_line_coding_t));
+
+ NRF_LOG_INFO("REQ_SET_LINE_CODING: baudrate: %"PRIu32", databits: %u, "
+ "format: %u, parity: %u",
+ uint32_decode(p_cdc_acm_ctx->line_coding.dwDTERate),
+ p_cdc_acm_ctx->line_coding.bDataBits,
+ p_cdc_acm_ctx->line_coding.bCharFormat,
+ p_cdc_acm_ctx->line_coding.bParityType);
+ break;
+ }
+ default:
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+/**
+ * @brief Class specific request data stage setup.
+ *
+ * @param[in] p_inst Generic class instance.
+ * @param[in] p_setup_ev Setup event.
+ *
+ * @return Standard error code.
+ */
+static ret_code_t cdc_acm_req_out_datastage(app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ app_usbd_cdc_acm_t const * p_cdc_acm = cdc_acm_get(p_inst);
+ app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm);
+
+ p_cdc_acm_ctx->request.type = p_setup_ev->setup.bmRequest;
+ p_cdc_acm_ctx->request.len = p_setup_ev->setup.wLength.w;
+
+ /*Request setup data*/
+ NRF_DRV_USBD_TRANSFER_OUT(transfer,
+ &p_cdc_acm_ctx->request.payload,
+ p_cdc_acm_ctx->request.len);
+ ret_code_t ret;
+ CRITICAL_REGION_ENTER();
+ ret = app_usbd_ep_transfer(NRF_DRV_USBD_EPOUT0, &transfer);
+ if (ret == NRF_SUCCESS)
+ {
+ const app_usbd_core_setup_data_handler_desc_t desc = {
+ .handler = cdc_acm_req_out_data_cb,
+ .p_context = (void*)p_cdc_acm
+ };
+
+ ret = app_usbd_core_setup_data_handler_set(NRF_DRV_USBD_EPOUT0, &desc);
+ }
+ CRITICAL_REGION_EXIT();
+
+ return ret;
+}
+
+/**
+ * @brief Reset port to default state.
+ *
+ * @param p_inst Generic class instance.
+ */
+static void cdc_acm_reset_port(app_usbd_class_inst_t const * p_inst)
+{
+ app_usbd_cdc_acm_t const * p_cdc_acm = cdc_acm_get(p_inst);
+ app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm);
+
+ p_cdc_acm_ctx->line_state = 0;
+
+ // Set rx transfers configuration to default state.
+ p_cdc_acm_ctx->rx_transfer[0].p_buf = NULL;
+ p_cdc_acm_ctx->rx_transfer[1].p_buf = NULL;
+ p_cdc_acm_ctx->bytes_left = 0;
+ p_cdc_acm_ctx->bytes_read = 0;
+ p_cdc_acm_ctx->last_read = 0;
+ p_cdc_acm_ctx->cur_read = 0;
+ p_cdc_acm_ctx->p_copy_pos = p_cdc_acm_ctx->internal_rx_buf;
+}
+
+/**
+ * @brief Internal SETUP class OUT request handler.
+ *
+ * @param[in] p_inst Generic class instance.
+ * @param[in] p_setup_ev Setup event.
+ *
+ * @return Standard error code.
+ */
+static ret_code_t setup_req_class_out(app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ app_usbd_cdc_acm_t const * p_cdc_acm = cdc_acm_get(p_inst);
+ app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm);
+
+ switch (p_setup_ev->setup.bmRequest)
+ {
+ case APP_USBD_CDC_REQ_SET_LINE_CODING:
+ {
+ if (p_setup_ev->setup.wLength.w != sizeof(app_usbd_cdc_line_coding_t))
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ return cdc_acm_req_out_datastage(p_inst, p_setup_ev);
+ }
+ case APP_USBD_CDC_REQ_SET_CONTROL_LINE_STATE:
+ {
+ if (p_setup_ev->setup.wLength.w != 0)
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ NRF_LOG_INFO("REQ_SET_CONTROL_LINE_STATE: 0x%x", p_setup_ev->setup.wValue.w);
+
+ bool old_dtr = (p_cdc_acm_ctx->line_state & APP_USBD_CDC_ACM_LINE_STATE_DTR) ?
+ true : false;
+ p_cdc_acm_ctx->line_state = p_setup_ev->setup.wValue.w;
+
+ bool new_dtr = (p_cdc_acm_ctx->line_state & APP_USBD_CDC_ACM_LINE_STATE_DTR) ?
+ true : false;
+
+ if (old_dtr == new_dtr)
+ {
+ return NRF_SUCCESS;
+ }
+
+ const app_usbd_cdc_acm_user_event_t ev = new_dtr ?
+ APP_USBD_CDC_ACM_USER_EVT_PORT_OPEN : APP_USBD_CDC_ACM_USER_EVT_PORT_CLOSE;
+
+ user_event_handler(p_inst, ev);
+
+ if (!new_dtr)
+ {
+ /*Abort DATA endpoints on port close */
+ nrf_drv_usbd_ep_t ep;
+ ep = data_ep_in_addr_get(p_inst);
+ nrf_drv_usbd_ep_abort(ep);
+ ep = data_ep_out_addr_get(p_inst);
+ nrf_drv_usbd_ep_abort(ep);
+
+ // Set rx transfers configuration to default state.
+ p_cdc_acm_ctx->rx_transfer[0].p_buf = NULL;
+ p_cdc_acm_ctx->rx_transfer[1].p_buf = NULL;
+ p_cdc_acm_ctx->bytes_left = 0;
+ p_cdc_acm_ctx->bytes_read = 0;
+ p_cdc_acm_ctx->last_read = 0;
+ p_cdc_acm_ctx->cur_read = 0;
+ p_cdc_acm_ctx->p_copy_pos = p_cdc_acm_ctx->internal_rx_buf;
+ }
+
+ return NRF_SUCCESS;
+ }
+ default:
+ break;
+ }
+
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+/**
+ * @brief Control endpoint handler.
+ *
+ * @param[in] p_inst Generic class instance.
+ * @param[in] p_setup_ev Setup event.
+ *
+ * @return Standard error code.
+ */
+static ret_code_t setup_event_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ ASSERT(p_inst != NULL);
+ ASSERT(p_setup_ev != NULL);
+
+ if (app_usbd_setup_req_dir(p_setup_ev->setup.bmRequestType) == APP_USBD_SETUP_REQDIR_IN)
+ {
+ switch (app_usbd_setup_req_typ(p_setup_ev->setup.bmRequestType))
+ {
+ case APP_USBD_SETUP_REQTYPE_STD:
+ return setup_req_std_in(p_inst, p_setup_ev);
+ case APP_USBD_SETUP_REQTYPE_CLASS:
+ return setup_req_class_in(p_inst, p_setup_ev);
+ default:
+ break;
+ }
+ }
+ else /*APP_USBD_SETUP_REQDIR_OUT*/
+ {
+ switch (app_usbd_setup_req_typ(p_setup_ev->setup.bmRequestType))
+ {
+ case APP_USBD_SETUP_REQTYPE_STD:
+ return setup_req_std_out(p_inst, p_setup_ev);
+ case APP_USBD_SETUP_REQTYPE_CLASS:
+ return setup_req_class_out(p_inst, p_setup_ev);
+ default:
+ break;
+ }
+ }
+
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+
+/**
+ * @brief CDC ACM consumer
+ *
+ * @note See @ref nrf_drv_usbd_consumer_t
+ */
+static bool cdc_acm_consumer(nrf_drv_usbd_ep_transfer_t * p_next,
+ void * p_context,
+ size_t ep_size,
+ size_t data_size)
+{
+ app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = (app_usbd_cdc_acm_ctx_t *) p_context;
+ p_next->size = data_size;
+
+ if (data_size <= p_cdc_acm_ctx->rx_transfer[0].read_left)
+ {
+ p_next->p_data.rx = p_cdc_acm_ctx->rx_transfer[0].p_buf;
+
+ p_cdc_acm_ctx->rx_transfer[0].p_buf += data_size;
+ p_cdc_acm_ctx->bytes_read += data_size;
+ p_cdc_acm_ctx->rx_transfer[0].read_left -= data_size;
+ NRF_LOG_DEBUG("Received %d bytes. Space left in user buffer: %d bytes.",
+ data_size,
+ p_cdc_acm_ctx->rx_transfer[0].read_left);
+ return (p_cdc_acm_ctx->rx_transfer[0].read_left) != 0;
+ }
+ else
+ {
+ p_next->p_data.rx = p_cdc_acm_ctx->internal_rx_buf;
+
+ p_cdc_acm_ctx->cur_read = data_size;
+ NRF_LOG_DEBUG("Received %d bytes. Stored in internal buffer.", data_size);
+ return false;
+ }
+}
+
+/**
+ * @brief CDC ACM single transfer consumer
+ *
+ * This function finalizes transfer after any received block
+ *
+ * @note See @ref nrf_drv_usbd_consumer_t
+ */
+static bool cdc_acm_single_shoot_consumer(nrf_drv_usbd_ep_transfer_t * p_next,
+ void * p_context,
+ size_t ep_size,
+ size_t data_size)
+{
+ app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = (app_usbd_cdc_acm_ctx_t *) p_context;
+ p_next->size = data_size;
+
+ if (data_size <= p_cdc_acm_ctx->rx_transfer[0].read_left)
+ {
+ p_next->p_data.rx = p_cdc_acm_ctx->rx_transfer[0].p_buf;
+
+ p_cdc_acm_ctx->bytes_read = data_size;
+ p_cdc_acm_ctx->rx_transfer[0].read_left = data_size;
+ NRF_LOG_DEBUG("Received %d bytes. Space left in user buffer: %d bytes.",
+ data_size,
+ p_cdc_acm_ctx->rx_transfer[0].read_left);
+ }
+ else
+ {
+ p_next->p_data.rx = p_cdc_acm_ctx->internal_rx_buf;
+ p_cdc_acm_ctx->cur_read = data_size;
+ NRF_LOG_DEBUG("Received %d bytes. Stored in internal buffer.", data_size);
+ }
+
+ return false;
+}
+
+/**
+ * @brief Manage switching between user buffers and copying data from internal buffer.
+ *
+ * @param p_inst Generic USB class instance.
+ *
+ * @return Standard error code
+ */
+static ret_code_t cdc_acm_rx_block_finished(app_usbd_class_inst_t const * p_inst)
+{
+ app_usbd_cdc_acm_t const * p_cdc_acm = cdc_acm_get(p_inst);
+ app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm);
+ nrf_drv_usbd_ep_t ep = data_ep_out_addr_get(p_inst);
+
+ nrf_drv_usbd_handler_desc_t handler_desc = {
+ .handler.consumer = cdc_acm_consumer,
+ .p_context = p_cdc_acm_ctx
+ };
+
+ if (p_cdc_acm_ctx->rx_transfer[0].read_left == 0) // Buffer completely filled by consumer
+ {
+ p_cdc_acm_ctx->last_read = p_cdc_acm_ctx->bytes_read;
+ p_cdc_acm_ctx->bytes_read = 0;
+ p_cdc_acm_ctx->bytes_left = 0;
+
+ if (p_cdc_acm_ctx->rx_transfer[1].p_buf != NULL)
+ {
+ p_cdc_acm_ctx->rx_transfer[0] = p_cdc_acm_ctx->rx_transfer[1];
+ p_cdc_acm_ctx->rx_transfer[1].p_buf = NULL;
+ return app_usbd_ep_handled_transfer(ep, &handler_desc);
+ }
+ else
+ {
+ p_cdc_acm_ctx->rx_transfer[0].p_buf = NULL;
+ return NRF_SUCCESS;
+ }
+ }
+
+ size_t bytes_read = p_cdc_acm_ctx->cur_read;
+ size_t bytes_to_cpy = bytes_read;
+
+ if (bytes_read > p_cdc_acm_ctx->rx_transfer[0].read_left)
+ {
+ bytes_to_cpy = p_cdc_acm_ctx->rx_transfer[0].read_left;
+ }
+ memcpy(p_cdc_acm_ctx->rx_transfer[0].p_buf,
+ p_cdc_acm_ctx->internal_rx_buf,
+ bytes_to_cpy);
+
+ // First buffer is full
+ p_cdc_acm_ctx->last_read = p_cdc_acm_ctx->bytes_read + bytes_to_cpy;
+ p_cdc_acm_ctx->bytes_read = 0;
+ p_cdc_acm_ctx->bytes_left = bytes_read - bytes_to_cpy;
+ p_cdc_acm_ctx->p_copy_pos = p_cdc_acm_ctx->internal_rx_buf + bytes_to_cpy;
+
+ if (p_cdc_acm_ctx->rx_transfer[1].p_buf != NULL)
+ {
+ // If there is second transfer, copy it to first
+ p_cdc_acm_ctx->rx_transfer[0] = p_cdc_acm_ctx->rx_transfer[1];
+ p_cdc_acm_ctx->rx_transfer[1].p_buf = NULL;
+
+ while (p_cdc_acm_ctx->bytes_left > 0)
+ {
+
+ if (p_cdc_acm_ctx->bytes_left >= p_cdc_acm_ctx->rx_transfer[0].read_left)
+ {
+ // If there are enough bytes left in internal buffer to completely fill next transfer,
+ // we call user event handler to obtain next buffer and continue double buffering.
+ memcpy(p_cdc_acm_ctx->rx_transfer[0].p_buf,
+ p_cdc_acm_ctx->p_copy_pos,
+ p_cdc_acm_ctx->rx_transfer[0].read_left);
+
+ p_cdc_acm_ctx->bytes_left -= p_cdc_acm_ctx->rx_transfer[0].read_left;
+ p_cdc_acm_ctx->p_copy_pos += p_cdc_acm_ctx->rx_transfer[0].read_left;
+ p_cdc_acm_ctx->last_read = p_cdc_acm_ctx->rx_transfer[0].read_left;
+ user_event_handler(p_inst, APP_USBD_CDC_ACM_USER_EVT_RX_DONE);
+
+ if (p_cdc_acm_ctx->rx_transfer[1].p_buf != NULL)
+ {
+ p_cdc_acm_ctx->rx_transfer[0] = p_cdc_acm_ctx->rx_transfer[1];
+ p_cdc_acm_ctx->rx_transfer[1].p_buf = NULL;
+ }
+ else
+ {
+ // If user does not specify a second buffer, all data transfers are done
+ // and data left in internal buffer is lost.
+ p_cdc_acm_ctx->rx_transfer[0].p_buf = NULL;
+ break;
+ }
+ }
+ else
+ {
+ memcpy(p_cdc_acm_ctx->rx_transfer[0].p_buf,
+ p_cdc_acm_ctx->p_copy_pos,
+ p_cdc_acm_ctx->bytes_left);
+ p_cdc_acm_ctx->bytes_read = p_cdc_acm_ctx->bytes_left;
+
+ p_cdc_acm_ctx->rx_transfer[0].read_left -= p_cdc_acm_ctx->bytes_left;
+ p_cdc_acm_ctx->rx_transfer[0].p_buf += p_cdc_acm_ctx->bytes_left;
+ break;
+ }
+ }
+
+
+ }
+ else
+ {
+ p_cdc_acm_ctx->rx_transfer[0].p_buf = NULL;
+ }
+
+ if (p_cdc_acm_ctx->rx_transfer[0].p_buf != NULL)
+ {
+ return app_usbd_ep_handled_transfer(ep, &handler_desc);
+ }
+ return NRF_SUCCESS;
+}
+
+/**
+ * @brief Class specific endpoint transfer handler.
+ *
+ * @param[in] p_inst Generic class instance.
+ * @param[in] p_setup_ev Setup event.
+ *
+ * @return Standard error code.
+ */
+static ret_code_t cdc_acm_endpoint_ev(app_usbd_class_inst_t const * p_inst,
+ app_usbd_complex_evt_t const * p_event)
+{
+ if (comm_ep_in_addr_get(p_inst) == p_event->drv_evt.data.eptransfer.ep)
+ {
+ NRF_LOG_INFO("EPIN_COMM: notify");
+ return NRF_SUCCESS;
+ }
+ ret_code_t ret;
+ if (NRF_USBD_EPIN_CHECK(p_event->drv_evt.data.eptransfer.ep))
+ {
+ switch (p_event->drv_evt.data.eptransfer.status)
+ {
+ case NRF_USBD_EP_OK:
+ NRF_LOG_INFO("EPIN_DATA: %02x done", p_event->drv_evt.data.eptransfer.ep);
+ user_event_handler(p_inst, APP_USBD_CDC_ACM_USER_EVT_TX_DONE);
+ return NRF_SUCCESS;
+ case NRF_USBD_EP_ABORTED:
+ return NRF_SUCCESS;
+ default:
+ return NRF_ERROR_INTERNAL;
+ }
+ }
+
+ if (NRF_USBD_EPOUT_CHECK(p_event->drv_evt.data.eptransfer.ep))
+ {
+ switch (p_event->drv_evt.data.eptransfer.status)
+ {
+ case NRF_USBD_EP_OK:
+ ret = cdc_acm_rx_block_finished(p_inst);
+ NRF_LOG_INFO("EPOUT_DATA: %02x done", p_event->drv_evt.data.eptransfer.ep);
+ user_event_handler(p_inst, APP_USBD_CDC_ACM_USER_EVT_RX_DONE);
+ return ret;
+ case NRF_USBD_EP_WAITING:
+ case NRF_USBD_EP_ABORTED:
+ return NRF_SUCCESS;
+ default:
+ return NRF_ERROR_INTERNAL;
+ }
+ }
+
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+
+/**
+ * @brief @ref app_usbd_class_methods_t::event_handler
+ */
+static ret_code_t cdc_acm_event_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_complex_evt_t const * p_event)
+{
+ ASSERT(p_inst != NULL);
+ ASSERT(p_event != NULL);
+
+ ret_code_t ret = NRF_SUCCESS;
+ switch (p_event->app_evt.type)
+ {
+ case APP_USBD_EVT_DRV_SOF:
+ break;
+ case APP_USBD_EVT_DRV_RESET:
+ cdc_acm_reset_port(p_inst);
+ break;
+ case APP_USBD_EVT_DRV_SETUP:
+ ret = setup_event_handler(p_inst, (app_usbd_setup_evt_t const *)p_event);
+ break;
+ case APP_USBD_EVT_DRV_EPTRANSFER:
+ ret = cdc_acm_endpoint_ev(p_inst, p_event);
+ break;
+ case APP_USBD_EVT_DRV_SUSPEND:
+ break;
+ case APP_USBD_EVT_DRV_RESUME:
+ break;
+ case APP_USBD_EVT_INST_APPEND:
+ break;
+ case APP_USBD_EVT_INST_REMOVE:
+ break;
+ case APP_USBD_EVT_STARTED:
+ break;
+ case APP_USBD_EVT_STOPPED:
+ break;
+ case APP_USBD_EVT_POWER_REMOVED:
+ cdc_acm_reset_port(p_inst);
+ break;
+ default:
+ ret = NRF_ERROR_NOT_SUPPORTED;
+ break;
+ }
+
+ return ret;
+}
+
+
+static bool cdc_acm_feed_descriptors(app_usbd_class_descriptor_ctx_t * p_ctx,
+ app_usbd_class_inst_t const * p_inst,
+ uint8_t * p_buff,
+ size_t max_size)
+{
+ static uint8_t ifaces = 0;
+ ifaces = app_usbd_class_iface_count_get(p_inst);
+ app_usbd_cdc_acm_t const * p_cdc_acm = cdc_acm_get(p_inst);
+
+ APP_USBD_CLASS_DESCRIPTOR_BEGIN(p_ctx, p_buff, max_size);
+
+ /* INTERFACE ASSOCIATION DESCRIPTOR */
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x08); // bLength
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_INTERFACE_ASSOCIATION); // bDescriptorType = Interface Association
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(p_cdc_acm->specific.inst.comm_interface); // bFirstInterface
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x02); // bInterfaceCount
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_CDC_COMM_CLASS); // bFunctionClass
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_CDC_SUBCLASS_ACM); // bFunctionSubClass
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(p_cdc_acm->specific.inst.protocol); // bFunctionProtocol
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // iFunction
+
+ static uint8_t i = 0;
+
+ for (i = 0; i < ifaces; i++)
+ {
+ /* INTERFACE DESCRIPTOR */
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x09); // bLength
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_INTERFACE); // bDescriptorType = Interface
+
+ static app_usbd_class_iface_conf_t const * p_cur_iface = NULL;
+ p_cur_iface = app_usbd_class_iface_get(p_inst, i);
+
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(app_usbd_class_iface_number_get(p_cur_iface)); // bInterfaceNumber
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // bAlternateSetting
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(app_usbd_class_iface_ep_count_get(p_cur_iface)); // bNumEndpoints
+
+ if (p_cdc_acm->specific.inst.comm_interface == app_usbd_class_iface_number_get(p_cur_iface))
+ {
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_CDC_COMM_CLASS); // bInterfaceClass = CDC COMM
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_CDC_SUBCLASS_ACM); // bInterfaceSubclass
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(p_cdc_acm->specific.inst.protocol); // bInterfaceProtocol
+ }
+ else if (p_cdc_acm->specific.inst.data_interface ==
+ app_usbd_class_iface_number_get(p_cur_iface))
+ {
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_CDC_DATA_CLASS); // bInterfaceClass = CDC DATA
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // bInterfaceSubclass
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // bInterfaceProtocol
+ }
+ else
+ {
+ ASSERT(0);
+ }
+
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // iInterface
+
+ if (p_cdc_acm->specific.inst.comm_interface == app_usbd_class_iface_number_get(p_cur_iface))
+ {
+ /* HEADER DESCRIPTOR */
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x05); // bLength
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_CDC_CS_INTERFACE); // bDescriptorType = Class Specific Interface
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_CDC_SCS_HEADER); // bDescriptorSubtype = Header Functional Descriptor
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x10); // bcdCDC LSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x01); // bcdCDC MSB
+
+ /* CALL MANAGEMENT DESCRIPTOR */
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x05); // bLength
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_CDC_CS_INTERFACE); // bDescriptorType = Class Specific Interface
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_CDC_SCS_CALL_MGMT); // bDescriptorSubtype = Call Management Functional Descriptor
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x03); // bmCapabilities
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(p_cdc_acm->specific.inst.data_interface); // bDataInterface
+
+ /* ABSTRACT CONTROL MANAGEMENT DESCRIPTOR */
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x04); // bLength
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_CDC_CS_INTERFACE); // bDescriptorType = Class Specific Interface
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_CDC_SCS_ACM); // bDescriptorSubtype = Abstract Control Management Functional Descriptor
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x02); // bmCapabilities
+
+ /* UNION DESCRIPTOR */
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x05);
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_CDC_CS_INTERFACE); // bDescriptorType = Class Specific Interface
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_CDC_SCS_UNION); // bDescriptorSubtype = Union Functional Descriptor
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(p_cdc_acm->specific.inst.comm_interface); // bControlInterface
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(p_cdc_acm->specific.inst.data_interface); // bSubordinateInterface
+ }
+ else if (p_cdc_acm->specific.inst.data_interface ==
+ app_usbd_class_iface_number_get(p_cur_iface))
+ {
+ ;
+ }
+ else
+ {
+ ASSERT(0);
+ }
+
+ /* ENDPOINT DESCRIPTORS */
+ static uint8_t endpoints = 0;
+ endpoints = app_usbd_class_iface_ep_count_get(p_cur_iface);
+
+ static uint8_t j = 0;
+
+ for (j = 0; j < endpoints; j++)
+ {
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x07); // bLength
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_ENDPOINT); // bDescriptorType = Endpoint
+
+ static app_usbd_class_ep_conf_t const * p_cur_ep = NULL;
+ p_cur_ep = app_usbd_class_iface_ep_get(p_cur_iface, j);
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(app_usbd_class_ep_address_get(p_cur_ep)); // bEndpointAddress
+
+ if (p_cdc_acm->specific.inst.comm_interface ==
+ app_usbd_class_iface_number_get(p_cur_iface))
+ {
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_INTERRUPT); // bmAttributes
+ }
+ else if (p_cdc_acm->specific.inst.data_interface ==
+ app_usbd_class_iface_number_get(p_cur_iface))
+ {
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_BULK); // bmAttributes
+ }
+ else
+ {
+ ASSERT(0);
+ }
+
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(LSB_16(NRF_DRV_USBD_EPSIZE)); // wMaxPacketSize LSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(MSB_16(NRF_DRV_USBD_EPSIZE)); // wMaxPacketSize MSB
+
+ if (p_cdc_acm->specific.inst.comm_interface ==
+ app_usbd_class_iface_number_get(p_cur_iface))
+ {
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(16); // bInterval
+ }
+ else if (p_cdc_acm->specific.inst.data_interface ==
+ app_usbd_class_iface_number_get(p_cur_iface))
+ {
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // bInterval
+ }
+ else
+ {
+ ASSERT(0);
+ }
+
+ }
+
+ }
+
+ APP_USBD_CLASS_DESCRIPTOR_END();
+}
+
+/**
+ * @brief Public cdc_acm class interface
+ *
+ */
+const app_usbd_class_methods_t app_usbd_cdc_acm_class_methods = {
+ .event_handler = cdc_acm_event_handler,
+ .feed_descriptors = cdc_acm_feed_descriptors,
+};
+
+/** @} */
+
+ret_code_t app_usbd_cdc_acm_write(app_usbd_cdc_acm_t const * p_cdc_acm,
+ const void * p_buf,
+ size_t length)
+{
+ app_usbd_class_inst_t const * p_inst = app_usbd_cdc_acm_class_inst_get(p_cdc_acm);
+ app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm);
+
+ bool dtr_state = (p_cdc_acm_ctx->line_state & APP_USBD_CDC_ACM_LINE_STATE_DTR) ?
+ true : false;
+ if (!dtr_state)
+ {
+ /*Port is not opened*/
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ nrf_drv_usbd_ep_t ep = data_ep_in_addr_get(p_inst);
+ NRF_DRV_USBD_TRANSFER_IN(transfer, p_buf, length);
+ return app_usbd_ep_transfer(ep, &transfer);
+}
+
+size_t app_usbd_cdc_acm_rx_size(app_usbd_cdc_acm_t const * p_cdc_acm)
+{
+ app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm);
+
+ return p_cdc_acm_ctx->last_read;
+}
+
+size_t app_usbd_cdc_acm_bytes_stored(app_usbd_cdc_acm_t const * p_cdc_acm)
+{
+ app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm);
+
+ return p_cdc_acm_ctx->bytes_left;
+}
+
+ret_code_t app_usbd_cdc_acm_read(app_usbd_cdc_acm_t const * p_cdc_acm,
+ void * p_buf,
+ size_t length)
+{
+ ASSERT(p_buf != NULL);
+ ret_code_t ret;
+ app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm);
+
+ if (0U == (p_cdc_acm_ctx->line_state & APP_USBD_CDC_ACM_LINE_STATE_DTR))
+ {
+ /*Port is not opened*/
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+#if (APP_USBD_CONFIG_EVENT_QUEUE_ENABLE == 0)
+ CRITICAL_REGION_ENTER();
+#endif // (APP_USBD_CONFIG_EVENT_QUEUE_ENABLE == 0)
+
+ if (p_cdc_acm_ctx->rx_transfer[0].p_buf == NULL)
+ {
+ if (p_cdc_acm_ctx->bytes_left >= length)
+ {
+ memcpy(p_buf, p_cdc_acm_ctx->p_copy_pos, length);
+ p_cdc_acm_ctx->bytes_left -= length;
+ p_cdc_acm_ctx->p_copy_pos += length;
+ p_cdc_acm_ctx->last_read = length;
+ ret = NRF_SUCCESS;
+ }
+ else
+ {
+ p_cdc_acm_ctx->rx_transfer[0].p_buf = p_buf;
+ p_cdc_acm_ctx->rx_transfer[0].read_left = length;
+ nrf_drv_usbd_ep_t ep = data_ep_out_addr_get(app_usbd_cdc_acm_class_inst_get(p_cdc_acm));
+ nrf_drv_usbd_handler_desc_t const handler_desc = {
+ .handler.consumer = cdc_acm_consumer,
+ .p_context = p_cdc_acm_ctx
+ };
+
+ if (p_cdc_acm_ctx->bytes_left > 0)
+ {
+ memcpy(p_cdc_acm_ctx->rx_transfer[0].p_buf,
+ p_cdc_acm_ctx->p_copy_pos,
+ p_cdc_acm_ctx->bytes_left);
+ p_cdc_acm_ctx->rx_transfer[0].read_left -= p_cdc_acm_ctx->bytes_left;
+ p_cdc_acm_ctx->rx_transfer[0].p_buf += p_cdc_acm_ctx->bytes_left;
+ p_cdc_acm_ctx->bytes_read = p_cdc_acm_ctx->bytes_left;
+ p_cdc_acm_ctx->bytes_left = 0;
+
+ }
+ ret = app_usbd_ep_handled_transfer(ep, &handler_desc);
+ if (ret == NRF_SUCCESS)
+ {
+ ret = NRF_ERROR_IO_PENDING;
+ }
+ }
+ }
+ else if (p_cdc_acm_ctx->rx_transfer[1].p_buf == NULL)
+ {
+ p_cdc_acm_ctx->rx_transfer[1].p_buf = p_buf;
+ p_cdc_acm_ctx->rx_transfer[1].read_left = length;
+ ret = NRF_ERROR_IO_PENDING;
+ }
+ else
+ {
+ ret = NRF_ERROR_BUSY;
+ }
+#if (APP_USBD_CONFIG_EVENT_QUEUE_ENABLE == 0)
+ CRITICAL_REGION_EXIT();
+#endif // (APP_USBD_CONFIG_EVENT_QUEUE_ENABLE == 0)
+
+ return ret;
+}
+
+ret_code_t app_usbd_cdc_acm_read_any(app_usbd_cdc_acm_t const * p_cdc_acm,
+ void * p_buf,
+ size_t length)
+{
+ ASSERT(p_buf != NULL);
+ ret_code_t ret;
+ app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm);
+
+ if (0U == (p_cdc_acm_ctx->line_state & APP_USBD_CDC_ACM_LINE_STATE_DTR))
+ {
+ /*Port is not opened*/
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+#if (APP_USBD_CONFIG_EVENT_QUEUE_ENABLE == 0)
+ CRITICAL_REGION_ENTER();
+#endif // (APP_USBD_CONFIG_EVENT_QUEUE_ENABLE == 0)
+ if (p_cdc_acm_ctx->bytes_left > 0)
+ {
+ size_t to_copy = MIN(length, p_cdc_acm_ctx->bytes_left);
+ memcpy(p_buf, p_cdc_acm_ctx->p_copy_pos, to_copy);
+ p_cdc_acm_ctx->bytes_left -= to_copy;
+ p_cdc_acm_ctx->p_copy_pos += to_copy;
+ p_cdc_acm_ctx->last_read = to_copy;
+ ret = NRF_SUCCESS;
+ }
+ else
+ {
+ if (p_cdc_acm_ctx->rx_transfer[0].p_buf == NULL)
+ {
+ p_cdc_acm_ctx->rx_transfer[0].p_buf = p_buf;
+ p_cdc_acm_ctx->rx_transfer[0].read_left = length;
+ nrf_drv_usbd_ep_t ep = data_ep_out_addr_get(app_usbd_cdc_acm_class_inst_get(p_cdc_acm));
+ nrf_drv_usbd_handler_desc_t const handler_desc = {
+ .handler.consumer = cdc_acm_single_shoot_consumer,
+ .p_context = p_cdc_acm_ctx
+ };
+
+ ret = app_usbd_ep_handled_transfer(ep, &handler_desc);
+ if (ret == NRF_SUCCESS)
+ {
+ ret = NRF_ERROR_IO_PENDING;
+ }
+ }
+ else
+ {
+ ret = NRF_ERROR_BUSY;
+ }
+ }
+
+#if (APP_USBD_CONFIG_EVENT_QUEUE_ENABLE == 0)
+ CRITICAL_REGION_EXIT();
+#endif // (APP_USBD_CONFIG_EVENT_QUEUE_ENABLE == 0)
+
+ return ret;
+}
+
+static ret_code_t cdc_acm_serial_state_notify(app_usbd_cdc_acm_t const * p_cdc_acm)
+{
+ app_usbd_class_inst_t const * p_inst = app_usbd_cdc_acm_class_inst_get(p_cdc_acm);
+ app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm);
+
+ nrf_drv_usbd_ep_t ep = comm_ep_in_addr_get(p_inst);
+
+ NRF_DRV_USBD_TRANSFER_OUT(transfer,
+ &p_cdc_acm_ctx->request.payload,
+ sizeof(app_usbd_cdc_acm_notify_t));
+ return app_usbd_ep_transfer(ep, &transfer);
+}
+
+ret_code_t app_usbd_cdc_acm_serial_state_notify(app_usbd_cdc_acm_t const * p_cdc_acm,
+ app_usbd_cdc_acm_serial_state_t serial_state,
+ bool value)
+{
+ app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm);
+
+ ret_code_t ret;
+ CRITICAL_REGION_ENTER();
+ ret = NRF_SUCCESS;
+ switch (serial_state)
+ {
+ case APP_USBD_CDC_ACM_SERIAL_STATE_DCD:
+ case APP_USBD_CDC_ACM_SERIAL_STATE_DSR:
+ case APP_USBD_CDC_ACM_SERIAL_STATE_BREAK:
+ case APP_USBD_CDC_ACM_SERIAL_STATE_RING:
+ case APP_USBD_CDC_ACM_SERIAL_STATE_FRAMING:
+ case APP_USBD_CDC_ACM_SERIAL_STATE_PARITY:
+ case APP_USBD_CDC_ACM_SERIAL_STATE_OVERRUN:
+
+ if (value)
+ {
+ p_cdc_acm_ctx->serial_state |= serial_state;
+ }
+ else
+ {
+ p_cdc_acm_ctx->serial_state &= ~serial_state;
+ }
+
+ break;
+ default:
+ ret = NRF_ERROR_NOT_SUPPORTED;
+ break;
+ }
+
+ if (ret == NRF_SUCCESS)
+ {
+ app_usbd_cdc_acm_notify_t * notify = &p_cdc_acm_ctx->request.payload.notify;
+ notify->cdc_notify.bmRequestType = app_usbd_setup_req_val(APP_USBD_SETUP_REQREC_INTERFACE,
+ APP_USBD_SETUP_REQTYPE_CLASS,
+ APP_USBD_SETUP_REQDIR_IN);
+ notify->cdc_notify.bmRequest = APP_USBD_CDC_NOTIF_SERIAL_STATE;
+ notify->cdc_notify.wValue = 0;
+ notify->cdc_notify.wIndex = 0;
+ notify->cdc_notify.wLength = sizeof(notify->serial_state);
+
+ notify->serial_state = p_cdc_acm_ctx->serial_state;
+
+ ret = cdc_acm_serial_state_notify(p_cdc_acm);
+ }
+ CRITICAL_REGION_EXIT();
+
+ return ret;
+}
+
+ret_code_t app_usbd_cdc_acm_line_state_get(app_usbd_cdc_acm_t const * p_cdc_acm,
+ app_usbd_cdc_acm_line_state_t line_state,
+ uint32_t * value)
+{
+ app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm);
+
+ ret_code_t ret;
+ CRITICAL_REGION_ENTER();
+ ret = NRF_SUCCESS;
+ switch (line_state)
+ {
+ case APP_USBD_CDC_ACM_LINE_STATE_DTR:
+ case APP_USBD_CDC_ACM_LINE_STATE_RTS:
+ *value = (p_cdc_acm_ctx->line_state & line_state) != 0;
+ break;
+ default:
+ ret = NRF_ERROR_NOT_SUPPORTED;
+ break;
+ }
+ CRITICAL_REGION_EXIT();
+
+ return ret;
+}
+
+#endif //NRF_MODULE_ENABLED(APP_USBD_CDC_ACM)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm.h
new file mode 100644
index 0000000..5af0226
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm.h
@@ -0,0 +1,362 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef APP_USBD_CDC_ACM_H__
+#define APP_USBD_CDC_ACM_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "nrf_drv_usbd.h"
+#include "app_usbd_class_base.h"
+#include "app_usbd.h"
+#include "app_usbd_core.h"
+#include "app_usbd_descriptor.h"
+
+#include "app_usbd_cdc_desc.h"
+#include "app_usbd_cdc_types.h"
+#include "app_usbd_cdc_acm_internal.h"
+
+/**
+ * @defgroup app_usbd_cdc_acm USB CDC ACM class
+ * @ingroup app_usbd
+ *
+ * @brief @tagAPI52840 Module with types, definitions and API used by CDC ACM class.
+ *
+ * @details References:
+ * - "Universal Serial Bus Class Definitions for Communications Devices"
+ * Revision 1.2, November 3, 2010
+ * - "Universal Serial Bus Communications Class Subclass Specification for PSTN Devices"
+ * Revision 1.2, February 9, 2007
+ *
+ * @{
+ */
+
+#ifdef DOXYGEN
+/**
+ * @brief CDC ACM class instance type
+ *
+ * @ref APP_USBD_CLASS_TYPEDEF
+ */
+typedef struct { } app_usbd_cdc_acm_t;
+#else
+/*lint -save -e10 -e26 -e123 -e505 */
+APP_USBD_CLASS_TYPEDEF(app_usbd_cdc_acm, \
+ APP_USBD_CDC_ACM_CONFIG(0, 0, 0, 0, 0), \
+ APP_USBD_CDC_ACM_INSTANCE_SPECIFIC_DEC, \
+ APP_USBD_CDC_ACM_DATA_SPECIFIC_DEC \
+);
+/*lint -restore*/
+#endif
+
+
+/*lint -save -e407 */
+
+/**
+ * @brief Events passed to user event handler.
+ *
+ * @note Example prototype of user event handler:
+ *
+ * @code
+ void cdc_acm_user_ev_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_cdc_acm_user_event_t event);
+ * @endcode
+ */
+typedef enum app_usbd_cdc_acm_user_event_e {
+ APP_USBD_CDC_ACM_USER_EVT_RX_DONE, /**< User event RX_DONE. */
+ APP_USBD_CDC_ACM_USER_EVT_TX_DONE, /**< User event TX_DONE. */
+
+ APP_USBD_CDC_ACM_USER_EVT_PORT_OPEN, /**< User event PORT_OPEN. */
+ APP_USBD_CDC_ACM_USER_EVT_PORT_CLOSE, /**< User event PORT_CLOSE. */
+} app_usbd_cdc_acm_user_event_t;
+
+/*lint -restore*/
+
+/**
+ * @brief Default CDC ACM descriptors.
+ *
+ * @param comm_interface COMM interface number.
+ * @param comm_epin COMM interface IN endpoint.
+ * @param data_interface DATA interface number.
+ * @param data_epin DATA interface IN endpoint.
+ * @param data_epout DATA interface OUT endpoint.
+ */
+#define APP_USBD_CDC_ACM_DEFAULT_DESC(comm_interface, \
+ comm_epin, \
+ data_interface, \
+ data_epin, \
+ data_epout) \
+ APP_USBD_CDC_IAD_DSC(comm_interface, \
+ APP_USBD_CDC_SUBCLASS_ACM, \
+ APP_USBD_CDC_COMM_PROTOCOL_AT_V250) \
+ APP_USBD_CDC_COMM_INTERFACE_DSC(comm_interface, \
+ APP_USBD_CDC_SUBCLASS_ACM, \
+ APP_USBD_CDC_COMM_PROTOCOL_AT_V250) \
+ APP_USBD_CDC_HEADER_DSC(0x0110) \
+ APP_USBD_CDC_CALL_MGMT_DSC(0x03, data_interface) \
+ APP_USBD_CDC_ACM_DSC(0x02) \
+ APP_USBD_CDC_UNION_DSC(comm_interface, data_interface) \
+ APP_USBD_CDC_COM_EP_DSC(comm_epin, NRF_DRV_USBD_EPSIZE) \
+ APP_USBD_CDC_DATA_INTERFACE_DSC(data_interface, 0, 0) \
+ APP_USBD_CDC_DATA_EP_DSC(data_epin, data_epout, NRF_DRV_USBD_EPSIZE)
+
+/**
+ * @brief Global definition of app_usbd_cdc_acm_t class instance.
+ *
+ * @param instance_name Name of global instance.
+ * @param user_ev_handler User event handler (optional).
+ * @param comm_ifc Interface number of cdc_acm control.
+ * @param data_ifc Interface number of cdc_acm DATA.
+ * @param comm_ein COMM subclass IN endpoint.
+ * @param data_ein DATA subclass IN endpoint.
+ * @param data_eout DATA subclass OUT endpoint.
+ * @param cdc_protocol CDC protocol @ref app_usbd_cdc_comm_protocol_t
+ *
+ * @note This macro is just simplified version of @ref APP_USBD_CDC_ACM_GLOBAL_DEF_INTERNAL.
+ *
+ */
+#define APP_USBD_CDC_ACM_GLOBAL_DEF(instance_name, \
+ user_ev_handler, \
+ comm_ifc, \
+ data_ifc, \
+ comm_ein, \
+ data_ein, \
+ data_eout, \
+ cdc_protocol) \
+ APP_USBD_CDC_ACM_GLOBAL_DEF_INTERNAL(instance_name, \
+ user_ev_handler, \
+ comm_ifc, \
+ data_ifc, \
+ comm_ein, \
+ data_ein, \
+ data_eout, \
+ cdc_protocol) \
+
+/**
+ * @brief Helper function to get class instance from CDC ACM class.
+ *
+ * @param[in] p_cdc_acm CDC ACM class instance (defined by @ref APP_USBD_CDC_ACM_GLOBAL_DEF).
+ *
+ * @return Base class instance.
+ */
+static inline app_usbd_class_inst_t const *
+app_usbd_cdc_acm_class_inst_get(app_usbd_cdc_acm_t const * p_cdc_acm)
+{
+ return &p_cdc_acm->base;
+}
+
+/**
+ * @brief Helper function to get cdc_acm specific request from cdc_acm class.
+ *
+ * @param[in] p_cdc_acm CDC ACM class instance (defined by @ref APP_USBD_CDC_ACM_GLOBAL_DEF).
+ *
+ * @return CDC ACM class specific request.
+ */
+static inline app_usbd_cdc_acm_req_t *
+app_usbd_cdc_acm_class_request_get(app_usbd_cdc_acm_t const * p_cdc_acm)
+{
+ return &p_cdc_acm->specific.p_data->ctx.request;
+}
+
+/**
+ * @brief Helper function to get cdc_acm from base class instance.
+ *
+ * @param[in] p_inst Base class instance.
+ *
+ * @return CDC ACM class handle.
+ */
+static inline app_usbd_cdc_acm_t const *
+app_usbd_cdc_acm_class_get(app_usbd_class_inst_t const * p_inst)
+{
+ return (app_usbd_cdc_acm_t const *)p_inst;
+}
+
+
+/**
+ * @brief Writes data to CDC ACM serial port.
+ *
+ * This is asynchronous call. User should wait for @ref APP_USBD_CDC_ACM_USER_EVT_TX_DONE event
+ * to be sure that all data has been sent and input buffer could be accessed again.
+ *
+ * @param[in] p_cdc_acm CDC ACM class instance (defined by @ref APP_USBD_CDC_ACM_GLOBAL_DEF).
+ * @param[in] p_buf Input buffer.
+ * @param[in] length Input buffer length.
+ *
+ * @return Standard error code.
+ */
+ret_code_t app_usbd_cdc_acm_write(app_usbd_cdc_acm_t const * p_cdc_acm,
+ const void * p_buf,
+ size_t length);
+
+/**
+ * @brief Returns the amount of data that was read.
+ *
+ * This function should be used on @ref APP_USBD_CDC_ACM_USER_EVT_RX_DONE event to get
+ * information how many bytes have been transfered into user buffer.
+ *
+ * @param[in] p_cdc_acm CDC ACM class instance (defined by @ref APP_USBD_CDC_ACM_GLOBAL_DEF).
+ *
+ * @return Amount of data transfered.
+ */
+size_t app_usbd_cdc_acm_rx_size(app_usbd_cdc_acm_t const * p_cdc_acm);
+
+/**
+ * @brief Returns the amount of data that was stored into internal buffer
+ *
+ * This function should be used on @ref APP_USBD_CDC_ACM_USER_EVT_RX_DONE event to get
+ * information how many bytes are waiting in internal buffer.
+ *
+ * @param[in] p_cdc_acm CDC ACM class instance (defined by @ref APP_USBD_CDC_ACM_GLOBAL_DEF).
+ *
+ * @return Amount of data waiting.
+ */
+size_t app_usbd_cdc_acm_bytes_stored(app_usbd_cdc_acm_t const * p_cdc_acm);
+
+/**
+ * @brief Reads data from CDC ACM serial port.
+ *
+ * This function uses internal buffer and double buffering for continuous transmission.
+ *
+ * If there is enough data in internal buffer to fill user buffer, NRF_SUCCESS is
+ * returned and data is immediately available in the user buffer.
+ *
+ * If not, up to two user buffers can be scheduled, function returns NRF_ERROR_IO_PENDING
+ * when first buffer is filled and @ref APP_USBD_CDC_ACM_USER_EVT_RX_DONE event is generated.
+ *
+ * @sa app_usbd_cdc_acm_read_any
+ * @sa app_usbd_cdc_acm_rx_size
+ *
+ * @param[in] p_cdc_acm CDC ACM class instance (defined by @ref APP_USBD_CDC_ACM_GLOBAL_DEF).
+ * @param[out] p_buf Output buffer.
+ * @param[in] length Number of bytes to read.
+ *
+ * @retval NRF_SUCCESS Data is stored into user buffer.
+ * @retval NRF_ERROR_IO_PENDING Awaiting transmission, when data is stored into user buffer,
+ * @ref APP_USBD_CDC_ACM_USER_EVT_RX_DONE event will be raised.
+ * @retval NRF_ERROR_BUSY There are already 2 buffers queued for transfers.
+ * @retval other Standard error code.
+ */
+ret_code_t app_usbd_cdc_acm_read(app_usbd_cdc_acm_t const * p_cdc_acm,
+ void * p_buf,
+ size_t length);
+
+/**
+ * @brief Read any data from CDC ACM port up to given buffer size
+ *
+ * This function is very similar to the @ref app_usbd_cdc_acm_read but it returns
+ * data as quick as any data is available, even if the given buffer was not totally full.
+ *
+ * @note This function cannot use double buffering.
+ * @note To check the number of bytes really read use @ref app_usbd_cdc_acm_rx_size
+ * function.
+ *
+ * @sa app_usbd_cdc_acm_read
+ * @sa app_usbd_cdc_acm_rx_size
+ *
+ * @param p_cdc_acm CDC ACM class instance (defined by @ref APP_USBD_CDC_ACM_GLOBAL_DEF).
+ * @param[out] p_buf Output buffer.
+ * @param[in] length Maximum number of bytes to read.
+ *
+ * @retval NRF_SUCCESS Data is stored into user buffer.
+ * @retval NRF_ERROR_IO_PENDING Awaiting transmission, when data is stored into user buffer,
+ * @ref APP_USBD_CDC_ACM_USER_EVT_RX_DONE event will be raised.
+ * @retval NRF_ERROR_BUSY There is already buffer set for a transfer.
+ * @retval other Standard error code.
+ */
+ret_code_t app_usbd_cdc_acm_read_any(app_usbd_cdc_acm_t const * p_cdc_acm,
+ void * p_buf,
+ size_t length);
+
+/**
+ * @brief Serial state notifications.
+ * */
+typedef enum {
+ APP_USBD_CDC_ACM_SERIAL_STATE_DCD = (1u << 0), /**< Notification bit DCD. */
+ APP_USBD_CDC_ACM_SERIAL_STATE_DSR = (1u << 1), /**< Notification bit DSR. */
+ APP_USBD_CDC_ACM_SERIAL_STATE_BREAK = (1u << 2), /**< Notification bit BREAK. */
+ APP_USBD_CDC_ACM_SERIAL_STATE_RING = (1u << 3), /**< Notification bit RING. */
+ APP_USBD_CDC_ACM_SERIAL_STATE_FRAMING = (1u << 4), /**< Notification bit FRAMING.*/
+ APP_USBD_CDC_ACM_SERIAL_STATE_PARITY = (1u << 5), /**< Notification bit PARITY. */
+ APP_USBD_CDC_ACM_SERIAL_STATE_OVERRUN = (1u << 6), /**< Notification bit OVERRUN.*/
+} app_usbd_cdc_acm_serial_state_t;
+
+/**
+ * @brief Serial line state.
+ */
+typedef enum {
+ APP_USBD_CDC_ACM_LINE_STATE_DTR = (1u << 0), /**< Line state bit DTR.*/
+ APP_USBD_CDC_ACM_LINE_STATE_RTS = (1u << 1), /**< Line state bit RTS.*/
+} app_usbd_cdc_acm_line_state_t;
+
+/**
+ * @brief Serial state notification via IN interrupt endpoint.
+ *
+ * @param[in] p_cdc_acm CDC ACM class instance (defined by @ref APP_USBD_CDC_ACM_GLOBAL_DEF).
+ * @param[in] serial_state Serial state notification type.
+ * @param[in] value Serial state value.
+ *
+ * @return Standard error code.
+ */
+ret_code_t app_usbd_cdc_acm_serial_state_notify(app_usbd_cdc_acm_t const * p_cdc_acm,
+ app_usbd_cdc_acm_serial_state_t serial_state,
+ bool value);
+
+/**
+ * @brief Control line value get.
+ *
+ * @param[in] p_cdc_acm CDC ACM class instance (defined by @ref APP_USBD_CDC_ACM_GLOBAL_DEF).
+ * @param[in] line_state Line control value type.
+ * @param[out] value Line control value.
+ *
+ * @return Standard error code.
+ */
+ret_code_t app_usbd_cdc_acm_line_state_get(app_usbd_cdc_acm_t const * p_cdc_acm,
+ app_usbd_cdc_acm_line_state_t line_state,
+ uint32_t * value);
+
+/** @} */
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_CDC_ACM_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm_internal.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm_internal.h
new file mode 100644
index 0000000..5e09249
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm_internal.h
@@ -0,0 +1,268 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef APP_USBD_CDC_ACM_INTERNAL_H__
+#define APP_USBD_CDC_ACM_INTERNAL_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#include "app_util.h"
+
+/**
+ * @defgroup app_usbd_cdc_acm_internal USB CDC ACM internals
+ * @ingroup app_usbd_cdc_acm
+ * @brief @tagAPI52840 Internals of the USB ACM class implementation.
+ * @{
+ */
+
+/**
+ * @brief Forward declaration of type defined by @ref APP_USBD_CLASS_TYPEDEF in cdc_acm class.
+ *
+ */
+APP_USBD_CLASS_FORWARD(app_usbd_cdc_acm);
+
+/*lint -save -e165*/
+/**
+ * @brief Forward declaration of @ref app_usbd_cdc_acm_user_event_e.
+ *
+ */
+enum app_usbd_cdc_acm_user_event_e;
+
+/*lint -restore*/
+
+/**
+ * @brief User event handler.
+ *
+ * @param[in] p_inst Class instance.
+ * @param[in] event User event.
+ *
+ */
+typedef void (*app_usbd_cdc_acm_user_ev_handler_t)(app_usbd_class_inst_t const * p_inst,
+ enum app_usbd_cdc_acm_user_event_e event);
+
+/**
+ * @brief CDC ACM class part of class instance data.
+ */
+typedef struct {
+ uint8_t comm_interface; //!< Interface number of cdc_acm control.
+ uint8_t comm_epin; //!< COMM subclass IN endpoint.
+ uint8_t data_interface; //!< Interface number of cdc_acm DATA.
+ uint8_t data_epout; //!< DATA subclass OUT endpoint.
+ uint8_t data_epin; //!< DATA subclass IN endpoint.
+
+ app_usbd_cdc_comm_protocol_t protocol; //!< User specified CDC protocol.
+
+ app_usbd_cdc_acm_user_ev_handler_t user_ev_handler; //!< User event handler.
+} app_usbd_cdc_acm_inst_t;
+
+
+/**
+ * @brief CDC ACM serial state class notify
+ */
+typedef struct {
+ app_usbd_cdc_notify_t cdc_notify; //!< CDC notify.
+ uint16_t serial_state; //!< Serial port state.
+} app_usbd_cdc_acm_notify_t;
+
+/**
+ * @brief CDC ACM class specific request handled via control endpoint.
+ */
+typedef struct {
+ uint8_t type; //!< Request type.
+ uint8_t len; //!< Request length.
+
+ union {
+ app_usbd_cdc_line_coding_t line_coding; //!< CDC ACM current line coding.
+ app_usbd_cdc_acm_notify_t notify; //!< CDC ACM class notify.
+ } payload;
+} app_usbd_cdc_acm_req_t;
+
+/**
+ * @brief CDC ACM rx transfer buffer
+ */
+typedef struct {
+ uint8_t * p_buf; //!< User buffer pointer.
+ size_t read_left; //!< Bytes left to read into buffer.
+} cdc_rx_buffer_t;
+
+/**
+ * @brief CDC ACM class context
+ */
+typedef struct {
+ app_usbd_cdc_acm_req_t request; //!< CDC ACM class request.
+ app_usbd_cdc_line_coding_t line_coding; //!< CDC ACM current line coding.
+
+ uint16_t line_state; //!< CDC ACM line state bitmap, DTE side.
+ uint16_t serial_state; //!< CDC ACM serial state bitmap, DCE side.
+
+ cdc_rx_buffer_t rx_transfer[2]; //!< User receive transfers.
+
+ uint8_t internal_rx_buf[NRF_DRV_USBD_EPSIZE]; //!< Internal receive buffer.
+ uint8_t * p_copy_pos; //!< Current copy position from internal buffer.
+
+ size_t bytes_left; //!< Bytes left in internal buffer to copy.
+ size_t bytes_read; //!< Bytes currently written to user buffer.
+ size_t last_read; //!< Bytes read in last transfer.
+ size_t cur_read; //!< Bytes currently read to internal buffer.
+} app_usbd_cdc_acm_ctx_t;
+
+
+/**
+ * @brief CDC ACM class configuration macro.
+ *
+ * Used by @ref APP_USBD_CDC_ACM_GLOBAL_DEF
+ *
+ * @param iface_comm Interface number of cdc_acm control.
+ * @param epin_comm COMM subclass IN endpoint.
+ * @param iface_data Interface number of cdc_acm DATA.
+ * @param epin_data DATA subclass IN endpoint.
+ * @param epout_data DATA subclass OUT endpoint.
+ *
+ */
+#define APP_USBD_CDC_ACM_CONFIG(iface_comm, epin_comm, iface_data, epin_data, epout_data) \
+ ((iface_comm, epin_comm), \
+ (iface_data, epin_data, epout_data))
+
+
+/**
+ * @brief Specific class constant data for cdc_acm class.
+ *
+ * @ref app_usbd_cdc_acm_inst_t
+ */
+#define APP_USBD_CDC_ACM_INSTANCE_SPECIFIC_DEC app_usbd_cdc_acm_inst_t inst;
+
+
+/**
+ * @brief Configures cdc_acm class instance.
+ *
+ * @param user_event_handler User event handler.
+ * @param comm_ifc Interface number of cdc_acm control.
+ * @param comm_ein COMM subclass IN endpoint.
+ * @param data_ifc Interface number of cdc_acm DATA.
+ * @param data_ein DATA subclass IN endpoint.
+ * @param data_eout DATA subclass OUT endpoint.
+ * @param cdc_protocol CDC protocol.
+ */
+#define APP_USBD_CDC_ACM_INST_CONFIG(user_event_handler, comm_ifc, comm_ein, data_ifc, data_ein, \
+ data_eout, cdc_protocol) \
+ .inst = { \
+ .user_ev_handler = user_event_handler, \
+ .comm_interface = comm_ifc, \
+ .comm_epin = comm_ifc, \
+ .data_interface = data_ifc, \
+ .data_epin = data_ein, \
+ .data_epout = data_eout, \
+ .protocol = cdc_protocol \
+ }
+
+/**
+ * @brief Specific class data for cdc_acm class.
+ *
+ * @ref app_usbd_cdc_acm_ctx_t
+ */
+#define APP_USBD_CDC_ACM_DATA_SPECIFIC_DEC app_usbd_cdc_acm_ctx_t ctx;
+
+
+/**
+ * @brief CDC ACM class descriptors config macro.
+ *
+ * @param interface_number Interface number.
+ * @param ... Extracted endpoint list.
+ */
+#define APP_USBD_CDC_ACM_DSC_CONFIG(interface_number, ...) { \
+ APP_USBD_CDC_ACM_INTERFACE_DSC(interface_number, \
+ 0, \
+ 0, \
+ APP_USBD_CDC_ACM_SUBCLASS_CDC_ACMCONTROL) \
+}
+
+/**
+ * @brief Public cdc_acm class interface.
+ *
+ */
+extern const app_usbd_class_methods_t app_usbd_cdc_acm_class_methods;
+
+/**
+ * @brief Global definition of @ref app_usbd_cdc_acm_t class.
+ *
+ * @param instance_name Name of global instance.
+ * @param user_ev_handler User event handler.
+ * @param comm_ifc Interface number of cdc_acm control.
+ * @param data_ifc Interface number of cdc_acm DATA.
+ * @param comm_ein COMM subclass IN endpoint.
+ * @param data_ein DATA subclass IN endpoint.
+ * @param data_eout DATA subclass OUT endpoint.
+ * @param cdc_protocol CDC protocol @ref app_usbd_cdc_comm_protocol_t
+ */
+/*lint -save -emacro(26 64 123 505 651, APP_USBD_CDC_ACM_GLOBAL_DEF_INTERNAL)*/
+#define APP_USBD_CDC_ACM_GLOBAL_DEF_INTERNAL(instance_name, \
+ user_ev_handler, \
+ comm_ifc, \
+ data_ifc, \
+ comm_ein, \
+ data_ein, \
+ data_eout, \
+ cdc_protocol) \
+ APP_USBD_CLASS_INST_GLOBAL_DEF( \
+ instance_name, \
+ app_usbd_cdc_acm, \
+ &app_usbd_cdc_acm_class_methods, \
+ APP_USBD_CDC_ACM_CONFIG(comm_ifc, comm_ein, data_ifc, data_ein, data_eout), \
+ (APP_USBD_CDC_ACM_INST_CONFIG(user_ev_handler, \
+ comm_ifc, \
+ comm_ein, \
+ data_ifc, \
+ data_ein, \
+ data_eout, \
+ cdc_protocol)) \
+ )
+/*lint -restore*/
+
+/** @} */
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_CDC_ACM_INTERNAL_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc/app_usbd_cdc_desc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc/app_usbd_cdc_desc.h
new file mode 100644
index 0000000..091065d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc/app_usbd_cdc_desc.h
@@ -0,0 +1,208 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef APP_USBD_CDC_DESC_H__
+#define APP_USBD_CDC_DESC_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "app_usbd_descriptor.h"
+#include "app_usbd_cdc_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup app_usbd_cdc_desc CDC class descriptors
+ * @brief @tagAPI52840 Descriptors used in the USB CDC class implementation.
+ * @ingroup app_usbd_cdc_acm
+ *
+ * A group of macros used to initialize CDC descriptors
+ * @{
+ */
+
+/**
+ * @brief Initializer of IAD descriptor for CDC class.
+ *
+ * @param interface_number Interface number.
+ * @param subclass Subclass, @ref app_usbd_cdc_subclass_t.
+ * @param protocol Protocol, @ref app_usbd_cdc_comm_protocol_t.
+ */
+#define APP_USBD_CDC_IAD_DSC(interface_number, subclass, protocol) \
+ /*.bLength = */ sizeof(app_usbd_descriptor_iad_t), \
+ /*.bDescriptorType = */ APP_USBD_DESCRIPTOR_INTERFACE_ASSOCIATION, \
+ /*.bFirstInterface = */ interface_number, \
+ /*.bInterfaceCount = */ 2, \
+ /*.bFunctionClass = */ APP_USBD_CDC_COMM_CLASS, \
+ /*.bFunctionSubClass = */ subclass, \
+ /*.bFunctionProtocol = */ protocol, \
+ /*.iFunction = */ 0, \
+
+/**
+ * @brief Initializer of interface descriptor for CDC COMM class.
+ *
+ * @param interface_number Interface number.
+ * @param subclass Subclass, @ref app_usbd_cdc_subclass_t.
+ * @param protocol Protocol, @ref app_usbd_cdc_comm_protocol_t.
+ */
+#define APP_USBD_CDC_COMM_INTERFACE_DSC(interface_number, subclass, protocol) \
+ /*.bLength = */ sizeof(app_usbd_descriptor_iface_t), \
+ /*.bDescriptorType = */ APP_USBD_DESCRIPTOR_INTERFACE, \
+ /*.bInterfaceNumber = */ interface_number, \
+ /*.bAlternateSetting = */ 0x00, \
+ /*.bNumEndpoints = */ 1, \
+ /*.bInterfaceClass = */ APP_USBD_CDC_COMM_CLASS, \
+ /*.bInterfaceSubClass = */ subclass, \
+ /*.bInterfaceProtocol = */ protocol, \
+ /*.iInterface = 0, */ 0x00, \
+
+
+/**
+ * @brief Initializer of interface descriptor for CDC DATA class.
+ *
+ * @param interface_number Interface number.
+ * @param subclass Subclass, @ref app_usbd_cdc_subclass_t.
+ * @param protocol Protocol, @ref app_usbd_cdc_data_protocol_t.
+ */
+#define APP_USBD_CDC_DATA_INTERFACE_DSC(interface_number, subclass, protocol) \
+ /*.bLength = */ sizeof(app_usbd_descriptor_iface_t), \
+ /*.bDescriptorType = */ APP_USBD_DESCRIPTOR_INTERFACE, \
+ /*.bInterfaceNumber = */ interface_number, \
+ /*.bAlternateSetting = */ 0x00, \
+ /*.bNumEndpoints = */ 2, \
+ /*.bInterfaceClass = */ APP_USBD_CDC_DATA_CLASS, \
+ /*.bInterfaceSubClass = */ subclass, \
+ /*.bInterfaceProtocol = */ protocol, \
+ /*.iInterface = 0, */ 0x00, \
+
+
+
+/**
+ * @brief Initializer of endpoint descriptor for CDC COM class.
+ *
+ * @param endpoint_in IN endpoint.
+ * @param ep_size Endpoint size.
+ */
+#define APP_USBD_CDC_COM_EP_DSC(endpoint_in, ep_size) \
+ /*.bLength = */ sizeof(app_usbd_descriptor_ep_t), \
+ /*.bDescriptorType = */ APP_USBD_DESCRIPTOR_ENDPOINT, \
+ /*.bEndpointAddress = */ endpoint_in, \
+ /*.bmAttributes = */ APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_INTERRUPT, \
+ /*.wMaxPacketSize = */ APP_USBD_U16_TO_RAW_DSC(ep_size), \
+ /*.bInterval = */ 16, \
+
+/**
+ * @brief Initializer of endpoint descriptors for CDC DATA class.
+ *
+ * @param endpoint_in IN endpoint.
+ * @param endpoint_out OUT endpoint.
+ * @param ep_size Endpoint size.
+ */
+#define APP_USBD_CDC_DATA_EP_DSC(endpoint_in, endpoint_out, ep_size) \
+ /*.bLength = */ sizeof(app_usbd_descriptor_ep_t), \
+ /*.bDescriptorType = */ APP_USBD_DESCRIPTOR_ENDPOINT, \
+ /*.bEndpointAddress = */ endpoint_in, \
+ /*.bmAttributes = */ APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_BULK, \
+ /*.wMaxPacketSize = */ APP_USBD_U16_TO_RAW_DSC(ep_size), \
+ /*.bInterval = */ 0, \
+ /*.bLength = */ sizeof(app_usbd_descriptor_ep_t), \
+ /*.bDescriptorType = */ APP_USBD_DESCRIPTOR_ENDPOINT, \
+ /*.bEndpointAddress = */ endpoint_out, \
+ /*.bmAttributes = */ APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_BULK, \
+ /*.wMaxPacketSize = */ APP_USBD_U16_TO_RAW_DSC(ep_size), \
+ /*.bInterval = */ 0, \
+
+/**
+ * @brief Initializer of endpoint descriptors for CDC header descriptor.
+ *
+ * @param bcd_cdc BCD CDC version.
+ */
+#define APP_USBD_CDC_HEADER_DSC(bcd_cdc) \
+ /*.bLength = */ sizeof(app_usbd_cdc_desc_header_t), \
+ /*.bDescriptorType = */ APP_USBD_CDC_CS_INTERFACE, \
+ /*.bDescriptorSubtype = */ APP_USBD_CDC_SCS_HEADER, \
+ /*.bcdCDC = */ APP_USBD_U16_TO_RAW_DSC(bcd_cdc), \
+
+/**
+ * @brief Initializer of endpoint descriptors for CDC call management descriptor.
+ *
+ * @param capabilities Capabilities.
+ * @param data_interface Data interface.
+ */
+#define APP_USBD_CDC_CALL_MGMT_DSC(capabilities, data_interface) \
+ /*.bLength = */ sizeof(app_usbd_cdc_desc_call_mgmt_t), \
+ /*.bDescriptorType = */ APP_USBD_CDC_CS_INTERFACE, \
+ /*.bDescriptorSubtype = */ APP_USBD_CDC_SCS_CALL_MGMT, \
+ /*.bmCapabilities = */ capabilities, \
+ /*.bDataInterface = */ data_interface, \
+
+
+/**
+ * @brief Initializer of endpoint descriptors for CDC DATA class.
+ *
+ * @param capabilities Capabilities.
+ */
+#define APP_USBD_CDC_ACM_DSC(capabilities) \
+ /*.bLength = */ sizeof(app_usbd_cdc_desc_acm_t), \
+ /*.bDescriptorType = */ APP_USBD_CDC_CS_INTERFACE, \
+ /*.bDescriptorSubtype = */ APP_USBD_CDC_SCS_ACM, \
+ /*.bmCapabilities = */ capabilities, \
+
+/**
+ * @brief Initializer of endpoint descriptors for CDC DATA class.
+ *
+ * @param control_interface Control interface.
+ * @param ... Subordinate interfaces list.
+ */
+#define APP_USBD_CDC_UNION_DSC(control_interface, ...) \
+ /*.bLength = */ sizeof(app_usbd_cdc_desc_union_t) + (NUM_VA_ARGS(__VA_ARGS__)), \
+ /*.bDescriptorType = */ APP_USBD_CDC_CS_INTERFACE, \
+ /*.bDescriptorSubtype = */ APP_USBD_CDC_SCS_UNION, \
+ /*.bControlInterface = */ control_interface, \
+ /*.bSubordinateInterface = */ __VA_ARGS__, \
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_CDC_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc/app_usbd_cdc_types.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc/app_usbd_cdc_types.h
new file mode 100644
index 0000000..9b8a482
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc/app_usbd_cdc_types.h
@@ -0,0 +1,360 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef APP_USBD_CDC_TYPES_H__
+#define APP_USBD_CDC_TYPES_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * @defgroup app_usbd_cdc_types CDC class types
+ * @ingroup app_usbd_cdc_acm
+ *
+ * @brief @tagAPI52840 Variable types used by the CDC class implementation.
+ * @{
+ */
+
+/**
+ * @brief Communications Interface Class code.
+ *
+ * Used for control interface in communication class.
+ * @ref app_usbd_descriptor_iface_t::bInterfaceClass
+ */
+#define APP_USBD_CDC_COMM_CLASS 0x02
+
+/**
+ * @brief Data Class Interface code.
+ *
+ * Used for data interface in communication class.
+ * @ref app_usbd_descriptor_iface_t::bInterfaceClass
+ */
+#define APP_USBD_CDC_DATA_CLASS 0x0A
+
+/**
+ * @brief CDC subclass possible values.
+ *
+ * @ref app_usbd_descriptor_iface_t::bInterfaceSubClass
+ */
+typedef enum {
+ APP_USBD_CDC_SUBCLASS_RESERVED = 0x00, /**< Reserved in documentation. */
+ APP_USBD_CDC_SUBCLASS_DLCM = 0x01, /**< Direct Line Control Model. */
+ APP_USBD_CDC_SUBCLASS_ACM = 0x02, /**< Abstract Control Model. */
+ APP_USBD_CDC_SUBCLASS_TCM = 0x03, /**< Telephone Control Model. */
+ APP_USBD_CDC_SUBCLASS_MCCM = 0x04, /**< Multi-Channel Control Model. */
+ APP_USBD_CDC_SUBCLASS_CAPI = 0x05, /**< CAPI Control Model. */
+ APP_USBD_CDC_SUBCLASS_ENCM = 0x06, /**< Ethernet Networking Control Model. */
+ APP_USBD_CDC_SUBCLASS_ATM = 0x07, /**< ATM Networking Control Model. */
+ APP_USBD_CDC_SUBCLASS_WHCM = 0x08, /**< Wireless Handset Control Model. */
+ APP_USBD_CDC_SUBCLASS_DM = 0x09, /**< Device Management. */
+ APP_USBD_CDC_SUBCLASS_MDLM = 0x0A, /**< Mobile Direct Line Model. */
+ APP_USBD_CDC_SUBCLASS_OBEX = 0x0B, /**< OBEX. */
+ APP_USBD_CDC_SUBCLASS_EEM = 0x0C, /**< Ethernet Emulation Model. */
+ APP_USBD_CDC_SUBCLASS_NCM = 0x0D /**< Network Control Model. */
+} app_usbd_cdc_subclass_t;
+
+/**
+ * @brief CDC protocol possible values.
+ *
+ * @ref app_usbd_descriptor_iface_t::bInterfaceProtocol
+ */
+typedef enum {
+ APP_USBD_CDC_COMM_PROTOCOL_NONE = 0x00, /**< No class specific protocol required. */
+ APP_USBD_CDC_COMM_PROTOCOL_AT_V250 = 0x01, /**< AT Commands: V.250 etc. */
+ APP_USBD_CDC_COMM_PROTOCOL_AT_PCCA101 = 0x02, /**< AT Commands defined by PCCA-101. */
+ APP_USBD_CDC_COMM_PROTOCOL_AT_PCCA101_ANNEXO = 0x03, /**< AT Commands defined by PCCA-101 & Annex O. */
+ APP_USBD_CDC_COMM_PROTOCOL_AT_GSM707 = 0x04, /**< AT Commands defined by GSM 07.07. */
+ APP_USBD_CDC_COMM_PROTOCOL_AT_3GPP_27007 = 0x05, /**< AT Commands defined by 3GPP 27.007. */
+ APP_USBD_CDC_COMM_PROTOCOL_AT_CDMA = 0x06, /**< AT Commands defined by TIA for CDMA. */
+ APP_USBD_CDC_COMM_PROTOCOL_EEM = 0x07, /**< Ethernet Emulation Model. */
+ APP_USBD_CDC_COMM_PROTOCOL_EXTERNAL = 0xFE, /**< External Protocol: Commands defined by Command Set Functional Descriptor. */
+ APP_USBD_CDC_COMM_PROTOCOL_VENDOR = 0xFF /**< Vendor-specific. */
+} app_usbd_cdc_comm_protocol_t;
+
+/**
+ * @brief CDC data interface protocols possible values.
+ */
+typedef enum {
+ APP_USBD_CDC_DATA_PROTOCOL_NONE = 0x00, /**< No class specific protocol required. */
+ APP_USBD_CDC_DATA_PROTOCOL_NTB = 0x01, /**< Network Transfer Block. */
+ APP_USBD_CDC_DATA_PROTOCOL_ISDN_BRI = 0x30, /**< Physical interface protocol for ISDN BRI. */
+ APP_USBD_CDC_DATA_PROTOCOL_HDLC = 0x31, /**< HDLC. */
+ APP_USBD_CDC_DATA_PROTOCOL_TRANSPARENT = 0x32, /**< Transparent. */
+ APP_USBD_CDC_DATA_PROTOCOL_Q921M = 0x50, /**< Management protocol for Q.921 data link protocol. */
+ APP_USBD_CDC_DATA_PROTOCOL_Q921 = 0x51, /**< Data link protocol for Q.921. */
+ APP_USBD_CDC_DATA_PROTOCOL_Q921TM = 0x52, /**< TEI-multiplexor for Q.921 data link protocol. */
+ APP_USBD_CDC_DATA_PROTOCOL_V42BIS = 0x90, /**< Data compression procedures. */
+ APP_USBD_CDC_DATA_PROTOCOL_Q931 = 0x91, /**< Euro-ISDN protocol control. */
+ APP_USBD_CDC_DATA_PROTOCOL_V120 = 0x92, /**< V.24 rate adaptation to ISDN. */
+ APP_USBD_CDC_DATA_PROTOCOL_CAPI20 = 0x93, /**< CAPI Commands. */
+ APP_USBD_CDC_DATA_PROTOCOL_HOST = 0xFD, /**< Host based driver.
+ * @note This protocol code should only be used in messages
+ * between host and device to identify the host driver portion
+ * of a protocol stack.
+ */
+ APP_USBD_CDC_DATA_PROTOCOL_EXTERNAL = 0xFE, /**< The protocol(s) are described using a Protocol Unit Functional
+ * Descriptors on Communications Class Interface.
+ */
+ APP_USBD_CDC_DATA_PROTOCOL_VENDOR = 0xFF /**< Vendor-specific. */
+} app_usbd_cdc_data_protocol_t;
+
+/**
+ * @brief CDC Functional Descriptor types.
+ */
+typedef enum {
+ APP_USBD_CDC_CS_INTERFACE = 0x24, /**< Class specific interface descriptor type.*/
+ APP_USBD_CDC_CS_ENDPOINT = 0x25 /**< Class specific endpoint descriptor type.*/
+} app_usbd_cdc_func_type_t;
+
+/**
+ * @brief CDC Functional Descriptor subtypes
+ */
+typedef enum {
+ APP_USBD_CDC_SCS_HEADER = 0x00, /**< Header Functional Descriptor, which marks the beginning of the concatenated set of functional descriptors for the interface. */
+ APP_USBD_CDC_SCS_CALL_MGMT = 0x01, /**< Call Management Functional Descriptor. */
+ APP_USBD_CDC_SCS_ACM = 0x02, /**< Abstract Control Management Functional Descriptor. */
+ APP_USBD_CDC_SCS_DLM = 0x03, /**< Direct Line Management Functional Descriptor. */
+ APP_USBD_CDC_SCS_TEL_R = 0x04, /**< Telephone Ringer Functional Descriptor. */
+ APP_USBD_CDC_SCS_TEL_CAP = 0x05, /**< Telephone Call and Line State Reporting Capabilities Functional Descriptor. */
+ APP_USBD_CDC_SCS_UNION = 0x06, /**< Union Functional Descriptor. */
+ APP_USBD_CDC_SCS_COUNTRY_SEL = 0x07, /**< Country Selection Functional Descriptor. */
+ APP_USBD_CDC_SCS_TEL_OM = 0x08, /**< Telephone Operational Modes Functional Descriptor. */
+ APP_USBD_CDC_SCS_USB_TERM = 0x09, /**< USB Terminal Functional Descriptor. */
+ APP_USBD_CDC_SCS_NCT = 0x0A, /**< Network Channel Terminal Descriptor. */
+ APP_USBD_CDC_SCS_PU = 0x0B, /**< Protocol Unit Functional Descriptor. */
+ APP_USBD_CDC_SCS_EU = 0x0C, /**< Extension Unit Functional Descriptor. */
+ APP_USBD_CDC_SCS_MCM = 0x0D, /**< Multi-Channel Management Functional Descriptor. */
+ APP_USBD_CDC_SCS_CAPI = 0x0E, /**< CAPI Control Management Functional Descriptor. */
+ APP_USBD_CDC_SCS_ETH = 0x0F, /**< Ethernet Networking Functional Descriptor. */
+ APP_USBD_CDC_SCS_ATM = 0x10, /**< ATM Networking Functional Descriptor. */
+ APP_USBD_CDC_SCS_WHCM = 0x11, /**< Wireless Handset Control Model Functional Descriptor. */
+ APP_USBD_CDC_SCS_MDLM = 0x12, /**< Mobile Direct Line Model Functional Descriptor. */
+ APP_USBD_CDC_SCS_MDLM_DET = 0x13, /**< MDLM Detail Functional Descriptor. */
+ APP_USBD_CDC_SCS_DMM = 0x14, /**< Device Management Model Functional Descriptor. */
+ APP_USBD_CDC_SCS_OBEX = 0x15, /**< OBEX Functional Descriptor. */
+ APP_USBD_CDC_SCS_CS = 0x16, /**< Command Set Functional Descriptor. */
+ APP_USBD_CDC_SCS_CS_DET = 0x17, /**< Command Set Detail Functional Descriptor. */
+ APP_USBD_CDC_SCS_TEL_CM = 0x18, /**< Telephone Control Model Functional Descriptor. */
+ APP_USBD_CDC_SCS_OBEX_SI = 0x19, /**< OBEX Service Identifier Functional Descriptor. */
+ APP_USBD_CDC_SCS_NCM = 0x1A /**< NCM Functional Descriptor. */
+} app_usbd_cdc_func_subtype_t;
+
+/* Make all descriptors packed */
+#pragma pack(push, 1)
+
+/**
+ * @brief Header Functional Descriptor
+ */
+typedef struct {
+ uint8_t bFunctionLength; //!< Size of this descriptor in bytes.
+ uint8_t bDescriptorType; //!< @ref APP_USBD_CDC_CS_INTERFACE descriptor type.
+ uint8_t bDescriptorSubtype; //!< Descriptor subtype @ref APP_USBD_CDC_SCS_HEADER.
+ uint8_t bcdCDC[2]; //!< USB Class Definitions for Communications Devices Specification release number in binary-coded decimal.
+} app_usbd_cdc_desc_header_t;
+
+/**
+ * @brief Call management capabilities.
+ *
+ * @ref app_usbd_cdc_desc_call_mgmt_t::bmCapabilities bit
+ * */
+typedef enum {
+ APP_USBD_CDC_CALL_MGMT_SUPPORTED = (1 << 0), /**< Call management capability bit 0.*/
+ APP_USBD_CDC_CALL_MGMT_OVER_DCI = (1 << 1), /**< Call management capability bit 1.*/
+} app_subd_cdc_call_mgmt_cap_t;
+
+/**
+ * @brief CDC Call Management Functional Descriptor.
+ */
+typedef struct {
+ uint8_t bFunctionLength; //!< Size of this functional descriptor, in bytes.
+ uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_CDC_CS_INTERFACE.
+ uint8_t bDescriptorSubtype; //!< Descriptor subtype @ref APP_USBD_CDC_SCS_CALL_MGMT.
+ uint8_t bmCapabilities; //!< Capabilities @ref app_subd_cdc_call_mgmt_cap_t.
+ uint8_t bDataInterface; //!< Data interface number.
+} app_usbd_cdc_desc_call_mgmt_t;
+
+/**
+ * @brief ACM capabilities.
+ *
+ * @ref app_usbd_cdc_desc_acm_t::bmCapabilities bit
+ * */
+typedef enum {
+ APP_USBD_CDC_ACM_FEATURE_REQUESTS = (1 << 0), /**< ACM capability bit FEATURE_REQUESTS. */
+ APP_USBD_CDC_ACM_LINE_REQUESTS = (1 << 1), /**< ACM capability bit LINE_REQUESTS. */
+ APP_USBD_CDC_ACM_SENDBREAK_REQUESTS = (1 << 2), /**< ACM capability bit SENDBREAK_REQUESTS.*/
+ APP_USBD_CDC_ACM_NOTIFY_REQUESTS = (1 << 3), /**< ACM capability bit NOTIFY_REQUESTS. */
+} app_subd_cdc_acm_cap_t;
+
+/**
+ * @brief CDC ACM Functional Descriptor.
+ */
+typedef struct {
+ uint8_t bFunctionLength; //!< Size of this functional descriptor, in bytes.
+ uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_CDC_CS_INTERFACE.
+ uint8_t bDescriptorSubtype; //!< Descriptor subtype @ref APP_USBD_CDC_SCS_ACM.
+ uint8_t bmCapabilities; //!< Capabilities @ref app_subd_cdc_acm_cap_t.
+} app_usbd_cdc_desc_acm_t;
+
+/**
+ * @brief Union Functional Descriptor.
+ */
+typedef struct {
+ uint8_t bFunctionLength; //!< Size of this functional descriptor, in bytes.
+ uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_CDC_CS_INTERFACE.
+ uint8_t bDescriptorSubtype; //!< Descriptor subtype @ref APP_USBD_CDC_SCS_UNION.
+ uint8_t bControlInterface; //!< The interface number of the Communications or Data Class interface, designated as the controlling interface for the union.
+ uint8_t bSubordinateInterface[]; //!< Interface number of subordinate interfaces in the union. Number of interfaced depends on descriptor size.
+} app_usbd_cdc_desc_union_t;
+
+/**
+ * @brief Country Selection Functional Descriptor.
+ */
+typedef struct {
+ uint8_t bFunctionLength; //!< Size of this functional descriptor, in bytes.
+ uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_CDC_CS_INTERFACE.
+ uint8_t bDescriptorSubtype; //!< Descriptor subtype @ref APP_USBD_CDC_SCS_COUNTRY_SEL.
+ uint8_t iCountryCodeRelDate; //!< Index of a string giving the release date for the implemented ISO 3166 Country Codes.
+} app_usbd_cdc_desc_country_sel_t;
+
+/**
+ * @brief CDC Requests
+ *
+ */
+typedef enum {
+ /* CDC General */
+ APP_USBD_CDC_REQ_SEND_ENCAPSULATED_COMMAND = 0x00, /**< This request is used to issue a command in the format of the supported control protocol of the Communications Class interface. */
+ APP_USBD_CDC_REQ_GET_ENCAPSULATED_RESPONSE = 0x01, /**< This request is used to request a response in the format of the supported control protocol of the Communications Class interface. */
+ /* CDC PSTN */
+ APP_USBD_CDC_REQ_SET_COMM_FEATURE = 0x02, /**< This request controls the settings for a particular communications feature of a particular target. */
+ APP_USBD_CDC_REQ_GET_COMM_FEATURE = 0x03, /**< This request returns the current settings for the communications feature as selected. */
+ APP_USBD_CDC_REQ_CLEAR_COMM_FEATURE = 0x04, /**< This request controls the settings for a particular communications feature of a particular target, setting the selected feature to its default state. */
+ APP_USBD_CDC_REQ_SET_AUX_LINE_STATE = 0x10, /**< This request is used to connect or disconnect a secondary jack to POTS circuit or CODEC, depending on hook state. */
+ APP_USBD_CDC_REQ_SET_HOOK_STATE = 0x11, /**< This request is used to set the necessary PSTN line relay code for on-hook, off-hook, and caller ID states. */
+ APP_USBD_CDC_REQ_PULSE_SETUP = 0x12, /**< This request is used to prepare for a pulse-dialing cycle. */
+ APP_USBD_CDC_REQ_SEND_PULSE = 0x13, /**< This request is used to generate a specified number of make/break pulse cycles. */
+ APP_USBD_CDC_REQ_SET_PULSE_TIME = 0x14, /**< This request sets the timing of the make and break periods for pulse dialing. */
+ APP_USBD_CDC_REQ_RING_AUX_JACK = 0x15, /**< This request is used to generate a ring signal on a secondary phone jack. */
+ APP_USBD_CDC_REQ_SET_LINE_CODING = 0x20, /**< This request allows the host to specify typical asynchronous line-character formatting properties. */
+ APP_USBD_CDC_REQ_GET_LINE_CODING = 0x21, /**< This request allows the host to find out the currently configured line coding. */
+ APP_USBD_CDC_REQ_SET_CONTROL_LINE_STATE = 0x22, /**< This request generates RS-232/V.24 style control signals. */
+ APP_USBD_CDC_REQ_SEND_BREAK = 0x23, /**< This request sends special carrier modulation that generates an RS-232 style break. */
+ APP_USBD_CDC_REQ_SET_RINGER_PARMS = 0x30, /**< This request configures the ringer for the communications device. */
+ APP_USBD_CDC_REQ_GET_RINGER_PARMS = 0x31, /**< This request returns the ringer capabilities of the device and the current status of the device’s ringer. */
+ APP_USBD_CDC_REQ_SET_OPERATION_PARMS = 0x32, /**< Sets the operational mode for the device, between a simple mode, standalone mode and a host centric mode. */
+ APP_USBD_CDC_REQ_GET_OPERATION_PARMS = 0x33, /**< This request gets the current operational mode for the device. */
+ APP_USBD_CDC_REQ_SET_LINE_PARMS = 0x34, /**< This request is used to change the state of the line, corresponding to the interface or master interface of a union to which the command was sent. */
+ APP_USBD_CDC_REQ_GET_LINE_PARMS = 0x35, /**< This request is used to report the state of the line that corresponds to the interface or master interface of a union to which the command was sent. */
+ APP_USBD_CDC_REQ_DIAL_DIGITS = 0x36, /**< This request dials the DTMF digits over the specified line. */
+} app_usbd_cdc_req_id_t;
+
+/**
+ * @brief CDC Notifications.
+ */
+typedef enum {
+ /* CDC General */
+ APP_USBD_CDC_NOTIF_NETWORK_CONNECTION = 0x00, /**< This notification allows the device to notify the host about network connection status. */
+ APP_USBD_CDC_NOTIF_RESPONSE_AVAILABLE = 0x01, /**< This notification allows the device to notify the host that a response is available.
+ * This response can be retrieved with a subsequent GetEncapsulatedResponse request.
+ _ */
+ APP_USBD_CDC_NOTIF_CONNECTION_SPEED_CHANGE = 0x2A, /**< This notification allows the device to inform the host-networking driver
+ * that a change in either the up-link or the down-link bit rate of the connection has occurred.
+ */
+ /* CDC PSTN */
+ APP_USBD_CDC_NOTIF_AUX_JACK_HOOK_STATE = 0x08, /**< (DLM) This notification indicates the loop has changed on the auxiliary phone interface of the USB device. */
+ APP_USBD_CDC_NOTIF_RING_DETECT = 0x09, /**< (DLM) This notification indicates ring voltage on the POTS line interface of the USB device. */
+ APP_USBD_CDC_NOTIF_SERIAL_STATE = 0x20, /**< (ACM) This notification sends asynchronous notification of UART status. */
+ APP_USBD_CDC_NOTIF_CALL_STATE_CHANGE = 0x28, /**< (TCM) This notification identifies that a change has occurred to the state of a call on the line corresponding to the interface or union for the line. */
+ APP_USBD_CDC_NOTIF_LINE_STATE_CHANGE = 0x29 /**< (TCM) This notification identifies that a change has occurred to the state of the line corresponding to the interface or master interface of a union sending the notification message. */
+} app_usbd_cdc_notify_id_t;
+
+/**
+ * @brief Notification sent via CDC COMM endpoint.
+ * */
+typedef struct {
+ uint8_t bmRequestType; //!< Request type.
+ uint8_t bmRequest; //!< Request ID @ref app_usbd_cdc_req_id_t.
+ uint16_t wValue; //!< Value field.
+ uint16_t wIndex; //!< Index field.
+ uint16_t wLength; //!< Length of payload following.
+} app_usbd_cdc_notify_t;
+
+/**
+ * @brief CDC line coding structure.
+ */
+typedef struct {
+ uint8_t dwDTERate[4]; //!< Line baudrate.
+ uint8_t bCharFormat; //!< Character format @ref app_usbd_cdc_line_stopbit_t.
+ uint8_t bParityType; //!< Parity bits @ref app_usbd_cdc_line_parity_t.
+ uint8_t bDataBits; //!< Number of data bits.
+} app_usbd_cdc_line_coding_t;
+
+/**
+ * @brief Possible values of @ref app_usbd_cdc_line_coding_t::bCharFormat.
+ */
+typedef enum {
+ APP_USBD_CDC_LINE_STOPBIT_1 = 0, /**< 1 stop bit. */
+ APP_USBD_CDC_LINE_STOPBIT_1_5 = 1, /**< 1.5 stop bits. */
+ APP_USBD_CDC_LINE_STOPBIT_2 = 2, /**< 2 stop bits. */
+} app_usbd_cdc_line_stopbit_t;
+
+/**
+ * @brief Possible values of @ref app_usbd_cdc_line_coding_t::bParityType.
+ */
+typedef enum {
+ APP_USBD_CDC_LINE_PARITY_NONE = 0, /**< No parity. */
+ APP_USBD_CDC_LINE_PARITY_ODD = 1, /**< Odd parity. */
+ APP_USBD_CDC_LINE_PARITY_EVEN = 2, /**< Even parity. */
+ APP_USBD_CDC_LINE_PARITY_MARK = 3, /**< Parity forced to 0 (space).*/
+ APP_USBD_CDC_LINE_PARITY_SPACE = 4, /**< Parity forced to 1 (mark). */
+} app_usbd_cdc_line_parity_t;
+
+
+#pragma pack(pop)
+
+/** @} */
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_TYPES_H__ */