Repostiory containing DAPLink source code with Reset Pin workaround for HANI_IOT board.

Upstream: https://github.com/ARMmbed/DAPLink

Committer:
Pawel Zarembski
Date:
Tue Apr 07 12:55:42 2020 +0200
Revision:
0:01f31e923fe2
hani: DAPLink with reset workaround

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Pawel Zarembski 0:01f31e923fe2 1 /**
Pawel Zarembski 0:01f31e923fe2 2 * @file usbd_hid.c
Pawel Zarembski 0:01f31e923fe2 3 * @brief Human Interface Device driver
Pawel Zarembski 0:01f31e923fe2 4 *
Pawel Zarembski 0:01f31e923fe2 5 * DAPLink Interface Firmware
Pawel Zarembski 0:01f31e923fe2 6 * Copyright (c) 2009-2016, ARM Limited, All Rights Reserved
Pawel Zarembski 0:01f31e923fe2 7 * SPDX-License-Identifier: Apache-2.0
Pawel Zarembski 0:01f31e923fe2 8 *
Pawel Zarembski 0:01f31e923fe2 9 * Licensed under the Apache License, Version 2.0 (the "License"); you may
Pawel Zarembski 0:01f31e923fe2 10 * not use this file except in compliance with the License.
Pawel Zarembski 0:01f31e923fe2 11 * You may obtain a copy of the License at
Pawel Zarembski 0:01f31e923fe2 12 *
Pawel Zarembski 0:01f31e923fe2 13 * http://www.apache.org/licenses/LICENSE-2.0
Pawel Zarembski 0:01f31e923fe2 14 *
Pawel Zarembski 0:01f31e923fe2 15 * Unless required by applicable law or agreed to in writing, software
Pawel Zarembski 0:01f31e923fe2 16 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
Pawel Zarembski 0:01f31e923fe2 17 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Pawel Zarembski 0:01f31e923fe2 18 * See the License for the specific language governing permissions and
Pawel Zarembski 0:01f31e923fe2 19 * limitations under the License.
Pawel Zarembski 0:01f31e923fe2 20 */
Pawel Zarembski 0:01f31e923fe2 21
Pawel Zarembski 0:01f31e923fe2 22 #include <string.h>
Pawel Zarembski 0:01f31e923fe2 23
Pawel Zarembski 0:01f31e923fe2 24 #include "rl_usb.h"
Pawel Zarembski 0:01f31e923fe2 25 #include "usb_for_lib.h"
Pawel Zarembski 0:01f31e923fe2 26
Pawel Zarembski 0:01f31e923fe2 27
Pawel Zarembski 0:01f31e923fe2 28 U8 USBD_HID_Protocol;
Pawel Zarembski 0:01f31e923fe2 29
Pawel Zarembski 0:01f31e923fe2 30 BOOL DataOutAsyncReq;
Pawel Zarembski 0:01f31e923fe2 31 U32 DataOutUpdateReqMask;
Pawel Zarembski 0:01f31e923fe2 32 U8 *ptrDataOut;
Pawel Zarembski 0:01f31e923fe2 33 volatile U16 DataOutToSendLen;
Pawel Zarembski 0:01f31e923fe2 34 U16 DataOutSentLen;
Pawel Zarembski 0:01f31e923fe2 35 BOOL DataOutEndWithShortPacket;
Pawel Zarembski 0:01f31e923fe2 36
Pawel Zarembski 0:01f31e923fe2 37 U8 *ptrDataIn;
Pawel Zarembski 0:01f31e923fe2 38 U16 DataInReceMax;
Pawel Zarembski 0:01f31e923fe2 39 U16 DataInReceLen;
Pawel Zarembski 0:01f31e923fe2 40
Pawel Zarembski 0:01f31e923fe2 41 U8 *ptrDataFeat;
Pawel Zarembski 0:01f31e923fe2 42 U16 DataFeatReceLen;
Pawel Zarembski 0:01f31e923fe2 43
Pawel Zarembski 0:01f31e923fe2 44
Pawel Zarembski 0:01f31e923fe2 45 /* Dummy Weak Functions that need to be provided by user */
Pawel Zarembski 0:01f31e923fe2 46 __weak void usbd_hid_init(void)
Pawel Zarembski 0:01f31e923fe2 47 {
Pawel Zarembski 0:01f31e923fe2 48
Pawel Zarembski 0:01f31e923fe2 49 }
Pawel Zarembski 0:01f31e923fe2 50 __weak int usbd_hid_get_report(U8 rtype, U8 rid, U8 *buf, U8 req)
Pawel Zarembski 0:01f31e923fe2 51 {
Pawel Zarembski 0:01f31e923fe2 52 return (0);
Pawel Zarembski 0:01f31e923fe2 53 };
Pawel Zarembski 0:01f31e923fe2 54 __weak void usbd_hid_set_report(U8 rtype, U8 rid, U8 *buf, int len, U8 req)
Pawel Zarembski 0:01f31e923fe2 55 {
Pawel Zarembski 0:01f31e923fe2 56
Pawel Zarembski 0:01f31e923fe2 57 }
Pawel Zarembski 0:01f31e923fe2 58 __weak U8 usbd_hid_get_protocol(void)
Pawel Zarembski 0:01f31e923fe2 59 {
Pawel Zarembski 0:01f31e923fe2 60 return (0);
Pawel Zarembski 0:01f31e923fe2 61 };
Pawel Zarembski 0:01f31e923fe2 62 __weak void usbd_hid_set_protocol(U8 protocol)
Pawel Zarembski 0:01f31e923fe2 63 {
Pawel Zarembski 0:01f31e923fe2 64
Pawel Zarembski 0:01f31e923fe2 65 };
Pawel Zarembski 0:01f31e923fe2 66
Pawel Zarembski 0:01f31e923fe2 67
Pawel Zarembski 0:01f31e923fe2 68 /*
Pawel Zarembski 0:01f31e923fe2 69 * USB Device HID Get Report Request Callback
Pawel Zarembski 0:01f31e923fe2 70 * Called automatically on USB Device HID Get Report Request
Pawel Zarembski 0:01f31e923fe2 71 * Parameters: None
Pawel Zarembski 0:01f31e923fe2 72 * Return Value: TRUE - Success, FALSE - Error
Pawel Zarembski 0:01f31e923fe2 73 */
Pawel Zarembski 0:01f31e923fe2 74
Pawel Zarembski 0:01f31e923fe2 75 BOOL USBD_HID_GetReport(void)
Pawel Zarembski 0:01f31e923fe2 76 {
Pawel Zarembski 0:01f31e923fe2 77 U8 *ptr_buf = 0;
Pawel Zarembski 0:01f31e923fe2 78
Pawel Zarembski 0:01f31e923fe2 79 /* Report Type = USBD_SetupPacket.wValueH */
Pawel Zarembski 0:01f31e923fe2 80 /* Report ID = USBD_SetupPacket.wValueL */
Pawel Zarembski 0:01f31e923fe2 81 /* Report Length = USBD_SetupPacket.wLength */
Pawel Zarembski 0:01f31e923fe2 82 switch (USBD_SetupPacket.wValueH) {
Pawel Zarembski 0:01f31e923fe2 83 case HID_REPORT_INPUT:
Pawel Zarembski 0:01f31e923fe2 84 ptr_buf = &USBD_HID_InReport[1];
Pawel Zarembski 0:01f31e923fe2 85 break;
Pawel Zarembski 0:01f31e923fe2 86
Pawel Zarembski 0:01f31e923fe2 87 case HID_REPORT_OUTPUT:
Pawel Zarembski 0:01f31e923fe2 88 return (__FALSE); /* Not Supported */
Pawel Zarembski 0:01f31e923fe2 89
Pawel Zarembski 0:01f31e923fe2 90 case HID_REPORT_FEATURE:
Pawel Zarembski 0:01f31e923fe2 91 ptr_buf = &USBD_HID_FeatReport[1];
Pawel Zarembski 0:01f31e923fe2 92 break;
Pawel Zarembski 0:01f31e923fe2 93 }
Pawel Zarembski 0:01f31e923fe2 94
Pawel Zarembski 0:01f31e923fe2 95 usbd_hid_get_report(USBD_SetupPacket.wValueH, USBD_SetupPacket.wValueL, ptr_buf, USBD_HID_REQ_EP_CTRL);
Pawel Zarembski 0:01f31e923fe2 96 return (__TRUE);
Pawel Zarembski 0:01f31e923fe2 97 }
Pawel Zarembski 0:01f31e923fe2 98
Pawel Zarembski 0:01f31e923fe2 99
Pawel Zarembski 0:01f31e923fe2 100 /*
Pawel Zarembski 0:01f31e923fe2 101 * USB Device HID Set Report Request Callback
Pawel Zarembski 0:01f31e923fe2 102 * Called automatically on USB Device HID Set Report Request
Pawel Zarembski 0:01f31e923fe2 103 * Parameters: None
Pawel Zarembski 0:01f31e923fe2 104 * Return Value: TRUE - Success, FALSE - Error
Pawel Zarembski 0:01f31e923fe2 105 */
Pawel Zarembski 0:01f31e923fe2 106
Pawel Zarembski 0:01f31e923fe2 107 BOOL USBD_HID_SetReport(void)
Pawel Zarembski 0:01f31e923fe2 108 {
Pawel Zarembski 0:01f31e923fe2 109 U8 *ptr_buf = 0;
Pawel Zarembski 0:01f31e923fe2 110
Pawel Zarembski 0:01f31e923fe2 111 /* Report Type = USBD_SetupPacket.wValueH */
Pawel Zarembski 0:01f31e923fe2 112 /* Report ID = USBD_SetupPacket.wValueL */
Pawel Zarembski 0:01f31e923fe2 113 /* Report Length = USBD_SetupPacket.wLength */
Pawel Zarembski 0:01f31e923fe2 114 switch (USBD_SetupPacket.wValueH) {
Pawel Zarembski 0:01f31e923fe2 115 case HID_REPORT_INPUT:
Pawel Zarembski 0:01f31e923fe2 116 return (__FALSE); /* Not Supported */
Pawel Zarembski 0:01f31e923fe2 117
Pawel Zarembski 0:01f31e923fe2 118 case HID_REPORT_OUTPUT:
Pawel Zarembski 0:01f31e923fe2 119 ptr_buf = &USBD_HID_OutReport[1];
Pawel Zarembski 0:01f31e923fe2 120 break;
Pawel Zarembski 0:01f31e923fe2 121
Pawel Zarembski 0:01f31e923fe2 122 case HID_REPORT_FEATURE:
Pawel Zarembski 0:01f31e923fe2 123 ptr_buf = &USBD_HID_FeatReport[1];
Pawel Zarembski 0:01f31e923fe2 124 break;
Pawel Zarembski 0:01f31e923fe2 125 }
Pawel Zarembski 0:01f31e923fe2 126
Pawel Zarembski 0:01f31e923fe2 127 usbd_hid_set_report(USBD_SetupPacket.wValueH, USBD_SetupPacket.wValueL, ptr_buf, USBD_SetupPacket.wLength, USBD_HID_REQ_EP_CTRL);
Pawel Zarembski 0:01f31e923fe2 128 return (__TRUE);
Pawel Zarembski 0:01f31e923fe2 129 }
Pawel Zarembski 0:01f31e923fe2 130
Pawel Zarembski 0:01f31e923fe2 131
Pawel Zarembski 0:01f31e923fe2 132 /*
Pawel Zarembski 0:01f31e923fe2 133 * USB Device HID Get Idle Request Callback
Pawel Zarembski 0:01f31e923fe2 134 * Called automatically on USB Device HID Get Idle Request
Pawel Zarembski 0:01f31e923fe2 135 * Parameters: None
Pawel Zarembski 0:01f31e923fe2 136 * Return Value: TRUE - Success, FALSE - Error
Pawel Zarembski 0:01f31e923fe2 137 */
Pawel Zarembski 0:01f31e923fe2 138
Pawel Zarembski 0:01f31e923fe2 139 BOOL USBD_HID_GetIdle(void)
Pawel Zarembski 0:01f31e923fe2 140 {
Pawel Zarembski 0:01f31e923fe2 141 USBD_EP0Buf[0] = USBD_HID_IdleSet[USBD_SetupPacket.wValueL];
Pawel Zarembski 0:01f31e923fe2 142 return (__TRUE);
Pawel Zarembski 0:01f31e923fe2 143 }
Pawel Zarembski 0:01f31e923fe2 144
Pawel Zarembski 0:01f31e923fe2 145
Pawel Zarembski 0:01f31e923fe2 146 /*
Pawel Zarembski 0:01f31e923fe2 147 * USB Device HID Set Idle Request Callback
Pawel Zarembski 0:01f31e923fe2 148 * Called automatically on USB Device HID Set Idle Request
Pawel Zarembski 0:01f31e923fe2 149 * Parameters: None
Pawel Zarembski 0:01f31e923fe2 150 * Return Value: TRUE - Success, FALSE - Error
Pawel Zarembski 0:01f31e923fe2 151 */
Pawel Zarembski 0:01f31e923fe2 152
Pawel Zarembski 0:01f31e923fe2 153 BOOL USBD_HID_SetIdle(void)
Pawel Zarembski 0:01f31e923fe2 154 {
Pawel Zarembski 0:01f31e923fe2 155 U8 i;
Pawel Zarembski 0:01f31e923fe2 156
Pawel Zarembski 0:01f31e923fe2 157 if (USBD_SetupPacket.wValueL) { /* If > 0 Report ID specified */
Pawel Zarembski 0:01f31e923fe2 158 USBD_HID_IdleSet[USBD_SetupPacket.wValueL - 1] = USBD_SetupPacket.wValueH;
Pawel Zarembski 0:01f31e923fe2 159 } else { /* If == 0 all reports */
Pawel Zarembski 0:01f31e923fe2 160 for (i = 0; i < usbd_hid_inreport_num; i++) {
Pawel Zarembski 0:01f31e923fe2 161 USBD_HID_IdleSet[i] = USBD_SetupPacket.wValueH;
Pawel Zarembski 0:01f31e923fe2 162 }
Pawel Zarembski 0:01f31e923fe2 163 }
Pawel Zarembski 0:01f31e923fe2 164
Pawel Zarembski 0:01f31e923fe2 165 return (__TRUE);
Pawel Zarembski 0:01f31e923fe2 166 }
Pawel Zarembski 0:01f31e923fe2 167
Pawel Zarembski 0:01f31e923fe2 168
Pawel Zarembski 0:01f31e923fe2 169 /*
Pawel Zarembski 0:01f31e923fe2 170 * USB Device HID Get Protocol Request Callback
Pawel Zarembski 0:01f31e923fe2 171 * Called automatically on USB Device HID Get Protocol Request
Pawel Zarembski 0:01f31e923fe2 172 * Parameters: None
Pawel Zarembski 0:01f31e923fe2 173 * Return Value: TRUE - Success, FALSE - Error
Pawel Zarembski 0:01f31e923fe2 174 */
Pawel Zarembski 0:01f31e923fe2 175
Pawel Zarembski 0:01f31e923fe2 176 BOOL USBD_HID_GetProtocol(void)
Pawel Zarembski 0:01f31e923fe2 177 {
Pawel Zarembski 0:01f31e923fe2 178 USBD_EP0Buf[0] = usbd_hid_get_protocol();
Pawel Zarembski 0:01f31e923fe2 179 return (__TRUE);
Pawel Zarembski 0:01f31e923fe2 180 }
Pawel Zarembski 0:01f31e923fe2 181
Pawel Zarembski 0:01f31e923fe2 182
Pawel Zarembski 0:01f31e923fe2 183 /*
Pawel Zarembski 0:01f31e923fe2 184 * USB Device HID Set Protocol Request Callback
Pawel Zarembski 0:01f31e923fe2 185 * Called automatically on USB Device HID Set Protocol Request
Pawel Zarembski 0:01f31e923fe2 186 * Parameters: None
Pawel Zarembski 0:01f31e923fe2 187 * Return Value: TRUE - Success, FALSE - Error
Pawel Zarembski 0:01f31e923fe2 188 */
Pawel Zarembski 0:01f31e923fe2 189
Pawel Zarembski 0:01f31e923fe2 190 BOOL USBD_HID_SetProtocol(void)
Pawel Zarembski 0:01f31e923fe2 191 {
Pawel Zarembski 0:01f31e923fe2 192 usbd_hid_set_protocol(USBD_SetupPacket.wValueL);
Pawel Zarembski 0:01f31e923fe2 193 return (__TRUE);
Pawel Zarembski 0:01f31e923fe2 194 }
Pawel Zarembski 0:01f31e923fe2 195
Pawel Zarembski 0:01f31e923fe2 196
Pawel Zarembski 0:01f31e923fe2 197 /*
Pawel Zarembski 0:01f31e923fe2 198 * USB Device HID Interrupt In Endpoint Event Callback
Pawel Zarembski 0:01f31e923fe2 199 * Parameters: event: not used (just for compatibility)
Pawel Zarembski 0:01f31e923fe2 200 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 201 */
Pawel Zarembski 0:01f31e923fe2 202
Pawel Zarembski 0:01f31e923fe2 203 void USBD_HID_EP_INTIN_Event(U32 event)
Pawel Zarembski 0:01f31e923fe2 204 {
Pawel Zarembski 0:01f31e923fe2 205 U8 i;
Pawel Zarembski 0:01f31e923fe2 206 U16 bytes_to_send;
Pawel Zarembski 0:01f31e923fe2 207
Pawel Zarembski 0:01f31e923fe2 208 /* Check if sending is finished */
Pawel Zarembski 0:01f31e923fe2 209 if ((DataOutSentLen >= DataOutToSendLen) &&
Pawel Zarembski 0:01f31e923fe2 210 !DataOutEndWithShortPacket) { /* If all sent and short packet also */
Pawel Zarembski 0:01f31e923fe2 211 ptrDataOut = NULL;
Pawel Zarembski 0:01f31e923fe2 212 DataOutSentLen = 0;
Pawel Zarembski 0:01f31e923fe2 213 DataOutToSendLen = usbd_hid_get_report(HID_REPORT_INPUT, USBD_HID_InReport[0], &USBD_HID_InReport[1], USBD_HID_REQ_EP_INT);
Pawel Zarembski 0:01f31e923fe2 214
Pawel Zarembski 0:01f31e923fe2 215 if (DataOutToSendLen) { /* If new send should be started */
Pawel Zarembski 0:01f31e923fe2 216 ptrDataOut = USBD_HID_InReport;
Pawel Zarembski 0:01f31e923fe2 217
Pawel Zarembski 0:01f31e923fe2 218 if (usbd_hid_inreport_num <= 1) { /* If only in 1 report skip ReportID */
Pawel Zarembski 0:01f31e923fe2 219 ptrDataOut++;
Pawel Zarembski 0:01f31e923fe2 220 } else { /* If more in reports, send ReportID */
Pawel Zarembski 0:01f31e923fe2 221 DataOutToSendLen++;
Pawel Zarembski 0:01f31e923fe2 222 }
Pawel Zarembski 0:01f31e923fe2 223 }
Pawel Zarembski 0:01f31e923fe2 224 }
Pawel Zarembski 0:01f31e923fe2 225
Pawel Zarembski 0:01f31e923fe2 226 /* Check if new data out sending should be started */
Pawel Zarembski 0:01f31e923fe2 227 if (!DataOutToSendLen) { /* If send not in progress */
Pawel Zarembski 0:01f31e923fe2 228 if (DataOutAsyncReq) { /* If asynchronous send requested */
Pawel Zarembski 0:01f31e923fe2 229 DataOutAsyncReq = __FALSE;
Pawel Zarembski 0:01f31e923fe2 230 } else if (DataOutUpdateReqMask) { /* If update requested */
Pawel Zarembski 0:01f31e923fe2 231 if (usbd_hid_inreport_num <= 1) { /* If only one in report in system */
Pawel Zarembski 0:01f31e923fe2 232 if (DataOutUpdateReqMask) {
Pawel Zarembski 0:01f31e923fe2 233 USBD_HID_InReport[0] = 0; /* ReportID = 0 */
Pawel Zarembski 0:01f31e923fe2 234 DataOutSentLen = 0;
Pawel Zarembski 0:01f31e923fe2 235 DataOutToSendLen = usbd_hid_get_report(HID_REPORT_INPUT, 0, &USBD_HID_InReport[1], USBD_HID_REQ_PERIOD_UPDATE);
Pawel Zarembski 0:01f31e923fe2 236
Pawel Zarembski 0:01f31e923fe2 237 if (DataOutToSendLen) {
Pawel Zarembski 0:01f31e923fe2 238 ptrDataOut = &USBD_HID_InReport[1];
Pawel Zarembski 0:01f31e923fe2 239 }
Pawel Zarembski 0:01f31e923fe2 240
Pawel Zarembski 0:01f31e923fe2 241 DataOutUpdateReqMask = 0;
Pawel Zarembski 0:01f31e923fe2 242 }
Pawel Zarembski 0:01f31e923fe2 243 } else { /* If multiple reports in system */
Pawel Zarembski 0:01f31e923fe2 244 for (i = USBD_HID_InReport[0]; ; i++) {
Pawel Zarembski 0:01f31e923fe2 245 if (i >= 32) {
Pawel Zarembski 0:01f31e923fe2 246 i = 0;
Pawel Zarembski 0:01f31e923fe2 247 }
Pawel Zarembski 0:01f31e923fe2 248
Pawel Zarembski 0:01f31e923fe2 249 if (DataOutUpdateReqMask & (1 << i)) {
Pawel Zarembski 0:01f31e923fe2 250 USBD_HID_InReport[0] = i + 1; /* ReportID */
Pawel Zarembski 0:01f31e923fe2 251 DataOutSentLen = 0;
Pawel Zarembski 0:01f31e923fe2 252 DataOutToSendLen = usbd_hid_get_report(HID_REPORT_INPUT, i + 1, &USBD_HID_InReport[1], USBD_HID_REQ_PERIOD_UPDATE);
Pawel Zarembski 0:01f31e923fe2 253
Pawel Zarembski 0:01f31e923fe2 254 if (DataOutToSendLen) {
Pawel Zarembski 0:01f31e923fe2 255 ptrDataOut = USBD_HID_InReport;
Pawel Zarembski 0:01f31e923fe2 256 DataOutToSendLen++;
Pawel Zarembski 0:01f31e923fe2 257 }
Pawel Zarembski 0:01f31e923fe2 258
Pawel Zarembski 0:01f31e923fe2 259 DataOutUpdateReqMask &= ~(1 << i);
Pawel Zarembski 0:01f31e923fe2 260 break;
Pawel Zarembski 0:01f31e923fe2 261 }
Pawel Zarembski 0:01f31e923fe2 262 }
Pawel Zarembski 0:01f31e923fe2 263 }
Pawel Zarembski 0:01f31e923fe2 264 }
Pawel Zarembski 0:01f31e923fe2 265 }
Pawel Zarembski 0:01f31e923fe2 266
Pawel Zarembski 0:01f31e923fe2 267 /* Check if data needs to be sent */
Pawel Zarembski 0:01f31e923fe2 268 if (DataOutToSendLen ||
Pawel Zarembski 0:01f31e923fe2 269 DataOutEndWithShortPacket) { /* If sending is in progress */
Pawel Zarembski 0:01f31e923fe2 270 bytes_to_send = DataOutToSendLen - DataOutSentLen;
Pawel Zarembski 0:01f31e923fe2 271
Pawel Zarembski 0:01f31e923fe2 272 if (bytes_to_send > usbd_hid_maxpacketsize[USBD_HighSpeed]) {
Pawel Zarembski 0:01f31e923fe2 273 bytes_to_send = usbd_hid_maxpacketsize[USBD_HighSpeed];
Pawel Zarembski 0:01f31e923fe2 274 }
Pawel Zarembski 0:01f31e923fe2 275
Pawel Zarembski 0:01f31e923fe2 276 if (usbd_hid_ep_intin != 0) { //control ep does the sending to host
Pawel Zarembski 0:01f31e923fe2 277 USBD_WriteEP(usbd_hid_ep_intin | 0x80, ptrDataOut, bytes_to_send);
Pawel Zarembski 0:01f31e923fe2 278 }
Pawel Zarembski 0:01f31e923fe2 279
Pawel Zarembski 0:01f31e923fe2 280 ptrDataOut += bytes_to_send;
Pawel Zarembski 0:01f31e923fe2 281 DataOutSentLen += bytes_to_send;
Pawel Zarembski 0:01f31e923fe2 282
Pawel Zarembski 0:01f31e923fe2 283 if ((DataOutSentLen < usbd_hid_inreport_max_sz) &&
Pawel Zarembski 0:01f31e923fe2 284 (bytes_to_send == usbd_hid_maxpacketsize[USBD_HighSpeed])) {
Pawel Zarembski 0:01f31e923fe2 285 /* If short packet should be sent also*/
Pawel Zarembski 0:01f31e923fe2 286 DataOutEndWithShortPacket = __TRUE;
Pawel Zarembski 0:01f31e923fe2 287 } else {
Pawel Zarembski 0:01f31e923fe2 288 DataOutEndWithShortPacket = __FALSE;
Pawel Zarembski 0:01f31e923fe2 289 }
Pawel Zarembski 0:01f31e923fe2 290 }
Pawel Zarembski 0:01f31e923fe2 291 }
Pawel Zarembski 0:01f31e923fe2 292
Pawel Zarembski 0:01f31e923fe2 293
Pawel Zarembski 0:01f31e923fe2 294 /*
Pawel Zarembski 0:01f31e923fe2 295 * USB Device HID Interrupt Out Endpoint Event Callback
Pawel Zarembski 0:01f31e923fe2 296 * Parameters: event: not used (just for compatibility)
Pawel Zarembski 0:01f31e923fe2 297 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 298 */
Pawel Zarembski 0:01f31e923fe2 299
Pawel Zarembski 0:01f31e923fe2 300 void USBD_HID_EP_INTOUT_Event(U32 event)
Pawel Zarembski 0:01f31e923fe2 301 {
Pawel Zarembski 0:01f31e923fe2 302 U16 bytes_rece;
Pawel Zarembski 0:01f31e923fe2 303
Pawel Zarembski 0:01f31e923fe2 304 if (!DataInReceLen) { /* Check if new reception */
Pawel Zarembski 0:01f31e923fe2 305 ptrDataIn = USBD_HID_OutReport;
Pawel Zarembski 0:01f31e923fe2 306 DataInReceMax = usbd_hid_outreport_max_sz;
Pawel Zarembski 0:01f31e923fe2 307 DataInReceLen = 0;
Pawel Zarembski 0:01f31e923fe2 308 }
Pawel Zarembski 0:01f31e923fe2 309
Pawel Zarembski 0:01f31e923fe2 310 bytes_rece = USBD_ReadEP(usbd_hid_ep_intout, ptrDataIn, DataInReceMax - DataInReceLen);
Pawel Zarembski 0:01f31e923fe2 311 ptrDataIn += bytes_rece;
Pawel Zarembski 0:01f31e923fe2 312 DataInReceLen += bytes_rece;
Pawel Zarembski 0:01f31e923fe2 313
Pawel Zarembski 0:01f31e923fe2 314 if (!bytes_rece ||
Pawel Zarembski 0:01f31e923fe2 315 (DataInReceLen >= usbd_hid_outreport_max_sz) ||
Pawel Zarembski 0:01f31e923fe2 316 (bytes_rece < usbd_hid_maxpacketsize[USBD_HighSpeed])) {
Pawel Zarembski 0:01f31e923fe2 317 if (usbd_hid_outreport_num <= 1) { /* If only one out report in system */
Pawel Zarembski 0:01f31e923fe2 318 usbd_hid_set_report(HID_REPORT_OUTPUT, 0 , USBD_HID_OutReport , DataInReceLen, USBD_HID_REQ_EP_INT);
Pawel Zarembski 0:01f31e923fe2 319 } else {
Pawel Zarembski 0:01f31e923fe2 320 usbd_hid_set_report(HID_REPORT_OUTPUT, USBD_HID_OutReport[0], &USBD_HID_OutReport[1], DataInReceLen - 1, USBD_HID_REQ_EP_INT);
Pawel Zarembski 0:01f31e923fe2 321 }
Pawel Zarembski 0:01f31e923fe2 322
Pawel Zarembski 0:01f31e923fe2 323 DataInReceLen = 0;
Pawel Zarembski 0:01f31e923fe2 324 }
Pawel Zarembski 0:01f31e923fe2 325 }
Pawel Zarembski 0:01f31e923fe2 326
Pawel Zarembski 0:01f31e923fe2 327
Pawel Zarembski 0:01f31e923fe2 328 /*
Pawel Zarembski 0:01f31e923fe2 329 * USB Device HID Configure Callback
Pawel Zarembski 0:01f31e923fe2 330 * Parameters: None
Pawel Zarembski 0:01f31e923fe2 331 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 332 */
Pawel Zarembski 0:01f31e923fe2 333
Pawel Zarembski 0:01f31e923fe2 334 void USBD_HID_Configure_Event(void)
Pawel Zarembski 0:01f31e923fe2 335 {
Pawel Zarembski 0:01f31e923fe2 336 /* Reset all variables after connect event */
Pawel Zarembski 0:01f31e923fe2 337 USBD_HID_Protocol = 0;
Pawel Zarembski 0:01f31e923fe2 338 DataOutAsyncReq = __FALSE;
Pawel Zarembski 0:01f31e923fe2 339 DataOutUpdateReqMask = __FALSE;
Pawel Zarembski 0:01f31e923fe2 340 ptrDataOut = NULL;
Pawel Zarembski 0:01f31e923fe2 341 DataOutToSendLen = 0;
Pawel Zarembski 0:01f31e923fe2 342 DataOutSentLen = 0;
Pawel Zarembski 0:01f31e923fe2 343 DataOutEndWithShortPacket = __FALSE;
Pawel Zarembski 0:01f31e923fe2 344 ptrDataIn = NULL;
Pawel Zarembski 0:01f31e923fe2 345 DataInReceMax = 0;
Pawel Zarembski 0:01f31e923fe2 346 DataInReceLen = 0;
Pawel Zarembski 0:01f31e923fe2 347 ptrDataFeat = NULL;
Pawel Zarembski 0:01f31e923fe2 348 DataFeatReceLen = 0;
Pawel Zarembski 0:01f31e923fe2 349 }
Pawel Zarembski 0:01f31e923fe2 350
Pawel Zarembski 0:01f31e923fe2 351
Pawel Zarembski 0:01f31e923fe2 352 /*
Pawel Zarembski 0:01f31e923fe2 353 * USB Device HID Interrupt In/Out Endpoint Event Callback
Pawel Zarembski 0:01f31e923fe2 354 * Parameters: event: USB Device Event
Pawel Zarembski 0:01f31e923fe2 355 * USBD_EVT_IN: Input Event
Pawel Zarembski 0:01f31e923fe2 356 * USBD_EVT_OUT: Output Event
Pawel Zarembski 0:01f31e923fe2 357 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 358 */
Pawel Zarembski 0:01f31e923fe2 359
Pawel Zarembski 0:01f31e923fe2 360 void USBD_HID_EP_INT_Event(U32 event)
Pawel Zarembski 0:01f31e923fe2 361 {
Pawel Zarembski 0:01f31e923fe2 362 if (event & USBD_EVT_IN) {
Pawel Zarembski 0:01f31e923fe2 363 USBD_HID_EP_INTIN_Event(event);
Pawel Zarembski 0:01f31e923fe2 364 }
Pawel Zarembski 0:01f31e923fe2 365
Pawel Zarembski 0:01f31e923fe2 366 if (event & USBD_EVT_OUT) {
Pawel Zarembski 0:01f31e923fe2 367 USBD_HID_EP_INTOUT_Event(event);
Pawel Zarembski 0:01f31e923fe2 368 }
Pawel Zarembski 0:01f31e923fe2 369 }
Pawel Zarembski 0:01f31e923fe2 370
Pawel Zarembski 0:01f31e923fe2 371
Pawel Zarembski 0:01f31e923fe2 372 /*
Pawel Zarembski 0:01f31e923fe2 373 * USB Device HID SOF Handler (handles report timings: polling and idle times)
Pawel Zarembski 0:01f31e923fe2 374 * Called automatically on USB Device Start of Frame
Pawel Zarembski 0:01f31e923fe2 375 * Parameters: None
Pawel Zarembski 0:01f31e923fe2 376 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 377 */
Pawel Zarembski 0:01f31e923fe2 378
Pawel Zarembski 0:01f31e923fe2 379 void USBD_HID_SOF_Event(void)
Pawel Zarembski 0:01f31e923fe2 380 {
Pawel Zarembski 0:01f31e923fe2 381 static U8 cnt_for_4ms = 0;
Pawel Zarembski 0:01f31e923fe2 382 U8 i;
Pawel Zarembski 0:01f31e923fe2 383 BOOL tick_4ms, do_polling, polling_reload, idle_reload;
Pawel Zarembski 0:01f31e923fe2 384
Pawel Zarembski 0:01f31e923fe2 385 if (USBD_Configuration) {
Pawel Zarembski 0:01f31e923fe2 386 tick_4ms = __FALSE;
Pawel Zarembski 0:01f31e923fe2 387
Pawel Zarembski 0:01f31e923fe2 388 if (cnt_for_4ms++ >= ((4 << (3 * USBD_HighSpeed))) - 1) {
Pawel Zarembski 0:01f31e923fe2 389 cnt_for_4ms = 0;
Pawel Zarembski 0:01f31e923fe2 390 tick_4ms = __TRUE;
Pawel Zarembski 0:01f31e923fe2 391 }
Pawel Zarembski 0:01f31e923fe2 392
Pawel Zarembski 0:01f31e923fe2 393 polling_reload = __FALSE;
Pawel Zarembski 0:01f31e923fe2 394
Pawel Zarembski 0:01f31e923fe2 395 if (USBD_HID_PollingCnt < 255) {
Pawel Zarembski 0:01f31e923fe2 396 USBD_HID_PollingCnt++;
Pawel Zarembski 0:01f31e923fe2 397 }
Pawel Zarembski 0:01f31e923fe2 398
Pawel Zarembski 0:01f31e923fe2 399 if (USBD_HID_PollingCnt == usbd_hid_interval[USBD_HighSpeed]) {
Pawel Zarembski 0:01f31e923fe2 400 polling_reload = __TRUE; /* If polling interval expired */
Pawel Zarembski 0:01f31e923fe2 401 }
Pawel Zarembski 0:01f31e923fe2 402
Pawel Zarembski 0:01f31e923fe2 403 for (i = 0; i < usbd_hid_inreport_num; i++) {
Pawel Zarembski 0:01f31e923fe2 404 idle_reload = __FALSE;
Pawel Zarembski 0:01f31e923fe2 405
Pawel Zarembski 0:01f31e923fe2 406 if (tick_4ms) {
Pawel Zarembski 0:01f31e923fe2 407 if (USBD_HID_IdleCnt[i] < 255) {
Pawel Zarembski 0:01f31e923fe2 408 USBD_HID_IdleCnt[i]++;
Pawel Zarembski 0:01f31e923fe2 409 }
Pawel Zarembski 0:01f31e923fe2 410
Pawel Zarembski 0:01f31e923fe2 411 if (USBD_HID_IdleReload[i]) {
Pawel Zarembski 0:01f31e923fe2 412 if (USBD_HID_IdleCnt[i] >= USBD_HID_IdleReload[i]) {
Pawel Zarembski 0:01f31e923fe2 413 idle_reload = __TRUE; /* If idle period expired */
Pawel Zarembski 0:01f31e923fe2 414 }
Pawel Zarembski 0:01f31e923fe2 415 }
Pawel Zarembski 0:01f31e923fe2 416 }
Pawel Zarembski 0:01f31e923fe2 417
Pawel Zarembski 0:01f31e923fe2 418 do_polling = (usbd_hid_interval[USBD_HighSpeed] > ((U16)(USBD_HID_IdleReload[i]) << (2 << (3 * USBD_HighSpeed)))) && (USBD_HID_IdleReload[i] != 0);
Pawel Zarembski 0:01f31e923fe2 419
Pawel Zarembski 0:01f31e923fe2 420 if (polling_reload) {
Pawel Zarembski 0:01f31e923fe2 421 if (do_polling) {
Pawel Zarembski 0:01f31e923fe2 422 /* If polling is longer than idle */
Pawel Zarembski 0:01f31e923fe2 423 DataOutUpdateReqMask |= (1 << i);
Pawel Zarembski 0:01f31e923fe2 424 }
Pawel Zarembski 0:01f31e923fe2 425 }
Pawel Zarembski 0:01f31e923fe2 426
Pawel Zarembski 0:01f31e923fe2 427 if (USBD_HID_IdleReload[i] != USBD_HID_IdleSet[i]) {
Pawel Zarembski 0:01f31e923fe2 428 if (USBD_HID_IdleCnt[i] >= USBD_HID_IdleSet[i]) {
Pawel Zarembski 0:01f31e923fe2 429 DataOutUpdateReqMask |= (1 << i);
Pawel Zarembski 0:01f31e923fe2 430 cnt_for_4ms = 0;
Pawel Zarembski 0:01f31e923fe2 431 }
Pawel Zarembski 0:01f31e923fe2 432
Pawel Zarembski 0:01f31e923fe2 433 USBD_HID_IdleReload[i] = USBD_HID_IdleSet[i];
Pawel Zarembski 0:01f31e923fe2 434 }
Pawel Zarembski 0:01f31e923fe2 435
Pawel Zarembski 0:01f31e923fe2 436 if (idle_reload) {
Pawel Zarembski 0:01f31e923fe2 437 if (!do_polling) {
Pawel Zarembski 0:01f31e923fe2 438 DataOutUpdateReqMask |= (1 << i);
Pawel Zarembski 0:01f31e923fe2 439 }
Pawel Zarembski 0:01f31e923fe2 440
Pawel Zarembski 0:01f31e923fe2 441 USBD_HID_IdleCnt[i] = 0;
Pawel Zarembski 0:01f31e923fe2 442 }
Pawel Zarembski 0:01f31e923fe2 443 }
Pawel Zarembski 0:01f31e923fe2 444
Pawel Zarembski 0:01f31e923fe2 445 if (polling_reload) {
Pawel Zarembski 0:01f31e923fe2 446 USBD_HID_PollingCnt = 0;
Pawel Zarembski 0:01f31e923fe2 447 }
Pawel Zarembski 0:01f31e923fe2 448
Pawel Zarembski 0:01f31e923fe2 449 if (DataOutUpdateReqMask && !DataOutToSendLen) { /* If pending */
Pawel Zarembski 0:01f31e923fe2 450 /* refresh request and no active data */
Pawel Zarembski 0:01f31e923fe2 451 /* out then start data out */
Pawel Zarembski 0:01f31e923fe2 452 USBD_HID_EP_INTIN_Event(0);
Pawel Zarembski 0:01f31e923fe2 453 }
Pawel Zarembski 0:01f31e923fe2 454 }
Pawel Zarembski 0:01f31e923fe2 455 }
Pawel Zarembski 0:01f31e923fe2 456
Pawel Zarembski 0:01f31e923fe2 457
Pawel Zarembski 0:01f31e923fe2 458 #ifdef __RTX /* RTX task for handling events */
Pawel Zarembski 0:01f31e923fe2 459
Pawel Zarembski 0:01f31e923fe2 460 /*
Pawel Zarembski 0:01f31e923fe2 461 * USB Device HID Interrupt In Endpoint Event Handler Task
Pawel Zarembski 0:01f31e923fe2 462 * Parameters: None
Pawel Zarembski 0:01f31e923fe2 463 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 464 */
Pawel Zarembski 0:01f31e923fe2 465
Pawel Zarembski 0:01f31e923fe2 466 void USBD_RTX_HID_EP_INTIN_Event(void)
Pawel Zarembski 0:01f31e923fe2 467 {
Pawel Zarembski 0:01f31e923fe2 468 for (;;) {
Pawel Zarembski 0:01f31e923fe2 469 usbd_os_evt_wait_or(0xFFFF, 0xFFFF);
Pawel Zarembski 0:01f31e923fe2 470
Pawel Zarembski 0:01f31e923fe2 471 if (usbd_os_evt_get() & USBD_EVT_IN) {
Pawel Zarembski 0:01f31e923fe2 472 USBD_HID_EP_INTIN_Event(0);
Pawel Zarembski 0:01f31e923fe2 473 }
Pawel Zarembski 0:01f31e923fe2 474 }
Pawel Zarembski 0:01f31e923fe2 475 }
Pawel Zarembski 0:01f31e923fe2 476
Pawel Zarembski 0:01f31e923fe2 477
Pawel Zarembski 0:01f31e923fe2 478 /*
Pawel Zarembski 0:01f31e923fe2 479 * USB Device HID Interrupt Out Endpoint Event Handler Task
Pawel Zarembski 0:01f31e923fe2 480 * Parameters: None
Pawel Zarembski 0:01f31e923fe2 481 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 482 */
Pawel Zarembski 0:01f31e923fe2 483
Pawel Zarembski 0:01f31e923fe2 484 void USBD_RTX_HID_EP_INTOUT_Event(void)
Pawel Zarembski 0:01f31e923fe2 485 {
Pawel Zarembski 0:01f31e923fe2 486 for (;;) {
Pawel Zarembski 0:01f31e923fe2 487 usbd_os_evt_wait_or(0xFFFF, 0xFFFF);
Pawel Zarembski 0:01f31e923fe2 488
Pawel Zarembski 0:01f31e923fe2 489 if (usbd_os_evt_get() & USBD_EVT_OUT) {
Pawel Zarembski 0:01f31e923fe2 490 USBD_HID_EP_INTOUT_Event(0);
Pawel Zarembski 0:01f31e923fe2 491 }
Pawel Zarembski 0:01f31e923fe2 492 }
Pawel Zarembski 0:01f31e923fe2 493 }
Pawel Zarembski 0:01f31e923fe2 494
Pawel Zarembski 0:01f31e923fe2 495
Pawel Zarembski 0:01f31e923fe2 496 /*
Pawel Zarembski 0:01f31e923fe2 497 * USB Device HID Interrupt In/Out Endpoint Event Handler Task
Pawel Zarembski 0:01f31e923fe2 498 * Parameters: None
Pawel Zarembski 0:01f31e923fe2 499 * Return Value: None
Pawel Zarembski 0:01f31e923fe2 500 */
Pawel Zarembski 0:01f31e923fe2 501
Pawel Zarembski 0:01f31e923fe2 502 void USBD_RTX_HID_EP_INT_Event(void)
Pawel Zarembski 0:01f31e923fe2 503 {
Pawel Zarembski 0:01f31e923fe2 504 for (;;) {
Pawel Zarembski 0:01f31e923fe2 505 usbd_os_evt_wait_or(0xFFFF, 0xFFFF);
Pawel Zarembski 0:01f31e923fe2 506 USBD_HID_EP_INT_Event(usbd_os_evt_get());
Pawel Zarembski 0:01f31e923fe2 507 }
Pawel Zarembski 0:01f31e923fe2 508 }
Pawel Zarembski 0:01f31e923fe2 509 #endif
Pawel Zarembski 0:01f31e923fe2 510
Pawel Zarembski 0:01f31e923fe2 511
Pawel Zarembski 0:01f31e923fe2 512 /*
Pawel Zarembski 0:01f31e923fe2 513 * USB Device HID Get Report Trigger (asynchronous Get_Report request)
Pawel Zarembski 0:01f31e923fe2 514 * Parameters: rid: Report ID
Pawel Zarembski 0:01f31e923fe2 515 * buf: Pointer to data buffer
Pawel Zarembski 0:01f31e923fe2 516 * len: Number of bytes to be sent
Pawel Zarembski 0:01f31e923fe2 517 * Return Value: TRUE - Success, FALSE - Error
Pawel Zarembski 0:01f31e923fe2 518 */
Pawel Zarembski 0:01f31e923fe2 519
Pawel Zarembski 0:01f31e923fe2 520 BOOL usbd_hid_get_report_trigger(U8 rid, U8 *buf, int len)
Pawel Zarembski 0:01f31e923fe2 521 {
Pawel Zarembski 0:01f31e923fe2 522 if (len > usbd_hid_inreport_max_sz) {
Pawel Zarembski 0:01f31e923fe2 523 return (__FALSE);
Pawel Zarembski 0:01f31e923fe2 524 }
Pawel Zarembski 0:01f31e923fe2 525
Pawel Zarembski 0:01f31e923fe2 526 if (USBD_Configuration) {
Pawel Zarembski 0:01f31e923fe2 527 DataOutAsyncReq = __TRUE; /* Asynchronous data out request */
Pawel Zarembski 0:01f31e923fe2 528
Pawel Zarembski 0:01f31e923fe2 529 while (DataOutToSendLen) {
Pawel Zarembski 0:01f31e923fe2 530 if (!USBD_Configuration) { /* If device not configured reject rq */
Pawel Zarembski 0:01f31e923fe2 531 DataOutAsyncReq = __FALSE; /* Asynchronous data out request */
Pawel Zarembski 0:01f31e923fe2 532 ptrDataOut = NULL;
Pawel Zarembski 0:01f31e923fe2 533 DataOutSentLen = 0;
Pawel Zarembski 0:01f31e923fe2 534 DataOutToSendLen = 0;
Pawel Zarembski 0:01f31e923fe2 535 return (__FALSE);
Pawel Zarembski 0:01f31e923fe2 536 }
Pawel Zarembski 0:01f31e923fe2 537 }
Pawel Zarembski 0:01f31e923fe2 538
Pawel Zarembski 0:01f31e923fe2 539 USBD_HID_InReport[0] = rid;
Pawel Zarembski 0:01f31e923fe2 540 memcpy(&USBD_HID_InReport[1], buf, len);
Pawel Zarembski 0:01f31e923fe2 541 ptrDataOut = USBD_HID_InReport;
Pawel Zarembski 0:01f31e923fe2 542 DataOutSentLen = 0;
Pawel Zarembski 0:01f31e923fe2 543 DataOutToSendLen = len;
Pawel Zarembski 0:01f31e923fe2 544
Pawel Zarembski 0:01f31e923fe2 545 if (usbd_hid_inreport_num <= 1) { /* If only 1 in report skip ReportID */
Pawel Zarembski 0:01f31e923fe2 546 ptrDataOut ++;
Pawel Zarembski 0:01f31e923fe2 547 } else { /* If more in reports, send ReportID */
Pawel Zarembski 0:01f31e923fe2 548 DataOutToSendLen ++;
Pawel Zarembski 0:01f31e923fe2 549 }
Pawel Zarembski 0:01f31e923fe2 550
Pawel Zarembski 0:01f31e923fe2 551 USBD_HID_EP_INTIN_Event(0);
Pawel Zarembski 0:01f31e923fe2 552 USBD_HID_IdleCnt[rid] = 0;
Pawel Zarembski 0:01f31e923fe2 553 return (__TRUE);
Pawel Zarembski 0:01f31e923fe2 554 }
Pawel Zarembski 0:01f31e923fe2 555
Pawel Zarembski 0:01f31e923fe2 556 return (__FALSE);
Pawel Zarembski 0:01f31e923fe2 557 }