usb.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784
  1. /*
  2. * This file is part of the MicroPython project, http://micropython.org/
  3. *
  4. * The MIT License (MIT)
  5. *
  6. * Copyright (c) 2013, 2014, 2015 Damien P. George
  7. *
  8. * Permission is hereby granted, free of charge, to any person obtaining a copy
  9. * of this software and associated documentation files (the "Software"), to deal
  10. * in the Software without restriction, including without limitation the rights
  11. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  12. * copies of the Software, and to permit persons to whom the Software is
  13. * furnished to do so, subject to the following conditions:
  14. *
  15. * The above copyright notice and this permission notice shall be included in
  16. * all copies or substantial portions of the Software.
  17. *
  18. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  21. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  22. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  24. * THE SOFTWARE.
  25. */
  26. #include <stdarg.h>
  27. #include <string.h>
  28. #include "usbd_core.h"
  29. #include "usbd_desc.h"
  30. #include "usbd_cdc_msc_hid.h"
  31. #include "usbd_cdc_interface.h"
  32. #include "usbd_msc_storage.h"
  33. #include "usbd_hid_interface.h"
  34. #include "py/objstr.h"
  35. #include "py/runtime.h"
  36. #include "py/stream.h"
  37. #include "py/mperrno.h"
  38. #include "py/mphal.h"
  39. #include "bufhelper.h"
  40. #include "usb.h"
  41. #if MICROPY_HW_ENABLE_USB
  42. // Work out which USB device to use as the main one (the one with the REPL)
  43. #if !defined(MICROPY_HW_USB_MAIN_DEV)
  44. #if defined(MICROPY_HW_USB_FS)
  45. #define MICROPY_HW_USB_MAIN_DEV (USB_PHY_FS_ID)
  46. #elif defined(MICROPY_HW_USB_HS) && defined(MICROPY_HW_USB_HS_IN_FS)
  47. #define MICROPY_HW_USB_MAIN_DEV (USB_PHY_HS_ID)
  48. #else
  49. #error Unable to determine proper MICROPY_HW_USB_MAIN_DEV to use
  50. #endif
  51. #endif
  52. // this will be persistent across a soft-reset
  53. mp_uint_t pyb_usb_flags = 0;
  54. typedef struct _usb_device_t {
  55. uint32_t enabled;
  56. USBD_HandleTypeDef hUSBDDevice;
  57. usbd_cdc_msc_hid_state_t usbd_cdc_msc_hid_state;
  58. usbd_cdc_itf_t usbd_cdc_itf;
  59. #if MICROPY_HW_USB_ENABLE_CDC2
  60. usbd_cdc_itf_t usbd_cdc2_itf;
  61. #endif
  62. usbd_hid_itf_t usbd_hid_itf;
  63. } usb_device_t;
  64. usb_device_t usb_device;
  65. pyb_usb_storage_medium_t pyb_usb_storage_medium = PYB_USB_STORAGE_MEDIUM_NONE;
  66. // predefined hid mouse data
  67. STATIC const mp_obj_str_t pyb_usb_hid_mouse_desc_obj = {
  68. {&mp_type_bytes},
  69. 0, // hash not valid
  70. USBD_HID_MOUSE_REPORT_DESC_SIZE,
  71. USBD_HID_MOUSE_ReportDesc,
  72. };
  73. const mp_rom_obj_tuple_t pyb_usb_hid_mouse_obj = {
  74. {&mp_type_tuple},
  75. 5,
  76. {
  77. MP_ROM_INT(1), // subclass: boot
  78. MP_ROM_INT(2), // protocol: mouse
  79. MP_ROM_INT(USBD_HID_MOUSE_MAX_PACKET),
  80. MP_ROM_INT(8), // polling interval: 8ms
  81. MP_ROM_PTR(&pyb_usb_hid_mouse_desc_obj),
  82. },
  83. };
  84. // predefined hid keyboard data
  85. STATIC const mp_obj_str_t pyb_usb_hid_keyboard_desc_obj = {
  86. {&mp_type_bytes},
  87. 0, // hash not valid
  88. USBD_HID_KEYBOARD_REPORT_DESC_SIZE,
  89. USBD_HID_KEYBOARD_ReportDesc,
  90. };
  91. const mp_rom_obj_tuple_t pyb_usb_hid_keyboard_obj = {
  92. {&mp_type_tuple},
  93. 5,
  94. {
  95. MP_ROM_INT(1), // subclass: boot
  96. MP_ROM_INT(1), // protocol: keyboard
  97. MP_ROM_INT(USBD_HID_KEYBOARD_MAX_PACKET),
  98. MP_ROM_INT(8), // polling interval: 8ms
  99. MP_ROM_PTR(&pyb_usb_hid_keyboard_desc_obj),
  100. },
  101. };
  102. void pyb_usb_init0(void) {
  103. mp_hal_set_interrupt_char(-1);
  104. MP_STATE_PORT(pyb_hid_report_desc) = MP_OBJ_NULL;
  105. }
  106. bool pyb_usb_dev_init(uint16_t vid, uint16_t pid, usb_device_mode_t mode, USBD_HID_ModeInfoTypeDef *hid_info) {
  107. bool high_speed = (mode & USBD_MODE_HIGH_SPEED) != 0;
  108. mode &= 0x7f;
  109. usb_device_t *usb_dev = &usb_device;
  110. if (!usb_dev->enabled) {
  111. // only init USB once in the device's power-lifetime
  112. // set up the USBD state
  113. USBD_HandleTypeDef *usbd = &usb_dev->hUSBDDevice;
  114. usbd->id = MICROPY_HW_USB_MAIN_DEV;
  115. usbd->dev_state = USBD_STATE_DEFAULT;
  116. usbd->pDesc = (USBD_DescriptorsTypeDef*)&USBD_Descriptors;
  117. usbd->pClass = &USBD_CDC_MSC_HID;
  118. usb_dev->usbd_cdc_msc_hid_state.pdev = usbd;
  119. usb_dev->usbd_cdc_msc_hid_state.cdc = &usb_dev->usbd_cdc_itf.base;
  120. #if MICROPY_HW_USB_ENABLE_CDC2
  121. usb_dev->usbd_cdc_msc_hid_state.cdc2 = &usb_dev->usbd_cdc2_itf.base;
  122. #endif
  123. usb_dev->usbd_cdc_msc_hid_state.hid = &usb_dev->usbd_hid_itf.base;
  124. usbd->pClassData = &usb_dev->usbd_cdc_msc_hid_state;
  125. // configure the VID, PID and the USBD mode (interfaces it will expose)
  126. USBD_SetVIDPIDRelease(&usb_dev->usbd_cdc_msc_hid_state, vid, pid, 0x0200, mode == USBD_MODE_CDC);
  127. if (USBD_SelectMode(&usb_dev->usbd_cdc_msc_hid_state, mode, hid_info) != 0) {
  128. return false;
  129. }
  130. switch (pyb_usb_storage_medium) {
  131. #if MICROPY_HW_HAS_SDCARD
  132. case PYB_USB_STORAGE_MEDIUM_SDCARD:
  133. USBD_MSC_RegisterStorage(&usb_dev->usbd_cdc_msc_hid_state, (USBD_StorageTypeDef*)&USBD_SDCARD_STORAGE_fops);
  134. break;
  135. #endif
  136. default:
  137. USBD_MSC_RegisterStorage(&usb_dev->usbd_cdc_msc_hid_state, (USBD_StorageTypeDef*)&USBD_FLASH_STORAGE_fops);
  138. break;
  139. }
  140. // start the USB device
  141. USBD_LL_Init(usbd, high_speed);
  142. USBD_LL_Start(usbd);
  143. usb_dev->enabled = true;
  144. }
  145. return true;
  146. }
  147. void pyb_usb_dev_deinit(void) {
  148. usb_device_t *usb_dev = &usb_device;
  149. if (usb_dev->enabled) {
  150. USBD_Stop(&usb_dev->hUSBDDevice);
  151. usb_dev->enabled = false;
  152. }
  153. }
  154. bool usb_vcp_is_enabled(void) {
  155. return usb_device.enabled;
  156. }
  157. int usb_vcp_recv_byte(uint8_t *c) {
  158. return usbd_cdc_rx(&usb_device.usbd_cdc_itf, c, 1, 0);
  159. }
  160. void usb_vcp_send_strn(const char *str, int len) {
  161. if (usb_device.enabled) {
  162. usbd_cdc_tx_always(&usb_device.usbd_cdc_itf, (const uint8_t*)str, len);
  163. }
  164. }
  165. usbd_cdc_itf_t *usb_vcp_get(int idx) {
  166. #if MICROPY_HW_USB_ENABLE_CDC2
  167. if (idx == 1) {
  168. return &usb_device.usbd_cdc2_itf;
  169. }
  170. #endif
  171. return &usb_device.usbd_cdc_itf;
  172. }
  173. /******************************************************************************/
  174. // MicroPython bindings for USB
  175. /*
  176. Philosophy of USB driver and Python API: pyb.usb_mode(...) configures the USB
  177. on the board. The USB itself is not an entity, rather the interfaces are, and
  178. can be accessed by creating objects, such as pyb.USB_VCP() and pyb.USB_HID().
  179. We have:
  180. pyb.usb_mode() # return the current usb mode
  181. pyb.usb_mode(None) # disable USB
  182. pyb.usb_mode('VCP') # enable with VCP interface
  183. pyb.usb_mode('VCP+MSC') # enable with VCP and MSC interfaces
  184. pyb.usb_mode('VCP+HID') # enable with VCP and HID, defaulting to mouse protocol
  185. pyb.usb_mode('VCP+HID', vid=0xf055, pid=0x9800) # specify VID and PID
  186. pyb.usb_mode('VCP+HID', hid=pyb.hid_mouse)
  187. pyb.usb_mode('VCP+HID', hid=pyb.hid_keyboard)
  188. pyb.usb_mode('VCP+HID', pid=0x1234, hid=(subclass, protocol, max_packet_len, polling_interval, report_desc))
  189. vcp = pyb.USB_VCP() # get the VCP device for read/write
  190. hid = pyb.USB_HID() # get the HID device for write/poll
  191. Possible extensions:
  192. pyb.usb_mode('host', ...)
  193. pyb.usb_mode('OTG', ...)
  194. pyb.usb_mode(..., port=2) # for second USB port
  195. */
  196. STATIC mp_obj_t pyb_usb_mode(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
  197. static const mp_arg_t allowed_args[] = {
  198. { MP_QSTR_mode, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_PTR(&mp_const_none_obj)} },
  199. { MP_QSTR_vid, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = USBD_VID} },
  200. { MP_QSTR_pid, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} },
  201. { MP_QSTR_hid, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_PTR(&pyb_usb_hid_mouse_obj)} },
  202. #if USBD_SUPPORT_HS_MODE
  203. { MP_QSTR_high_speed, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
  204. #endif
  205. };
  206. // fetch the current usb mode -> pyb.usb_mode()
  207. if (n_args == 0) {
  208. #if defined(USE_HOST_MODE)
  209. return MP_OBJ_NEW_QSTR(MP_QSTR_host);
  210. #else
  211. uint8_t mode = USBD_GetMode(&usb_device.usbd_cdc_msc_hid_state);
  212. switch (mode) {
  213. case USBD_MODE_CDC:
  214. return MP_OBJ_NEW_QSTR(MP_QSTR_VCP);
  215. case USBD_MODE_MSC:
  216. return MP_OBJ_NEW_QSTR(MP_QSTR_MSC);
  217. case USBD_MODE_HID:
  218. return MP_OBJ_NEW_QSTR(MP_QSTR_HID);
  219. case USBD_MODE_CDC_MSC:
  220. return MP_OBJ_NEW_QSTR(MP_QSTR_VCP_plus_MSC);
  221. case USBD_MODE_CDC_HID:
  222. return MP_OBJ_NEW_QSTR(MP_QSTR_VCP_plus_HID);
  223. case USBD_MODE_MSC_HID:
  224. return MP_OBJ_NEW_QSTR(MP_QSTR_MSC_plus_HID);
  225. default:
  226. return mp_const_none;
  227. }
  228. #endif
  229. }
  230. // parse args
  231. mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
  232. mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
  233. // record the fact that the usb has been explicitly configured
  234. pyb_usb_flags |= PYB_USB_FLAG_USB_MODE_CALLED;
  235. // check if user wants to disable the USB
  236. if (args[0].u_obj == mp_const_none) {
  237. // disable usb
  238. pyb_usb_dev_deinit();
  239. return mp_const_none;
  240. }
  241. // get mode string
  242. const char *mode_str = mp_obj_str_get_str(args[0].u_obj);
  243. #if defined(USE_HOST_MODE)
  244. // hardware configured for USB host mode
  245. if (strcmp(mode_str, "host") == 0) {
  246. pyb_usb_host_init();
  247. } else {
  248. goto bad_mode;
  249. }
  250. #else
  251. // hardware configured for USB device mode
  252. // get the VID, PID and USB mode
  253. // note: PID=-1 means select PID based on mode
  254. // note: we support CDC as a synonym for VCP for backward compatibility
  255. uint16_t vid = args[1].u_int;
  256. uint16_t pid = args[2].u_int;
  257. usb_device_mode_t mode;
  258. if (strcmp(mode_str, "CDC+MSC") == 0 || strcmp(mode_str, "VCP+MSC") == 0) {
  259. if (args[2].u_int == -1) {
  260. pid = USBD_PID_CDC_MSC;
  261. }
  262. mode = USBD_MODE_CDC_MSC;
  263. #if MICROPY_HW_USB_ENABLE_CDC2
  264. } else if (strcmp(mode_str, "VCP+VCP+MSC") == 0) {
  265. if (args[2].u_int == -1) {
  266. pid = USBD_PID_CDC2_MSC;
  267. }
  268. mode = USBD_MODE_CDC2_MSC;
  269. #endif
  270. } else if (strcmp(mode_str, "CDC+HID") == 0 || strcmp(mode_str, "VCP+HID") == 0) {
  271. if (args[2].u_int == -1) {
  272. pid = USBD_PID_CDC_HID;
  273. }
  274. mode = USBD_MODE_CDC_HID;
  275. } else if (strcmp(mode_str, "CDC") == 0 || strcmp(mode_str, "VCP") == 0) {
  276. if (args[2].u_int == -1) {
  277. pid = USBD_PID_CDC;
  278. }
  279. mode = USBD_MODE_CDC;
  280. } else if (strcmp(mode_str, "MSC") == 0) {
  281. if (args[2].u_int == -1) {
  282. pid = USBD_PID_MSC;
  283. }
  284. mode = USBD_MODE_MSC;
  285. } else {
  286. goto bad_mode;
  287. }
  288. // get hid info if user selected such a mode
  289. USBD_HID_ModeInfoTypeDef hid_info;
  290. if (mode & USBD_MODE_HID) {
  291. mp_obj_t *items;
  292. mp_obj_get_array_fixed_n(args[3].u_obj, 5, &items);
  293. hid_info.subclass = mp_obj_get_int(items[0]);
  294. hid_info.protocol = mp_obj_get_int(items[1]);
  295. hid_info.max_packet_len = mp_obj_get_int(items[2]);
  296. hid_info.polling_interval = mp_obj_get_int(items[3]);
  297. mp_buffer_info_t bufinfo;
  298. mp_get_buffer_raise(items[4], &bufinfo, MP_BUFFER_READ);
  299. hid_info.report_desc = bufinfo.buf;
  300. hid_info.report_desc_len = bufinfo.len;
  301. // need to keep a copy of this so report_desc does not get GC'd
  302. MP_STATE_PORT(pyb_hid_report_desc) = items[4];
  303. }
  304. #if USBD_SUPPORT_HS_MODE
  305. if (args[4].u_bool) {
  306. mode |= USBD_MODE_HIGH_SPEED;
  307. }
  308. #endif
  309. // init the USB device
  310. if (!pyb_usb_dev_init(vid, pid, mode, &hid_info)) {
  311. goto bad_mode;
  312. }
  313. #endif
  314. return mp_const_none;
  315. bad_mode:
  316. mp_raise_ValueError("bad USB mode");
  317. }
  318. MP_DEFINE_CONST_FUN_OBJ_KW(pyb_usb_mode_obj, 0, pyb_usb_mode);
  319. /******************************************************************************/
  320. // MicroPython bindings for USB VCP
  321. /// \moduleref pyb
  322. /// \class USB_VCP - USB virtual comm port
  323. ///
  324. /// The USB_VCP class allows creation of an object representing the USB
  325. /// virtual comm port. It can be used to read and write data over USB to
  326. /// the connected host.
  327. typedef struct _pyb_usb_vcp_obj_t {
  328. mp_obj_base_t base;
  329. usbd_cdc_itf_t *cdc_itf;
  330. } pyb_usb_vcp_obj_t;
  331. STATIC const pyb_usb_vcp_obj_t pyb_usb_vcp_obj = {{&pyb_usb_vcp_type}, &usb_device.usbd_cdc_itf};
  332. #if MICROPY_HW_USB_ENABLE_CDC2
  333. STATIC const pyb_usb_vcp_obj_t pyb_usb_vcp2_obj = {{&pyb_usb_vcp_type}, &usb_device.usbd_cdc2_itf};
  334. #endif
  335. STATIC void pyb_usb_vcp_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
  336. int id = ((pyb_usb_vcp_obj_t*)MP_OBJ_TO_PTR(self_in))->cdc_itf - &usb_device.usbd_cdc_itf;
  337. mp_printf(print, "USB_VCP(%u)", id);
  338. }
  339. /// \classmethod \constructor()
  340. /// Create a new USB_VCP object.
  341. STATIC mp_obj_t pyb_usb_vcp_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
  342. // check arguments
  343. mp_arg_check_num(n_args, n_kw, 0, 1, false);
  344. // TODO raise exception if USB is not configured for VCP
  345. int id = (n_args == 0) ? 0 : mp_obj_get_int(args[0]);
  346. if (id == 0) {
  347. return MP_OBJ_FROM_PTR(&pyb_usb_vcp_obj);
  348. #if MICROPY_HW_USB_ENABLE_CDC2
  349. } else if (id == 1) {
  350. return MP_OBJ_FROM_PTR(&pyb_usb_vcp2_obj);
  351. #endif
  352. } else {
  353. mp_raise_ValueError(NULL);
  354. }
  355. }
  356. STATIC mp_obj_t pyb_usb_vcp_setinterrupt(mp_obj_t self_in, mp_obj_t int_chr_in) {
  357. mp_hal_set_interrupt_char(mp_obj_get_int(int_chr_in));
  358. return mp_const_none;
  359. }
  360. STATIC MP_DEFINE_CONST_FUN_OBJ_2(pyb_usb_vcp_setinterrupt_obj, pyb_usb_vcp_setinterrupt);
  361. STATIC mp_obj_t pyb_usb_vcp_isconnected(mp_obj_t self_in) {
  362. pyb_usb_vcp_obj_t *self = MP_OBJ_TO_PTR(self_in);
  363. return mp_obj_new_bool(usbd_cdc_is_connected(self->cdc_itf));
  364. }
  365. STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_usb_vcp_isconnected_obj, pyb_usb_vcp_isconnected);
  366. // deprecated in favour of USB_VCP.isconnected
  367. STATIC mp_obj_t pyb_have_cdc(void) {
  368. return pyb_usb_vcp_isconnected(MP_OBJ_FROM_PTR(&pyb_usb_vcp_obj));
  369. }
  370. MP_DEFINE_CONST_FUN_OBJ_0(pyb_have_cdc_obj, pyb_have_cdc);
  371. /// \method any()
  372. /// Return `True` if any characters waiting, else `False`.
  373. STATIC mp_obj_t pyb_usb_vcp_any(mp_obj_t self_in) {
  374. pyb_usb_vcp_obj_t *self = MP_OBJ_TO_PTR(self_in);
  375. if (usbd_cdc_rx_num(self->cdc_itf) > 0) {
  376. return mp_const_true;
  377. } else {
  378. return mp_const_false;
  379. }
  380. }
  381. STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_usb_vcp_any_obj, pyb_usb_vcp_any);
  382. /// \method send(data, *, timeout=5000)
  383. /// Send data over the USB VCP:
  384. ///
  385. /// - `data` is the data to send (an integer to send, or a buffer object).
  386. /// - `timeout` is the timeout in milliseconds to wait for the send.
  387. ///
  388. /// Return value: number of bytes sent.
  389. STATIC const mp_arg_t pyb_usb_vcp_send_args[] = {
  390. { MP_QSTR_data, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
  391. { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 5000} },
  392. };
  393. #define PYB_USB_VCP_SEND_NUM_ARGS MP_ARRAY_SIZE(pyb_usb_vcp_send_args)
  394. STATIC mp_obj_t pyb_usb_vcp_send(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
  395. // parse args
  396. pyb_usb_vcp_obj_t *self = MP_OBJ_TO_PTR(args[0]);
  397. mp_arg_val_t vals[PYB_USB_VCP_SEND_NUM_ARGS];
  398. mp_arg_parse_all(n_args - 1, args + 1, kw_args, PYB_USB_VCP_SEND_NUM_ARGS, pyb_usb_vcp_send_args, vals);
  399. // get the buffer to send from
  400. mp_buffer_info_t bufinfo;
  401. uint8_t data[1];
  402. pyb_buf_get_for_send(vals[0].u_obj, &bufinfo, data);
  403. // send the data
  404. int ret = usbd_cdc_tx(self->cdc_itf, bufinfo.buf, bufinfo.len, vals[1].u_int);
  405. return mp_obj_new_int(ret);
  406. }
  407. STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_usb_vcp_send_obj, 1, pyb_usb_vcp_send);
  408. /// \method recv(data, *, timeout=5000)
  409. ///
  410. /// Receive data on the bus:
  411. ///
  412. /// - `data` can be an integer, which is the number of bytes to receive,
  413. /// or a mutable buffer, which will be filled with received bytes.
  414. /// - `timeout` is the timeout in milliseconds to wait for the receive.
  415. ///
  416. /// Return value: if `data` is an integer then a new buffer of the bytes received,
  417. /// otherwise the number of bytes read into `data` is returned.
  418. STATIC mp_obj_t pyb_usb_vcp_recv(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
  419. // parse args
  420. pyb_usb_vcp_obj_t *self = MP_OBJ_TO_PTR(args[0]);
  421. mp_arg_val_t vals[PYB_USB_VCP_SEND_NUM_ARGS];
  422. mp_arg_parse_all(n_args - 1, args + 1, kw_args, PYB_USB_VCP_SEND_NUM_ARGS, pyb_usb_vcp_send_args, vals);
  423. // get the buffer to receive into
  424. vstr_t vstr;
  425. mp_obj_t o_ret = pyb_buf_get_for_recv(vals[0].u_obj, &vstr);
  426. // receive the data
  427. int ret = usbd_cdc_rx(self->cdc_itf, (uint8_t*)vstr.buf, vstr.len, vals[1].u_int);
  428. // return the received data
  429. if (o_ret != MP_OBJ_NULL) {
  430. return mp_obj_new_int(ret); // number of bytes read into given buffer
  431. } else {
  432. vstr.len = ret; // set actual number of bytes read
  433. return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); // create a new buffer
  434. }
  435. }
  436. STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_usb_vcp_recv_obj, 1, pyb_usb_vcp_recv);
  437. mp_obj_t pyb_usb_vcp___exit__(size_t n_args, const mp_obj_t *args) {
  438. return mp_const_none;
  439. }
  440. STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_usb_vcp___exit___obj, 4, 4, pyb_usb_vcp___exit__);
  441. STATIC const mp_rom_map_elem_t pyb_usb_vcp_locals_dict_table[] = {
  442. { MP_ROM_QSTR(MP_QSTR_setinterrupt), MP_ROM_PTR(&pyb_usb_vcp_setinterrupt_obj) },
  443. { MP_ROM_QSTR(MP_QSTR_isconnected), MP_ROM_PTR(&pyb_usb_vcp_isconnected_obj) },
  444. { MP_ROM_QSTR(MP_QSTR_any), MP_ROM_PTR(&pyb_usb_vcp_any_obj) },
  445. { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&pyb_usb_vcp_send_obj) },
  446. { MP_ROM_QSTR(MP_QSTR_recv), MP_ROM_PTR(&pyb_usb_vcp_recv_obj) },
  447. { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) },
  448. { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) },
  449. { MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj)},
  450. { MP_ROM_QSTR(MP_QSTR_readlines), MP_ROM_PTR(&mp_stream_unbuffered_readlines_obj)},
  451. { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) },
  452. { MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&mp_identity_obj) },
  453. { MP_ROM_QSTR(MP_QSTR___del__), MP_ROM_PTR(&mp_identity_obj) },
  454. { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&mp_identity_obj) },
  455. { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&pyb_usb_vcp___exit___obj) },
  456. };
  457. STATIC MP_DEFINE_CONST_DICT(pyb_usb_vcp_locals_dict, pyb_usb_vcp_locals_dict_table);
  458. STATIC mp_uint_t pyb_usb_vcp_read(mp_obj_t self_in, void *buf, mp_uint_t size, int *errcode) {
  459. pyb_usb_vcp_obj_t *self = MP_OBJ_TO_PTR(self_in);
  460. int ret = usbd_cdc_rx(self->cdc_itf, (byte*)buf, size, 0);
  461. if (ret == 0) {
  462. // return EAGAIN error to indicate non-blocking
  463. *errcode = MP_EAGAIN;
  464. return MP_STREAM_ERROR;
  465. }
  466. return ret;
  467. }
  468. STATIC mp_uint_t pyb_usb_vcp_write(mp_obj_t self_in, const void *buf, mp_uint_t size, int *errcode) {
  469. pyb_usb_vcp_obj_t *self = MP_OBJ_TO_PTR(self_in);
  470. int ret = usbd_cdc_tx(self->cdc_itf, (const byte*)buf, size, 0);
  471. if (ret == 0) {
  472. // return EAGAIN error to indicate non-blocking
  473. *errcode = MP_EAGAIN;
  474. return MP_STREAM_ERROR;
  475. }
  476. return ret;
  477. }
  478. STATIC mp_uint_t pyb_usb_vcp_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode) {
  479. mp_uint_t ret;
  480. pyb_usb_vcp_obj_t *self = MP_OBJ_TO_PTR(self_in);
  481. if (request == MP_STREAM_POLL) {
  482. uintptr_t flags = arg;
  483. ret = 0;
  484. if ((flags & MP_STREAM_POLL_RD) && usbd_cdc_rx_num(self->cdc_itf) > 0) {
  485. ret |= MP_STREAM_POLL_RD;
  486. }
  487. if ((flags & MP_STREAM_POLL_WR) && usbd_cdc_tx_half_empty(self->cdc_itf)) {
  488. ret |= MP_STREAM_POLL_WR;
  489. }
  490. } else {
  491. *errcode = MP_EINVAL;
  492. ret = MP_STREAM_ERROR;
  493. }
  494. return ret;
  495. }
  496. STATIC const mp_stream_p_t pyb_usb_vcp_stream_p = {
  497. .read = pyb_usb_vcp_read,
  498. .write = pyb_usb_vcp_write,
  499. .ioctl = pyb_usb_vcp_ioctl,
  500. };
  501. const mp_obj_type_t pyb_usb_vcp_type = {
  502. { &mp_type_type },
  503. .name = MP_QSTR_USB_VCP,
  504. .print = pyb_usb_vcp_print,
  505. .make_new = pyb_usb_vcp_make_new,
  506. .getiter = mp_identity_getiter,
  507. .iternext = mp_stream_unbuffered_iter,
  508. .protocol = &pyb_usb_vcp_stream_p,
  509. .locals_dict = (mp_obj_dict_t*)&pyb_usb_vcp_locals_dict,
  510. };
  511. /******************************************************************************/
  512. // MicroPython bindings for USB HID
  513. typedef struct _pyb_usb_hid_obj_t {
  514. mp_obj_base_t base;
  515. usb_device_t *usb_dev;
  516. } pyb_usb_hid_obj_t;
  517. STATIC const pyb_usb_hid_obj_t pyb_usb_hid_obj = {{&pyb_usb_hid_type}, &usb_device};
  518. STATIC mp_obj_t pyb_usb_hid_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
  519. // check arguments
  520. mp_arg_check_num(n_args, n_kw, 0, 0, false);
  521. // TODO raise exception if USB is not configured for HID
  522. // return the USB HID object
  523. return MP_OBJ_FROM_PTR(&pyb_usb_hid_obj);
  524. }
  525. /// \method recv(data, *, timeout=5000)
  526. ///
  527. /// Receive data on the bus:
  528. ///
  529. /// - `data` can be an integer, which is the number of bytes to receive,
  530. /// or a mutable buffer, which will be filled with received bytes.
  531. /// - `timeout` is the timeout in milliseconds to wait for the receive.
  532. ///
  533. /// Return value: if `data` is an integer then a new buffer of the bytes received,
  534. /// otherwise the number of bytes read into `data` is returned.
  535. STATIC mp_obj_t pyb_usb_hid_recv(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
  536. static const mp_arg_t allowed_args[] = {
  537. { MP_QSTR_data, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
  538. { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 5000} },
  539. };
  540. // parse args
  541. pyb_usb_hid_obj_t *self = MP_OBJ_TO_PTR(args[0]);
  542. mp_arg_val_t vals[MP_ARRAY_SIZE(allowed_args)];
  543. mp_arg_parse_all(n_args - 1, args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, vals);
  544. // get the buffer to receive into
  545. vstr_t vstr;
  546. mp_obj_t o_ret = pyb_buf_get_for_recv(vals[0].u_obj, &vstr);
  547. // receive the data
  548. int ret = usbd_hid_rx(&self->usb_dev->usbd_hid_itf, vstr.len, (uint8_t*)vstr.buf, vals[1].u_int);
  549. // return the received data
  550. if (o_ret != MP_OBJ_NULL) {
  551. return mp_obj_new_int(ret); // number of bytes read into given buffer
  552. } else {
  553. vstr.len = ret; // set actual number of bytes read
  554. return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr); // create a new buffer
  555. }
  556. }
  557. STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_usb_hid_recv_obj, 1, pyb_usb_hid_recv);
  558. STATIC mp_obj_t pyb_usb_hid_send(mp_obj_t self_in, mp_obj_t report_in) {
  559. pyb_usb_hid_obj_t *self = MP_OBJ_TO_PTR(self_in);
  560. mp_buffer_info_t bufinfo;
  561. byte temp_buf[8];
  562. // get the buffer to send from
  563. // we accept either a byte array, or a tuple/list of integers
  564. if (!mp_get_buffer(report_in, &bufinfo, MP_BUFFER_READ)) {
  565. mp_obj_t *items;
  566. mp_obj_get_array(report_in, &bufinfo.len, &items);
  567. if (bufinfo.len > sizeof(temp_buf)) {
  568. mp_raise_ValueError("tuple/list too large for HID report; use bytearray instead");
  569. }
  570. for (int i = 0; i < bufinfo.len; i++) {
  571. temp_buf[i] = mp_obj_get_int(items[i]);
  572. }
  573. bufinfo.buf = temp_buf;
  574. }
  575. // send the data
  576. if (USBD_OK == USBD_HID_SendReport(&self->usb_dev->usbd_hid_itf.base, bufinfo.buf, bufinfo.len)) {
  577. return mp_obj_new_int(bufinfo.len);
  578. } else {
  579. return mp_obj_new_int(0);
  580. }
  581. return mp_const_none;
  582. }
  583. STATIC MP_DEFINE_CONST_FUN_OBJ_2(pyb_usb_hid_send_obj, pyb_usb_hid_send);
  584. // deprecated in favour of USB_HID.send
  585. STATIC mp_obj_t pyb_hid_send_report(mp_obj_t arg) {
  586. return pyb_usb_hid_send(MP_OBJ_FROM_PTR(&pyb_usb_hid_obj), arg);
  587. }
  588. MP_DEFINE_CONST_FUN_OBJ_1(pyb_hid_send_report_obj, pyb_hid_send_report);
  589. STATIC const mp_rom_map_elem_t pyb_usb_hid_locals_dict_table[] = {
  590. { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&pyb_usb_hid_send_obj) },
  591. { MP_ROM_QSTR(MP_QSTR_recv), MP_ROM_PTR(&pyb_usb_hid_recv_obj) },
  592. };
  593. STATIC MP_DEFINE_CONST_DICT(pyb_usb_hid_locals_dict, pyb_usb_hid_locals_dict_table);
  594. STATIC mp_uint_t pyb_usb_hid_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode) {
  595. pyb_usb_hid_obj_t *self = MP_OBJ_TO_PTR(self_in);
  596. mp_uint_t ret;
  597. if (request == MP_STREAM_POLL) {
  598. uintptr_t flags = arg;
  599. ret = 0;
  600. if ((flags & MP_STREAM_POLL_RD) && usbd_hid_rx_num(&self->usb_dev->usbd_hid_itf) > 0) {
  601. ret |= MP_STREAM_POLL_RD;
  602. }
  603. if ((flags & MP_STREAM_POLL_WR) && USBD_HID_CanSendReport(&self->usb_dev->usbd_hid_itf.base)) {
  604. ret |= MP_STREAM_POLL_WR;
  605. }
  606. } else {
  607. *errcode = MP_EINVAL;
  608. ret = MP_STREAM_ERROR;
  609. }
  610. return ret;
  611. }
  612. STATIC const mp_stream_p_t pyb_usb_hid_stream_p = {
  613. .ioctl = pyb_usb_hid_ioctl,
  614. };
  615. const mp_obj_type_t pyb_usb_hid_type = {
  616. { &mp_type_type },
  617. .name = MP_QSTR_USB_HID,
  618. .make_new = pyb_usb_hid_make_new,
  619. .protocol = &pyb_usb_hid_stream_p,
  620. .locals_dict = (mp_obj_dict_t*)&pyb_usb_hid_locals_dict,
  621. };
  622. /******************************************************************************/
  623. // code for experimental USB OTG support
  624. #ifdef USE_HOST_MODE
  625. #include "led.h"
  626. #include "usbh_core.h"
  627. #include "usbh_usr.h"
  628. #include "usbh_hid_core.h"
  629. #include "usbh_hid_keybd.h"
  630. #include "usbh_hid_mouse.h"
  631. __ALIGN_BEGIN USBH_HOST USB_Host __ALIGN_END ;
  632. static int host_is_enabled = 0;
  633. void pyb_usb_host_init(void) {
  634. if (!host_is_enabled) {
  635. // only init USBH once in the device's power-lifetime
  636. /* Init Host Library */
  637. USBH_Init(&USB_OTG_Core, USB_OTG_FS_CORE_ID, &USB_Host, &HID_cb, &USR_Callbacks);
  638. }
  639. host_is_enabled = 1;
  640. }
  641. void pyb_usb_host_process(void) {
  642. USBH_Process(&USB_OTG_Core, &USB_Host);
  643. }
  644. uint8_t usb_keyboard_key = 0;
  645. // TODO this is an ugly hack to get key presses
  646. uint pyb_usb_host_get_keyboard(void) {
  647. uint key = usb_keyboard_key;
  648. usb_keyboard_key = 0;
  649. return key;
  650. }
  651. void USR_MOUSE_Init(void) {
  652. led_state(4, 1);
  653. USB_OTG_BSP_mDelay(100);
  654. led_state(4, 0);
  655. }
  656. void USR_MOUSE_ProcessData(HID_MOUSE_Data_TypeDef *data) {
  657. led_state(4, 1);
  658. USB_OTG_BSP_mDelay(50);
  659. led_state(4, 0);
  660. }
  661. void USR_KEYBRD_Init(void) {
  662. led_state(4, 1);
  663. USB_OTG_BSP_mDelay(100);
  664. led_state(4, 0);
  665. }
  666. void USR_KEYBRD_ProcessData(uint8_t pbuf) {
  667. led_state(4, 1);
  668. USB_OTG_BSP_mDelay(50);
  669. led_state(4, 0);
  670. usb_keyboard_key = pbuf;
  671. }
  672. #endif // USE_HOST_MODE
  673. #endif // MICROPY_HW_ENABLE_USB