usbd_hid_interface.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. /*
  2. * This file is part of the MicroPython project, http://micropython.org/
  3. *
  4. * Taken from ST Cube library and heavily modified. See below for original
  5. * copyright header.
  6. */
  7. /**
  8. ******************************************************************************
  9. * @file USB_Device/CDC_Standalone/Src/usbd_cdc_interface.c
  10. * @author MCD Application Team
  11. * @version V1.0.1
  12. * @date 26-February-2014
  13. * @brief Source file for USBD CDC interface
  14. ******************************************************************************
  15. * @attention
  16. *
  17. * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
  18. *
  19. * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
  20. * You may not use this file except in compliance with the License.
  21. * You may obtain a copy of the License at:
  22. *
  23. * http://www.st.com/software_license_agreement_liberty_v2
  24. *
  25. * Unless required by applicable law or agreed to in writing, software
  26. * distributed under the License is distributed on an "AS IS" BASIS,
  27. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  28. * See the License for the specific language governing permissions and
  29. * limitations under the License.
  30. *
  31. ******************************************************************************
  32. */
  33. /* Includes ------------------------------------------------------------------*/
  34. #include <stdint.h>
  35. #include "usbd_hid_interface.h"
  36. #include "py/obj.h"
  37. #include "irq.h"
  38. #include "usb.h"
  39. uint8_t *usbd_hid_init(usbd_hid_state_t *hid_in) {
  40. usbd_hid_itf_t *hid = (usbd_hid_itf_t*)hid_in;
  41. hid->current_read_buffer = 0;
  42. hid->last_read_len = 0;
  43. hid->current_write_buffer = 0;
  44. // Return the buffer to place the first USB OUT packet
  45. return hid->buffer[hid->current_write_buffer];
  46. }
  47. // Data received over USB OUT endpoint is processed here.
  48. // len: number of bytes received into the buffer we passed to USBD_HID_ReceivePacket
  49. // Returns USBD_OK if all operations are OK else USBD_FAIL
  50. int8_t usbd_hid_receive(usbd_hid_state_t *hid_in, size_t len) {
  51. usbd_hid_itf_t *hid = (usbd_hid_itf_t*)hid_in;
  52. hid->current_write_buffer = !hid->current_write_buffer;
  53. hid->last_read_len = len;
  54. // initiate next USB packet transfer, to append to existing data in buffer
  55. USBD_HID_ReceivePacket(&hid->base, hid->buffer[hid->current_write_buffer]);
  56. // Set NAK to indicate we need to process read buffer
  57. USBD_HID_SetNAK(&hid->base);
  58. return USBD_OK;
  59. }
  60. // Returns number of ready rx buffers.
  61. int usbd_hid_rx_num(usbd_hid_itf_t *hid) {
  62. return hid->current_read_buffer != hid->current_write_buffer;
  63. }
  64. // timout in milliseconds.
  65. // Returns number of bytes read from the device.
  66. int usbd_hid_rx(usbd_hid_itf_t *hid, size_t len, uint8_t *buf, uint32_t timeout) {
  67. // Wait until we have buffer to read
  68. uint32_t start = HAL_GetTick();
  69. while (hid->current_read_buffer == hid->current_write_buffer) {
  70. // Wraparound of tick is taken care of by 2's complement arithmetic.
  71. if (HAL_GetTick() - start >= timeout) {
  72. // timeout
  73. return 0;
  74. }
  75. if (query_irq() == IRQ_STATE_DISABLED) {
  76. // IRQs disabled so buffer will never be filled; return immediately
  77. return 0;
  78. }
  79. __WFI(); // enter sleep mode, waiting for interrupt
  80. }
  81. // There is not enough space in buffer
  82. if (len < hid->last_read_len) {
  83. return 0;
  84. }
  85. // Copy bytes from device to user buffer
  86. int read_len = hid->last_read_len;
  87. memcpy(buf, hid->buffer[hid->current_read_buffer], read_len);
  88. hid->current_read_buffer = !hid->current_read_buffer;
  89. // Clear NAK to indicate we are ready to read more data
  90. USBD_HID_ClearNAK(&hid->base);
  91. // Success, return number of bytes read
  92. return read_len;
  93. }