1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* Taken from ST Cube library and heavily modified. See below for original
* copyright header.
*/
/**
******************************************************************************
* @file USB_Device/CDC_Standalone/Src/usbd_cdc_interface.c
* @author MCD Application Team
* @version V1.0.1
* @date 26-February-2014
* @brief Source file for USBD CDC interface
******************************************************************************
* @attention
*
* <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
*
* Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.st.com/software_license_agreement_liberty_v2
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include <stdint.h>
#include "usbd_cdc_msc_hid.h"
#include "usbd_hid_interface.h"
#include "py/obj.h"
#include "irq.h"
#include "usb.h"
/* Private variables ---------------------------------------------------------*/
static uint8_t buffer[2][HID_DATA_FS_MAX_PACKET_SIZE]; // pair of buffers to read individual packets into
static int8_t current_read_buffer = 0; // which buffer to read from
static uint32_t last_read_len = 0; // length of last read
static int8_t current_write_buffer = 0; // which buffer to write to
/* Private function prototypes -----------------------------------------------*/
static int8_t HID_Itf_Init (void);
static int8_t HID_Itf_Receive (uint8_t* pbuf, uint32_t Len);
const USBD_HID_ItfTypeDef USBD_HID_fops = {
HID_Itf_Init,
HID_Itf_Receive
};
/**
* @brief HID_Itf_Init
* Initializes the HID media low layer
* @param None
* @retval Result of the opeartion: USBD_OK if all operations are OK else USBD_FAIL
*/
static int8_t HID_Itf_Init(void)
{
current_read_buffer = 0;
last_read_len = 0;
current_write_buffer = 0;
USBD_HID_SetRxBuffer(&hUSBDDevice, buffer[current_write_buffer]);
return USBD_OK;
}
/**
* @brief HID_Itf_Receive
* Data received over USB OUT endpoint is processed here.
* @param Buf: Buffer of data received
* @param Len: Number of data received (in bytes)
* @retval Result of the opeartion: USBD_OK if all operations are OK else USBD_FAIL
* @note The buffer we are passed here is just UserRxBuffer, so we are
* free to modify it.
*/
static int8_t HID_Itf_Receive(uint8_t* Buf, uint32_t Len) {
current_write_buffer = !current_write_buffer;
last_read_len = Len;
// initiate next USB packet transfer, to append to existing data in buffer
USBD_HID_SetRxBuffer(&hUSBDDevice, buffer[current_write_buffer]);
USBD_HID_ReceivePacket(&hUSBDDevice);
// Set NAK to indicate we need to process read buffer
USBD_HID_SetNAK(&hUSBDDevice);
return USBD_OK;
}
// Returns number of ready rx buffers.
int USBD_HID_RxNum(void) {
return (current_read_buffer != current_write_buffer);
}
// timout in milliseconds.
// Returns number of bytes read from the device.
int USBD_HID_Rx(uint8_t *buf, uint32_t len, uint32_t timeout) {
// Wait until we have buffer to read
uint32_t start = HAL_GetTick();
while (current_read_buffer == current_write_buffer) {
// Wraparound of tick is taken care of by 2's complement arithmetic.
if (HAL_GetTick() - start >= timeout) {
// timeout
return 0;
}
if (query_irq() == IRQ_STATE_DISABLED) {
// IRQs disabled so buffer will never be filled; return immediately
return 0;
}
__WFI(); // enter sleep mode, waiting for interrupt
}
// There is not enough space in buffer
if (len < last_read_len) {
return 0;
}
// Copy bytes from device to user buffer
memcpy(buf, buffer[current_read_buffer], last_read_len);
current_read_buffer = !current_read_buffer;
// Clear NAK to indicate we are ready to read more data
USBD_HID_ClearNAK(&hUSBDDevice);
// Success, return number of bytes read
return last_read_len;
}
|