main.c 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305
  1. /**
  2. * Copyright (c) 2016 - 2020, Nordic Semiconductor ASA
  3. *
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without modification,
  7. * are permitted provided that the following conditions are met:
  8. *
  9. * 1. Redistributions of source code must retain the above copyright notice, this
  10. * list of conditions and the following disclaimer.
  11. *
  12. * 2. Redistributions in binary form, except as embedded into a Nordic
  13. * Semiconductor ASA integrated circuit in a product or a software update for
  14. * such product, must reproduce the above copyright notice, this list of
  15. * conditions and the following disclaimer in the documentation and/or other
  16. * materials provided with the distribution.
  17. *
  18. * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
  19. * contributors may be used to endorse or promote products derived from this
  20. * software without specific prior written permission.
  21. *
  22. * 4. This software, with or without modification, must only be used with a
  23. * Nordic Semiconductor ASA integrated circuit.
  24. *
  25. * 5. Any software provided in binary form under this license must not be reverse
  26. * engineered, decompiled, modified and/or disassembled.
  27. *
  28. * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
  29. * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  30. * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
  31. * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
  32. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  33. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  34. * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  35. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  36. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  37. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  38. *
  39. */
  40. #include <stdint.h>
  41. #include <stdbool.h>
  42. #include <stddef.h>
  43. #include "nrf.h"
  44. #include "nrf_drv_usbd.h"
  45. #include "nrf_drv_clock.h"
  46. #include "nrf_gpio.h"
  47. #include "nrf_delay.h"
  48. #include "nrf_drv_power.h"
  49. #include "nrf_log.h"
  50. #include "nrf_log_ctrl.h"
  51. #include "nrf_log_default_backends.h"
  52. #include "app_timer.h"
  53. #include "app_error.h"
  54. #include "bsp.h"
  55. #include "bsp_cli.h"
  56. #include "nrf_cli.h"
  57. #include "nrf_cli_uart.h"
  58. /**
  59. * @brief CLI interface over UART
  60. */
  61. NRF_CLI_UART_DEF(m_cli_uart_transport, 0, 64, 16);
  62. NRF_CLI_DEF(m_cli_uart,
  63. "uart_cli:~$ ",
  64. &m_cli_uart_transport.transport,
  65. '\r',
  66. 4);
  67. static bool m_send_flag = 0;
  68. #define BTN_DATA_SEND 0
  69. #define BTN_DATA_KEY_RELEASE (bsp_event_t)(BSP_EVENT_KEY_LAST + 1)
  70. /**
  71. * @brief Button used to simulate mouse move
  72. *
  73. * Every button press would move the cursor one step in the square.
  74. */
  75. #define BTN_MOUSE_MOVE BSP_BOARD_BUTTON_0
  76. /**
  77. * @brief Button for system OFF request
  78. *
  79. * This button would set the request for system OFF.
  80. */
  81. #define BTN_SYSTEM_OFF BSP_BOARD_BUTTON_1
  82. /**
  83. * @brief Configuration status LED
  84. *
  85. * This LED would blink quickly (5&nbsp;Hz) when device is not configured
  86. * or slowly (1&nbsp;Hz) when configured and working properly.
  87. */
  88. #define LED_USB_STATUS BSP_BOARD_LED_0
  89. /**
  90. * @brief Power detect LED
  91. *
  92. * The LED is ON when connection is detected on USB port.
  93. * It is turned off when connection is removed.
  94. */
  95. #define LED_USB_POWER BSP_BOARD_LED_1
  96. /**
  97. * @brief Running LED
  98. *
  99. * LED that turns on when program is not sleeping
  100. */
  101. #define LED_RUNNING BSP_BOARD_LED_2
  102. /**
  103. * @brief Active LED
  104. *
  105. * LED that turns on when program is not in system OFF
  106. */
  107. #define LED_ACTIVE BSP_BOARD_LED_3
  108. /**
  109. * @brief Enable power USB detection
  110. *
  111. * Configure if example supports USB port connection
  112. */
  113. #ifndef USBD_POWER_DETECTION
  114. #define USBD_POWER_DETECTION true
  115. #endif
  116. /**
  117. * @brief Startup delay
  118. *
  119. * Number of microseconds to start USBD after powering up.
  120. * Kind of port insert debouncing.
  121. */
  122. #define STARTUP_DELAY 100
  123. /** Maximum size of the packed transfered by EP0 */
  124. #define EP0_MAXPACKETSIZE NRF_DRV_USBD_EPSIZE
  125. /** Device descriptor */
  126. #define USBD_DEVICE_DESCRIPTOR \
  127. 0x12, /* bLength | size of descriptor */\
  128. 0x01, /* bDescriptorType | descriptor type */\
  129. 0x00, 0x02, /* bcdUSB | USB spec release (ver 2.0) */\
  130. 0x00, /* bDeviceClass ¦ class code (each interface specifies class information) */\
  131. 0x00, /* bDeviceSubClass ¦ device sub-class (must be set to 0 because class code is 0) */\
  132. 0x00, /* bDeviceProtocol | device protocol (no class specific protocol) */\
  133. EP0_MAXPACKETSIZE, /* bMaxPacketSize0 | maximum packet size (64 bytes) */\
  134. 0x15, 0x19, /* vendor ID (0x1915 Nordic) */\
  135. 0x0A, 0x52, /* product ID (0x520A nRF52 HID mouse on nrf_drv) */\
  136. 0x01, 0x01, /* bcdDevice | final device release number in BCD Format */\
  137. USBD_STRING_MANUFACTURER_IX, /* iManufacturer | index of manufacturer string */\
  138. USBD_STRING_PRODUCT_IX, /* iProduct | index of product string */\
  139. USBD_STRING_SERIAL_IX, /* iSerialNumber | Serial Number string */\
  140. 0x01 /* bNumConfigurations | number of configurations */
  141. /** Configuration descriptor */
  142. #define DEVICE_SELF_POWERED 1
  143. #define REMOTE_WU 1
  144. #define USBD_CONFIG_DESCRIPTOR_SIZE 9
  145. #define USBD_CONFIG_DESCRIPTOR_FULL_SIZE (9 + (9 + 9 + 7))
  146. #define USBD_CONFIG_DESCRIPTOR \
  147. 0x09, /* bLength | length of descriptor */\
  148. 0x02, /* bDescriptorType | descriptor type (CONFIGURATION) */\
  149. USBD_CONFIG_DESCRIPTOR_FULL_SIZE, 0x00, /* wTotalLength | total length of descriptor(s) */\
  150. 0x01, /* bNumInterfaces */\
  151. 0x01, /* bConfigurationValue */\
  152. 0x00, /* index of string Configuration | configuration string index (not supported) */\
  153. 0x80| (((DEVICE_SELF_POWERED) ? 1U:0U)<<6) | (((REMOTE_WU) ? 1U:0U)<<5), /* bmAttributes */\
  154. 49 /* maximum power in steps of 2mA (98mA) */
  155. #define USBD_INTERFACE0_DESCRIPTOR \
  156. 0x09, /* bLength */\
  157. 0x04, /* bDescriptorType | descriptor type (INTERFACE) */\
  158. 0x00, /* bInterfaceNumber */\
  159. 0x00, /* bAlternateSetting */\
  160. 0x01, /* bNumEndpoints | number of endpoints (1) */\
  161. 0x03, /* bInterfaceClass | interface class (3..defined by USB spec: HID) */\
  162. 0x00, /* bInterfaceSubClass |interface sub-class (0.. no boot interface) */\
  163. 0x02, /* bInterfaceProtocol | interface protocol (1..defined by USB spec: mouse) */\
  164. 0x00 /* interface string index (not supported) */
  165. /**
  166. * HID Table must normally be between Interface and EndPoint Descriptor
  167. * as written in HID spec§7.1 but it doesn't work with OSR2.1
  168. */
  169. #define USBD_HID0_DESCRIPTOR \
  170. 0x09, /* bLength | length of descriptor (9 bytes) */\
  171. 0x21, /* bHIDDescriptor | descriptor type (HID) */\
  172. 0x11, 0x01, /* HID wBcdHID | Spec version 01.11 */\
  173. 0x00, /* bCountryCode | HW Target country */\
  174. 0x01, /* bNumDescriptors | Number of HID class descriptors to follow */\
  175. 0x22, /* bDescriptorType | Report descriptor type is 0x22 (report) */\
  176. (uint8_t)(USBD_MOUSE_REPORT_DESCRIPTOR_SIZE), /* Total length of Report descr., low byte */ \
  177. (uint8_t)(USBD_MOUSE_REPORT_DESCRIPTOR_SIZE / 256) /* Total length of Report descr., high byte */
  178. #define USBD_ENDPOINT1_DESCRIPTOR \
  179. 0x07, /* bLength | length of descriptor (7 bytes) */\
  180. 0x05, /* bDescriptorType | descriptor type (ENDPOINT) */\
  181. 0x81, /* bEndpointAddress | endpoint address (IN endpoint, endpoint 1) */\
  182. 0x03, /* bmAttributes | endpoint attributes (interrupt) */\
  183. 0x08,0x00, /* bMaxPacketSizeLowByte,bMaxPacketSizeHighByte | maximum packet size (8 bytes) */\
  184. 0x08 /* bInterval | polling interval (10ms) */
  185. /**
  186. * String config descriptor
  187. */
  188. #define USBD_STRING_LANG_IX 0x00
  189. #define USBD_STRING_LANG \
  190. 0x04, /* length of descriptor */\
  191. 0x03, /* descriptor type */\
  192. 0x09, /* */\
  193. 0x04 /* Supported LangID = 0x0409 (US-English) */
  194. #define USBD_STRING_MANUFACTURER_IX 0x01
  195. #define USBD_STRING_MANUFACTURER \
  196. 42, /* length of descriptor (? bytes) */\
  197. 0x03, /* descriptor type */\
  198. 'N', 0x00, /* Define Unicode String "Nordic Semiconductor */\
  199. 'o', 0x00, \
  200. 'r', 0x00, \
  201. 'd', 0x00, \
  202. 'i', 0x00, \
  203. 'c', 0x00, \
  204. ' ', 0x00, \
  205. 'S', 0x00, \
  206. 'e', 0x00, \
  207. 'm', 0x00, \
  208. 'i', 0x00, \
  209. 'c', 0x00, \
  210. 'o', 0x00, \
  211. 'n', 0x00, \
  212. 'd', 0x00, \
  213. 'u', 0x00, \
  214. 'c', 0x00, \
  215. 't', 0x00, \
  216. 'o', 0x00, \
  217. 'r', 0x00
  218. #define USBD_STRING_PRODUCT_IX 0x02
  219. #define USBD_STRING_PRODUCT \
  220. 72, /* length of descriptor (? bytes) */\
  221. 0x03, /* descriptor type */\
  222. 'n', 0x00, /* generic unicode string for all devices */\
  223. 'R', 0x00, \
  224. 'F', 0x00, \
  225. '5', 0x00, \
  226. '2', 0x00, \
  227. ' ', 0x00, \
  228. 'U', 0x00, \
  229. 'S', 0x00, \
  230. 'B', 0x00, \
  231. ' ', 0x00, \
  232. 'H', 0x00, \
  233. 'I', 0x00, \
  234. 'D', 0x00, \
  235. ' ', 0x00, \
  236. 'm', 0x00, \
  237. 'o', 0x00, \
  238. 'u', 0x00, \
  239. 's', 0x00, \
  240. 'e', 0x00, \
  241. ' ', 0x00, \
  242. 'o', 0x00, \
  243. 'n', 0x00, \
  244. ' ', 0x00, \
  245. 'n', 0x00, \
  246. 'r', 0x00, \
  247. 'f', 0x00, \
  248. '_', 0x00, \
  249. 'd', 0x00, \
  250. 'r', 0x00, \
  251. 'v', 0x00, \
  252. ' ', 0x00, \
  253. 'D', 0x00, \
  254. 'e', 0x00, \
  255. 'm', 0x00, \
  256. 'o', 0x00, \
  257. #define USBD_STRING_SERIAL_IX 0x00
  258. #define USBD_MOUSE_REPORT_DESCRIPTOR_SIZE 46
  259. #define USBD_MOUSE_REPORT_DESCRIPTOR \
  260. 0x05, 0x01, /* usage page (generic desktop). Global item, applies to all subsequent items */\
  261. 0x09, 0x02, /* usage (mouse). Local item */\
  262. 0xA1, 0x01, /* collection (application) */\
  263. 0x09, 0x01, /* usage (pointer) */\
  264. 0xA1, 0x00, /* collection (physical) */\
  265. 0x05, 0x09, /* usage page (buttons). Global item, applies to all subsequent items */\
  266. 0x19, 0x01, /* usage minimum (1) */\
  267. 0x29, 0x08, /* usage maximum (8) */\
  268. 0x15, 0x00, /* logical minimum (0) */\
  269. 0x25, 0x01, /* logical maximum (1) */\
  270. 0x95, 0x08, /* report count (8) */\
  271. 0x75, 0x01, /* report size (1) */\
  272. 0x81, 0x02, /* input (data, var, abs) */\
  273. 0x05, 0x01, /* usage page (generic desktop). Global item, applies to all subsequent items */\
  274. 0x15, 0x81, /* logical minimum (-127) */\
  275. 0x25, 0x7F, /* logical maximum (127) */\
  276. 0x75, 0x08, /* report size (8) */\
  277. 0x09, 0x30, /* usage (X) */\
  278. 0x09, 0x31, /* usage (Y) */\
  279. 0x09, 0x38, /* usage wheel */\
  280. 0x95, 0x03, /* report count (3) */\
  281. 0x81, 0x06, /* input (3 position bytes X, Y & roller) */\
  282. 0xC0, /* end collection */\
  283. 0xC0 /* End Collection */
  284. static const uint8_t get_descriptor_device[] = {
  285. USBD_DEVICE_DESCRIPTOR
  286. };
  287. static const uint8_t get_descriptor_configuration[] = {
  288. USBD_CONFIG_DESCRIPTOR,
  289. USBD_INTERFACE0_DESCRIPTOR,
  290. USBD_HID0_DESCRIPTOR,
  291. USBD_ENDPOINT1_DESCRIPTOR
  292. };
  293. static const uint8_t get_descriptor_string_lang[] = {
  294. USBD_STRING_LANG
  295. };
  296. static const uint8_t get_descriptor_string_manuf[] = {
  297. USBD_STRING_MANUFACTURER
  298. };
  299. static const uint8_t get_descriptor_string_prod[] = {
  300. USBD_STRING_PRODUCT
  301. };
  302. static const uint8_t get_descriptor_report_interface_0[] = {
  303. USBD_MOUSE_REPORT_DESCRIPTOR
  304. };
  305. static const uint8_t get_config_resp_configured[] = {1};
  306. static const uint8_t get_config_resp_unconfigured[] = {0};
  307. static const uint8_t get_status_device_resp_nrwu[] = {
  308. ((DEVICE_SELF_POWERED) ? 1 : 0), //LSB first: self-powered, no remoteWk
  309. 0
  310. };
  311. static const uint8_t get_status_device_resp_rwu[] = {
  312. ((DEVICE_SELF_POWERED) ? 1 : 0) | 2, //LSB first: self-powered, remoteWk
  313. 0
  314. };
  315. static const uint8_t get_status_interface_resp[] = {0, 0};
  316. static const uint8_t get_status_ep_halted_resp[] = {1, 0};
  317. static const uint8_t get_status_ep_active_resp[] = {0, 0};
  318. #define GET_CONFIG_DESC_SIZE sizeof(get_descriptor_configuration)
  319. #define GET_INTERFACE_DESC_SIZE 9
  320. #define GET_HID_DESC_SIZE 9
  321. #define GET_ENDPOINT_DESC_SIZE 7
  322. #define get_descriptor_interface_0 \
  323. &get_descriptor_configuration[9]
  324. #define get_descriptor_hid_0 \
  325. &get_descriptor_configuration[9+GET_INTERFACE_DESC_SIZE]
  326. #define get_descriptor_endpoint_1 \
  327. &get_descriptor_configuration[9+GET_INTERFACE_DESC_SIZE+GET_HID_DESC_SIZE]
  328. /**
  329. * @brief USB configured flag
  330. *
  331. * The flag that is used to mark the fact that USB is configured and ready
  332. * to transmit data
  333. */
  334. static volatile bool m_usbd_configured = false;
  335. /**
  336. * @brief USB suspended
  337. *
  338. * The flag that is used to mark the fact that USB is suspended and requires wake up
  339. * if new data is available.
  340. *
  341. * @note This variable is changed from the main loop.
  342. */
  343. static bool m_usbd_suspended = false;
  344. /**
  345. * @brief Mark the fact if remote wake up is enabled
  346. *
  347. * The internal flag that marks if host enabled the remote wake up functionality in this device.
  348. */
  349. static
  350. #if REMOTE_WU
  351. volatile // Disallow optimization only if Remote wakeup is enabled
  352. #endif
  353. bool m_usbd_rwu_enabled = false;
  354. /**
  355. * @brief Current mouse position
  356. *
  357. * The index of current mouse position that would be changed to real offset.
  358. */
  359. static volatile uint8_t m_mouse_position = 0;
  360. /**
  361. * @brief The flag for mouse position send pending
  362. *
  363. * Setting this flag means that USB endpoint is busy by sending
  364. * last mouse position.
  365. */
  366. static volatile bool m_send_mouse_position = false;
  367. /**
  368. * @brief The requested suspend state
  369. *
  370. * The currently requested suspend state based on the events
  371. * received from USBD library.
  372. * If the value here is different than the @ref m_usbd_suspended
  373. * the state changing would be processed inside main loop.
  374. */
  375. static volatile bool m_usbd_suspend_state_req = false;
  376. /**
  377. * @brief System OFF request flag
  378. *
  379. * This flag is used in button event processing and marks the fact that
  380. * system OFF should be activated from main loop.
  381. */
  382. static volatile bool m_system_off_req = false;
  383. /**
  384. * @brief Setup all the endpoints for selected configuration
  385. *
  386. * Function sets all the endpoints for specific configuration.
  387. *
  388. * @note
  389. * Setting the configuration index 0 means technically disabling the HID interface.
  390. * Such configuration should be set when device is starting or USB reset is detected.
  391. *
  392. * @param index Configuration index
  393. *
  394. * @retval NRF_ERROR_INVALID_PARAM Invalid configuration
  395. * @retval NRF_SUCCESS Configuration successfully set
  396. */
  397. static ret_code_t ep_configuration(uint8_t index)
  398. {
  399. if ( index == 1 )
  400. {
  401. nrf_drv_usbd_ep_dtoggle_clear(NRF_DRV_USBD_EPIN1);
  402. nrf_drv_usbd_ep_stall_clear(NRF_DRV_USBD_EPIN1);
  403. nrf_drv_usbd_ep_enable(NRF_DRV_USBD_EPIN1);
  404. m_usbd_configured = true;
  405. nrf_drv_usbd_setup_clear();
  406. }
  407. else if ( index == 0 )
  408. {
  409. nrf_drv_usbd_ep_disable(NRF_DRV_USBD_EPIN1);
  410. m_usbd_configured = false;
  411. nrf_drv_usbd_setup_clear();
  412. }
  413. else
  414. {
  415. return NRF_ERROR_INVALID_PARAM;
  416. }
  417. return NRF_SUCCESS;
  418. }
  419. /**
  420. * @name Processing setup requests
  421. *
  422. * @{
  423. */
  424. /**
  425. * @brief Respond on ep 0
  426. *
  427. * Auxiliary function for sending respond on endpoint 0
  428. * @param[in] p_setup Pointer to setup data from current setup request.
  429. * It would be used to calculate the size of data to send.
  430. * @param[in] p_data Pointer to the data to send.
  431. * @param[in] size Number of bytes to send.
  432. * @note Data pointed by p_data has to be available till the USBD_EVT_BUFREADY event.
  433. */
  434. static void respond_setup_data(
  435. nrf_drv_usbd_setup_t const * const p_setup,
  436. void const * p_data, size_t size)
  437. {
  438. /* Check the size against required response size */
  439. if (size > p_setup->wLength)
  440. {
  441. size = p_setup->wLength;
  442. }
  443. ret_code_t ret;
  444. nrf_drv_usbd_transfer_t transfer =
  445. {
  446. .p_data = {.tx = p_data},
  447. .size = size
  448. };
  449. ret = nrf_drv_usbd_ep_transfer(NRF_DRV_USBD_EPIN0, &transfer);
  450. if (ret != NRF_SUCCESS)
  451. {
  452. NRF_LOG_ERROR("Transfer starting failed: %d", (uint32_t)ret);
  453. }
  454. ASSERT(ret == NRF_SUCCESS);
  455. UNUSED_VARIABLE(ret);
  456. }
  457. /** React to GetStatus */
  458. static void usbd_setup_GetStatus(nrf_drv_usbd_setup_t const * const p_setup)
  459. {
  460. switch (p_setup->bmRequestType)
  461. {
  462. case 0x80: // Device
  463. if (((p_setup->wIndex) & 0xff) == 0)
  464. {
  465. respond_setup_data(
  466. p_setup,
  467. m_usbd_rwu_enabled ? get_status_device_resp_rwu : get_status_device_resp_nrwu,
  468. sizeof(get_status_device_resp_nrwu));
  469. return;
  470. }
  471. break;
  472. case 0x81: // Interface
  473. if (m_usbd_configured) // Respond only if configured
  474. {
  475. if (((p_setup->wIndex) & 0xff) == 0) // Only interface 0 supported
  476. {
  477. respond_setup_data(
  478. p_setup,
  479. get_status_interface_resp,
  480. sizeof(get_status_interface_resp));
  481. return;
  482. }
  483. }
  484. break;
  485. case 0x82: // Endpoint
  486. if (((p_setup->wIndex) & 0xff) == 0) // Endpoint 0
  487. {
  488. respond_setup_data(
  489. p_setup,
  490. get_status_ep_active_resp,
  491. sizeof(get_status_ep_active_resp));
  492. return;
  493. }
  494. if (m_usbd_configured) // Other endpoints responds if configured
  495. {
  496. if (((p_setup->wIndex) & 0xff) == NRF_DRV_USBD_EPIN1)
  497. {
  498. if (nrf_drv_usbd_ep_stall_check(NRF_DRV_USBD_EPIN1))
  499. {
  500. respond_setup_data(
  501. p_setup,
  502. get_status_ep_halted_resp,
  503. sizeof(get_status_ep_halted_resp));
  504. return;
  505. }
  506. else
  507. {
  508. respond_setup_data(
  509. p_setup,
  510. get_status_ep_active_resp,
  511. sizeof(get_status_ep_active_resp));
  512. return;
  513. }
  514. }
  515. }
  516. break;
  517. default:
  518. break; // Just go to stall
  519. }
  520. NRF_LOG_ERROR("Unknown status: 0x%2x", p_setup->bmRequestType);
  521. nrf_drv_usbd_setup_stall();
  522. }
  523. static void usbd_setup_ClearFeature(nrf_drv_usbd_setup_t const * const p_setup)
  524. {
  525. if ((p_setup->bmRequestType) == 0x02) // standard request, recipient=endpoint
  526. {
  527. if ((p_setup->wValue) == 0)
  528. {
  529. if ((p_setup->wIndex) == NRF_DRV_USBD_EPIN1)
  530. {
  531. nrf_drv_usbd_ep_stall_clear(NRF_DRV_USBD_EPIN1);
  532. nrf_drv_usbd_setup_clear();
  533. return;
  534. }
  535. }
  536. }
  537. else if ((p_setup->bmRequestType) == 0x0) // standard request, recipient=device
  538. {
  539. if (REMOTE_WU)
  540. {
  541. if ((p_setup->wValue) == 1) // Feature Wakeup
  542. {
  543. m_usbd_rwu_enabled = false;
  544. nrf_drv_usbd_setup_clear();
  545. return;
  546. }
  547. }
  548. }
  549. NRF_LOG_ERROR("Unknown feature to clear");
  550. nrf_drv_usbd_setup_stall();
  551. }
  552. static void usbd_setup_SetFeature(nrf_drv_usbd_setup_t const * const p_setup)
  553. {
  554. if ((p_setup->bmRequestType) == 0x02) // standard request, recipient=endpoint
  555. {
  556. if ((p_setup->wValue) == 0) // Feature HALT
  557. {
  558. if ((p_setup->wIndex) == NRF_DRV_USBD_EPIN1)
  559. {
  560. nrf_drv_usbd_ep_stall(NRF_DRV_USBD_EPIN1);
  561. nrf_drv_usbd_setup_clear();
  562. return;
  563. }
  564. }
  565. }
  566. else if ((p_setup->bmRequestType) == 0x0) // standard request, recipient=device
  567. {
  568. if (REMOTE_WU)
  569. {
  570. if ((p_setup->wValue) == 1) // Feature Wakeup
  571. {
  572. m_usbd_rwu_enabled = true;
  573. nrf_drv_usbd_setup_clear();
  574. return;
  575. }
  576. }
  577. }
  578. NRF_LOG_ERROR("Unknown feature to set");
  579. nrf_drv_usbd_setup_stall();
  580. }
  581. static void usbd_setup_GetDescriptor(nrf_drv_usbd_setup_t const * const p_setup)
  582. {
  583. //determine which descriptor has been asked for
  584. switch ((p_setup->wValue) >> 8)
  585. {
  586. case 1: // Device
  587. if ((p_setup->bmRequestType) == 0x80)
  588. {
  589. respond_setup_data(
  590. p_setup,
  591. get_descriptor_device,
  592. sizeof(get_descriptor_device));
  593. return;
  594. }
  595. break;
  596. case 2: // Configuration
  597. if ((p_setup->bmRequestType) == 0x80)
  598. {
  599. respond_setup_data(
  600. p_setup,
  601. get_descriptor_configuration,
  602. GET_CONFIG_DESC_SIZE);
  603. return;
  604. }
  605. break;
  606. case 3: // String
  607. if ((p_setup->bmRequestType) == 0x80)
  608. {
  609. // Select the string
  610. switch ((p_setup->wValue) & 0xFF)
  611. {
  612. case USBD_STRING_LANG_IX:
  613. respond_setup_data(
  614. p_setup,
  615. get_descriptor_string_lang,
  616. sizeof(get_descriptor_string_lang));
  617. return;
  618. case USBD_STRING_MANUFACTURER_IX:
  619. respond_setup_data(
  620. p_setup,
  621. get_descriptor_string_manuf,
  622. sizeof(get_descriptor_string_manuf));
  623. return;
  624. case USBD_STRING_PRODUCT_IX:
  625. respond_setup_data(p_setup,
  626. get_descriptor_string_prod,
  627. sizeof(get_descriptor_string_prod));
  628. return;
  629. default:
  630. break;
  631. }
  632. }
  633. break;
  634. case 4: // Interface
  635. if ((p_setup->bmRequestType) == 0x80)
  636. {
  637. // Which interface?
  638. if ((((p_setup->wValue) & 0xFF) == 0))
  639. {
  640. respond_setup_data(
  641. p_setup,
  642. get_descriptor_interface_0,
  643. GET_INTERFACE_DESC_SIZE);
  644. return;
  645. }
  646. }
  647. break;
  648. case 5: // Endpoint
  649. if ((p_setup->bmRequestType) == 0x80)
  650. {
  651. // Which endpoint?
  652. if (((p_setup->wValue) & 0xFF) == 1)
  653. {
  654. respond_setup_data(
  655. p_setup,
  656. get_descriptor_endpoint_1,
  657. GET_ENDPOINT_DESC_SIZE);
  658. return;
  659. }
  660. }
  661. break;
  662. case 0x21: // HID
  663. if ((p_setup->bmRequestType) == 0x81)
  664. {
  665. // Which interface
  666. if (((p_setup->wValue) & 0xFF) == 0)
  667. {
  668. respond_setup_data(
  669. p_setup,
  670. get_descriptor_hid_0,
  671. GET_HID_DESC_SIZE);
  672. return;
  673. }
  674. }
  675. break;
  676. case 0x22: // HID report
  677. if ((p_setup->bmRequestType) == 0x81)
  678. {
  679. // Which interface?
  680. if (((p_setup->wValue) & 0xFF) == 0)
  681. {
  682. respond_setup_data(
  683. p_setup,
  684. get_descriptor_report_interface_0,
  685. sizeof(get_descriptor_report_interface_0));
  686. return;
  687. }
  688. }
  689. break;
  690. default:
  691. break; // Not supported - go to stall
  692. }
  693. NRF_LOG_ERROR("Unknown descriptor requested: 0x%2x, type: 0x%2x or value: 0x%2x",
  694. p_setup->wValue >> 8,
  695. p_setup->bmRequestType,
  696. p_setup->wValue & 0xFF);
  697. nrf_drv_usbd_setup_stall();
  698. }
  699. static void usbd_setup_GetConfig(nrf_drv_usbd_setup_t const * const p_setup)
  700. {
  701. if (m_usbd_configured)
  702. {
  703. respond_setup_data(
  704. p_setup,
  705. get_config_resp_configured,
  706. sizeof(get_config_resp_configured));
  707. }
  708. else
  709. {
  710. respond_setup_data(
  711. p_setup,
  712. get_config_resp_unconfigured,
  713. sizeof(get_config_resp_unconfigured));
  714. }
  715. }
  716. static void usbd_setup_SetConfig(nrf_drv_usbd_setup_t const * const p_setup)
  717. {
  718. if ((p_setup->bmRequestType) == 0x00)
  719. {
  720. // accept only 0 and 1
  721. if (((p_setup->wIndex) == 0) && ((p_setup->wLength) == 0) &&
  722. ((p_setup->wValue) <= UINT8_MAX))
  723. {
  724. if (NRF_SUCCESS == ep_configuration((uint8_t)(p_setup->wValue)))
  725. {
  726. nrf_drv_usbd_setup_clear();
  727. return;
  728. }
  729. }
  730. }
  731. NRF_LOG_ERROR("Wrong configuration: Index: 0x%2x, Value: 0x%2x.",
  732. p_setup->wIndex,
  733. p_setup->wValue);
  734. nrf_drv_usbd_setup_stall();
  735. }
  736. static void usbd_setup_SetIdle(nrf_drv_usbd_setup_t const * const p_setup)
  737. {
  738. if (p_setup->bmRequestType == 0x21)
  739. {
  740. //accept any value
  741. nrf_drv_usbd_setup_clear();
  742. return;
  743. }
  744. NRF_LOG_ERROR("Set Idle wrong type: 0x%2x.", p_setup->bmRequestType);
  745. nrf_drv_usbd_setup_stall();
  746. }
  747. static void usbd_setup_SetInterface(
  748. nrf_drv_usbd_setup_t const * const p_setup)
  749. {
  750. //no alternate setting is supported - STALL always
  751. NRF_LOG_ERROR("No alternate interfaces supported.");
  752. nrf_drv_usbd_setup_stall();
  753. }
  754. static void usbd_setup_SetProtocol(
  755. nrf_drv_usbd_setup_t const * const p_setup)
  756. {
  757. if (p_setup->bmRequestType == 0x21)
  758. {
  759. //accept any value
  760. nrf_drv_usbd_setup_clear();
  761. return;
  762. }
  763. NRF_LOG_ERROR("Set Protocol wrong type: 0x%2x.", p_setup->bmRequestType);
  764. nrf_drv_usbd_setup_stall();
  765. }
  766. /** @} */ /* End of processing setup requests functions */
  767. static void usbd_event_handler(nrf_drv_usbd_evt_t const * const p_event)
  768. {
  769. switch (p_event->type)
  770. {
  771. case NRF_DRV_USBD_EVT_SUSPEND:
  772. NRF_LOG_INFO("SUSPEND state detected");
  773. m_usbd_suspend_state_req = true;
  774. break;
  775. case NRF_DRV_USBD_EVT_RESUME:
  776. NRF_LOG_INFO("RESUMING from suspend");
  777. m_usbd_suspend_state_req = false;
  778. break;
  779. case NRF_DRV_USBD_EVT_WUREQ:
  780. NRF_LOG_INFO("RemoteWU initiated");
  781. m_usbd_suspend_state_req = false;
  782. break;
  783. case NRF_DRV_USBD_EVT_RESET:
  784. {
  785. ret_code_t ret = ep_configuration(0);
  786. ASSERT(ret == NRF_SUCCESS);
  787. UNUSED_VARIABLE(ret);
  788. m_usbd_suspend_state_req = false;
  789. break;
  790. }
  791. case NRF_DRV_USBD_EVT_SOF:
  792. {
  793. static uint32_t cycle = 0;
  794. ++cycle;
  795. if ((cycle % (m_usbd_configured ? 500 : 100)) == 0)
  796. {
  797. bsp_board_led_invert(LED_USB_STATUS);
  798. }
  799. break;
  800. }
  801. case NRF_DRV_USBD_EVT_EPTRANSFER:
  802. if (NRF_DRV_USBD_EPIN1 == p_event->data.eptransfer.ep)
  803. {
  804. m_send_mouse_position = false;
  805. }
  806. else
  807. if (NRF_DRV_USBD_EPIN0 == p_event->data.eptransfer.ep)
  808. {
  809. if (NRF_USBD_EP_OK == p_event->data.eptransfer.status)
  810. {
  811. /* Transfer ok - allow status stage */
  812. nrf_drv_usbd_setup_clear();
  813. }
  814. else if (NRF_USBD_EP_ABORTED == p_event->data.eptransfer.status)
  815. {
  816. /* Just ignore */
  817. NRF_LOG_INFO("Transfer aborted event on EPIN0");
  818. }
  819. else
  820. {
  821. NRF_LOG_ERROR("Transfer failed on EPIN0: %d", p_event->data.eptransfer.status);
  822. nrf_drv_usbd_setup_stall();
  823. }
  824. }
  825. else
  826. if (NRF_DRV_USBD_EPOUT0 == p_event->data.eptransfer.ep)
  827. {
  828. /* NOTE: No EPOUT0 data transfers are used.
  829. * The code is here as a pattern how to support such a transfer. */
  830. if (NRF_USBD_EP_OK == p_event->data.eptransfer.status)
  831. {
  832. /* Transfer ok - allow status stage */
  833. nrf_drv_usbd_setup_clear();
  834. }
  835. else if (NRF_USBD_EP_ABORTED == p_event->data.eptransfer.status)
  836. {
  837. /* Just ignore */
  838. NRF_LOG_INFO("Transfer aborted event on EPOUT0");
  839. }
  840. else
  841. {
  842. NRF_LOG_ERROR("Transfer failed on EPOUT0: %d", p_event->data.eptransfer.status);
  843. nrf_drv_usbd_setup_stall();
  844. }
  845. }
  846. else
  847. {
  848. /* Nothing to do */
  849. }
  850. break;
  851. case NRF_DRV_USBD_EVT_SETUP:
  852. {
  853. nrf_drv_usbd_setup_t setup;
  854. nrf_drv_usbd_setup_get(&setup);
  855. switch (setup.bRequest)
  856. {
  857. case 0x00: // GetStatus
  858. usbd_setup_GetStatus(&setup);
  859. break;
  860. case 0x01: // CleartFeature
  861. usbd_setup_ClearFeature(&setup);
  862. break;
  863. case 0x03: // SetFeature
  864. usbd_setup_SetFeature(&setup);
  865. break;
  866. case 0x05: // SetAddress
  867. //nothing to do, handled by hardware; but don't STALL
  868. break;
  869. case 0x06: // GetDescriptor
  870. usbd_setup_GetDescriptor(&setup);
  871. break;
  872. case 0x08: // GetConfig
  873. usbd_setup_GetConfig(&setup);
  874. break;
  875. case 0x09: // SetConfig
  876. usbd_setup_SetConfig(&setup);
  877. break;
  878. //HID class
  879. case 0x0A: // SetIdle
  880. usbd_setup_SetIdle(&setup);
  881. break;
  882. case 0x0B: // SetProtocol or SetInterface
  883. if (setup.bmRequestType == 0x01) // standard request, recipient=interface
  884. {
  885. usbd_setup_SetInterface(&setup);
  886. }
  887. else if (setup.bmRequestType == 0x21) // class request, recipient=interface
  888. {
  889. usbd_setup_SetProtocol(&setup);
  890. }
  891. else
  892. {
  893. NRF_LOG_ERROR("Command 0xB. Unknown request: 0x%2x", setup.bmRequestType);
  894. nrf_drv_usbd_setup_stall();
  895. }
  896. break;
  897. default:
  898. NRF_LOG_ERROR("Unknown request: 0x%2x", setup.bRequest);
  899. nrf_drv_usbd_setup_stall();
  900. return;
  901. }
  902. break;
  903. }
  904. default:
  905. break;
  906. }
  907. }
  908. static void move_mouse_pointer(void)
  909. {
  910. static uint32_t databuffer;
  911. if (!m_usbd_configured)
  912. return;
  913. if (!m_send_mouse_position)
  914. {
  915. switch (m_mouse_position & 0x3)
  916. {
  917. case 0:
  918. /* X = 10, rest all are unchanged */
  919. databuffer = 0x00000A00;
  920. break;
  921. case 1:
  922. /* Y = 10, rest all are unchanged */
  923. databuffer = 0x000A0000;
  924. break;
  925. case 2:
  926. /* X = -10, rest all are unchanged */
  927. databuffer = 0x0000F600;
  928. break;
  929. case 3:
  930. /* Y = -10, rest all are unchanged */
  931. databuffer = 0x00F60000;
  932. break;
  933. }
  934. m_mouse_position++;
  935. /* Send data */
  936. static const nrf_drv_usbd_transfer_t transfer =
  937. {
  938. .p_data = {.tx = &databuffer},
  939. .size = sizeof(databuffer)
  940. };
  941. m_send_mouse_position = true;
  942. UNUSED_RETURN_VALUE(nrf_drv_usbd_ep_transfer(
  943. NRF_DRV_USBD_EPIN1,
  944. &transfer));
  945. }
  946. }
  947. static void power_usb_event_handler(nrf_drv_power_usb_evt_t event)
  948. {
  949. switch (event)
  950. {
  951. case NRF_DRV_POWER_USB_EVT_DETECTED:
  952. NRF_LOG_INFO("USB power detected");
  953. if (!nrf_drv_usbd_is_enabled())
  954. {
  955. nrf_drv_usbd_enable();
  956. }
  957. break;
  958. case NRF_DRV_POWER_USB_EVT_REMOVED:
  959. NRF_LOG_INFO("USB power removed");
  960. m_usbd_configured = false;
  961. m_send_mouse_position = false;
  962. if (nrf_drv_usbd_is_started())
  963. {
  964. nrf_drv_usbd_stop();
  965. }
  966. if (nrf_drv_usbd_is_enabled())
  967. {
  968. nrf_drv_usbd_disable();
  969. }
  970. /* Turn OFF LEDs */
  971. bsp_board_led_off(LED_USB_STATUS);
  972. bsp_board_led_off(LED_USB_POWER);
  973. break;
  974. case NRF_DRV_POWER_USB_EVT_READY:
  975. NRF_LOG_INFO("USB ready");
  976. bsp_board_led_on(LED_USB_POWER);
  977. if (!nrf_drv_usbd_is_started())
  978. {
  979. nrf_drv_usbd_start(true);
  980. }
  981. break;
  982. default:
  983. ASSERT(false);
  984. }
  985. }
  986. static void bsp_evt_handler(bsp_event_t evt)
  987. {
  988. switch ((unsigned int)evt)
  989. {
  990. case BSP_EVENT_SYSOFF:
  991. {
  992. m_system_off_req = true;
  993. break;
  994. }
  995. case CONCAT_2(BSP_EVENT_KEY_, BTN_DATA_SEND):
  996. {
  997. m_send_flag = 1;
  998. break;
  999. }
  1000. case BTN_DATA_KEY_RELEASE:
  1001. {
  1002. m_send_flag = 0;
  1003. break;
  1004. }
  1005. default:
  1006. return;
  1007. }
  1008. }
  1009. static void init_power_clock(void)
  1010. {
  1011. ret_code_t ret;
  1012. /* Initializing power and clock */
  1013. ret = nrf_drv_clock_init();
  1014. APP_ERROR_CHECK(ret);
  1015. ret = nrf_drv_power_init(NULL);
  1016. APP_ERROR_CHECK(ret);
  1017. nrf_drv_clock_hfclk_request(NULL);
  1018. nrf_drv_clock_lfclk_request(NULL);
  1019. while (!(nrf_drv_clock_hfclk_is_running() &&
  1020. nrf_drv_clock_lfclk_is_running()))
  1021. {
  1022. /* Just waiting */
  1023. }
  1024. ret = app_timer_init();
  1025. APP_ERROR_CHECK(ret);
  1026. /* Avoid warnings if assertion is disabled */
  1027. UNUSED_VARIABLE(ret);
  1028. }
  1029. static void init_bsp(void)
  1030. {
  1031. ret_code_t ret;
  1032. ret = bsp_init(BSP_INIT_BUTTONS, bsp_evt_handler);
  1033. APP_ERROR_CHECK(ret);
  1034. ret = bsp_event_to_button_action_assign(
  1035. BTN_SYSTEM_OFF,
  1036. BSP_BUTTON_ACTION_RELEASE,
  1037. BSP_EVENT_SYSOFF);
  1038. APP_ERROR_CHECK(ret);
  1039. ret = bsp_event_to_button_action_assign(BTN_DATA_SEND,
  1040. BSP_BUTTON_ACTION_RELEASE,
  1041. BTN_DATA_KEY_RELEASE);
  1042. APP_ERROR_CHECK(ret);
  1043. /* Avoid warnings if assertion is disabled */
  1044. UNUSED_VARIABLE(ret);
  1045. }
  1046. static void init_cli(void)
  1047. {
  1048. ret_code_t ret;
  1049. ret = bsp_cli_init(bsp_evt_handler);
  1050. APP_ERROR_CHECK(ret);
  1051. nrf_drv_uart_config_t uart_config = NRF_DRV_UART_DEFAULT_CONFIG;
  1052. uart_config.pseltxd = TX_PIN_NUMBER;
  1053. uart_config.pselrxd = RX_PIN_NUMBER;
  1054. uart_config.hwfc = NRF_UART_HWFC_DISABLED;
  1055. ret = nrf_cli_init(&m_cli_uart, &uart_config, true, true, NRF_LOG_SEVERITY_INFO);
  1056. APP_ERROR_CHECK(ret);
  1057. ret = nrf_cli_start(&m_cli_uart);
  1058. APP_ERROR_CHECK(ret);
  1059. }
  1060. static void log_resetreason(void)
  1061. {
  1062. /* Reset reason */
  1063. uint32_t rr = nrf_power_resetreas_get();
  1064. NRF_LOG_INFO("Reset reasons:");
  1065. if (0 == rr)
  1066. {
  1067. NRF_LOG_INFO("- NONE");
  1068. }
  1069. if (0 != (rr & NRF_POWER_RESETREAS_RESETPIN_MASK))
  1070. {
  1071. NRF_LOG_INFO("- RESETPIN");
  1072. }
  1073. if (0 != (rr & NRF_POWER_RESETREAS_DOG_MASK ))
  1074. {
  1075. NRF_LOG_INFO("- DOG");
  1076. }
  1077. if (0 != (rr & NRF_POWER_RESETREAS_SREQ_MASK ))
  1078. {
  1079. NRF_LOG_INFO("- SREQ");
  1080. }
  1081. if (0 != (rr & NRF_POWER_RESETREAS_LOCKUP_MASK ))
  1082. {
  1083. NRF_LOG_INFO("- LOCKUP");
  1084. }
  1085. if (0 != (rr & NRF_POWER_RESETREAS_OFF_MASK ))
  1086. {
  1087. NRF_LOG_INFO("- OFF");
  1088. }
  1089. #if defined(NRF_POWER_RESETREAS_LPCOMP_MASK)
  1090. if (0 != (rr & NRF_POWER_RESETREAS_LPCOMP_MASK ))
  1091. {
  1092. NRF_LOG_INFO("- LPCOMP");
  1093. }
  1094. #endif
  1095. if (0 != (rr & NRF_POWER_RESETREAS_DIF_MASK ))
  1096. {
  1097. NRF_LOG_INFO("- DIF");
  1098. }
  1099. #if defined(NRF_POWER_RESETREAS_NFC_MASK)
  1100. if (0 != (rr & NRF_POWER_RESETREAS_NFC_MASK ))
  1101. {
  1102. NRF_LOG_INFO("- NFC");
  1103. }
  1104. #endif
  1105. if (0 != (rr & NRF_POWER_RESETREAS_VBUS_MASK ))
  1106. {
  1107. NRF_LOG_INFO("- VBUS");
  1108. }
  1109. }
  1110. int main(void)
  1111. {
  1112. ret_code_t ret;
  1113. UNUSED_RETURN_VALUE(NRF_LOG_INIT(NULL));
  1114. init_power_clock();
  1115. init_bsp();
  1116. init_cli();
  1117. NRF_LOG_INFO("USDB example started.");
  1118. log_resetreason();
  1119. nrf_power_resetreas_clear(nrf_power_resetreas_get());
  1120. /* USB work starts right here */
  1121. ret = nrf_drv_usbd_init(usbd_event_handler);
  1122. APP_ERROR_CHECK(ret);
  1123. /* Configure selected size of the packed on EP0 */
  1124. nrf_drv_usbd_ep_max_packet_size_set(NRF_DRV_USBD_EPOUT0, EP0_MAXPACKETSIZE);
  1125. nrf_drv_usbd_ep_max_packet_size_set(NRF_DRV_USBD_EPIN0, EP0_MAXPACKETSIZE);
  1126. /* Configure LED and button */
  1127. bsp_board_init(BSP_INIT_LEDS);
  1128. bsp_board_led_on(LED_RUNNING);
  1129. bsp_board_led_on(LED_ACTIVE);
  1130. if (USBD_POWER_DETECTION)
  1131. {
  1132. static const nrf_drv_power_usbevt_config_t config =
  1133. {
  1134. .handler = power_usb_event_handler
  1135. };
  1136. ret = nrf_drv_power_usbevt_init(&config);
  1137. APP_ERROR_CHECK(ret);
  1138. }
  1139. else
  1140. {
  1141. NRF_LOG_INFO("No USB power detection enabled\r\nStarting USB now");
  1142. nrf_delay_us(STARTUP_DELAY);
  1143. if (!nrf_drv_usbd_is_enabled())
  1144. {
  1145. nrf_drv_usbd_enable();
  1146. ret = ep_configuration(0);
  1147. APP_ERROR_CHECK(ret);
  1148. }
  1149. /* Wait for regulator power up */
  1150. while (NRF_DRV_POWER_USB_STATE_CONNECTED
  1151. ==
  1152. nrf_drv_power_usbstatus_get())
  1153. {
  1154. /* Just waiting */
  1155. }
  1156. if (NRF_DRV_POWER_USB_STATE_READY == nrf_drv_power_usbstatus_get())
  1157. {
  1158. if (!nrf_drv_usbd_is_started())
  1159. {
  1160. nrf_drv_usbd_start(true);
  1161. }
  1162. }
  1163. else
  1164. {
  1165. nrf_drv_usbd_disable();
  1166. }
  1167. }
  1168. while (true)
  1169. {
  1170. if (m_system_off_req)
  1171. {
  1172. NRF_LOG_INFO("Going to system OFF");
  1173. NRF_LOG_FLUSH();
  1174. bsp_board_led_off(LED_RUNNING);
  1175. bsp_board_led_off(LED_ACTIVE);
  1176. nrf_power_system_off();
  1177. }
  1178. if (m_usbd_suspended != m_usbd_suspend_state_req)
  1179. {
  1180. if (m_usbd_suspend_state_req)
  1181. {
  1182. m_usbd_suspended = nrf_drv_usbd_suspend();
  1183. if (m_usbd_suspended)
  1184. {
  1185. bsp_board_leds_off();
  1186. }
  1187. }
  1188. else
  1189. {
  1190. m_usbd_suspended = false;
  1191. }
  1192. }
  1193. if (m_usbd_configured)
  1194. {
  1195. if (m_send_flag)
  1196. {
  1197. if (m_usbd_suspended)
  1198. {
  1199. if (m_usbd_rwu_enabled)
  1200. {
  1201. UNUSED_RETURN_VALUE(nrf_drv_usbd_wakeup_req());
  1202. }
  1203. }
  1204. else
  1205. {
  1206. NRF_LOG_INFO(" TX pointer");
  1207. move_mouse_pointer();
  1208. }
  1209. }
  1210. }
  1211. nrf_cli_process(&m_cli_uart);
  1212. UNUSED_RETURN_VALUE(NRF_LOG_PROCESS());
  1213. bsp_board_led_off(LED_RUNNING);
  1214. /* Even if we miss an event enabling USB,
  1215. * USB event would wake us up. */
  1216. __WFE();
  1217. /* Clear SEV flag if CPU was woken up by event */
  1218. __SEV();
  1219. __WFE();
  1220. bsp_board_led_on(LED_RUNNING);
  1221. }
  1222. }