12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919 |
- /**
- * 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)
- #include "app_usbd.h"
- #include "app_usbd_core.h"
- #include "app_usbd_request.h"
- #include "nrf_power.h"
- #include "nrf_drv_clock.h"
- #include "nrf_drv_power.h"
- #if APP_USBD_CONFIG_EVENT_QUEUE_ENABLE
- #include "nrf_atfifo.h"
- #include "nrf_atomic.h"
- #endif
- #define NRF_LOG_MODULE_NAME app_usbd
- #if APP_USBD_CONFIG_LOG_ENABLED
- #define NRF_LOG_LEVEL APP_USBD_CONFIG_LOG_LEVEL
- #define NRF_LOG_INFO_COLOR APP_USBD_CONFIG_INFO_COLOR
- #define NRF_LOG_DEBUG_COLOR APP_USBD_CONFIG_DEBUG_COLOR
- #else //APP_USBD_CONFIG_LOG_ENABLED
- #define NRF_LOG_LEVEL 0
- #endif //APP_USBD_CONFIG_LOG_ENABLED
- #include "nrf_log.h"
- NRF_LOG_MODULE_REGISTER();
- /* Base variables tests */
- /* Check event of app_usbd_event_type_t enumerator */
- STATIC_ASSERT((int32_t)APP_USBD_EVT_FIRST_POWER == (int32_t)NRF_DRV_USBD_EVT_CNT);
- STATIC_ASSERT(sizeof(app_usbd_event_type_t) == sizeof(nrf_drv_usbd_event_type_t));
- STATIC_ASSERT(sizeof(app_usbd_descriptor_header_t) == 2);
- STATIC_ASSERT(sizeof(app_usbd_descriptor_device_t) == 18);
- STATIC_ASSERT(sizeof(app_usbd_descriptor_configuration_t) == 9);
- STATIC_ASSERT(sizeof(app_usbd_descriptor_iface_t) == 9);
- STATIC_ASSERT(sizeof(app_usbd_descriptor_ep_t) == 7);
- STATIC_ASSERT(sizeof(app_usbd_descriptor_iad_t) == 8);
- STATIC_ASSERT(sizeof(app_usbd_setup_t) == sizeof(nrf_drv_usbd_setup_t));
- /**
- * @internal
- * @defgroup app_usbd_internals USBD library internals
- * @ingroup app_usbd
- *
- * Internal variables, auxiliary macros and functions of USBD library.
- * @{
- */
- #if (APP_USBD_PROVIDE_SOF_TIMESTAMP) || defined(__SDK_DOXYGEN__)
- /**
- * @brief The last received frame number.
- */
- static uint16_t m_last_frame;
- #endif
- /**
- * @brief Variable type for endpoint configuration.
- *
- * Each endpoint would have assigned this type of configuration structure.
- */
- typedef struct
- {
- /**
- * @brief The class instance.
- *
- * The pointer to the class instance that is connected to the endpoint.
- */
- app_usbd_class_inst_t const * p_cinst;
- /**
- * @brief Endpoint event handler.
- *
- * Event handler for the endpoint.
- * It is set to event handler for the class instance during connection by default,
- * but it can be then updated for as a reaction for @ref APP_USBD_EVT_ATTACHED event.
- * This way we can speed up the interpretation of endpoint related events.
- */
- app_usbd_ep_event_handler_t event_handler;
- }app_usbd_ep_conf_t;
- /**
- * @brief Internal event with SOF counter.
- */
- typedef struct
- {
- app_usbd_internal_evt_t evt; //!< Internal event type
- #if (APP_USBD_CONFIG_SOF_HANDLING_MODE == APP_USBD_SOF_HANDLING_COMPRESS_QUEUE) \
- || defined(__SDK_DOXYGEN__)
- uint16_t sof_cnt; //!< Number of the SOF events that appears before current event
- uint16_t start_frame; //!< Number of the SOF frame that starts this event
- #endif // (APP_USBD_CONFIG_SOF_HANDLING_MODE == APP_USBD_SOF_HANDLING_COMPRESS_QUEUE)
- } app_usbd_internal_queue_evt_t;
- #if (APP_USBD_CONFIG_EVENT_QUEUE_ENABLE) || defined(__SDK_DOXYGEN__)
- /**
- * @brief Event queue.
- *
- * The queue with events to be processed.
- */
- NRF_ATFIFO_DEF(m_event_queue, app_usbd_internal_queue_evt_t, APP_USBD_CONFIG_EVENT_QUEUE_SIZE);
- #if (APP_USBD_CONFIG_SOF_HANDLING_MODE == APP_USBD_SOF_HANDLING_COMPRESS_QUEUE) \
- || defined(__SDK_DOXYGEN__)
- /** @brief SOF events counter */
- static nrf_atomic_u32_t m_sof_events_cnt;
- /** @brief SOF Frame counter */
- static uint16_t m_event_frame;
- /* Limit of SOF events stacked until warning message. */
- #define APP_USBD_SOF_WARNING_LIMIT 500
- #endif // (APP_USBD_CONFIG_SOF_HANDLING_MODE == APP_USBD_SOF_HANDLING_COMPRESS_QUEUE)
- // || defined(__SDK_DOXYGEN__)
- #endif
- /**
- * @brief Instances connected with IN endpoints.
- *
- * Array of instance pointers connected with every IN endpoint.
- * @sa m_epout_instances
- */
- static app_usbd_ep_conf_t m_epin_conf[NRF_USBD_EPIN_CNT];
- /**
- * @brief Instances connected with OUT endpoints.
- *
- * Array of instance pointers connected with every OUT endpoint.
- * @sa m_epin_instances
- */
- static app_usbd_ep_conf_t m_epout_conf[NRF_USBD_EPIN_CNT];
- /**
- * @brief Beginning of classes list.
- *
- * All enabled in current configuration instances are connected into
- * a single linked list chain.
- * This variable points to first element.
- * Core class instance (connected to endpoint 0) is not listed here.
- */
- static app_usbd_class_inst_t const * m_p_first_cinst;
- /**
- * @brief Classes list that requires SOF events.
- *
- * Pointer to first class that requires SOF events.
- */
- static app_usbd_class_inst_t const * m_p_first_sof_cinst;
- /**
- * @brief Classes list that require SOF events in interrupt.
- *
- * Pointer to first class that requires SOF events in interrupt.
- */
- static app_usbd_class_inst_t const * m_p_first_sof_interrupt_cinst;
- /**
- * @brief Default configuration (when NULL is passed to @ref app_usbd_init).
- */
- static const app_usbd_config_t m_default_conf = {
- #if (!(APP_USBD_CONFIG_EVENT_QUEUE_ENABLE)) || defined(__SDK_DOXYGEN__)
- .ev_handler = app_usbd_event_execute,
- #endif
- #if (APP_USBD_CONFIG_EVENT_QUEUE_ENABLE) || defined(__SDK_DOXYGEN__)
- .ev_isr_handler = NULL,
- #endif
- .ev_state_proc = NULL,
- .enable_sof = false
- };
- /**
- * @brief SUSPEND state machine states.
- *
- * The enumeration of internal SUSPEND state machine states.
- */
- typedef enum
- {
- SUSTATE_STOPPED, /**< The USB driver was not started */
- SUSTATE_STARTED, /**< The USB driver was started - waiting for USB RESET */
- SUSTATE_ACTIVE, /**< Active state */
- SUSTATE_SUSPENDING, /**< Suspending - waiting for the user to acknowledge */
- SUSTATE_SUSPEND, /**< Suspended */
- SUSTATE_RESUMING, /**< Resuming - waiting for clock */
- SUSTATE_WAKINGUP_WAITING_HFCLK_WREQ, /**< Waking up - waiting for clock and WUREQ from driver */
- SUSTATE_WAKINGUP_WAITING_HFCLK, /**< Waking up - waiting for HFCLK (WUREQ detected) */
- SUSTATE_WAKINGUP_WAITING_WREQ, /**< Waking up - waiting for WREQ (HFCLK active) */
- }app_usbd_sustate_t;
- /**
- * @brief Current suspend state.
- *
- * The state of the suspend state machine.
- */
- static app_usbd_sustate_t m_sustate;
- /**
- * @brief Remote wake-up register/unregister.
- *
- * Counter incremented when appended instance required remote wake-up functionality.
- * It should be decremented when the class is removed.
- * When this counter is not zero, remote wake-up functionality is activated inside core.
- */
- static uint8_t m_rwu_registered_counter;
- /**
- * @brief Current configuration.
- */
- static app_usbd_config_t m_current_conf;
- /**
- * @brief Class interface call: event handler
- *
- * @ref app_usbd_class_interface_t::event_handler
- *
- * @param[in] p_cinst Class instance.
- * @param[in] p_event Event passed to class instance.
- *
- * @return Standard error code @ref ret_code_t
- * @retval NRF_SUCCESS event handled successfully.
- * @retval NRF_ERROR_NOT_SUPPORTED unsupported event.
- * */
- static inline ret_code_t class_event_handler(app_usbd_class_inst_t const * const p_cinst,
- app_usbd_complex_evt_t const * const p_event)
- {
- ASSERT(p_cinst != NULL);
- ASSERT(p_cinst->p_class_methods != NULL);
- ASSERT(p_cinst->p_class_methods->event_handler != NULL);
- return p_cinst->p_class_methods->event_handler(p_cinst, p_event);
- }
- #if (APP_USBD_CONFIG_EVENT_QUEUE_ENABLE) || defined(__SDK_DOXYGEN__)
- static inline void class_sof_interrupt_handler(app_usbd_class_inst_t const * const p_cinst,
- app_usbd_complex_evt_t const * const p_event)
- {
- ASSERT(p_cinst != NULL);
- ASSERT(p_cinst->p_data != NULL);
- ASSERT(p_cinst->p_data->sof_handler != NULL);
- p_cinst->p_data->sof_handler(p_event->drv_evt.data.sof.framecnt);
- }
- /**
- * @brief User event handler call (passed via configuration).
- *
- * @param p_event Handler of an event that is going to be added into queue.
- * @param queued The event is visible in the queue.
- */
- static inline void user_event_handler(app_usbd_internal_evt_t const * const p_event, bool queued)
- {
- if ((m_current_conf.ev_isr_handler) != NULL)
- {
- m_current_conf.ev_isr_handler(p_event, queued);
- }
- }
- #endif
- /**
- * @brief User event processor call (passed via configuration).
- *
- * @param event Event type.
- */
- static inline void user_event_state_proc(app_usbd_event_type_t event)
- {
- if ((m_current_conf.ev_state_proc) != NULL)
- {
- m_current_conf.ev_state_proc(event);
- }
- }
- /**
- * @brief Find a specified descriptor.
- *
- * @param[in] p_cinst Class instance.
- * @param[in] desc_type Descriptor type @ref app_usbd_descriptor_t
- * @param[in] desc_index Descriptor index.
- * @param[out] p_desc Pointer to escriptor.
- * @param[out] p_desc_len Length of descriptor.
- *
- * @return Standard error code @ref ret_code_t
- * @retval NRF_SUCCESS Descriptor successfully found.
- * @retval NRF_ERROR_NOT_FOUND Descriptor not found.
- * */
- ret_code_t app_usbd_class_descriptor_find(app_usbd_class_inst_t const * const p_cinst,
- uint8_t desc_type,
- uint8_t desc_index,
- uint8_t * p_desc,
- size_t * p_desc_len)
- {
- app_usbd_class_descriptor_ctx_t siz;
- APP_USBD_CLASS_DESCRIPTOR_INIT(&siz);
- uint32_t total_size = 0;
- while(p_cinst->p_class_methods->feed_descriptors(&siz, p_cinst, NULL, sizeof(uint8_t)))
- {
- total_size++;
- }
- uint8_t cur_len = 0;
- uint32_t cur_size = 0;
- uint8_t index = 0;
- app_usbd_class_descriptor_ctx_t descr;
- APP_USBD_CLASS_DESCRIPTOR_INIT(&descr);
- while(cur_size < total_size)
- {
- /* First byte of a descriptor is its size */
- UNUSED_RETURN_VALUE(p_cinst->p_class_methods->feed_descriptors(&descr,
- p_cinst,
- &cur_len,
- sizeof(uint8_t)));
- /* Second byte is type of the descriptor */
- uint8_t type;
- UNUSED_RETURN_VALUE(p_cinst->p_class_methods->feed_descriptors(&descr,
- p_cinst,
- &type,
- sizeof(uint8_t)));
- if(type == desc_type)
- {
- if(index == desc_index)
- {
- /* Copy the length of descriptor to *p_desc_len */
- *p_desc_len = cur_len;
- /* Two first bytes of descriptor have already been fed - copy them to *p_desc */
- *p_desc++ = cur_len;
- *p_desc++ = desc_type;
- /* Copy the rest of descriptor to *p_desc */
- UNUSED_RETURN_VALUE(p_cinst->p_class_methods->feed_descriptors(&descr,
- p_cinst,
- p_desc,
- cur_len-2));
- return NRF_SUCCESS;
- }
- else
- {
- index++;
- }
- }
- /* Fast-forward through unmatched descriptor */
- UNUSED_RETURN_VALUE(p_cinst->p_class_methods->feed_descriptors(&descr,
- p_cinst,
- NULL,
- cur_len-2));
- cur_size += cur_len;
- }
- return NRF_ERROR_NOT_FOUND;
- }
- /**
- * @brief Access into selected endpoint configuration structure.
- *
- * @param ep Endpoint address.
- * @return A pointer to the endpoint configuration structure.
- *
- * @note This function would assert when endpoint number is not correct and debugging is enabled.
- */
- static app_usbd_ep_conf_t * app_usbd_ep_conf_access(nrf_drv_usbd_ep_t ep)
- {
- if (NRF_USBD_EPIN_CHECK(ep))
- {
- uint8_t nr = NRF_USBD_EP_NR_GET(ep);
- ASSERT(nr < NRF_USBD_EPIN_CNT);
- return &m_epin_conf[nr];
- }
- else
- {
- uint8_t nr = NRF_USBD_EP_NR_GET(ep);
- ASSERT(nr < NRF_USBD_EPOUT_CNT);
- return &m_epout_conf[nr];
- }
- }
- /**
- * @brief Accessing instance connected with selected endpoint.
- *
- * @param ep Endpoint number.
- *
- * @return The pointer to the instance connected with endpoint.
- */
- static inline app_usbd_class_inst_t const * app_usbd_ep_instance_get(nrf_drv_usbd_ep_t ep)
- {
- return app_usbd_ep_conf_access(ep)->p_cinst;
- }
- /**
- * @brief Connect instance with selected endpoint.
- *
- * This function configures instance connected to endpoint but also sets
- * default event handler function pointer.
- *
- * @param ep Endpoint number.
- * @param p_cinst The instance to connect into the selected endpoint.
- * NULL if endpoint is going to be disconnected.
- *
- * @note Disconnecting EP0 is not allowed and protected by assertion.
- */
- static void app_usbd_ep_instance_set(nrf_drv_usbd_ep_t ep, app_usbd_class_inst_t const * p_cinst)
- {
- app_usbd_ep_conf_t * p_ep_conf = app_usbd_ep_conf_access(ep);
- /* Set instance and default event handler */
- p_ep_conf->p_cinst = p_cinst;
- if (p_cinst == NULL)
- {
- ASSERT((ep != NRF_DRV_USBD_EPOUT0) && (ep != NRF_DRV_USBD_EPIN0)); /* EP0 should never be disconnected */
- p_ep_conf->event_handler = NULL;
- }
- else
- {
- p_ep_conf->event_handler = p_cinst->p_class_methods->event_handler;
- }
- }
- /**
- * @brief Call the core handler.
- *
- * Core instance is special kind of instance that is connected only to endpoint 0.
- * It is not present in instance list.
- * This auxiliary function makes future changes easier.
- * Just call the event instance for core module here.
- */
- static inline ret_code_t app_usbd_core_handler_call(app_usbd_internal_evt_t const * const p_event)
- {
- return m_epout_conf[0].event_handler(
- m_epout_conf[0].p_cinst,
- (app_usbd_complex_evt_t const *)p_event);
- }
- /**
- * @brief Add event for execution.
- *
- * Dependent on configuration event would be executed in place or would be added into queue
- * to be executed later.
- *
- * @param p_event_input Event to be executed.
- */
- static inline void app_usbd_event_add(app_usbd_internal_evt_t const * const p_event_input)
- {
- app_usbd_internal_evt_t const * p_event = p_event_input;
- if (p_event->type == APP_USBD_EVT_DRV_SETUP)
- {
- uint8_t bRequest = nrf_usbd_setup_brequest_get();
- uint8_t bmRequestType = nrf_usbd_setup_bmrequesttype_get();
- if ((bmRequestType == app_usbd_setup_req_val(
- APP_USBD_SETUP_REQREC_DEVICE,
- APP_USBD_SETUP_REQTYPE_STD,
- APP_USBD_SETUP_REQDIR_OUT))
- && (bRequest == APP_USBD_SETUP_STDREQ_SET_ADDRESS))
- {
- static const app_usbd_internal_evt_t event_setaddress =
- {
- .type = APP_USBD_EVT_SETUP_SETADDRESS,
- };
- p_event = &event_setaddress;
- }
- }
- #if (APP_USBD_CONFIG_EVENT_QUEUE_ENABLE)
- if (p_event->app_evt.type == APP_USBD_EVT_DRV_SOF)
- {
- /* Propagate SOF event to classes that need it in interrupt */
- app_usbd_class_inst_t const * p_inst = app_usbd_class_sof_interrupt_first_get();
- while (NULL != p_inst)
- {
- class_sof_interrupt_handler(p_inst, (app_usbd_complex_evt_t const *)p_event);
- p_inst = app_usbd_class_sof_interrupt_next_get(p_inst);
- }
- #if (APP_USBD_CONFIG_SOF_HANDLING_MODE == APP_USBD_SOF_HANDLING_COMPRESS_QUEUE)
- CRITICAL_REGION_ENTER();
- if (m_sof_events_cnt == 0)
- {
- m_event_frame = p_event->drv_evt.data.sof.framecnt;
- }
- UNUSED_RETURN_VALUE(nrf_atomic_u32_add(&m_sof_events_cnt, 1));
- CRITICAL_REGION_EXIT();
- user_event_handler(p_event, true);
- if (m_sof_events_cnt == APP_USBD_SOF_WARNING_LIMIT)
- {
- NRF_LOG_WARNING("Stacked over %d SOF events.", APP_USBD_SOF_WARNING_LIMIT);
- }
- return;
-
- #endif // (APP_USBD_CONFIG_SOF_HANDLING_MODE == APP_USBD_SOF_HANDLING_COMPRESS_QUEUE)
- #if (APP_USBD_CONFIG_SOF_HANDLING_MODE == APP_USBD_SOF_HANDLING_INTERRUPT)
- user_event_handler(p_event, false);
- app_usbd_event_execute(p_event);
- return;
- #endif // (APP_USBD_CONFIG_SOF_HANDLING_MODE == APP_USBD_SOF_HANDLING_INTERRUPT)
- }
- nrf_atfifo_item_put_t cx;
- app_usbd_internal_queue_evt_t * p_event_item = nrf_atfifo_item_alloc(m_event_queue, &cx);
- if (NULL != p_event_item)
- {
- bool visible;
- p_event_item->evt = *p_event;
- #if (APP_USBD_CONFIG_SOF_HANDLING_MODE == APP_USBD_SOF_HANDLING_COMPRESS_QUEUE)
- CRITICAL_REGION_ENTER();
- p_event_item->start_frame = m_event_frame - m_sof_events_cnt + 1;
- p_event_item->sof_cnt = nrf_atomic_u32_fetch_store(&m_sof_events_cnt, 0);
- CRITICAL_REGION_EXIT();
- #endif // (APP_USBD_CONFIG_SOF_HANDLING_MODE == APP_USBD_SOF_HANDLING_COMPRESS_QUEUE)
- visible = nrf_atfifo_item_put(m_event_queue, &cx);
- user_event_handler(p_event, visible);
- }
- else
- {
- NRF_LOG_ERROR("Event queue full.");
- }
- #else
- m_current_conf.ev_handler(p_event);
- #endif
- }
- /**
- * @brief Power event handler.
- *
- * The function that pushes power events into the queue.
- * @param p_event Event from power driver to map into APP_USBD_EVT_POWER_ event.
- */
- #if APP_USBD_CONFIG_POWER_EVENTS_PROCESS
- static void app_usbd_power_event_handler(nrf_drv_power_usb_evt_t event)
- {
- switch(event)
- {
- case NRF_DRV_POWER_USB_EVT_DETECTED:
- {
- static const app_usbd_internal_evt_t ev = {
- .type = APP_USBD_EVT_POWER_DETECTED
- };
- app_usbd_event_add(&ev);
- break;
- }
- case NRF_DRV_POWER_USB_EVT_REMOVED:
- {
- static const app_usbd_internal_evt_t ev = {
- .type = APP_USBD_EVT_POWER_REMOVED
- };
- app_usbd_event_add(&ev);
- break;
- }
- case NRF_DRV_POWER_USB_EVT_READY:
- {
- static const app_usbd_internal_evt_t ev = {
- .type = APP_USBD_EVT_POWER_READY
- };
- app_usbd_event_add(&ev);
- break;
- }
- default:
- ASSERT(false);
- }
- }
- #endif
- /**
- * @brief Event handler.
- *
- * The function that pushes the event into the queue.
- * @param p_event Event to push.
- */
- static void app_usbd_event_handler(nrf_drv_usbd_evt_t const * const p_event)
- {
- app_usbd_event_add((app_usbd_internal_evt_t const *)p_event);
- }
- /**
- * @brief HF clock ready event handler.
- *
- * Function that is called when high frequency clock is started.
- *
- * @param event Event type that comes from clock driver.
- */
- static void app_usbd_hfclk_ready(nrf_drv_clock_evt_type_t event)
- {
- ASSERT(NRF_DRV_CLOCK_EVT_HFCLK_STARTED == event);
- static const app_usbd_evt_t evt_data = {
- .type = APP_USBD_EVT_HFCLK_READY
- };
- app_usbd_event_add((app_usbd_internal_evt_t const * )&evt_data);
- }
- /**
- * @brief Check if the HFCLK was requested in selected suspend state machine state.
- *
- *
- * @param sustate State to be checked.
- *
- * @retval true High frequency clock was requested in selected state.
- * @retval false High frequency clock was released in selected state.
- */
- static inline bool app_usbd_sustate_with_requested_hfclk(app_usbd_sustate_t sustate)
- {
- switch(sustate)
- {
- case SUSTATE_STOPPED: return false;
- case SUSTATE_STARTED: return false;
- case SUSTATE_ACTIVE: return true;
- case SUSTATE_SUSPENDING: return false;
- case SUSTATE_SUSPEND: return false;
- case SUSTATE_RESUMING: return true;
- case SUSTATE_WAKINGUP_WAITING_HFCLK_WREQ: return true;
- case SUSTATE_WAKINGUP_WAITING_HFCLK: return true;
- case SUSTATE_WAKINGUP_WAITING_WREQ: return true;
- default:
- return false;
- }
- }
- /**
- * @brief Check it the HFCLK is running in selected suspend state machine state.
- *
- * @param sustate State to be checked.
- *
- * @retval true High frequency clock is running in selected state.
- * @retval false High frequency clock is released in selected state.
- */
- static inline bool app_usbd_sustate_with_running_hfclk(app_usbd_sustate_t sustate)
- {
- switch(sustate)
- {
- case SUSTATE_STOPPED: return false;
- case SUSTATE_STARTED: return false;
- case SUSTATE_ACTIVE: return true;
- case SUSTATE_SUSPENDING: return false;
- case SUSTATE_SUSPEND: return false;
- case SUSTATE_RESUMING: return false;
- case SUSTATE_WAKINGUP_WAITING_HFCLK_WREQ: return false;
- case SUSTATE_WAKINGUP_WAITING_HFCLK: return false;
- case SUSTATE_WAKINGUP_WAITING_WREQ: return true;
- default:
- return false;
- }
- }
- /**
- * @brief Get current suspend state machine state.
- *
- * @return The state of the suspend state machine.
- */
- static inline app_usbd_sustate_t sustate_get(void)
- {
- return m_sustate;
- }
- /**
- * @brief Set current suspend state machine state.
- *
- * @param sustate The requested state of the state machine.
- */
- static inline void sustate_set(app_usbd_sustate_t sustate)
- {
- if (app_usbd_sustate_with_requested_hfclk(sustate) != app_usbd_sustate_with_requested_hfclk(m_sustate))
- {
- if (app_usbd_sustate_with_requested_hfclk(sustate))
- {
- static nrf_drv_clock_handler_item_t clock_handler_item =
- {
- .event_handler = app_usbd_hfclk_ready
- };
- nrf_drv_clock_hfclk_request(&clock_handler_item);
- }
- else
- {
- nrf_drv_clock_hfclk_release();
- }
- }
- if (app_usbd_sustate_with_running_hfclk(sustate) != app_usbd_sustate_with_running_hfclk(m_sustate))
- {
- if (app_usbd_sustate_with_running_hfclk(sustate))
- {
- nrf_drv_usbd_active_irq_config();
- }
- else
- {
- nrf_drv_usbd_suspend_irq_config();
- }
- }
- m_sustate = sustate;
- }
- /**
- * @brief Default selection function for interface.
- *
- * This function just enables and clears interface endpoints.
- *
- * @param[in] p_inst Class instance.
- * @param[in] iface_idx Interface index.
- * @param[in] alternate Interface alternate setting.
- *
- * @note Currently only alternate setting 0 is supported.
- *
- * @return Standard error code @ref ret_code_t
- * @retval NRF_SUCCESS Endpoints enabled and cleared.
- * @retval NRF_ERROR_INVALID_PARAM Unsupported alternate selected.
- */
- static inline ret_code_t default_iface_select(
- app_usbd_class_inst_t const * const p_inst,
- uint8_t iface_idx,
- uint8_t alternate)
- {
- ASSERT(iface_idx <= app_usbd_class_iface_count_get(p_inst));
- if (alternate != 0)
- {
- return NRF_ERROR_INVALID_PARAM;
- }
- app_usbd_class_iface_conf_t const * p_iface = app_usbd_class_iface_get(p_inst, iface_idx);
- uint8_t ep_count = app_usbd_class_iface_ep_count_get(p_iface);
- for (uint8_t i = 0; i < ep_count; ++i)
- {
- /* Enable every endpoint */
- app_usbd_class_ep_conf_t const * p_ep = app_usbd_class_iface_ep_get(p_iface, i);
- app_usbd_ep_enable(p_ep->address);
- }
- return NRF_SUCCESS;
- }
- /**
- * @brief Default deselection function for interface.
- *
- * This function just disables all interface endpoints.
- *
- * @param[in] p_inst Class instance.
- * @param[in] iface_idx Interface index.
- */
- static inline void default_iface_deselect(
- app_usbd_class_inst_t const * const p_inst,
- uint8_t iface_idx)
- {
- ASSERT(iface_idx <= app_usbd_class_iface_count_get(p_inst));
- app_usbd_class_iface_conf_t const * p_iface = app_usbd_class_iface_get(p_inst, iface_idx);
- uint8_t ep_count = app_usbd_class_iface_ep_count_get(p_iface);
- for (uint8_t i = 0; i < ep_count; ++i)
- {
- /* Disable every endpoint */
- app_usbd_class_ep_conf_t const * p_ep = app_usbd_class_iface_ep_get(p_iface, i);
- app_usbd_ep_disable(p_ep->address);
- }
- }
- /** @} */
- #if (APP_USBD_PROVIDE_SOF_TIMESTAMP) || defined(__SDK_DOXYGEN__)
- uint32_t app_usbd_sof_timestamp_get(void)
- {
- return m_last_frame;
- }
- #endif
- ret_code_t app_usbd_init(app_usbd_config_t const * p_config)
- {
- ASSERT(nrf_drv_clock_init_check());
- ret_code_t ret;
- #if (APP_USBD_CONFIG_EVENT_QUEUE_ENABLE) || defined(__SDK_DOXYGEN__)
- ret = NRF_ATFIFO_INIT(m_event_queue);
- if (NRF_SUCCESS != ret)
- {
- return NRF_ERROR_INTERNAL;
- }
- #endif
- /* This is called at the beginning to secure multiple calls to init function */
- ret = nrf_drv_usbd_init(app_usbd_event_handler);
- if (NRF_SUCCESS != ret)
- {
- return ret;
- }
- /* Clear the variables */
- m_sustate = SUSTATE_STOPPED;
- m_p_first_cinst = NULL;
- m_p_first_sof_cinst = NULL;
- memset(m_epin_conf , 0, sizeof(m_epin_conf ));
- memset(m_epout_conf, 0, sizeof(m_epout_conf));
- /* Save the new configuration */
- if (p_config == NULL)
- {
- m_current_conf = m_default_conf;
- }
- else
- {
- m_current_conf = *p_config;
- }
- #if (!(APP_USBD_CONFIG_EVENT_QUEUE_ENABLE))
- if(m_current_conf.ev_handler == NULL)
- {
- m_current_conf.ev_handler = m_default_conf.ev_handler;
- }
- #endif
- #if APP_USBD_CONFIG_POWER_EVENTS_PROCESS
- ret = nrf_drv_power_init(NULL);
- if ((ret != NRF_SUCCESS) && (ret != NRF_ERROR_MODULE_ALREADY_INITIALIZED))
- {
- /* This should never happen */
- APP_ERROR_HANDLER(ret);
- }
- #endif
- /*Pin core class to required endpoints*/
- uint8_t iface_idx;
- app_usbd_class_iface_conf_t const * p_iface;
- app_usbd_class_inst_t const * const p_inst = app_usbd_core_instance_access();
- iface_idx = 0;
- while ((p_iface = app_usbd_class_iface_get(p_inst, iface_idx++)) != NULL)
- {
- uint8_t ep_idx = 0;
- app_usbd_class_ep_conf_t const * p_ep;
- while ((p_ep = app_usbd_class_iface_ep_get(p_iface, ep_idx++)) != NULL)
- {
- app_usbd_ep_instance_set(app_usbd_class_ep_address_get(p_ep), p_inst);
- }
- }
- /* Successfully attached */
- const app_usbd_evt_t evt_data = {
- .type = APP_USBD_EVT_INST_APPEND
- };
- ret = class_event_handler(p_inst, (app_usbd_complex_evt_t const *)(&evt_data));
- if (NRF_SUCCESS != ret)
- {
- UNUSED_RETURN_VALUE(nrf_drv_usbd_uninit());
- return ret;
- }
- return NRF_SUCCESS;
- }
- ret_code_t app_usbd_uninit(void)
- {
- #if APP_USBD_CONFIG_POWER_EVENTS_PROCESS
- nrf_drv_power_usbevt_uninit();
- #endif
- /* We get this error at very beginning but it would be used at the end of the function */
- const ret_code_t ret = nrf_drv_usbd_uninit();
- /* Unchain instance list */
- app_usbd_class_inst_t const * * pp_inst;
- pp_inst = &m_p_first_cinst;
- while (NULL != (*pp_inst))
- {
- app_usbd_class_inst_t const * * pp_next = &app_usbd_class_data_access(*pp_inst)->p_next;
- (*pp_inst) = NULL;
- pp_inst = pp_next;
- }
- /* Unchain SOF list */
- pp_inst = &m_p_first_sof_cinst;
- while (NULL != (*pp_inst))
- {
- app_usbd_class_inst_t const * * pp_next = &app_usbd_class_data_access(*pp_inst)->p_sof_next;
- (*pp_inst) = NULL;
- pp_inst = pp_next;
- }
-
- /* Unchain SOF interrupt list */
- pp_inst = &m_p_first_sof_interrupt_cinst;
- while (NULL != (*pp_inst))
- {
- app_usbd_class_inst_t const * * pp_next = &app_usbd_class_data_access(*pp_inst)->p_sof_next;
- (*pp_inst) = NULL;
- pp_inst = pp_next;
- }
- /* Clear all endpoints configurations */
- memset(m_epin_conf , 0, sizeof(m_epin_conf ));
- memset(m_epout_conf, 0, sizeof(m_epout_conf));
- /* Clear current configuration */
- memset(&m_current_conf, 0, sizeof(m_current_conf));
- return ret;
- }
- #if APP_USBD_CONFIG_POWER_EVENTS_PROCESS
- ret_code_t app_usbd_power_events_enable(void)
- {
- if (!nrf_drv_usbd_is_initialized() || nrf_drv_usbd_is_enabled())
- {
- return NRF_ERROR_INVALID_STATE;
- }
- ASSERT((!APP_USBD_CONFIG_EVENT_QUEUE_ENABLE) || (USBD_CONFIG_IRQ_PRIORITY == POWER_CONFIG_IRQ_PRIORITY));
- ret_code_t ret;
- static const nrf_drv_power_usbevt_config_t config =
- {
- .handler = app_usbd_power_event_handler
- };
- ret = nrf_drv_power_usbevt_init(&config);
- APP_ERROR_CHECK(ret);
- return NRF_SUCCESS;
- }
- #endif /* APP_USBD_CONFIG_POWER_EVENTS_PROCESS */
- void app_usbd_enable(void)
- {
- nrf_drv_usbd_enable();
- }
- void app_usbd_disable(void)
- {
- ASSERT(!nrf_drv_usbd_is_started());
- nrf_drv_usbd_disable();
- }
- void app_usbd_start(void)
- {
- ASSERT(nrf_drv_usbd_is_enabled());
- /* Check if interface numbers are in correct order */
- if (APP_USBD_CONFIG_LOG_ENABLED)
- {
- uint8_t next_iface = 0;
- for (app_usbd_class_inst_t const * * pp_inst = &m_p_first_cinst;
- (*pp_inst) != NULL;
- pp_inst = &(app_usbd_class_data_access(*pp_inst)->p_next))
- {
- uint8_t iface_idx = 0;
- app_usbd_class_iface_conf_t const * p_iface;
- while (NULL != (p_iface = app_usbd_class_iface_get(*pp_inst, iface_idx++)))
- {
- if (p_iface->number != next_iface)
- {
- NRF_LOG_WARNING("Unexpected interface number, expected %d, got %d",
- next_iface,
- p_iface->number);
- }
- ++next_iface;
- }
- }
- }
- /* Power should be already enabled - wait just in case if user calls
- * app_usbd_start just after app_usbd_enable without waiting for the event. */
- while (!nrf_power_usbregstatus_outrdy_get())
- {
- /* Wait for the power but terminate the function if USBD power disappears */
- if (!nrf_power_usbregstatus_vbusdet_get())
- return;
- }
- static const app_usbd_evt_t evt_data = {
- .type = APP_USBD_EVT_START_REQ
- };
- app_usbd_event_add((app_usbd_internal_evt_t const * )&evt_data);
- }
- void app_usbd_stop(void)
- {
- const app_usbd_evt_t evt_data = {
- .type = APP_USBD_EVT_STOP_REQ
- };
- app_usbd_event_add((app_usbd_internal_evt_t const * )&evt_data);
- }
- void app_usbd_suspend_req(void)
- {
- const app_usbd_evt_t evt_data = {
- .type = APP_USBD_EVT_SUSPEND_REQ
- };
- app_usbd_event_add((app_usbd_internal_evt_t const * )&evt_data);
- }
- bool app_usbd_wakeup_req(void)
- {
- ASSERT(app_usbd_class_rwu_enabled_check());
- if (!app_usbd_core_feature_state_get(APP_USBD_SETUP_STDFEATURE_DEVICE_REMOTE_WAKEUP))
- return false;
- const app_usbd_evt_t evt_data = {
- .type = APP_USBD_EVT_WAKEUP_REQ
- };
- app_usbd_event_add((app_usbd_internal_evt_t const * )&evt_data);
- return true;
- }
- bool app_usbd_active_check(void)
- {
- return (sustate_get() == SUSTATE_ACTIVE);
- }
- void app_usbd_event_execute(app_usbd_internal_evt_t const * const p_event)
- {
- ASSERT(NULL != m_p_first_cinst);
- /* If no event queue is implemented, it has to be ensured that this function is never called
- * from the context higher than USB interrupt level
- * If queue is implemented it would be called always from Thread level
- * if the library is used correctly.
- * NOTE: Higher interrupt level -> lower priority value.
- */
- ASSERT(USBD_CONFIG_IRQ_PRIORITY <= current_int_priority_get());
- /* Note - there should never be situation that event is generated on disconnected endpoint */
- switch (p_event->type)
- {
- case APP_USBD_EVT_START_REQ:
- {
- static const app_usbd_evt_t evt_data = {
- .type = APP_USBD_EVT_STARTED
- };
- /* Send event to all classes */
- UNUSED_RETURN_VALUE(app_usbd_core_handler_call((app_usbd_internal_evt_t const * )&evt_data));
- app_usbd_all_call((app_usbd_complex_evt_t const *)&evt_data);
- user_event_state_proc(APP_USBD_EVT_STARTED);
- app_usbd_all_iface_deselect();
- app_usbd_core_ep0_disable();
- nrf_drv_usbd_start((NULL != m_p_first_sof_cinst) || (m_current_conf.enable_sof) || (APP_USBD_PROVIDE_SOF_TIMESTAMP));
- sustate_set(SUSTATE_STARTED);
- break;
- }
- case APP_USBD_EVT_STOP_REQ:
- {
- static const app_usbd_evt_t evt_data = {
- .type = APP_USBD_EVT_STOPPED
- };
- app_usbd_all_iface_deselect();
- nrf_drv_usbd_stop();
- sustate_set(SUSTATE_STOPPED);
- /* Send event to all classes */
- app_usbd_all_call((app_usbd_complex_evt_t const * )&evt_data);
- UNUSED_RETURN_VALUE(app_usbd_core_handler_call((app_usbd_internal_evt_t const *)&evt_data));
- user_event_state_proc(APP_USBD_EVT_STOPPED);
- if (app_usbd_sustate_with_requested_hfclk(sustate_get()))
- {
- nrf_drv_clock_hfclk_release();
- }
- break;
- }
- case APP_USBD_EVT_HFCLK_READY:
- {
- switch(sustate_get())
- {
- case SUSTATE_RESUMING:
- {
- sustate_set(SUSTATE_ACTIVE);
- break;
- }
- case SUSTATE_WAKINGUP_WAITING_HFCLK_WREQ:
- {
- sustate_set(SUSTATE_WAKINGUP_WAITING_WREQ);
- break;
- }
- case SUSTATE_WAKINGUP_WAITING_HFCLK:
- {
- sustate_set(SUSTATE_ACTIVE);
- break;
- }
- default:
- break; // Just ignore - it can happen in specific situation
- }
- break;
- }
- case APP_USBD_EVT_SUSPEND_REQ:
- {
- /* Suspend request can be only processed when we are in suspending state */
- if (SUSTATE_SUSPENDING == sustate_get())
- {
- if (nrf_drv_usbd_suspend())
- {
- sustate_set(SUSTATE_SUSPEND);
- }
- }
- break;
- }
- case APP_USBD_EVT_WAKEUP_REQ:
- {
- /* Suspend temporary if no suspend function was called from the application.
- * This makes it possible to generate APP_USBD_EVT_DRV_WUREQ event from the driver */
- if (sustate_get() == SUSTATE_SUSPENDING)
- {
- if (nrf_drv_usbd_suspend())
- {
- sustate_set(SUSTATE_SUSPEND);
- }
- }
- if (nrf_drv_usbd_wakeup_req())
- {
- sustate_set(SUSTATE_WAKINGUP_WAITING_HFCLK_WREQ);
- }
- break;
- }
- case APP_USBD_EVT_DRV_SOF:
- {
- #if (APP_USBD_PROVIDE_SOF_TIMESTAMP) || defined(__SDK_DOXYGEN__)
- m_last_frame = p_event->drv_evt.data.sof.framecnt;
- #endif
- /* Wake up if suspended */
- if ((sustate_get() == SUSTATE_SUSPENDING) || (sustate_get() == SUSTATE_WAKINGUP_WAITING_WREQ))
- {
- static const app_usbd_evt_t evt_data = {
- .type = APP_USBD_EVT_DRV_RESUME
- };
- app_usbd_event_execute((app_usbd_internal_evt_t *)&evt_data);
- }
-
- user_event_state_proc(APP_USBD_EVT_DRV_SOF);
- app_usbd_class_inst_t const * p_inst = app_usbd_class_sof_first_get();
- while (NULL != p_inst)
- {
- ret_code_t r = class_event_handler(p_inst, (app_usbd_complex_evt_t const *)p_event);
- UNUSED_VARIABLE(r);
- p_inst = app_usbd_class_sof_next_get(p_inst);
- }
- break;
- }
- case APP_USBD_EVT_DRV_RESET:
- {
- app_usbd_all_iface_deselect();
- app_usbd_core_ep0_enable();
- sustate_set(SUSTATE_ACTIVE);
- user_event_state_proc(APP_USBD_EVT_DRV_RESET);
- /* Processing core interface (connected only to EP0) and then all instances from the list */
- UNUSED_RETURN_VALUE(app_usbd_core_handler_call(p_event));
- app_usbd_all_call((app_usbd_complex_evt_t const *)p_event);
- break;
- }
- case APP_USBD_EVT_DRV_RESUME:
- {
- if (sustate_get() == SUSTATE_WAKINGUP_WAITING_WREQ)
- {
- sustate_set(SUSTATE_ACTIVE);
- nrf_drv_usbd_force_bus_wakeup();
- }
- else
- {
- sustate_set(SUSTATE_RESUMING);
- }
- user_event_state_proc(APP_USBD_EVT_DRV_RESUME);
- /* Processing core interface (connected only to EP0) and then all instances from the list */
- UNUSED_RETURN_VALUE(app_usbd_core_handler_call(p_event));
- app_usbd_all_call((app_usbd_complex_evt_t const *)p_event);
- break;
- }
- case APP_USBD_EVT_DRV_WUREQ:
- {
- static const app_usbd_evt_t evt_data = {
- .type = APP_USBD_EVT_DRV_RESUME
- };
- user_event_state_proc(APP_USBD_EVT_DRV_RESUME);
- /* Processing core interface (connected only to EP0) and then all instances from the list */
- UNUSED_RETURN_VALUE(app_usbd_core_handler_call((app_usbd_internal_evt_t const *)&evt_data));
- app_usbd_all_call((app_usbd_complex_evt_t const *)&evt_data);
- switch(sustate_get())
- {
- case SUSTATE_WAKINGUP_WAITING_HFCLK_WREQ:
- sustate_set(SUSTATE_WAKINGUP_WAITING_HFCLK);
- break;
- case SUSTATE_WAKINGUP_WAITING_WREQ:
- sustate_set(SUSTATE_ACTIVE);
- break;
- default:
- {
- /* This should not happen - but try to recover by setting directly active state */
- NRF_LOG_WARNING("Unexpected state on WUREQ event (%u)", sustate_get());
- sustate_set(SUSTATE_ACTIVE);
- }
- }
- break;
- }
- case APP_USBD_EVT_DRV_SUSPEND:
- {
- sustate_set(SUSTATE_SUSPENDING);
- user_event_state_proc(APP_USBD_EVT_DRV_SUSPEND);
- /* Processing all instances from the list and then core interface (connected only to EP0) */
- app_usbd_all_call((app_usbd_complex_evt_t const *)p_event);
- UNUSED_RETURN_VALUE(app_usbd_core_handler_call(p_event));
- break;
- }
- case APP_USBD_EVT_STATE_CHANGED:
- {
- user_event_state_proc(APP_USBD_EVT_STATE_CHANGED);
- /* Processing all instances from the list and then core interface (connected only to EP0) */
- app_usbd_all_call((app_usbd_complex_evt_t const *)p_event);
- break;
- }
- case APP_USBD_EVT_DRV_SETUP:
- {
- UNUSED_RETURN_VALUE(app_usbd_core_handler_call(p_event));
- break;
- }
- case APP_USBD_EVT_SETUP_SETADDRESS:
- {
- UNUSED_RETURN_VALUE(app_usbd_core_handler_call(p_event));
- break;
- }
- case APP_USBD_EVT_DRV_EPTRANSFER:
- {
- app_usbd_ep_conf_t const * p_ep_conf =
- app_usbd_ep_conf_access(p_event->drv_evt.data.eptransfer.ep);
- ASSERT(NULL != p_ep_conf->p_cinst);
- ASSERT(NULL != p_ep_conf->event_handler);
- if (NRF_SUCCESS != p_ep_conf->event_handler(p_ep_conf->p_cinst,
- (app_usbd_complex_evt_t const *)p_event))
- {
- /* If error returned, every bulk/interrupt endpoint would be stalled */
- if (!(0 == NRF_USBD_EP_NR_GET(p_event->drv_evt.data.eptransfer.ep) ||
- NRF_USBD_EPISO_CHECK(p_event->drv_evt.data.eptransfer.ep)))
- {
- nrf_drv_usbd_ep_stall(p_event->drv_evt.data.eptransfer.ep);
- }
- }
- break;
- }
- #if APP_USBD_CONFIG_POWER_EVENTS_PROCESS
- case APP_USBD_EVT_POWER_DETECTED:
- {
- user_event_state_proc(APP_USBD_EVT_POWER_DETECTED);
- app_usbd_all_call((app_usbd_complex_evt_t const *)p_event);
- break;
- }
- case APP_USBD_EVT_POWER_REMOVED:
- {
- user_event_state_proc(APP_USBD_EVT_POWER_REMOVED);
- app_usbd_all_call((app_usbd_complex_evt_t const *)p_event);
- break;
- }
- case APP_USBD_EVT_POWER_READY:
- {
- user_event_state_proc(APP_USBD_EVT_POWER_READY);
- app_usbd_all_call((app_usbd_complex_evt_t const *)p_event);
- break;
- }
- #endif
- default:
- ASSERT(0);
- break;
- }
- }
- #if (APP_USBD_CONFIG_EVENT_QUEUE_ENABLE) || defined(__SDK_DOXYGEN__)
- bool app_usbd_event_queue_process(void)
- {
- #if (APP_USBD_CONFIG_SOF_HANDLING_MODE == APP_USBD_SOF_HANDLING_COMPRESS_QUEUE)
- app_usbd_internal_evt_t sof_event = {
- .app_evt.type = APP_USBD_EVT_DRV_SOF
- };
- #endif // (APP_USBD_CONFIG_SOF_HANDLING_MODE == APP_USBD_SOF_HANDLING_COMPRESS_QUEUE)
- static nrf_atfifo_item_get_t cx;
- static app_usbd_internal_queue_evt_t * p_event_item = NULL;
- if (NULL == p_event_item)
- {
- p_event_item = nrf_atfifo_item_get(m_event_queue, &cx);
- }
- if (NULL != p_event_item)
- {
- #if (APP_USBD_CONFIG_SOF_HANDLING_MODE == APP_USBD_SOF_HANDLING_COMPRESS_QUEUE)
- if (p_event_item->sof_cnt > 0)
- {
- if (p_event_item->start_frame > USBD_FRAMECNTR_FRAMECNTR_Msk)
- {
- p_event_item->start_frame = 0;
- }
- sof_event.drv_evt.data.sof.framecnt = (p_event_item->start_frame)++;
- --(p_event_item->sof_cnt);
- app_usbd_event_execute(&sof_event);
- return true;
- }
- #endif // (APP_USBD_CONFIG_SOF_HANDLING_MODE == APP_USBD_SOF_HANDLING_COMPRESS_QUEUE)
- app_usbd_event_execute(&(p_event_item->evt));
- UNUSED_RETURN_VALUE(nrf_atfifo_item_free(m_event_queue, &cx));
- p_event_item = NULL;
- return true;
- }
- #if (APP_USBD_CONFIG_SOF_HANDLING_MODE == APP_USBD_SOF_HANDLING_COMPRESS_QUEUE)
- else if (m_sof_events_cnt > 0)
- {
- CRITICAL_REGION_ENTER();
- if (m_event_frame > USBD_FRAMECNTR_FRAMECNTR_Msk)
- {
- m_event_frame = 0;
- }
- sof_event.drv_evt.data.sof.framecnt = m_event_frame++;
- UNUSED_RETURN_VALUE(nrf_atomic_u32_sub_hs(&m_sof_events_cnt, 1));
- CRITICAL_REGION_EXIT();
- app_usbd_event_execute(&sof_event);
- return true;
- }
- #endif // (APP_USBD_CONFIG_SOF_HANDLING_MODE == APP_USBD_SOF_HANDLING_COMPRESS_QUEUE)
- else
- {
- return false;
- }
- }
- #endif
- ret_code_t app_usbd_class_append(app_usbd_class_inst_t const * p_cinst)
- {
- ASSERT(NULL != p_cinst);
- ASSERT(NULL != p_cinst->p_class_methods);
- ASSERT(NULL != p_cinst->p_class_methods->event_handler);
- ASSERT(NULL == app_usbd_class_data_access(p_cinst)->p_next);
- /* This should be only called if USBD is disabled
- * We simply assume that USBD is enabled if its interrupts are */
- ASSERT(!nrf_drv_usbd_is_enabled() && nrf_drv_usbd_is_initialized());
- /* Check if all required endpoints are available
- * Checking is splitted from setting to avoid situation that anything
- * is modified and then operation finishes with error */
- uint8_t iface_idx;
- app_usbd_class_iface_conf_t const * p_iface;
- iface_idx = 0;
- while (NULL != (p_iface = app_usbd_class_iface_get(p_cinst, iface_idx++)))
- {
- uint8_t ep_idx = 0;
- app_usbd_class_ep_conf_t const * p_ep;
- while (NULL != (p_ep = app_usbd_class_iface_ep_get(p_iface, ep_idx++)))
- {
- if (NULL != app_usbd_ep_instance_get(app_usbd_class_ep_address_get(p_ep)))
- {
- return NRF_ERROR_BUSY;
- }
- }
- }
- /* Connecting all required endpoints */
- iface_idx = 0;
- while (NULL != (p_iface = app_usbd_class_iface_get(p_cinst, iface_idx++)))
- {
- uint8_t ep_idx = 0;
- app_usbd_class_ep_conf_t const * p_ep;
- while (NULL != (p_ep = app_usbd_class_iface_ep_get(p_iface, ep_idx++)))
- {
- app_usbd_ep_instance_set(app_usbd_class_ep_address_get(p_ep), p_cinst);
- }
- }
- /* Adding pointer to this instance to the end of the chain */
- app_usbd_class_inst_t const * * pp_last = &m_p_first_cinst;
- while (NULL != (*pp_last))
- {
- ASSERT((*pp_last) != p_cinst);
- pp_last = &(app_usbd_class_data_access(*pp_last)->p_next);
- }
- (*pp_last) = p_cinst;
- /* Successfully attached */
- const app_usbd_evt_t evt_data = {.type = APP_USBD_EVT_INST_APPEND };
- return class_event_handler(p_cinst, (app_usbd_complex_evt_t const *)(&evt_data));
- }
- ret_code_t app_usbd_class_remove(app_usbd_class_inst_t const * p_cinst)
- {
- ASSERT(NULL != p_cinst);
- ASSERT(NULL != p_cinst->p_class_methods);
- ASSERT(NULL != p_cinst->p_class_methods->event_handler);
- /* This function should be only called if USBD is disabled */
- ASSERT(!nrf_drv_usbd_is_enabled() && nrf_drv_usbd_is_initialized());
- ret_code_t ret;
- /* Remove this class from the chain */
- app_usbd_class_inst_t const * * pp_last = &m_p_first_cinst;
- while (NULL != (*pp_last))
- {
- if ((*pp_last) == p_cinst)
- {
- /* Inform class instance that removing process is going to be started */
- const app_usbd_evt_t evt_data = {
- .type = APP_USBD_EVT_INST_REMOVE
- };
- ret = class_event_handler(p_cinst, (app_usbd_complex_evt_t const *)(&evt_data));
- if (ret != NRF_SUCCESS)
- {
- return ret;
- }
- /* Breaking chain */
- (*pp_last) = (app_usbd_class_data_access(p_cinst)->p_next);
- app_usbd_class_data_access(p_cinst)->p_next = NULL;
- /* Disconnecting endpoints */
- uint8_t ep_idx;
- for (ep_idx = 0; ep_idx < NRF_USBD_EPIN_CNT; ++ep_idx)
- {
- nrf_drv_usbd_ep_t ep = NRF_DRV_USBD_EPIN(ep_idx);
- if (app_usbd_ep_instance_get(ep) == p_cinst)
- {
- app_usbd_ep_instance_set(ep, NULL);
- }
- }
- for (ep_idx = 0; ep_idx < NRF_USBD_EPOUT_CNT; ++ep_idx)
- {
- nrf_drv_usbd_ep_t ep = NRF_DRV_USBD_EPOUT(ep_idx);
- if (app_usbd_ep_instance_get(ep) == p_cinst)
- {
- app_usbd_ep_instance_set(ep, NULL);
- }
- }
- return NRF_SUCCESS;
- }
- pp_last = &(app_usbd_class_data_access(*pp_last)->p_next);
- }
- return NRF_ERROR_NOT_FOUND;
- }
- ret_code_t app_usbd_class_remove_all(void)
- {
- ret_code_t ret = NRF_SUCCESS;
- while (NULL != m_p_first_cinst)
- {
- ret = app_usbd_class_remove(m_p_first_cinst);
- if (ret != NRF_SUCCESS)
- {
- break;
- }
- }
- return ret;
- }
- ret_code_t app_usbd_ep_handler_set(app_usbd_class_inst_t const * const p_cinst,
- nrf_drv_usbd_ep_t ep,
- app_usbd_ep_event_handler_t handler)
- {
- ASSERT(NULL != p_cinst);
- ASSERT(NULL != handler);
- /* This function should be only called if USBD is disabled */
- ASSERT(!nrf_drv_usbd_is_enabled() && nrf_drv_usbd_is_initialized());
- if (p_cinst != app_usbd_ep_instance_get(ep))
- {
- return NRF_ERROR_INVALID_PARAM;
- }
- (app_usbd_ep_conf_access(ep))->event_handler = handler;
- return NRF_SUCCESS;
- }
- ret_code_t app_usbd_class_sof_register(app_usbd_class_inst_t const * p_cinst)
- {
- ASSERT(NULL != p_cinst);
- ASSERT(NULL != p_cinst->p_class_methods);
- ASSERT(NULL != p_cinst->p_class_methods->event_handler);
- /* This function should be only called if USBD is disabled */
- ASSERT(!nrf_drv_usbd_is_enabled() && nrf_drv_usbd_is_initialized());
- /* Make sure it's not in interrupt SOF list */
- app_usbd_class_inst_t const * * pp_last = &m_p_first_sof_interrupt_cinst;
- while (NULL != (*pp_last))
- {
- ASSERT((*pp_last) != p_cinst);
- pp_last = &(app_usbd_class_data_access(*pp_last)->p_sof_next);
- }
- /* Next SOF event requiring instance has to be NULL now */
- ASSERT(NULL == (app_usbd_class_data_access(p_cinst)->p_sof_next));
- /* Adding pointer to this instance to the end of the chain */
- pp_last = &m_p_first_sof_cinst;
- while (NULL != (*pp_last))
- {
- ASSERT((*pp_last) != p_cinst);
- pp_last = &(app_usbd_class_data_access(*pp_last)->p_sof_next);
- }
- (*pp_last) = p_cinst;
- return NRF_SUCCESS;
- }
- ret_code_t app_usbd_class_sof_unregister(app_usbd_class_inst_t const * p_cinst)
- {
- ASSERT(NULL != p_cinst);
- /** This function should be only called if USBD is disabled */
- ASSERT(!nrf_drv_usbd_is_enabled() && nrf_drv_usbd_is_initialized());
- app_usbd_class_inst_t const * * pp_last = &m_p_first_sof_cinst;
- while (NULL != (*pp_last))
- {
- if ((*pp_last) == p_cinst)
- {
- /* Breaking chain */
- (*pp_last) = (app_usbd_class_data_access(p_cinst)->p_sof_next);
- app_usbd_class_data_access(p_cinst)->p_sof_next = NULL;
- return NRF_SUCCESS;
- }
- pp_last = &(app_usbd_class_data_access(*pp_last)->p_sof_next);
- }
- return NRF_ERROR_NOT_FOUND;
- }
- ret_code_t app_usbd_class_sof_interrupt_register(app_usbd_class_inst_t const * p_cinst, app_usbd_sof_interrupt_handler_t handler)
- {
- ASSERT(NULL != p_cinst);
- ASSERT(NULL != p_cinst->p_class_methods);
- ASSERT(NULL != handler);
- /* This function should be only called if USBD is disabled */
- ASSERT(!nrf_drv_usbd_is_enabled() && nrf_drv_usbd_is_initialized());
- /* Next SOF event requiring instance has to be NULL now */
- ASSERT(NULL == (app_usbd_class_data_access(p_cinst)->p_sof_next));
-
- app_usbd_class_data_access(p_cinst)->sof_handler = handler;
-
- /* Make sure it's not in normal SOF list */
- app_usbd_class_inst_t const * * pp_last = &m_p_first_sof_cinst;
- while (NULL != (*pp_last))
- {
- ASSERT((*pp_last) != p_cinst);
- pp_last = &(app_usbd_class_data_access(*pp_last)->p_sof_next);
- }
- /* Adding pointer to this instance to the end of the interrupt chain */
- pp_last = &m_p_first_sof_interrupt_cinst;
- while (NULL != (*pp_last))
- {
- ASSERT((*pp_last) != p_cinst);
- pp_last = &(app_usbd_class_data_access(*pp_last)->p_sof_next);
- }
- (*pp_last) = p_cinst;
- return NRF_SUCCESS;
- }
- ret_code_t app_usbd_class_sof_interrupt_unregister(app_usbd_class_inst_t const * p_cinst)
- {
- ASSERT(NULL != p_cinst);
- /** This function should be only called if USBD is disabled */
- ASSERT(!nrf_drv_usbd_is_enabled() && nrf_drv_usbd_is_initialized());
- app_usbd_class_inst_t const * * pp_last = &m_p_first_sof_interrupt_cinst;
- while (NULL != (*pp_last))
- {
- if ((*pp_last) == p_cinst)
- {
- /* Breaking chain */
- (*pp_last) = (app_usbd_class_data_access(p_cinst)->p_sof_next);
- app_usbd_class_data_access(p_cinst)->p_sof_next = NULL;
- return NRF_SUCCESS;
- }
- pp_last = &(app_usbd_class_data_access(*pp_last)->p_sof_next);
- }
- return NRF_ERROR_NOT_FOUND;
- }
- ret_code_t app_usbd_class_rwu_register(app_usbd_class_inst_t const * const p_inst)
- {
- ASSERT(p_inst != NULL);
- ++m_rwu_registered_counter;
- /*Overflow check*/
- ASSERT(m_rwu_registered_counter != 0);
- return NRF_SUCCESS;
- }
- ret_code_t app_usbd_class_rwu_unregister(app_usbd_class_inst_t const * const p_inst)
- {
- ASSERT(p_inst != NULL);
- /* Usage validation. If counter is 0 unregister is not possible.*/
- ASSERT(m_rwu_registered_counter != 0);
- --m_rwu_registered_counter;
- return NRF_SUCCESS;
- }
- bool app_usbd_class_rwu_enabled_check(void)
- {
- return (m_rwu_registered_counter != 0);
- }
- ret_code_t app_usbd_interface_ep_reset(app_usbd_class_inst_t const * const p_cinst,
- uint8_t iface)
- {
- uint8_t iface_count = app_usbd_class_iface_count_get(p_cinst);
- app_usbd_class_iface_conf_t const * p_iface = NULL;
- for (uint8_t j = 0; j < iface_count; ++j)
- {
- p_iface = app_usbd_class_iface_get(p_cinst, j);
- if (app_usbd_class_iface_number_get(p_iface) == iface)
- {
- break;
- }
- }
- if (p_iface == NULL)
- {
- return NRF_ERROR_NOT_SUPPORTED;
- }
- uint8_t ep_count = app_usbd_class_iface_ep_count_get(p_iface);
- for (uint8_t j = 0; j < ep_count; ++j)
- {
- /*Clear stall for every endpoint*/
- app_usbd_class_ep_conf_t const * p_ep = app_usbd_class_iface_ep_get(p_iface, j);
- if (!NRF_USBD_EPISO_CHECK(p_ep->address))
- {
- nrf_drv_usbd_ep_dtoggle_clear(p_ep->address);
- nrf_drv_usbd_ep_stall_clear(p_ep->address);
- }
- }
- return NRF_SUCCESS;
- }
- void app_usbd_ep_enable(nrf_drv_usbd_ep_t ep)
- {
- if (!NRF_USBD_EPISO_CHECK(ep))
- {
- nrf_drv_usbd_ep_dtoggle_clear(ep);
- nrf_drv_usbd_ep_stall_clear(ep);
- }
- nrf_drv_usbd_ep_enable(ep);
- }
- void app_usbd_ep_disable(nrf_drv_usbd_ep_t ep)
- {
- nrf_drv_usbd_ep_disable(ep);
- }
- app_usbd_class_inst_t const * app_usbd_class_first_get(void)
- {
- return m_p_first_cinst;
- }
- app_usbd_class_inst_t const * app_usbd_class_sof_first_get(void)
- {
- return m_p_first_sof_cinst;
- }
- app_usbd_class_inst_t const * app_usbd_class_sof_interrupt_first_get(void)
- {
- return m_p_first_sof_interrupt_cinst;
- }
- app_usbd_class_inst_t const * app_usbd_iface_find(uint8_t iface, uint8_t * p_iface_idx)
- {
- app_usbd_class_inst_t const * p_inst = app_usbd_class_first_get();
- while (p_inst != NULL)
- {
- uint8_t iface_count = app_usbd_class_iface_count_get(p_inst);
- /* Iterate over interfaces */
- for (uint8_t i = 0; i < iface_count; ++i)
- {
- app_usbd_class_iface_conf_t const * p_iface;
- p_iface = app_usbd_class_iface_get(p_inst, i);
- if (app_usbd_class_iface_number_get(p_iface) == iface)
- {
- if (p_iface_idx != NULL)
- {
- (*p_iface_idx) = i;
- }
- return p_inst;
- }
- }
- p_inst = app_usbd_class_next_get(p_inst);
- }
- return NULL;
- }
- ret_code_t app_usbd_iface_call(
- app_usbd_class_inst_t const * const p_class_inst,
- uint8_t iface_idx,
- app_usbd_complex_evt_t const * const p_event)
- {
- UNUSED_PARAMETER(iface_idx);
- return class_event_handler(p_class_inst, p_event);
- }
- ret_code_t app_usbd_ep_call(nrf_drv_usbd_ep_t ep, app_usbd_complex_evt_t const * const p_event)
- {
- if (NRF_USBD_EP_VALIDATE(ep))
- {
- app_usbd_class_inst_t const * p_inst = app_usbd_ep_conf_access(ep)->p_cinst;
- if (p_inst != NULL)
- {
- return class_event_handler(p_inst, p_event);
- }
- }
- return NRF_ERROR_INVALID_ADDR;
- }
- void app_usbd_all_call(app_usbd_complex_evt_t const * const p_event)
- {
- app_usbd_class_inst_t const * p_inst;
- for (p_inst = app_usbd_class_first_get(); NULL != p_inst;
- p_inst = app_usbd_class_next_get(p_inst))
- {
- UNUSED_RETURN_VALUE(class_event_handler(p_inst, p_event));
- }
- }
- ret_code_t app_usbd_all_until_served_call(app_usbd_complex_evt_t const * const p_event)
- {
- app_usbd_class_inst_t const * p_inst;
- ret_code_t ret = NRF_ERROR_NOT_SUPPORTED;
- /* Try to process via every instance */
- for (p_inst = app_usbd_class_first_get(); NULL != p_inst;
- p_inst = app_usbd_class_next_get(p_inst))
- {
- ret = class_event_handler(p_inst, p_event);
- if (NRF_ERROR_NOT_SUPPORTED != ret)
- {
- /* Processing finished */
- break;
- }
- }
- return ret;
- }
- ret_code_t app_usbd_ep_transfer(
- nrf_drv_usbd_ep_t ep,
- nrf_drv_usbd_transfer_t const * const p_transfer)
- {
- if (!nrf_drv_usbd_ep_enable_check(ep))
- {
- return NRF_ERROR_INVALID_STATE;
- }
- if (m_sustate != SUSTATE_ACTIVE)
- {
- return NRF_ERROR_INVALID_STATE;
- }
- return nrf_drv_usbd_ep_transfer(ep, p_transfer);
- }
- ret_code_t app_usbd_ep_handled_transfer(
- nrf_drv_usbd_ep_t ep,
- nrf_drv_usbd_handler_desc_t const * const p_handler)
- {
- if (!nrf_drv_usbd_ep_enable_check(ep))
- {
- return NRF_ERROR_INVALID_STATE;
- }
- if (m_sustate != SUSTATE_ACTIVE)
- {
- return NRF_ERROR_INVALID_STATE;
- }
- return nrf_drv_usbd_ep_handled_transfer(ep, p_handler);
- }
- ret_code_t app_usbd_iface_select(
- app_usbd_class_inst_t const * const p_inst,
- uint8_t iface_idx,
- uint8_t alternate)
- {
- ret_code_t ret = NRF_ERROR_NOT_SUPPORTED;
- if (p_inst->p_class_methods->iface_select != NULL)
- {
- ret = p_inst->p_class_methods->iface_select(p_inst, iface_idx, alternate);
- }
- if(ret == NRF_ERROR_NOT_SUPPORTED)
- {
- ret = default_iface_select(p_inst, iface_idx, alternate);
- }
- return ret;
- }
- void app_usbd_iface_deselect(
- app_usbd_class_inst_t const * const p_inst,
- uint8_t iface_idx)
- {
- if (p_inst->p_class_methods->iface_deselect != NULL)
- {
- p_inst->p_class_methods->iface_deselect(p_inst, iface_idx);
- }
- default_iface_deselect(p_inst, iface_idx);
- }
- uint8_t app_usbd_iface_selection_get(
- app_usbd_class_inst_t const * const p_inst,
- uint8_t iface_idx)
- {
- uint8_t alt = 0;
- if (p_inst->p_class_methods->iface_selection_get != NULL)
- {
- alt = p_inst->p_class_methods->iface_selection_get(p_inst, iface_idx);
- }
- return alt;
- }
- void app_usbd_all_iface_select_0(void)
- {
- app_usbd_class_inst_t const * p_inst = app_usbd_class_first_get();
- while (p_inst != NULL)
- {
- uint8_t iface_count = app_usbd_class_iface_count_get(p_inst);
- for (uint8_t i = 0; i < iface_count; ++i)
- {
- ret_code_t ret;
- ret = app_usbd_iface_select(p_inst, i, 0);
- ASSERT(ret == NRF_SUCCESS);
- UNUSED_VARIABLE(ret);
- }
- p_inst = app_usbd_class_next_get(p_inst);
- }
- }
- void app_usbd_all_iface_deselect(void)
- {
- app_usbd_class_inst_t const * p_inst = app_usbd_class_first_get();
- while (p_inst != NULL)
- {
- uint8_t iface_count = app_usbd_class_iface_count_get(p_inst);
- for (uint8_t i = 0; i < iface_count; ++i)
- {
- app_usbd_iface_deselect(p_inst, i);
- }
- p_inst = app_usbd_class_next_get(p_inst);
- }
- }
- #endif //NRF_MODULE_ENABLED(APP_USBD)
|