소스 검색

Fixed line endings

Dmitry 9 년 전
부모
커밋
8c4898731f
24개의 변경된 파일5375개의 추가작업 그리고 5375개의 파일을 삭제
  1. 46 46
      inc/hid_usage_button.h
  2. 109 109
      inc/hid_usage_desktop.h
  3. 37 37
      inc/hid_usage_device.h
  4. 59 59
      inc/hid_usage_game.h
  5. 245 245
      inc/hid_usage_keyboard.h
  6. 107 107
      inc/hid_usage_led.h
  7. 45 45
      inc/hid_usage_ordinal.h
  8. 91 91
      inc/hid_usage_simulation.h
  9. 74 74
      inc/hid_usage_sport.h
  10. 105 105
      inc/hid_usage_telephony.h
  11. 44 44
      inc/hid_usage_vr.h
  12. 226 226
      inc/usb_cdc.h
  13. 124 124
      inc/usb_dfu.h
  14. 212 212
      inc/usb_hid.h
  15. 419 419
      inc/usb_std.h
  16. 441 441
      inc/usbd_core.h
  17. 43 43
      readme.md
  18. 8 8
      src/memmap.inc
  19. 457 457
      src/usb_32v0.c
  20. 813 813
      src/usb_32v0A.S
  21. 456 456
      src/usb_32v1.c
  22. 825 825
      src/usb_32v1A.S
  23. 376 376
      src/usbd_core.c
  24. 13 13
      usb.h

+ 46 - 46
inc/hid_usage_button.h

@@ -1,46 +1,46 @@
-/* This file is the part of the LUS32 project
- *
- * Copyright ©2016 Dmitry Filimonchuk <dmitrystu[at]gmail[dot]com>
- *
- * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
- * 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.
- */
-
-#ifndef _USB_HID_USAGE_BUTTON_H_
-#define _USB_HID_USAGE_BUTTON_H_
-#ifdef __cplusplus
-    extern "C" {
-#endif
-
-
-/**\ingroup USB_HID
- * \addtogroup USB_HID_USAGES_BUTTON HID Usage Tables for Button
- * \brief Contains USB HID Usages definitions for Button Page
- * \details This module based on
- * + [HID Usage Tables Version 1.12](http://www.usb.org/developers/hidpage/Hut1_12v2.pdf)
- * @{ */
-
-#define HID_PAGE_BUTTON                 0x09
-
-#define HID_BUTTON_NO_PRESSED           0x00
-#define HID_BUTTON_1                    0x01
-#define HID_BUTTON_2                    0x02
-#define HID_BUTTON_3                    0x03
-#define HID_BUTTON_4                    0x04
-#define HID_BUTTON_5                    0x05
-
-/** @}  */
-
-#ifdef __cplusplus
-    }
-#endif
-
-#endif
-
+/* This file is the part of the LUS32 project
+ *
+ * Copyright ©2016 Dmitry Filimonchuk <dmitrystu[at]gmail[dot]com>
+ *
+ * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ * 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.
+ */
+
+#ifndef _USB_HID_USAGE_BUTTON_H_
+#define _USB_HID_USAGE_BUTTON_H_
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+
+/**\ingroup USB_HID
+ * \addtogroup USB_HID_USAGES_BUTTON HID Usage Tables for Button
+ * \brief Contains USB HID Usages definitions for Button Page
+ * \details This module based on
+ * + [HID Usage Tables Version 1.12](http://www.usb.org/developers/hidpage/Hut1_12v2.pdf)
+ * @{ */
+
+#define HID_PAGE_BUTTON                 0x09
+
+#define HID_BUTTON_NO_PRESSED           0x00
+#define HID_BUTTON_1                    0x01
+#define HID_BUTTON_2                    0x02
+#define HID_BUTTON_3                    0x03
+#define HID_BUTTON_4                    0x04
+#define HID_BUTTON_5                    0x05
+
+/** @}  */
+
+#ifdef __cplusplus
+    }
+#endif
+
+#endif
+

+ 109 - 109
inc/hid_usage_desktop.h

@@ -1,109 +1,109 @@
-/* This file is the part of the LUS32 project
- *
- * Copyright ©2016 Dmitry Filimonchuk <dmitrystu[at]gmail[dot]com>
- *
- * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
- * 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.
- */
-
-#ifndef _USB_HID_USAGE_DESKTOP_H_
-#define _USB_HID_USAGE_DESKTOP_H_
-#ifdef __cplusplus
-    extern "C" {
-#endif
-
-
-/**\ingroup USB_HID
- * \addtogroup USB_HID_USAGES_DESKTOP HID Usage Tables for Desktop
- * \brief Contains USB HID Usages definitions for Generic Desktop Page
- * \details This module based on
- * + [HID Usage Tables Version 1.12](http://www.usb.org/developers/hidpage/Hut1_12v2.pdf)
- * @{ */
-
-#define HID_PAGE_DESKTOP                0x01
-
-#define HID_DESKTOP_POINTER             0x01
-#define HID_DESKTOP_MOUSE               0x02
-#define HID_DESKTOP_JOYSTICK            0x04
-#define HID_DESKTOP_GAMEPAD             0x05
-#define HID_DESKTOP_KEYBOARD            0x06
-#define HID_DESKTOP_KEYPAD              0x07
-#define HID_DESKTOP_MULTIAXIS           0x08
-#define HID_DESKTOP_TABLET              0x09
-#define HID_DESKTOP_X                   0x30
-#define HID_DESKTOP_Y                   0x31
-#define HID_DESKTOP_Z                   0x32
-#define HID_DESKTOP_RX                  0x33
-#define HID_DESKTOP_RY                  0x34
-#define HID_DESKTOP_RZ                  0x35
-#define HID_DESKTOP_SLIDER              0x36
-#define HID_DESKTOP_DIAL                0x37
-#define HID_DESKTOP_WHEEL               0x38
-#define HID_DESKTOP_HAT_SWITCH          0x39
-#define HID_DESKTOP_COUNTEDBUF          0x3A
-#define HID_DESKTOP_BYTECOUNT           0x3B
-#define HID_DESKTOP_MOTION_WAKEUP       0x3C
-#define HID_DESKTOP_START               0x3D
-#define HID_DESKTOP_SELECT              0x3C
-#define HID_DESKTOP_VX                  0x40
-#define HID_DESKTOP_VY                  0x41
-#define HID_DESKTOP_VZ                  0x42
-#define HID_DESKTOP_VBRX                0x43
-#define HID_DESKTOP_VBRY                0x44
-#define HID_DESKTOP_VBRZ                0x45
-#define HID_DESKTOP_VNO                 0x46
-#define HID_DESKTOP_FEATURE_NOTIFY      0x47
-#define HID_DESKTOP_RESOLUTION_MULTIPLY 0x48
-#define HID_DESKTOP_SYS_CONTROL         0x80
-#define HID_DESKTOP_SYS_PWR_DOWN        0x81
-#define HID_DESKTOP_SYS_SLEEP           0x82
-#define HID_DESKTOP_SYS_WAKEUP          0x83
-#define HID_DESKTOP_SYS_CONTEXT_MENU    0x84
-#define HID_DESKTOP_SYS_MAIN_MENU       0x85
-#define HID_DESKTOP_SYS_APP_MENU        0x86
-#define HID_DESKTOP_SYS_MENU_HELP       0x87
-#define HID_DESKTOP_SYS_MENU_EXIT       0x88
-#define HID_DESKTOP_SYS_MENU_SELECT     0x89
-#define HID_DESKTOP_SYS_MENU_RIGHT      0x8A
-#define HID_DESKTOP_SYS_MENU_LEFT       0x8B
-#define HID_DESKTOP_SYS_MENU_UP         0x8C
-#define HID_DESKTOP_SYS_MENU_DOWN       0x8D
-#define HID_DESKTOP_SYS_RESTART_COLD    0x8E
-#define HID_DESKTOP_SYS_RESTART_WARM    0x8F
-#define HID_DESKTOP_DPAD_UP             0x90
-#define HID_DESKTOP_DPAD_DOWN           0x91
-#define HID_DESKTOP_DPAD_RIGHT          0x92
-#define HID_DESKTOP_DPAD_LEFT           0x93
-#define HID_DESKTOP_SYS_DOCK            0xA0
-#define HID_DESKTOP_SYS_UNDOCK          0xA1
-#define HID_DESKTOP_SYS_STARTUP         0xA2
-#define HID_DESKTOP_SYS_BREAK           0xA3
-#define HID_DESKTOP_SYS_DBG_BREAK       0xA4
-#define HID_DESKTOP_APP_BREAK           0xA5
-#define HID_DESKTOP_APP_DBG_BREAK       0xA6
-#define HID_DESKTOP_SYS_SPKR_MUTE       0xA7
-#define HID_DESKTOP_SYS_HIBERNATE       0xA8
-#define HID_DESKTOP_SYS_DISP_INVERT     0xB0
-#define HID_DESKTOP_SYS_DISP_INT        0xB1
-#define HID_DESKTOP_SYS_DISP_EXT        0xB2
-#define HID_DESKTOP_SYS_DISP_BOTH       0xB3
-#define HID_DESKTOP_SYS_DISP_DUAL       0xB4
-#define HID_DESKTOP_SYS_DISP_TOGGLE     0xB5
-#define HID_DESKTOP_SYS_DISP_SWAP       0xB6
-#define HID_DESKTOP_SYS_DISP_AUTOSCALE  0xB7
-
-/** @}  */
-
-#ifdef __cplusplus
-    }
-#endif
-
-#endif
-
+/* This file is the part of the LUS32 project
+ *
+ * Copyright ©2016 Dmitry Filimonchuk <dmitrystu[at]gmail[dot]com>
+ *
+ * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ * 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.
+ */
+
+#ifndef _USB_HID_USAGE_DESKTOP_H_
+#define _USB_HID_USAGE_DESKTOP_H_
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+
+/**\ingroup USB_HID
+ * \addtogroup USB_HID_USAGES_DESKTOP HID Usage Tables for Desktop
+ * \brief Contains USB HID Usages definitions for Generic Desktop Page
+ * \details This module based on
+ * + [HID Usage Tables Version 1.12](http://www.usb.org/developers/hidpage/Hut1_12v2.pdf)
+ * @{ */
+
+#define HID_PAGE_DESKTOP                0x01
+
+#define HID_DESKTOP_POINTER             0x01
+#define HID_DESKTOP_MOUSE               0x02
+#define HID_DESKTOP_JOYSTICK            0x04
+#define HID_DESKTOP_GAMEPAD             0x05
+#define HID_DESKTOP_KEYBOARD            0x06
+#define HID_DESKTOP_KEYPAD              0x07
+#define HID_DESKTOP_MULTIAXIS           0x08
+#define HID_DESKTOP_TABLET              0x09
+#define HID_DESKTOP_X                   0x30
+#define HID_DESKTOP_Y                   0x31
+#define HID_DESKTOP_Z                   0x32
+#define HID_DESKTOP_RX                  0x33
+#define HID_DESKTOP_RY                  0x34
+#define HID_DESKTOP_RZ                  0x35
+#define HID_DESKTOP_SLIDER              0x36
+#define HID_DESKTOP_DIAL                0x37
+#define HID_DESKTOP_WHEEL               0x38
+#define HID_DESKTOP_HAT_SWITCH          0x39
+#define HID_DESKTOP_COUNTEDBUF          0x3A
+#define HID_DESKTOP_BYTECOUNT           0x3B
+#define HID_DESKTOP_MOTION_WAKEUP       0x3C
+#define HID_DESKTOP_START               0x3D
+#define HID_DESKTOP_SELECT              0x3C
+#define HID_DESKTOP_VX                  0x40
+#define HID_DESKTOP_VY                  0x41
+#define HID_DESKTOP_VZ                  0x42
+#define HID_DESKTOP_VBRX                0x43
+#define HID_DESKTOP_VBRY                0x44
+#define HID_DESKTOP_VBRZ                0x45
+#define HID_DESKTOP_VNO                 0x46
+#define HID_DESKTOP_FEATURE_NOTIFY      0x47
+#define HID_DESKTOP_RESOLUTION_MULTIPLY 0x48
+#define HID_DESKTOP_SYS_CONTROL         0x80
+#define HID_DESKTOP_SYS_PWR_DOWN        0x81
+#define HID_DESKTOP_SYS_SLEEP           0x82
+#define HID_DESKTOP_SYS_WAKEUP          0x83
+#define HID_DESKTOP_SYS_CONTEXT_MENU    0x84
+#define HID_DESKTOP_SYS_MAIN_MENU       0x85
+#define HID_DESKTOP_SYS_APP_MENU        0x86
+#define HID_DESKTOP_SYS_MENU_HELP       0x87
+#define HID_DESKTOP_SYS_MENU_EXIT       0x88
+#define HID_DESKTOP_SYS_MENU_SELECT     0x89
+#define HID_DESKTOP_SYS_MENU_RIGHT      0x8A
+#define HID_DESKTOP_SYS_MENU_LEFT       0x8B
+#define HID_DESKTOP_SYS_MENU_UP         0x8C
+#define HID_DESKTOP_SYS_MENU_DOWN       0x8D
+#define HID_DESKTOP_SYS_RESTART_COLD    0x8E
+#define HID_DESKTOP_SYS_RESTART_WARM    0x8F
+#define HID_DESKTOP_DPAD_UP             0x90
+#define HID_DESKTOP_DPAD_DOWN           0x91
+#define HID_DESKTOP_DPAD_RIGHT          0x92
+#define HID_DESKTOP_DPAD_LEFT           0x93
+#define HID_DESKTOP_SYS_DOCK            0xA0
+#define HID_DESKTOP_SYS_UNDOCK          0xA1
+#define HID_DESKTOP_SYS_STARTUP         0xA2
+#define HID_DESKTOP_SYS_BREAK           0xA3
+#define HID_DESKTOP_SYS_DBG_BREAK       0xA4
+#define HID_DESKTOP_APP_BREAK           0xA5
+#define HID_DESKTOP_APP_DBG_BREAK       0xA6
+#define HID_DESKTOP_SYS_SPKR_MUTE       0xA7
+#define HID_DESKTOP_SYS_HIBERNATE       0xA8
+#define HID_DESKTOP_SYS_DISP_INVERT     0xB0
+#define HID_DESKTOP_SYS_DISP_INT        0xB1
+#define HID_DESKTOP_SYS_DISP_EXT        0xB2
+#define HID_DESKTOP_SYS_DISP_BOTH       0xB3
+#define HID_DESKTOP_SYS_DISP_DUAL       0xB4
+#define HID_DESKTOP_SYS_DISP_TOGGLE     0xB5
+#define HID_DESKTOP_SYS_DISP_SWAP       0xB6
+#define HID_DESKTOP_SYS_DISP_AUTOSCALE  0xB7
+
+/** @}  */
+
+#ifdef __cplusplus
+    }
+#endif
+
+#endif
+

+ 37 - 37
inc/hid_usage_device.h

@@ -1,37 +1,37 @@
-/* This file is the part of the LUS32 project
- *
- * Copyright ©2016 Dmitry Filimonchuk <dmitrystu[at]gmail[dot]com>
- *
- * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
- * 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.
- */
-
-#ifndef _USB_HID_USAGE_DEVICE_H_
-#define _USB_HID_USAGE_DEVICE_H_
-
-/**\ingroup USB_HID
- * \addtogroup ISB_HID_USAGES_DEVICE HID Usages for Device
- * \brief Contains USB HID Usages definitions for Generic Device Control Page
- * \details This module based on
- * + [HID Usage Tables Version 1.12](http://www.usb.org/developers/hidpage/Hut1_12v2.pdf)
- * @{ */
-
-#define HID_PAGE_DEVICE                 0x06
-
-#define HID_DEVICE_BATTERY_STRENGHT     0x20
-#define HID_DEVICE_WIRELESS_CHANNEL     0x21
-#define HID_DEVICE_WIRELESS_ID          0x22
-#define HID_DEVICE_DISCO_WIRELESS_CTL   0x23
-#define HID_DEVICE_SECURITY_CHAR_ENT    0x24
-#define HID_DEVICE_SECURITY_CHAR_ERA    0x25
-#define HID_DEVICE_SCURITY_CODE_CLR     0x26
-
-#endif
-
+/* This file is the part of the LUS32 project
+ *
+ * Copyright ©2016 Dmitry Filimonchuk <dmitrystu[at]gmail[dot]com>
+ *
+ * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ * 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.
+ */
+
+#ifndef _USB_HID_USAGE_DEVICE_H_
+#define _USB_HID_USAGE_DEVICE_H_
+
+/**\ingroup USB_HID
+ * \addtogroup ISB_HID_USAGES_DEVICE HID Usages for Device
+ * \brief Contains USB HID Usages definitions for Generic Device Control Page
+ * \details This module based on
+ * + [HID Usage Tables Version 1.12](http://www.usb.org/developers/hidpage/Hut1_12v2.pdf)
+ * @{ */
+
+#define HID_PAGE_DEVICE                 0x06
+
+#define HID_DEVICE_BATTERY_STRENGHT     0x20
+#define HID_DEVICE_WIRELESS_CHANNEL     0x21
+#define HID_DEVICE_WIRELESS_ID          0x22
+#define HID_DEVICE_DISCO_WIRELESS_CTL   0x23
+#define HID_DEVICE_SECURITY_CHAR_ENT    0x24
+#define HID_DEVICE_SECURITY_CHAR_ERA    0x25
+#define HID_DEVICE_SCURITY_CODE_CLR     0x26
+
+#endif
+

+ 59 - 59
inc/hid_usage_game.h

@@ -1,59 +1,59 @@
-/* This file is the part of the LUS32 project
- *
- * Copyright ©2016 Dmitry Filimonchuk <dmitrystu[at]gmail[dot]com>
- *
- * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
- * 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.
- */
-
-#ifndef _USB_HID_USAGE_H_
-#define _USB_HID_USAGE_H_
-
-/**\ingroup USB_HID
- * \addtogroup USB_HID_USAGES_GAME HID Usage Tables for Game
- * \brief Contains USB HID Usages definitions for Game Controls Page
- * \details This module based on
- * + [HID Usage Tables Version 1.12](http://www.usb.org/developers/hidpage/Hut1_12v2.pdf)
- * @{ */
-
-#define HID_PAGE_GAME                   0x05
-
-#define HID_GAME_3D_GAME_CONTROLLER     0x01
-#define HID_GAME_PINBALL_DEVICE         0x02
-#define HID_GAME_GUN_DEVICE             0x03
-#define HID_GAME_POINT_OF_VIEW          0x20
-#define HID_GAME_TURN_LEFT_RIGHT        0x21
-#define HID_GAME_PITCH_FWD_BACK         0x22
-#define HID_GAME_ROLL_LEFT_RIGHT        0x23
-#define HID_GAME_MOVE_LEFT_RIGHT        0x24
-#define HID_GAME_MOVE_FWD_BACK          0x25     
-#define HID_GAME_MOVE_UP_DOWN           0x26
-#define HID_GAME_LEAN_LEFT_RIGHT        0x27
-#define HID_GAME_LEAN_FWD_BACK          0x28
-#define HID_GAME_HEIGHT_OF_POV          0x29
-#define HID_GAME_FLIPPER                0x2A
-#define HID_GAME_SECONDARY_FLIPPER      0x2B
-#define HID_GAME_BUMP                   0x2C
-#define HID_GAME_NEW_GAME               0x2D
-#define HID_GAME_SHOOT_BALL             0x2E
-#define HID_GAME_PLAYER                 0x2F
-#define HID_GAME_GUN_BOLT               0x30
-#define HID_GAME_GUN_CLIP               0x31
-#define HID_GAME_GUN_SELECTOR           0x32
-#define HID_GAME_GUN_SINGLE_SHOT        0x33
-#define HID_GAME_GUN_BURST              0x34
-#define HID_GAME_GUN_AUTOMATIC          0x35
-#define HID_GAME_GUN_SAFETY             0x36
-#define HID_GAME_GANEPAD_FIRE_JUMP      0x37
-#define HID_GAME_GAMEPAD_TRIGGER        0x38
-
-
-#endif
-
+/* This file is the part of the LUS32 project
+ *
+ * Copyright ©2016 Dmitry Filimonchuk <dmitrystu[at]gmail[dot]com>
+ *
+ * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ * 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.
+ */
+
+#ifndef _USB_HID_USAGE_H_
+#define _USB_HID_USAGE_H_
+
+/**\ingroup USB_HID
+ * \addtogroup USB_HID_USAGES_GAME HID Usage Tables for Game
+ * \brief Contains USB HID Usages definitions for Game Controls Page
+ * \details This module based on
+ * + [HID Usage Tables Version 1.12](http://www.usb.org/developers/hidpage/Hut1_12v2.pdf)
+ * @{ */
+
+#define HID_PAGE_GAME                   0x05
+
+#define HID_GAME_3D_GAME_CONTROLLER     0x01
+#define HID_GAME_PINBALL_DEVICE         0x02
+#define HID_GAME_GUN_DEVICE             0x03
+#define HID_GAME_POINT_OF_VIEW          0x20
+#define HID_GAME_TURN_LEFT_RIGHT        0x21
+#define HID_GAME_PITCH_FWD_BACK         0x22
+#define HID_GAME_ROLL_LEFT_RIGHT        0x23
+#define HID_GAME_MOVE_LEFT_RIGHT        0x24
+#define HID_GAME_MOVE_FWD_BACK          0x25     
+#define HID_GAME_MOVE_UP_DOWN           0x26
+#define HID_GAME_LEAN_LEFT_RIGHT        0x27
+#define HID_GAME_LEAN_FWD_BACK          0x28
+#define HID_GAME_HEIGHT_OF_POV          0x29
+#define HID_GAME_FLIPPER                0x2A
+#define HID_GAME_SECONDARY_FLIPPER      0x2B
+#define HID_GAME_BUMP                   0x2C
+#define HID_GAME_NEW_GAME               0x2D
+#define HID_GAME_SHOOT_BALL             0x2E
+#define HID_GAME_PLAYER                 0x2F
+#define HID_GAME_GUN_BOLT               0x30
+#define HID_GAME_GUN_CLIP               0x31
+#define HID_GAME_GUN_SELECTOR           0x32
+#define HID_GAME_GUN_SINGLE_SHOT        0x33
+#define HID_GAME_GUN_BURST              0x34
+#define HID_GAME_GUN_AUTOMATIC          0x35
+#define HID_GAME_GUN_SAFETY             0x36
+#define HID_GAME_GANEPAD_FIRE_JUMP      0x37
+#define HID_GAME_GAMEPAD_TRIGGER        0x38
+
+
+#endif
+

+ 245 - 245
inc/hid_usage_keyboard.h

@@ -1,245 +1,245 @@
-/* This file is the part of the LUS32 project
- *
- * Copyright ©2016 Dmitry Filimonchuk <dmitrystu[at]gmail[dot]com>
- *
- * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
- * 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.
- */
-#ifndef _USB_HID_USAGE_KEYBOARD_H_
-#define _USB_HID_USAGE_KEYBOARD_H_
-
-/**\ingroup USB_HID
- * \addtogroup ISB_HID_USAGES_KEYBOARD HID Usages for Keyboard
- * \brief Contains USB HID Usages definitions for Keyboard/Keypad Page
- * \details This module based on
- * + [HID Usage Tables Version 1.12](http://www.usb.org/developers/hidpage/Hut1_12v2.pdf)
- * @{ */
-
-#define HID_PAGE_KEYBOARD               0x07
-
-#define HID_KEYBOARD_ERR_ROLL_OVER      0x01
-#define HID_KEYBOARD_POST_FAIL          0x02
-#define HID_KEYBOARD_ERR_UNDEFINED      0x03
-#define HID_KEYBOARD_A                  0x04
-#define HID_KEYBOARD_B                  0x05
-#define HID_KEYBOARD_C                  0x06
-#define HID_KEYBOARD_D                  0x07
-#define HID_KEYBOARD_E                  0x08
-#define HID_KEYBOARD_F                  0x09
-#define HID_KEYBOARD_G                  0x0A
-#define HID_KEYBOARD_H                  0x0B
-#define HID_KEYBOARD_I                  0x0C
-#define HID_KEYBOARD_J                  0x0D
-#define HID_KEYBOARD_K                  0x0E
-#define HID_KEYBOARD_L                  0x0F
-#define HID_KEYBOARD_M                  0x10
-#define HID_KEYBOARD_N                  0x11
-#define HID_KEYBOARD_O                  0x12
-#define HID_KEYBOARD_P                  0x13
-#define HID_KEYBOARD_Q                  0x14
-#define HID_KEYBOARD_R                  0x15
-#define HID_KEYBOARD_S                  0x16
-#define HID_KEYBOARD_T                  0x17
-#define HID_KEYBOARD_U                  0x18
-#define HID_KEYBOARD_V                  0x19
-#define HID_KEYBOARD_W                  0x1A
-#define HID_KEYBOARD_X                  0x1B
-#define HID_KEYBOARD_Y                  0x1C
-#define HID_KEYBOARD_Z                  0x1D
-#define HID_KEYBOARD_1                  0x1E
-#define HID_KEYBOARD_2                  0x1F
-#define HID_KEYBOARD_3                  0x20
-#define HID_KEYBOARD_4                  0x21
-#define HID_KEYBOARD_5                  0x22
-#define HID_KEYBOARD_6                  0x23
-#define HID_KEYBOARD_7                  0x24
-#define HID_KEYBOARD_8                  0x25
-#define HID_KEYBOARD_9                  0x26
-#define HID_KEYBOARD_0                  0x27
-#define HID_KEYBOARD_RETURN             0x28
-#define HID_KEYBOARD_ESCAPE             0x29
-#define HID_KEYBOARD_DELETE             0x2A
-#define HID_KEYBOARD_TAB                0x2B
-#define HID_KEYBOARD_SPACEBAR           0x2C
-#define HID_KEYBOARD_MINUS              0x2D
-#define HID_KEYBOARD_EQUAL_SIGN         0x2E
-#define HID_KEYBOARD_OPEN_BRACKET       0x2F
-#define HID_KEYBOARD_CLOSE_BRACKET      0x30
-#define HID_KEYBOARD_BACKSLASH          0x31
-#define HID_KEYBOARD_NONUS_HASH         0x32
-#define HID_KEYBOARD_SEMICOLON          0x33
-#define HID_KEYBOARD_APOSTROPHE         0x34
-#define HID_KEYBOARD_GRAVE_ACCENT       0x35
-#define HID_KEYBOARD_COLON              0x36
-#define HID_KEYBOARD_DOT                0x37
-#define HID_KEYBOARD_SLASH              0x38
-#define HID_KEYBOARD_CAPS_LOCK          0x39
-#define HID_KEYBOARD_F1                 0x3A
-#define HID_KEYBOARD_F2                 0x3B
-#define HID_KEYBOARD_F3                 0x3C
-#define HID_KEYBOARD_F4                 0x3D
-#define HID_KEYBOARD_F5                 0x3E
-#define HID_KEYBOARD_F6                 0x3F
-#define HID_KEYBOARD_F7                 0x40
-#define HID_KEYBOARD_F8                 0x41
-#define HID_KEYBOARD_F9                 0x42
-#define HID_KEYBOARD_F10                0x43
-#define HID_KEYBOARD_F11                0x44
-#define HID_KEYBOARD_F12                0x45
-#define HID_KEYBOARD_PRINT_SCREEN       0x46
-#define HID_KEYBOARD_SCROLL_LOCK        0x47
-#define HID_KEYBOARD_PAUSE              0x48
-#define HID_KEYBOARD_INSERT             0x49
-#define HID_KEYBOARD_HOME               0x4A
-#define HID_KEYBOARD_PAGE_UP            0x4B
-#define HID_KEYBOARD_DELETE_FORWARD     0x4C
-#define HID_KEYBOARD_END                0x4D
-#define HID_KEYBOARD_PAGE_DOWN          0x4E
-#define HID_KEYBOARD_RIGHT_ARROW        0x4F
-#define HID_KEYBOARD_LEFT_ARROW         0x50
-#define HID_KEYBOARD_DOWN_ARROW         0x51
-#define HID_KEYBOARD_UP_ARROW           0x52
-#define HID_KEYPAD_NUMLOCK              0x53
-#define HID_KEYPAD_SLASH                0x54
-#define HID_KEYPAD_ASTERISK             0x55
-#define HID_KEYPAD_MINUS                0x56
-#define HID_KEYPAD_PLUS                 0x57
-#define HID_KEYPAD_ENTER                0x58
-#define HID_KEYPAD_1                    0x59
-#define HID_KEYPAD_2                    0x5A
-#define HID_KEYPAD_3                    0x5B
-#define HID_KEYPAD_4                    0x5C
-#define HID_KEYPAD_5                    0x5D
-#define HID_KEYPAD_6                    0x5E
-#define HID_KEYPAD_7                    0x5F
-#define HID_KEYPAD_8                    0x60
-#define HID_KEYPAD_9                    0x61
-#define HID_KEYPAD_0                    0x62
-#define HID_KEYPAD_DOT                  0x63
-#define HID_KEYBOARD_NONUS_BACKSLASH    0x64
-#define HID_KEYBOARD_APPLICATION        0x65
-#define HID_KEYBOARD_POWER              0x66
-#define HID_KEYPAD_EQUAL                0x67
-#define HID_KEYBOARD_F13                0x68
-#define HID_KEYBOARD_F14                0x69
-#define HID_KEYBOARD_F15                0x6A
-#define HID_KEYBOARD_F16                0x6B
-#define HID_KEYBOARD_F17                0x6C
-#define HID_KEYBOARD_F18                0x6D
-#define HID_KEYBOARD_F19                0x6E
-#define HID_KEYBOARD_F20                0x6F
-#define HID_KEYBOARD_F21                0x70
-#define HID_KEYBOARD_F22                0x71
-#define HID_KEYBOARD_F23                0x72
-#define HID_KEYBOARD_F24                0x73
-#define HID_KEYBOARD_EXECUTE            0x74
-#define HID_KEYBOARD_HELP               0x75
-#define HID_KEYBOARD_MENU               0x76
-#define HID_KEYBOARD_SELECT             0x77
-#define HID_KEYBOARD_STOP               0x78
-#define HID_KEYBOARD_AGAIN              0x79
-#define HID_KEYBOARD_UNDO               0x7A
-#define HID_KEYBOARD_CUT                0x7B
-#define HID_KEYBOARD_COPY               0x7C
-#define HID_KEYBOARD_PASTE              0x7D
-#define HID_KEYBOARD_FIND               0x7E
-#define HID_KEYBOARD_MUTE               0x7F
-#define HID_KEYBOARD_VOLUME_UP          0x80
-#define HID_KEYBOARD_VOLUME_DOWN        0x81
-#define HID_KEYBOARD_LOCK_CAPS_LOCK     0x82
-#define HID_KEYBOARD_LOCK_NUM_LOCK      0x83
-#define HID_KEYBOARD_LOCK_SCROLL_LOCK   0x84
-#define HID_KEYPAD_COMMA                0x85
-#define HID_KEYPAD_EQUAL_SIGN           0x86
-#define HID_KEYBOARD_INTERNATIONAL_1    0x87
-#define HID_KEYBOARD_INTERNATIONAL_2    0x88
-#define HID_KEYBOARD_INTERNATIONAL_3    0x89
-#define HID_KEYBOARD_INTERNATIONAL_4    0x8A
-#define HID_KEYBOARD_INTERNATIONAL_5    0x8B
-#define HID_KEYBOARD_INTERNATIONAL_6    0x8C
-#define HID_KEYBOARD_INTERNATIONAL_7    0x8D
-#define HID_KEYBOARD_INTERNATIONAL_8    0x8E
-#define HID_KEYBOARD_INTERNATIONAL_9    0x8F
-#define HID_KEYBOARD_LANG_1             0x90
-#define HID_KEYBOARD_LANG_2             0x91
-#define HID_KEYBOARD_LANG_3             0x92
-#define HID_KEYBOARD_LANG_4             0x93
-#define HID_KEYBOARD_LANG_5             0x94
-#define HID_KEYBOARD_LANG_6             0x95
-#define HID_KEYBOARD_LANG_7             0x96
-#define HID_KEYBOARD_LANG_8             0x97
-#define HID_KEYBOARD_LANG_9             0x98
-#define HID_KEYBOARD_ALTERNATE_ERASE    0x99
-#define HID_KEYBOARD_SYSREQ             0x9A
-#define HID_KEYBOARD_CANCEL             0x9B
-#define HID_KEYBOARD_CLEAR              0x9C
-#define HID_KEYBOARD_PRIOR              0x9D
-#define HID_KEYBOARD_RETURN_1           0x9E
-#define HID_KEYBOARD_SEPARATOR          0x9F
-#define HID_KEYBOARD_OUT                0xA0
-#define HID_KEYBOARD_OPER               0xA1
-#define HID_KEYBOARD_CLEAR_AGAIN        0xA2
-#define HID_KEYBOARD_CRSEL_PROPS        0xA3
-#define HID_KEYBOARD_EXSEL              0xA4
-#define HID_KEYPAD_00                   0xB0
-#define HID_KEYPAD_000                  0xB1
-#define HID_KEYPAD_OPEN_PARENTHESIS     0xB6
-#define HID_KEYPAD_CLOSE_PARENTHESIS    0xB7
-#define HID_KEYPAD_OPEN_BRACE           0xB8
-#define HID_KEYPAD_CLOSE_BRACE          0xB9
-#define HID_KEYPAD_TAB                  0xBA
-#define HID_KEYPAD_BACKSPACE            0xBB
-#define HID_KEYPAD_A                    0xBC
-#define HID_KEYPAD_B                    0xBD
-#define HID_KEYPAD_C                    0xBE
-#define HID_KEYPAD_D                    0xBF
-#define HID_KEYPAD_E                    0xC0
-#define HID_KEYPAD_F                    0xC1
-#define HID_KEYPAD_XOR                  0xC2
-#define HID_KEYPAD_CARET                0xC3
-#define HID_KEYPAD_PERCENT              0xC4
-#define HID_KEYPAD_LESS_THEN            0xC5
-#define HID_KEYPAD_GREATER_THEN         0xC6
-#define HID_KEYPAD_AMPERSAND            0xC7
-#define HID_KEYPAD_DOUBLE_AMPERSAND     0xC8
-#define HID_KEYPAD_PIPE                 0xC9
-#define HID_KEYPAD_DOUBLE_PIPE          0xCA
-#define HID_KEYPAD_COLON                0xCB
-#define HID_KEYPAD_HASH                 0xCC
-#define HID_KEYPAD_SPACE                0xCD
-#define HID_KEYPAD_AT                   0xCE
-#define HID_KEYPAD_BANG                 0xCF
-#define HID_KEYPAD_MEM_STORE            0xD0
-#define HID_KEYPAD_MEM_RECALL           0xD1
-#define HID_KEYPAD_MEM_CLEAR            0xD2
-#define HID_KEYPAD_MEM_ADD              0xD3
-#define HID_KEYPAD_MEM_SUBTRACT         0xD4
-#define HID_KEYPAD_MEM_MULTIPLY         0xD5
-#define HID_KEYPAD_MEM_DIVIDE           0xD6
-#define HID_KEYPAD_PLUS_MINUS           0xD7
-#define HID_KEYPAD_CLEAR                0xD8
-#define HID_KEYPAD_CLEAR_ENTRY          0xD9
-#define HID_KEYPAD_BINARY               0xDA
-#define HID_KEYPAD_OCTAL                0xDB
-#define HID_KEYPAD_DECIMAL              0xDC
-#define HID_KEYPAD_HEXADECIMAL          0xDD
-#define HID_KEYBOARD_L_CTRL             0xE0
-#define HID_KEYBOARD_L_SHIFT            0xE1
-#define HID_KEYBOARD_L_ALT              0xE2
-#define HID_KEYBOARD_L_GUI              0xE3
-#define HID_KEYBOARD_R_CTRL             0xE4
-#define HID_KEYBOARD_R_SHIFT            0xE5
-#define HID_KEYBOARD_R_ALT              0xE6
-#define HID_KEYBOARD_R_GUI              0xE7
-
-/** @}  */
-
-#endif
-
+/* This file is the part of the LUS32 project
+ *
+ * Copyright ©2016 Dmitry Filimonchuk <dmitrystu[at]gmail[dot]com>
+ *
+ * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ * 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.
+ */
+#ifndef _USB_HID_USAGE_KEYBOARD_H_
+#define _USB_HID_USAGE_KEYBOARD_H_
+
+/**\ingroup USB_HID
+ * \addtogroup ISB_HID_USAGES_KEYBOARD HID Usages for Keyboard
+ * \brief Contains USB HID Usages definitions for Keyboard/Keypad Page
+ * \details This module based on
+ * + [HID Usage Tables Version 1.12](http://www.usb.org/developers/hidpage/Hut1_12v2.pdf)
+ * @{ */
+
+#define HID_PAGE_KEYBOARD               0x07
+
+#define HID_KEYBOARD_ERR_ROLL_OVER      0x01
+#define HID_KEYBOARD_POST_FAIL          0x02
+#define HID_KEYBOARD_ERR_UNDEFINED      0x03
+#define HID_KEYBOARD_A                  0x04
+#define HID_KEYBOARD_B                  0x05
+#define HID_KEYBOARD_C                  0x06
+#define HID_KEYBOARD_D                  0x07
+#define HID_KEYBOARD_E                  0x08
+#define HID_KEYBOARD_F                  0x09
+#define HID_KEYBOARD_G                  0x0A
+#define HID_KEYBOARD_H                  0x0B
+#define HID_KEYBOARD_I                  0x0C
+#define HID_KEYBOARD_J                  0x0D
+#define HID_KEYBOARD_K                  0x0E
+#define HID_KEYBOARD_L                  0x0F
+#define HID_KEYBOARD_M                  0x10
+#define HID_KEYBOARD_N                  0x11
+#define HID_KEYBOARD_O                  0x12
+#define HID_KEYBOARD_P                  0x13
+#define HID_KEYBOARD_Q                  0x14
+#define HID_KEYBOARD_R                  0x15
+#define HID_KEYBOARD_S                  0x16
+#define HID_KEYBOARD_T                  0x17
+#define HID_KEYBOARD_U                  0x18
+#define HID_KEYBOARD_V                  0x19
+#define HID_KEYBOARD_W                  0x1A
+#define HID_KEYBOARD_X                  0x1B
+#define HID_KEYBOARD_Y                  0x1C
+#define HID_KEYBOARD_Z                  0x1D
+#define HID_KEYBOARD_1                  0x1E
+#define HID_KEYBOARD_2                  0x1F
+#define HID_KEYBOARD_3                  0x20
+#define HID_KEYBOARD_4                  0x21
+#define HID_KEYBOARD_5                  0x22
+#define HID_KEYBOARD_6                  0x23
+#define HID_KEYBOARD_7                  0x24
+#define HID_KEYBOARD_8                  0x25
+#define HID_KEYBOARD_9                  0x26
+#define HID_KEYBOARD_0                  0x27
+#define HID_KEYBOARD_RETURN             0x28
+#define HID_KEYBOARD_ESCAPE             0x29
+#define HID_KEYBOARD_DELETE             0x2A
+#define HID_KEYBOARD_TAB                0x2B
+#define HID_KEYBOARD_SPACEBAR           0x2C
+#define HID_KEYBOARD_MINUS              0x2D
+#define HID_KEYBOARD_EQUAL_SIGN         0x2E
+#define HID_KEYBOARD_OPEN_BRACKET       0x2F
+#define HID_KEYBOARD_CLOSE_BRACKET      0x30
+#define HID_KEYBOARD_BACKSLASH          0x31
+#define HID_KEYBOARD_NONUS_HASH         0x32
+#define HID_KEYBOARD_SEMICOLON          0x33
+#define HID_KEYBOARD_APOSTROPHE         0x34
+#define HID_KEYBOARD_GRAVE_ACCENT       0x35
+#define HID_KEYBOARD_COLON              0x36
+#define HID_KEYBOARD_DOT                0x37
+#define HID_KEYBOARD_SLASH              0x38
+#define HID_KEYBOARD_CAPS_LOCK          0x39
+#define HID_KEYBOARD_F1                 0x3A
+#define HID_KEYBOARD_F2                 0x3B
+#define HID_KEYBOARD_F3                 0x3C
+#define HID_KEYBOARD_F4                 0x3D
+#define HID_KEYBOARD_F5                 0x3E
+#define HID_KEYBOARD_F6                 0x3F
+#define HID_KEYBOARD_F7                 0x40
+#define HID_KEYBOARD_F8                 0x41
+#define HID_KEYBOARD_F9                 0x42
+#define HID_KEYBOARD_F10                0x43
+#define HID_KEYBOARD_F11                0x44
+#define HID_KEYBOARD_F12                0x45
+#define HID_KEYBOARD_PRINT_SCREEN       0x46
+#define HID_KEYBOARD_SCROLL_LOCK        0x47
+#define HID_KEYBOARD_PAUSE              0x48
+#define HID_KEYBOARD_INSERT             0x49
+#define HID_KEYBOARD_HOME               0x4A
+#define HID_KEYBOARD_PAGE_UP            0x4B
+#define HID_KEYBOARD_DELETE_FORWARD     0x4C
+#define HID_KEYBOARD_END                0x4D
+#define HID_KEYBOARD_PAGE_DOWN          0x4E
+#define HID_KEYBOARD_RIGHT_ARROW        0x4F
+#define HID_KEYBOARD_LEFT_ARROW         0x50
+#define HID_KEYBOARD_DOWN_ARROW         0x51
+#define HID_KEYBOARD_UP_ARROW           0x52
+#define HID_KEYPAD_NUMLOCK              0x53
+#define HID_KEYPAD_SLASH                0x54
+#define HID_KEYPAD_ASTERISK             0x55
+#define HID_KEYPAD_MINUS                0x56
+#define HID_KEYPAD_PLUS                 0x57
+#define HID_KEYPAD_ENTER                0x58
+#define HID_KEYPAD_1                    0x59
+#define HID_KEYPAD_2                    0x5A
+#define HID_KEYPAD_3                    0x5B
+#define HID_KEYPAD_4                    0x5C
+#define HID_KEYPAD_5                    0x5D
+#define HID_KEYPAD_6                    0x5E
+#define HID_KEYPAD_7                    0x5F
+#define HID_KEYPAD_8                    0x60
+#define HID_KEYPAD_9                    0x61
+#define HID_KEYPAD_0                    0x62
+#define HID_KEYPAD_DOT                  0x63
+#define HID_KEYBOARD_NONUS_BACKSLASH    0x64
+#define HID_KEYBOARD_APPLICATION        0x65
+#define HID_KEYBOARD_POWER              0x66
+#define HID_KEYPAD_EQUAL                0x67
+#define HID_KEYBOARD_F13                0x68
+#define HID_KEYBOARD_F14                0x69
+#define HID_KEYBOARD_F15                0x6A
+#define HID_KEYBOARD_F16                0x6B
+#define HID_KEYBOARD_F17                0x6C
+#define HID_KEYBOARD_F18                0x6D
+#define HID_KEYBOARD_F19                0x6E
+#define HID_KEYBOARD_F20                0x6F
+#define HID_KEYBOARD_F21                0x70
+#define HID_KEYBOARD_F22                0x71
+#define HID_KEYBOARD_F23                0x72
+#define HID_KEYBOARD_F24                0x73
+#define HID_KEYBOARD_EXECUTE            0x74
+#define HID_KEYBOARD_HELP               0x75
+#define HID_KEYBOARD_MENU               0x76
+#define HID_KEYBOARD_SELECT             0x77
+#define HID_KEYBOARD_STOP               0x78
+#define HID_KEYBOARD_AGAIN              0x79
+#define HID_KEYBOARD_UNDO               0x7A
+#define HID_KEYBOARD_CUT                0x7B
+#define HID_KEYBOARD_COPY               0x7C
+#define HID_KEYBOARD_PASTE              0x7D
+#define HID_KEYBOARD_FIND               0x7E
+#define HID_KEYBOARD_MUTE               0x7F
+#define HID_KEYBOARD_VOLUME_UP          0x80
+#define HID_KEYBOARD_VOLUME_DOWN        0x81
+#define HID_KEYBOARD_LOCK_CAPS_LOCK     0x82
+#define HID_KEYBOARD_LOCK_NUM_LOCK      0x83
+#define HID_KEYBOARD_LOCK_SCROLL_LOCK   0x84
+#define HID_KEYPAD_COMMA                0x85
+#define HID_KEYPAD_EQUAL_SIGN           0x86
+#define HID_KEYBOARD_INTERNATIONAL_1    0x87
+#define HID_KEYBOARD_INTERNATIONAL_2    0x88
+#define HID_KEYBOARD_INTERNATIONAL_3    0x89
+#define HID_KEYBOARD_INTERNATIONAL_4    0x8A
+#define HID_KEYBOARD_INTERNATIONAL_5    0x8B
+#define HID_KEYBOARD_INTERNATIONAL_6    0x8C
+#define HID_KEYBOARD_INTERNATIONAL_7    0x8D
+#define HID_KEYBOARD_INTERNATIONAL_8    0x8E
+#define HID_KEYBOARD_INTERNATIONAL_9    0x8F
+#define HID_KEYBOARD_LANG_1             0x90
+#define HID_KEYBOARD_LANG_2             0x91
+#define HID_KEYBOARD_LANG_3             0x92
+#define HID_KEYBOARD_LANG_4             0x93
+#define HID_KEYBOARD_LANG_5             0x94
+#define HID_KEYBOARD_LANG_6             0x95
+#define HID_KEYBOARD_LANG_7             0x96
+#define HID_KEYBOARD_LANG_8             0x97
+#define HID_KEYBOARD_LANG_9             0x98
+#define HID_KEYBOARD_ALTERNATE_ERASE    0x99
+#define HID_KEYBOARD_SYSREQ             0x9A
+#define HID_KEYBOARD_CANCEL             0x9B
+#define HID_KEYBOARD_CLEAR              0x9C
+#define HID_KEYBOARD_PRIOR              0x9D
+#define HID_KEYBOARD_RETURN_1           0x9E
+#define HID_KEYBOARD_SEPARATOR          0x9F
+#define HID_KEYBOARD_OUT                0xA0
+#define HID_KEYBOARD_OPER               0xA1
+#define HID_KEYBOARD_CLEAR_AGAIN        0xA2
+#define HID_KEYBOARD_CRSEL_PROPS        0xA3
+#define HID_KEYBOARD_EXSEL              0xA4
+#define HID_KEYPAD_00                   0xB0
+#define HID_KEYPAD_000                  0xB1
+#define HID_KEYPAD_OPEN_PARENTHESIS     0xB6
+#define HID_KEYPAD_CLOSE_PARENTHESIS    0xB7
+#define HID_KEYPAD_OPEN_BRACE           0xB8
+#define HID_KEYPAD_CLOSE_BRACE          0xB9
+#define HID_KEYPAD_TAB                  0xBA
+#define HID_KEYPAD_BACKSPACE            0xBB
+#define HID_KEYPAD_A                    0xBC
+#define HID_KEYPAD_B                    0xBD
+#define HID_KEYPAD_C                    0xBE
+#define HID_KEYPAD_D                    0xBF
+#define HID_KEYPAD_E                    0xC0
+#define HID_KEYPAD_F                    0xC1
+#define HID_KEYPAD_XOR                  0xC2
+#define HID_KEYPAD_CARET                0xC3
+#define HID_KEYPAD_PERCENT              0xC4
+#define HID_KEYPAD_LESS_THEN            0xC5
+#define HID_KEYPAD_GREATER_THEN         0xC6
+#define HID_KEYPAD_AMPERSAND            0xC7
+#define HID_KEYPAD_DOUBLE_AMPERSAND     0xC8
+#define HID_KEYPAD_PIPE                 0xC9
+#define HID_KEYPAD_DOUBLE_PIPE          0xCA
+#define HID_KEYPAD_COLON                0xCB
+#define HID_KEYPAD_HASH                 0xCC
+#define HID_KEYPAD_SPACE                0xCD
+#define HID_KEYPAD_AT                   0xCE
+#define HID_KEYPAD_BANG                 0xCF
+#define HID_KEYPAD_MEM_STORE            0xD0
+#define HID_KEYPAD_MEM_RECALL           0xD1
+#define HID_KEYPAD_MEM_CLEAR            0xD2
+#define HID_KEYPAD_MEM_ADD              0xD3
+#define HID_KEYPAD_MEM_SUBTRACT         0xD4
+#define HID_KEYPAD_MEM_MULTIPLY         0xD5
+#define HID_KEYPAD_MEM_DIVIDE           0xD6
+#define HID_KEYPAD_PLUS_MINUS           0xD7
+#define HID_KEYPAD_CLEAR                0xD8
+#define HID_KEYPAD_CLEAR_ENTRY          0xD9
+#define HID_KEYPAD_BINARY               0xDA
+#define HID_KEYPAD_OCTAL                0xDB
+#define HID_KEYPAD_DECIMAL              0xDC
+#define HID_KEYPAD_HEXADECIMAL          0xDD
+#define HID_KEYBOARD_L_CTRL             0xE0
+#define HID_KEYBOARD_L_SHIFT            0xE1
+#define HID_KEYBOARD_L_ALT              0xE2
+#define HID_KEYBOARD_L_GUI              0xE3
+#define HID_KEYBOARD_R_CTRL             0xE4
+#define HID_KEYBOARD_R_SHIFT            0xE5
+#define HID_KEYBOARD_R_ALT              0xE6
+#define HID_KEYBOARD_R_GUI              0xE7
+
+/** @}  */
+
+#endif
+

+ 107 - 107
inc/hid_usage_led.h

@@ -1,107 +1,107 @@
-/* This file is the part of the LUS32 project
- *
- * Copyright ©2016 Dmitry Filimonchuk <dmitrystu[at]gmail[dot]com>
- *
- * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
- * 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.
- */
-
-#ifndef _USB_HID_USAGE_LED_H_
-#define _USB_HID_USAGE_LED_H_
-
-/**\ingroup USB_HID
- * \addtogroup ISB_HID_USAGES_DEVICE HID Usages for LED's
- * \brief Contains USB HID Usages definitions for LED's Control Page
- * \details This module based on
- * + [HID Usage Tables Version 1.12](http://www.usb.org/developers/hidpage/Hut1_12v2.pdf)
- * @{ */
-
-#define HID_PAGE_LED                    0x08
-
-#define HID_LED_NUM_LOCK                0x01
-#define HID_LED_CAPS_LOCK               0x02
-#define HID_LED_SCROLL_LOCK             0x03
-#define HID_LED_COMPOSE                 0x04
-#define HID_LED_KANA                    0x05
-#define HID_LED_POWER                   0x06
-#define HID_LED_SHIFT                   0x07
-#define HID_LED_DO_NOT_DISTURB          0x08
-#define HID_LED_MUTE                    0x09
-#define HID_LED_TONE_ENABLE             0x0A
-#define HID_LED_HIGH_CUT_FILTER         0x0B
-#define HID_LED_LOW_CUT_FILTER          0x0C
-#define HID_LED_EQUALIZER_ENABLE        0x0D
-#define HID_LED_SOUND_FIELD_ON          0x0E
-#define HID_LED_SURROUND_ON             0x0F
-#define HID_LED_REPEAT                  0x10
-#define HID_LED_STEREO                  0x11
-#define HID_LED_SAMPLING_RATE_DETECT    0x12
-#define HID_LED_SPINNING                0x13
-#define HID_LED_CAV                     0x14
-#define HID_LED_CLV                     0x15
-#define HID_LED_REC_FORMAT_DETECT       0x16
-#define HID_LED_OFF_HOOK                0x17
-#define HID_LED_RING                    0x18
-#define HID_LED_MESSAGE_WAITING         0x19
-#define HID_LED_DATA_MODE               0x1A
-#define HID_LED_BATTERY_OPERATION       0x1B
-#define HID_LED_BATTERY_OK              0x1C
-#define HID_LED_BATTERY_LOW             0x1D
-#define HID_LED_SPEAKER                 0x1E
-#define HID_LED_HEADSET                 0x1F
-#define HID_LED_HOLD                    0x20
-#define HID_LED_MICROPHONE              0x21
-#define HID_LED_COVERAGE                0x22
-#define HID_LED_NIGHT_MODE              0x23
-#define HID_LED_SEND_CALLS              0x24
-#define HID_LED_CALL_PICKUP             0x25
-#define HID_LED_CONFERENCE              0x26
-#define HID_LED_STANDBY                 0x27
-#define HID_LED_CAMERA_ON               0x28
-#define HID_LED_CAMERA_OFF              0x29
-#define HID_LED_ONLINE                  0x2A
-#define HID_LED_OFFLINE                 0x2B
-#define HID_LED_BUSY                    0x2C
-#define HID_LED_READY                   0x2D
-#define HID_LED_PAPER_OUT               0x2E
-#define HID_LED_PAPER_JAM               0x2F
-#define HID_LED_REMOTE                  0x30
-#define HID_LED_FORWARD                 0x31
-#define HID_LED_REVERSE                 0x32
-#define HID_LED_STOP                    0x33
-#define HID_LED_REWIND                  0x34
-#define HID_LED_FAST_FORWARD            0x35
-#define HID_LED_PLAY                    0x36
-#define HID_LED_PAUSE                   0x37
-#define HID_LED_RECORD                  0x38
-#define HID_LED_ERROR                   0x39
-#define HID_LED_USAGE_SELECTED_IND      0x3A
-#define HID_LED_USAGE_INUSE_IND         0x3B
-#define HID_LED_USAGE_MULTIMODE_IND     0x3C
-#define HID_LED_INDICATOR_ON            0x3D
-#define HID_LED_INDICATOR_FLASH         0x3E
-#define HID_LED_INDICATOR_SLOW_BLINK    0x3F
-#define HID_LED_INDICATOR_FAST_BLINK    0x40
-#define HID_LED_INDICATOR_OFF           0x41
-#define HID_LED_FLASH_ON_TIME           0x42
-#define HID_LED_SLOW_BLINK_ON_TIME      0x43
-#define HID_LED_SLOW_BLINK_OFF_TIME     0x44
-#define HID_LED_FAST_BLINK_ON_TIME      0x45
-#define HID_LED_FAST_BLINK_OFF_TIME     0x46
-#define HID_LED_USAGE_INDICATOR_COLOR   0x47
-#define HID_LED_INDICATOR_RED           0x48
-#define HID_LED_INDICATOR_GREEN         0x49
-#define HID_LED_INDICATOR_AMBER         0x4A
-#define HID_LED_GENERIC_INDICATOR       0x4B
-#define HID_LED_SYSTEM_SUSPEND          0x4C
-#define HID_LED_EXT_POWER_CONNECTED     0x4D
-
-#endif
-
+/* This file is the part of the LUS32 project
+ *
+ * Copyright ©2016 Dmitry Filimonchuk <dmitrystu[at]gmail[dot]com>
+ *
+ * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ * 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.
+ */
+
+#ifndef _USB_HID_USAGE_LED_H_
+#define _USB_HID_USAGE_LED_H_
+
+/**\ingroup USB_HID
+ * \addtogroup ISB_HID_USAGES_DEVICE HID Usages for LED's
+ * \brief Contains USB HID Usages definitions for LED's Control Page
+ * \details This module based on
+ * + [HID Usage Tables Version 1.12](http://www.usb.org/developers/hidpage/Hut1_12v2.pdf)
+ * @{ */
+
+#define HID_PAGE_LED                    0x08
+
+#define HID_LED_NUM_LOCK                0x01
+#define HID_LED_CAPS_LOCK               0x02
+#define HID_LED_SCROLL_LOCK             0x03
+#define HID_LED_COMPOSE                 0x04
+#define HID_LED_KANA                    0x05
+#define HID_LED_POWER                   0x06
+#define HID_LED_SHIFT                   0x07
+#define HID_LED_DO_NOT_DISTURB          0x08
+#define HID_LED_MUTE                    0x09
+#define HID_LED_TONE_ENABLE             0x0A
+#define HID_LED_HIGH_CUT_FILTER         0x0B
+#define HID_LED_LOW_CUT_FILTER          0x0C
+#define HID_LED_EQUALIZER_ENABLE        0x0D
+#define HID_LED_SOUND_FIELD_ON          0x0E
+#define HID_LED_SURROUND_ON             0x0F
+#define HID_LED_REPEAT                  0x10
+#define HID_LED_STEREO                  0x11
+#define HID_LED_SAMPLING_RATE_DETECT    0x12
+#define HID_LED_SPINNING                0x13
+#define HID_LED_CAV                     0x14
+#define HID_LED_CLV                     0x15
+#define HID_LED_REC_FORMAT_DETECT       0x16
+#define HID_LED_OFF_HOOK                0x17
+#define HID_LED_RING                    0x18
+#define HID_LED_MESSAGE_WAITING         0x19
+#define HID_LED_DATA_MODE               0x1A
+#define HID_LED_BATTERY_OPERATION       0x1B
+#define HID_LED_BATTERY_OK              0x1C
+#define HID_LED_BATTERY_LOW             0x1D
+#define HID_LED_SPEAKER                 0x1E
+#define HID_LED_HEADSET                 0x1F
+#define HID_LED_HOLD                    0x20
+#define HID_LED_MICROPHONE              0x21
+#define HID_LED_COVERAGE                0x22
+#define HID_LED_NIGHT_MODE              0x23
+#define HID_LED_SEND_CALLS              0x24
+#define HID_LED_CALL_PICKUP             0x25
+#define HID_LED_CONFERENCE              0x26
+#define HID_LED_STANDBY                 0x27
+#define HID_LED_CAMERA_ON               0x28
+#define HID_LED_CAMERA_OFF              0x29
+#define HID_LED_ONLINE                  0x2A
+#define HID_LED_OFFLINE                 0x2B
+#define HID_LED_BUSY                    0x2C
+#define HID_LED_READY                   0x2D
+#define HID_LED_PAPER_OUT               0x2E
+#define HID_LED_PAPER_JAM               0x2F
+#define HID_LED_REMOTE                  0x30
+#define HID_LED_FORWARD                 0x31
+#define HID_LED_REVERSE                 0x32
+#define HID_LED_STOP                    0x33
+#define HID_LED_REWIND                  0x34
+#define HID_LED_FAST_FORWARD            0x35
+#define HID_LED_PLAY                    0x36
+#define HID_LED_PAUSE                   0x37
+#define HID_LED_RECORD                  0x38
+#define HID_LED_ERROR                   0x39
+#define HID_LED_USAGE_SELECTED_IND      0x3A
+#define HID_LED_USAGE_INUSE_IND         0x3B
+#define HID_LED_USAGE_MULTIMODE_IND     0x3C
+#define HID_LED_INDICATOR_ON            0x3D
+#define HID_LED_INDICATOR_FLASH         0x3E
+#define HID_LED_INDICATOR_SLOW_BLINK    0x3F
+#define HID_LED_INDICATOR_FAST_BLINK    0x40
+#define HID_LED_INDICATOR_OFF           0x41
+#define HID_LED_FLASH_ON_TIME           0x42
+#define HID_LED_SLOW_BLINK_ON_TIME      0x43
+#define HID_LED_SLOW_BLINK_OFF_TIME     0x44
+#define HID_LED_FAST_BLINK_ON_TIME      0x45
+#define HID_LED_FAST_BLINK_OFF_TIME     0x46
+#define HID_LED_USAGE_INDICATOR_COLOR   0x47
+#define HID_LED_INDICATOR_RED           0x48
+#define HID_LED_INDICATOR_GREEN         0x49
+#define HID_LED_INDICATOR_AMBER         0x4A
+#define HID_LED_GENERIC_INDICATOR       0x4B
+#define HID_LED_SYSTEM_SUSPEND          0x4C
+#define HID_LED_EXT_POWER_CONNECTED     0x4D
+
+#endif
+

+ 45 - 45
inc/hid_usage_ordinal.h

@@ -1,45 +1,45 @@
-/* This file is the part of the LUS32 project
- *
- * Copyright ©2016 Dmitry Filimonchuk <dmitrystu[at]gmail[dot]com>
- *
- * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
- * 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.
- */
-
-#ifndef _USB_HID_USAGE_ORDINAL_H_
-#define _USB_HID_USAGE_ORDINAL_H_
-#ifdef __cplusplus
-    extern "C" {
-#endif
-
-
-/**\ingroup USB_HID
- * \addtogroup USB_HID_USAGES_ORDINAL HID Usage Tables for Ordinal
- * \brief Contains USB HID Usages definitions for Ordinal Page
- * \details This module based on
- * + [HID Usage Tables Version 1.12](http://www.usb.org/developers/hidpage/Hut1_12v2.pdf)
- * @{ */
-
-#define HID_PAGE_ORDINAL                0x0A
-
-#define HID_ORDINAL_INSTANCE_1          0x01
-#define HID_ORDINAL_INSTANCE_2          0x02
-#define HID_ORDINAL_INSTANCE_3          0x03
-#define HID_ORDINAL_INSTANCE_4          0x04
-#define HID_ORDINAL_INSTANCE_5          0x05
-
-/** @}  */
-
-#ifdef __cplusplus
-    }
-#endif
-
-#endif
-
+/* This file is the part of the LUS32 project
+ *
+ * Copyright ©2016 Dmitry Filimonchuk <dmitrystu[at]gmail[dot]com>
+ *
+ * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ * 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.
+ */
+
+#ifndef _USB_HID_USAGE_ORDINAL_H_
+#define _USB_HID_USAGE_ORDINAL_H_
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+
+/**\ingroup USB_HID
+ * \addtogroup USB_HID_USAGES_ORDINAL HID Usage Tables for Ordinal
+ * \brief Contains USB HID Usages definitions for Ordinal Page
+ * \details This module based on
+ * + [HID Usage Tables Version 1.12](http://www.usb.org/developers/hidpage/Hut1_12v2.pdf)
+ * @{ */
+
+#define HID_PAGE_ORDINAL                0x0A
+
+#define HID_ORDINAL_INSTANCE_1          0x01
+#define HID_ORDINAL_INSTANCE_2          0x02
+#define HID_ORDINAL_INSTANCE_3          0x03
+#define HID_ORDINAL_INSTANCE_4          0x04
+#define HID_ORDINAL_INSTANCE_5          0x05
+
+/** @}  */
+
+#ifdef __cplusplus
+    }
+#endif
+
+#endif
+

+ 91 - 91
inc/hid_usage_simulation.h

@@ -1,91 +1,91 @@
-/* This file is the part of the LUS32 project
- *
- * Copyright ©2016 Dmitry Filimonchuk <dmitrystu[at]gmail[dot]com>
- *
- * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
- * 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.
- */
-
-#ifndef _USB_HID_USAGE_SIMUL_H_
-#define _USB_HID_USAGE_SUMUL_H_
-#ifdef __cplusplus
-    extern "C" {
-#endif
-
-
-/**\ingroup USB_HID
- * \addtogroup USB_HID_USAGES HID Usage Tables for Simulation
- * \brief Contains USB HID Usages definitions for Simulation Controls Page
- * \details This module based on
- * + [HID Usage Tables Version 1.12](http://www.usb.org/developers/hidpage/Hut1_12v2.pdf)
- * @{ */
-
-#define HID_PAGE_SIMULATION             0x02
-
-#define HID_SIMUL_FLIGHT                0x01
-#define HID_SIMUL_AUTOMOBILE            0x02
-#define HID_SIMUL_TANK                  0x03
-#define HID_SIMUL_SPACESHIP             0x04
-#define HID_SIMUL_SUBMARINE             0x05
-#define HID_SIMUL_SAILING               0x06
-#define HID_SIMUL_MOTOCYCLE             0x07
-#define HID_SIMUL_SPORTS                0x08
-#define HID_SIMUL_AIRPLANE              0x09
-#define HID_SIMUL_HELICOPTER            0x0A
-#define HID_SIMUL_MAGIC_CARPET          0x0B
-#define HID_SIMUL_BICYCLE               0x0C
-#define HID_SIMUL_FLIGHT_CONTROL_STICK  0x20
-#define HID_SIMUL_FLIGHT_STICK          0x21
-#define HID_SIMUL_CYCLIC_CONTROL        0x22
-#define HID_SIMUL_CYCLIC_TRIM           0x23
-#define HID_SIMUL_FLIGHT_YOKE           0x24
-#define HID_SIMUL_TRACK_CONTROL         0x25
-#define HID_SIMUL_ALIERON               0xB0
-#define HID_SIMUL_ALIERIN_TRIM          0xB1
-#define HID_SIMUL_ANTI_TORQUE           0xB2
-#define HID_SIMUL_AUTOPILOT_ENABLE      0xB3
-#define HID_SIMUL_CHAFF_RELEASE         0xB4
-#define HID_SIMUL_COLLECTIVE_CONTROL    0xB5
-#define HID_SIMUL_DRIVE_BRAKE           0xB6
-#define HID_SIMUL_ELECTR_COUNTERMEAS    0xB7
-#define HID_SIMUL_ELEVATOR              0xB8
-#define HID_SIMUL_ELEVATOR_TRIM         0xB9
-#define HID_SIMUL_RUDDER                0xBA
-#define HID_SIMUL_THROTTLE              0xBB
-#define HID_SIMUL_FLIGHT_COMM           0xBC
-#define HID_SIMUL_FLARE_RELEASE         0xBD
-#define HID_SIMUL_LANDING_GEAR          0xBE
-#define HID_SIMUL_TOE_BRAKE             0xBF
-#define HID_SIMUL_TRIGGER               0xC0
-#define HID_SIMUL_WEAPONS_ARM           0xC1
-#define HID_SIMUL_WEAPONS_SELECT        0xC2
-#define HID_SIMUL_WING_FLAPS            0xC3
-#define HID_SIMUL_ACCELERATOR           0xC4
-#define HID_SIMUL_BRAKE                 0xC5
-#define HID_SIMUL_CLUTCH                0xC6
-#define HID_SIMUL_SHIFTER               0xC7
-#define HID_SIMUL_STEERING              0xC8
-#define HID_SIMUL_TURRET_DIRECTION      0xC9
-#define HID_SIMUL_BARREL_ELEVATION      0xCA
-#define HID_SIMUL_DRIVE_PLANE           0xCB
-#define HID_SIMUL_BALLAST               0xCC
-#define HID_SIMUL_BICYCLE_CRANK         0xCD
-#define HID_SIMUL_HANDLE_BARS           0xCE
-#define HID_SIMUL_FRONT_BRAKE           0xCF
-#define HID_SIMUL_REAR_BRAKE            0xD0
-
-/** @}  */
-
-#ifdef __cplusplus
-    }
-#endif
-
-#endif
-
+/* This file is the part of the LUS32 project
+ *
+ * Copyright ©2016 Dmitry Filimonchuk <dmitrystu[at]gmail[dot]com>
+ *
+ * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ * 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.
+ */
+
+#ifndef _USB_HID_USAGE_SIMUL_H_
+#define _USB_HID_USAGE_SUMUL_H_
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+
+/**\ingroup USB_HID
+ * \addtogroup USB_HID_USAGES HID Usage Tables for Simulation
+ * \brief Contains USB HID Usages definitions for Simulation Controls Page
+ * \details This module based on
+ * + [HID Usage Tables Version 1.12](http://www.usb.org/developers/hidpage/Hut1_12v2.pdf)
+ * @{ */
+
+#define HID_PAGE_SIMULATION             0x02
+
+#define HID_SIMUL_FLIGHT                0x01
+#define HID_SIMUL_AUTOMOBILE            0x02
+#define HID_SIMUL_TANK                  0x03
+#define HID_SIMUL_SPACESHIP             0x04
+#define HID_SIMUL_SUBMARINE             0x05
+#define HID_SIMUL_SAILING               0x06
+#define HID_SIMUL_MOTOCYCLE             0x07
+#define HID_SIMUL_SPORTS                0x08
+#define HID_SIMUL_AIRPLANE              0x09
+#define HID_SIMUL_HELICOPTER            0x0A
+#define HID_SIMUL_MAGIC_CARPET          0x0B
+#define HID_SIMUL_BICYCLE               0x0C
+#define HID_SIMUL_FLIGHT_CONTROL_STICK  0x20
+#define HID_SIMUL_FLIGHT_STICK          0x21
+#define HID_SIMUL_CYCLIC_CONTROL        0x22
+#define HID_SIMUL_CYCLIC_TRIM           0x23
+#define HID_SIMUL_FLIGHT_YOKE           0x24
+#define HID_SIMUL_TRACK_CONTROL         0x25
+#define HID_SIMUL_ALIERON               0xB0
+#define HID_SIMUL_ALIERIN_TRIM          0xB1
+#define HID_SIMUL_ANTI_TORQUE           0xB2
+#define HID_SIMUL_AUTOPILOT_ENABLE      0xB3
+#define HID_SIMUL_CHAFF_RELEASE         0xB4
+#define HID_SIMUL_COLLECTIVE_CONTROL    0xB5
+#define HID_SIMUL_DRIVE_BRAKE           0xB6
+#define HID_SIMUL_ELECTR_COUNTERMEAS    0xB7
+#define HID_SIMUL_ELEVATOR              0xB8
+#define HID_SIMUL_ELEVATOR_TRIM         0xB9
+#define HID_SIMUL_RUDDER                0xBA
+#define HID_SIMUL_THROTTLE              0xBB
+#define HID_SIMUL_FLIGHT_COMM           0xBC
+#define HID_SIMUL_FLARE_RELEASE         0xBD
+#define HID_SIMUL_LANDING_GEAR          0xBE
+#define HID_SIMUL_TOE_BRAKE             0xBF
+#define HID_SIMUL_TRIGGER               0xC0
+#define HID_SIMUL_WEAPONS_ARM           0xC1
+#define HID_SIMUL_WEAPONS_SELECT        0xC2
+#define HID_SIMUL_WING_FLAPS            0xC3
+#define HID_SIMUL_ACCELERATOR           0xC4
+#define HID_SIMUL_BRAKE                 0xC5
+#define HID_SIMUL_CLUTCH                0xC6
+#define HID_SIMUL_SHIFTER               0xC7
+#define HID_SIMUL_STEERING              0xC8
+#define HID_SIMUL_TURRET_DIRECTION      0xC9
+#define HID_SIMUL_BARREL_ELEVATION      0xCA
+#define HID_SIMUL_DRIVE_PLANE           0xCB
+#define HID_SIMUL_BALLAST               0xCC
+#define HID_SIMUL_BICYCLE_CRANK         0xCD
+#define HID_SIMUL_HANDLE_BARS           0xCE
+#define HID_SIMUL_FRONT_BRAKE           0xCF
+#define HID_SIMUL_REAR_BRAKE            0xD0
+
+/** @}  */
+
+#ifdef __cplusplus
+    }
+#endif
+
+#endif
+

+ 74 - 74
inc/hid_usage_sport.h

@@ -1,74 +1,74 @@
-/* This file is the part of the LUS32 project
- *
- * Copyright ©2016 Dmitry Filimonchuk <dmitrystu[at]gmail[dot]com>
- *
- * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
- * 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.
- */
-
-#ifndef _USB_HID_USAGE_SPORT_H_
-#define _USB_HID_USAGE_SPORT_H_
-#ifdef __cplusplus
-    extern "C" {
-#endif
-
-
-/**\ingroup USB_HID
- * \addtogroup USB_HID_USAGES_SPORT HID Usage Tables for Sport
- * \brief Contains USB HID Usages definitions for Sport Controls Page
- * \details This module based on
- * + [HID Usage Tables Version 1.12](http://www.usb.org/developers/hidpage/Hut1_12v2.pdf)
- * @{ */
-
-#define HID_PAGE_SPORT                  0x04
-
-#define HID_SPORT_BASEBALL_BAT          0x01
-#define HID_SPORT_GOLF_CLUB             0x02
-#define HID_SPORT_ROWING_MACHINE        0x03
-#define HID_SPORT_TREADMILL             0x04
-#define HID_SPORT_OAR                   0x30
-#define HID_SPORT_SLOPE                 0x31
-#define HID_SPORT_RATE                  0x32
-#define HID_SPORT_STICK_SPEED           0x33
-#define HID_SPORT_STICK_FACE_ANGLE      0x34
-#define HID_SPORT_STICK_HEEL_TOE        0x35
-#define HID_SPORT_STICK_FOLLOW_THROUGH  0x36
-#define HID_SPORT_STICK_TEMPO           0x37
-#define HID_SPORT_STICK_TYPE            0x38
-#define HID_SPORT_STICK_HEIGHT          0x39
-#define HID_SPORT_PUTTER                0x50
-#define HID_SPORT_1_IRON                0x51
-#define HID_SPORT_2_IRON                0x52
-#define HID_SPORT_3_IRON                0x53
-#define HID_SPORT_4_IRON                0x54
-#define HID_SPORT_5_IRON                0x55
-#define HID_SPORT_6_IRON                0x56
-#define HID_SPORT_7_IRON                0x57
-#define HID_SPORT_8_IRON                0x58
-#define HID_SPORT_9_IRON                0x59
-#define HID_SPORT_10_IRON               0x5A
-#define HID_SPORT_11_IRON               0x5B
-#define HID_SPORT_SAND_WEDGE            0x5C
-#define HID_SPORT_LOFT_WEDGE            0x5D
-#define HID_SPORT_POWER_WEDGE           0x5E
-#define HID_SPORT_1_WOOD                0x5F
-#define HID_SPORT_3_WOOD                0x60
-#define HID_SPORT_5_WOOD                0x61
-#define HID_SPORT_7_WOOD                0x62
-#define HID_SPORT_9_WOOD                0x63
-
-/** @}  */
-
-#ifdef __cplusplus
-    }
-#endif
-
-#endif
-
+/* This file is the part of the LUS32 project
+ *
+ * Copyright ©2016 Dmitry Filimonchuk <dmitrystu[at]gmail[dot]com>
+ *
+ * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ * 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.
+ */
+
+#ifndef _USB_HID_USAGE_SPORT_H_
+#define _USB_HID_USAGE_SPORT_H_
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+
+/**\ingroup USB_HID
+ * \addtogroup USB_HID_USAGES_SPORT HID Usage Tables for Sport
+ * \brief Contains USB HID Usages definitions for Sport Controls Page
+ * \details This module based on
+ * + [HID Usage Tables Version 1.12](http://www.usb.org/developers/hidpage/Hut1_12v2.pdf)
+ * @{ */
+
+#define HID_PAGE_SPORT                  0x04
+
+#define HID_SPORT_BASEBALL_BAT          0x01
+#define HID_SPORT_GOLF_CLUB             0x02
+#define HID_SPORT_ROWING_MACHINE        0x03
+#define HID_SPORT_TREADMILL             0x04
+#define HID_SPORT_OAR                   0x30
+#define HID_SPORT_SLOPE                 0x31
+#define HID_SPORT_RATE                  0x32
+#define HID_SPORT_STICK_SPEED           0x33
+#define HID_SPORT_STICK_FACE_ANGLE      0x34
+#define HID_SPORT_STICK_HEEL_TOE        0x35
+#define HID_SPORT_STICK_FOLLOW_THROUGH  0x36
+#define HID_SPORT_STICK_TEMPO           0x37
+#define HID_SPORT_STICK_TYPE            0x38
+#define HID_SPORT_STICK_HEIGHT          0x39
+#define HID_SPORT_PUTTER                0x50
+#define HID_SPORT_1_IRON                0x51
+#define HID_SPORT_2_IRON                0x52
+#define HID_SPORT_3_IRON                0x53
+#define HID_SPORT_4_IRON                0x54
+#define HID_SPORT_5_IRON                0x55
+#define HID_SPORT_6_IRON                0x56
+#define HID_SPORT_7_IRON                0x57
+#define HID_SPORT_8_IRON                0x58
+#define HID_SPORT_9_IRON                0x59
+#define HID_SPORT_10_IRON               0x5A
+#define HID_SPORT_11_IRON               0x5B
+#define HID_SPORT_SAND_WEDGE            0x5C
+#define HID_SPORT_LOFT_WEDGE            0x5D
+#define HID_SPORT_POWER_WEDGE           0x5E
+#define HID_SPORT_1_WOOD                0x5F
+#define HID_SPORT_3_WOOD                0x60
+#define HID_SPORT_5_WOOD                0x61
+#define HID_SPORT_7_WOOD                0x62
+#define HID_SPORT_9_WOOD                0x63
+
+/** @}  */
+
+#ifdef __cplusplus
+    }
+#endif
+
+#endif
+

+ 105 - 105
inc/hid_usage_telephony.h

@@ -1,105 +1,105 @@
-/* This file is the part of the LUS32 project
- *
- * Copyright ©2016 Dmitry Filimonchuk <dmitrystu[at]gmail[dot]com>
- *
- * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
- * 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.
- */
-
-#ifndef _USB_HID_USAGE_TELEPHONY_H_
-#define _USB_HID_USAGE_TELEPHONY_H_
-#ifdef __cplusplus
-    extern "C" {
-#endif
-
-
-/**\ingroup USB_HID
- * \addtogroup USB_HID_USAGES_TELEPHONY HID Usage Tables for Telephony
- * \brief Contains USB HID Usages definitions for Telephony Page
- * \details This module based on
- * + [HID Usage Tables Version 1.12](http://www.usb.org/developers/hidpage/Hut1_12v2.pdf)
- * @{ */
-
-#define HID_PAGE_TELEPHONY              0x0B
-
-#define HID_PHONE_PHONE                 0x01
-#define HID_PHONE_ANSWERING_MACHINE     0x02
-#define HID_PHONE_MESSAGE_CONTROLS      0x03
-#define HID_PHONE_HANDSET               0x04
-#define HID_PHONE_HEADSET               0x05
-#define HID_PHONE_TELEPHONY_KEYPAD      0x06
-#define HID_PHONE_PROGRAMMABLE_BUTTON   0x07
-#define HID_PHONE_HOOK_SWITCH           0x20
-#define HID_PHONE_FLASH                 0x21
-#define HID_PHONE_FEATURE               0x22
-#define HID_PHONE_HOLD                  0x23
-#define HID_PHONE_REDIAL                0x24
-#define HID_PHONE_TRANSFER              0x25
-#define HID_PHONE_DROP                  0x26
-#define HID_PHONE_PARK                  0x27
-#define HID_PHONE_FORWARD_CALLS         0x28
-#define HID_PHONE_ALTERNATE_FUNCTION    0x29
-#define HID_PHONE_LINE                  0x2A
-#define HID_PHONE_SPEAKERPHONE          0x2B
-#define HID_PHONE_CONFERENCE            0x2C
-#define HID_PHONE_RING_ENABLE           0x2D
-#define HID_PHONE_RING_SELECT           0x2E
-#define HID_PHONE_PHONE_MUTE            0x2F
-#define HID_PHONE_CALLER_ID             0x30
-#define HID_PHONE_SEND                  0x31
-#define HID_PHONE_SPEED_DIAL            0x50
-#define HID_PHONE_STORE_NUMBER          0x51
-#define HID_PHONE_RECALL_NUMBER         0x52
-#define HID_PHONE_PHONE_DIRECTORY       0x53
-#define HID_PHONE_VOICE_MAIL            0x70
-#define HID_PHONE_SCREEN_CALLS          0x71
-#define HID_PHONE_DO_NOT_DISTURB        0x72
-#define HID_PHONE_MESSAGE               0x73
-#define HID_PHONE_ANSWER_ON_OFF         0x74
-#define HID_PHONE_INSIDE_DIAL_TONE      0x90
-#define HID_PHONE_OUTSIDE_DIAL_TONE     0x91
-#define HID_PHONE_INSIDE_RING_TONE      0x92
-#define HID_PHONE_OUTSIDE_RING_TONE     0x93
-#define HID_PHONE_PRIORITY_RING_TONE    0x94
-#define HID_PHONE_INSIDE_RINGBACK       0x95
-#define HID_PHONE_PRIORITY_RINGBACK     0x96
-#define HID_PHONE_LINE_BUSY_TONE        0x97
-#define HID_PHONE_REORDER_TONE          0x98
-#define HID_PHONE_CALL_WAITING_TONE     0x99
-#define HID_PHONE_CONFIRMATION_TONE_1   0x9A
-#define HID_PHONE_CONFIRMATION_TONE_2   0x9B
-#define HID_PHONE_TONES_OFF             0x9C
-#define HID_PHONE_OUTSIDE_RINGBACK      0x9D
-#define HID_PHONE_RINGER                0x9E
-#define HID_PHONE_KEY_0                 0xB0
-#define HID_PHONE_KEY_1                 0xB1
-#define HID_PHONE_KEY_2                 0xB2
-#define HID_PHONE_KEY_3                 0xB3
-#define HID_PHONE_KEY_4                 0xB4
-#define HID_PHONE_KEY_5                 0xB5
-#define HID_PHONE_KEY_6                 0xB6
-#define HID_PHONE_KEY_7                 0xB7
-#define HID_PHONE_KEY_8                 0xB8
-#define HID_PHONE_KEY_9                 0xB9
-#define HID_PHONE_KEY_STAR              0xBA
-#define HID_PHONE_KEY_POUND             0xBB
-#define HID_PHONE_KEY_A                 0xBC
-#define HID_PHONE_KEY_B                 0xBD
-#define HID_PHONE_KEY_C                 0xBE
-#define HID_PHONE_KEY_D                 0xBF
-
-/** @}  */
-
-#ifdef __cplusplus
-    }
-#endif
-
-#endif
-
+/* This file is the part of the LUS32 project
+ *
+ * Copyright ©2016 Dmitry Filimonchuk <dmitrystu[at]gmail[dot]com>
+ *
+ * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ * 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.
+ */
+
+#ifndef _USB_HID_USAGE_TELEPHONY_H_
+#define _USB_HID_USAGE_TELEPHONY_H_
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+
+/**\ingroup USB_HID
+ * \addtogroup USB_HID_USAGES_TELEPHONY HID Usage Tables for Telephony
+ * \brief Contains USB HID Usages definitions for Telephony Page
+ * \details This module based on
+ * + [HID Usage Tables Version 1.12](http://www.usb.org/developers/hidpage/Hut1_12v2.pdf)
+ * @{ */
+
+#define HID_PAGE_TELEPHONY              0x0B
+
+#define HID_PHONE_PHONE                 0x01
+#define HID_PHONE_ANSWERING_MACHINE     0x02
+#define HID_PHONE_MESSAGE_CONTROLS      0x03
+#define HID_PHONE_HANDSET               0x04
+#define HID_PHONE_HEADSET               0x05
+#define HID_PHONE_TELEPHONY_KEYPAD      0x06
+#define HID_PHONE_PROGRAMMABLE_BUTTON   0x07
+#define HID_PHONE_HOOK_SWITCH           0x20
+#define HID_PHONE_FLASH                 0x21
+#define HID_PHONE_FEATURE               0x22
+#define HID_PHONE_HOLD                  0x23
+#define HID_PHONE_REDIAL                0x24
+#define HID_PHONE_TRANSFER              0x25
+#define HID_PHONE_DROP                  0x26
+#define HID_PHONE_PARK                  0x27
+#define HID_PHONE_FORWARD_CALLS         0x28
+#define HID_PHONE_ALTERNATE_FUNCTION    0x29
+#define HID_PHONE_LINE                  0x2A
+#define HID_PHONE_SPEAKERPHONE          0x2B
+#define HID_PHONE_CONFERENCE            0x2C
+#define HID_PHONE_RING_ENABLE           0x2D
+#define HID_PHONE_RING_SELECT           0x2E
+#define HID_PHONE_PHONE_MUTE            0x2F
+#define HID_PHONE_CALLER_ID             0x30
+#define HID_PHONE_SEND                  0x31
+#define HID_PHONE_SPEED_DIAL            0x50
+#define HID_PHONE_STORE_NUMBER          0x51
+#define HID_PHONE_RECALL_NUMBER         0x52
+#define HID_PHONE_PHONE_DIRECTORY       0x53
+#define HID_PHONE_VOICE_MAIL            0x70
+#define HID_PHONE_SCREEN_CALLS          0x71
+#define HID_PHONE_DO_NOT_DISTURB        0x72
+#define HID_PHONE_MESSAGE               0x73
+#define HID_PHONE_ANSWER_ON_OFF         0x74
+#define HID_PHONE_INSIDE_DIAL_TONE      0x90
+#define HID_PHONE_OUTSIDE_DIAL_TONE     0x91
+#define HID_PHONE_INSIDE_RING_TONE      0x92
+#define HID_PHONE_OUTSIDE_RING_TONE     0x93
+#define HID_PHONE_PRIORITY_RING_TONE    0x94
+#define HID_PHONE_INSIDE_RINGBACK       0x95
+#define HID_PHONE_PRIORITY_RINGBACK     0x96
+#define HID_PHONE_LINE_BUSY_TONE        0x97
+#define HID_PHONE_REORDER_TONE          0x98
+#define HID_PHONE_CALL_WAITING_TONE     0x99
+#define HID_PHONE_CONFIRMATION_TONE_1   0x9A
+#define HID_PHONE_CONFIRMATION_TONE_2   0x9B
+#define HID_PHONE_TONES_OFF             0x9C
+#define HID_PHONE_OUTSIDE_RINGBACK      0x9D
+#define HID_PHONE_RINGER                0x9E
+#define HID_PHONE_KEY_0                 0xB0
+#define HID_PHONE_KEY_1                 0xB1
+#define HID_PHONE_KEY_2                 0xB2
+#define HID_PHONE_KEY_3                 0xB3
+#define HID_PHONE_KEY_4                 0xB4
+#define HID_PHONE_KEY_5                 0xB5
+#define HID_PHONE_KEY_6                 0xB6
+#define HID_PHONE_KEY_7                 0xB7
+#define HID_PHONE_KEY_8                 0xB8
+#define HID_PHONE_KEY_9                 0xB9
+#define HID_PHONE_KEY_STAR              0xBA
+#define HID_PHONE_KEY_POUND             0xBB
+#define HID_PHONE_KEY_A                 0xBC
+#define HID_PHONE_KEY_B                 0xBD
+#define HID_PHONE_KEY_C                 0xBE
+#define HID_PHONE_KEY_D                 0xBF
+
+/** @}  */
+
+#ifdef __cplusplus
+    }
+#endif
+
+#endif
+

+ 44 - 44
inc/hid_usage_vr.h

@@ -1,44 +1,44 @@
-/* This file is the part of the LUS32 project
- *
- * Copyright ©2016 Dmitry Filimonchuk <dmitrystu[at]gmail[dot]com>
- *
- * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
- * 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.
- */
-
-#ifndef _USB_HID_USAGE_VR_H_
-#define _USB_HID_USAGE_VR_H_
-
-/**\ingroup USB_HID
- * \addtogroup USB_HID_USAGES_VR HID Usage Tables for VR
- * \brief Contains USB HID Usages definitions for VR Control Page
- * \details This module based on
- * + [HID Usage Tables Version 1.12](http://www.usb.org/developers/hidpage/Hut1_12v2.pdf)
- * @{ */
-
-#define HID_PAGE_VR                     0x03
-
-#define HID_VR_BELT                     0x01
-#define HID_VR_BODY_SUIT                0x02
-#define HID_VR_FLEXTOR                  0x03
-#define HID_VR_GLOVE                    0x04
-#define HID_VR_HEAD_TRACKER             0x05
-#define HID_VR_HEAD_MOUNTED_DISPLAY     0x06
-#define HID_VR_HAND_TRACKER             0x07
-#define HID_VR_OCULOMETER               0x08
-#define HID_VR_VEST                     0x09
-#define HID_VR_ANIMATRONIC_DEVICE       0x0A
-#define HID_VR_STEREO_ENABLE            0x20
-#define HID_VR_DISPLAY_ENABLE           0x21
-
-/** @}  */
-
-#endif
-
+/* This file is the part of the LUS32 project
+ *
+ * Copyright ©2016 Dmitry Filimonchuk <dmitrystu[at]gmail[dot]com>
+ *
+ * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ * 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.
+ */
+
+#ifndef _USB_HID_USAGE_VR_H_
+#define _USB_HID_USAGE_VR_H_
+
+/**\ingroup USB_HID
+ * \addtogroup USB_HID_USAGES_VR HID Usage Tables for VR
+ * \brief Contains USB HID Usages definitions for VR Control Page
+ * \details This module based on
+ * + [HID Usage Tables Version 1.12](http://www.usb.org/developers/hidpage/Hut1_12v2.pdf)
+ * @{ */
+
+#define HID_PAGE_VR                     0x03
+
+#define HID_VR_BELT                     0x01
+#define HID_VR_BODY_SUIT                0x02
+#define HID_VR_FLEXTOR                  0x03
+#define HID_VR_GLOVE                    0x04
+#define HID_VR_HEAD_TRACKER             0x05
+#define HID_VR_HEAD_MOUNTED_DISPLAY     0x06
+#define HID_VR_HAND_TRACKER             0x07
+#define HID_VR_OCULOMETER               0x08
+#define HID_VR_VEST                     0x09
+#define HID_VR_ANIMATRONIC_DEVICE       0x0A
+#define HID_VR_STEREO_ENABLE            0x20
+#define HID_VR_DISPLAY_ENABLE           0x21
+
+/** @}  */
+
+#endif
+

+ 226 - 226
inc/usb_cdc.h

@@ -1,226 +1,226 @@
-/* This file is the part of the LUS32 project
- *
- * Copyright ©2016 Dmitry Filimonchuk <dmitrystu[at]gmail[dot]com>
- *
- * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
- * 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.
- */
-#ifndef _USB_CDC_H_
-#define _USB_CDC_H_
-
-#ifdef __cplusplus
-    extern "C" {
-#endif
-
-/**\addtogroup USB_CDC USB CDC class
- * \brief Generic USB CDC class definitions
- * \details This module based on
- * + Universal Serial Bus Class Definitions for Communications Devices Revision 1.2 (Errata 1)
- * @{ */
-
-/**\name USB CDC Class codes
- * @{ */
-#define USB_CLASS_CDC                       0x02 /**< Device/Interface belongs to the Communicational device class */
-#define USB_CLASS_CDC_DATA                  0x0A /**< Interface belongs to the Data Interface class */
-/** @} */
-
-/**\name USB CDC subclass codes
- * @{ */
-#define USB_CDC_SUBCLASS_ACM                0x02 /**< Abstract Control Model */ 
- /** @} */
-
-/**\name Communications Class Protocol Codes
- * @{ */
-#define USB_CDC_PROTO_V25TER                0x01 /**< AT Commands: V.250 etc */
- /** @} */
-
-
-/** \name Data Interface Class Protocol Codes 
- * @{ */
-#define USB_CDC_PROTO_NTB                   0x01 /**< Network Transfer Block */ 
-#define USB_CDC_PROTO_HOST                  0xFD /**< Host based driver. \note This protocol code should only be used in messages between
-                                                  * host and device to identify the host driver portion of a protocol stack.*/
-#define USB_CDC_PROTO_CDCSPEC               0xFE /**< The protocol(s) are described using a Protocol Unit Functional Descriptors on Communication Class Interface.*/
-/** @} */
-
-/**\name USB CDC class-specified functional descriptors 
- * @{ */
-#define USB_DTYPE_CDC_HEADER                0x00 /**< Header Functional Descriptor. \ref usb_cdc_header_desc */
-#define USB_DTYPE_CDC_CALL_MANAGEMENT       0x01 /**< Call Management Functional Descriptor. \ref usb_cdc_call_mgmt_desc */ 
-#define USB_DTYPE_CDC_ACM                   0x02 /**< Abstract Control Management Functional Descriptor. \ref usb_cdc_acm_desc */
-#define USB_DTYPE_CDC_UNION                 0x06 /**< Union Functional descriptor */
-#define USB_DTYPE_CDC_COUNTRY               0x07 /**< Country Selection Functional Descriptor */
-/** @} */
-
-
-
-/** \name USB CDC class-specific requests
- * @{ */
-#define USB_CDC_SEND_ENCAPSULATED_CMD       0x00 /**< Used to issue a command in the format of the supported control protocol of the Communication Class interface. */
-#define USB_CDC_GET_ENCAPSULATED_RESP       0x01 /**< Used to request a response in the format of the supported control protocol of the Communication Class interface. */
-#define USB_CDC_SET_COMM_FEATURE            0x02 /**< Controls the settings for a particular communication feature of a particular target */
-#define USB_CDC_GET_COMM_FEATURE            0x03 /**< Returns the current settings for the communication feature as selected */
-#define USB_CDC_CLEAR_COMM_FEATURE          0x04 /**< Controls the settings for a particular communication feature of a particular 
-                                                  * target, setting the selected feature to its default state. */
-#define USB_CDC_SET_LINE_CODING             0x20 /**< Allows the host to specify typical asynchronous line-character formatting properties. */
-#define USB_CDC_GET_LINE_CODING             0x21 /**< Allows the host to find out the currently configured line coding. */
-#define USB_CDC_SET_CONTROL_LINE_STATE      0x22 /**< Generates RS-232/V.24 style control signals. */
-#define USB_CDC_SEND_BREAK                  0x23 /**< Sends special carrier modulation that generates an RS-232 style break. */
-/** @} */
-
-
-/**\name Generic CDC specific notifications
- * @{ */
-#define USB_CDC_NTF_NETWORK_CONNECTION      0x00  /**< Allows the device to notify the host about network connection status. */
-#define USB_CDC_NTF_RESPONSE_AVAILABLE      0x01  /**< Allows the device to notify the host that a response is available. */
-#define USB_CDC_NTF_SERIAL_STATE            0x20  /**< Sends asynchronous notification of UART status. */ 
-#define USB_CDC_NTF_SPEED_CHANGE            0x2A  /**< allows the device to inform the host-networking driver that a change in either the uplink 
-                                                   * or the downlink bit rate of the connection has occurred. */
-/** @} */
-
-
-/**\anchor USB_CDC_ACMGMNTCAP
- * \name USB CDC Abstract Control Management capabilities 
- * @{ */
-#define USB_CDC_COMM_FEATURE                0x01 /**< Supports the request combination of Set_Comm_Feature, Clear_Comm_Feature, and Get_Comm_Feature. */
-#define USB_CDC_CAP_LINE                    0x02 /**< Supports the request combination of Set_Line_Coding, Set_Control_Line_State, Get_Line_Coding, and the notification Serial_State. */
-#define USB_CDC_CAP_BRK                     0x04 /**< Supports the request Send_Break */
-#define USB_CDC_CAP_NOTIFY                  0x08 /**< Supports notification Network_Connection. */
-/** @} */
-
-/**\anchor USB_CDC_CALLMGMTCAP
- * \name USB CDC Call Management capabilities
- * @{ */
-#define USB_CDC_CALL_MGMT_CAP_CALL_MGMT     0x01 /**< Device handles call management itself. */
-#define USB_CDC_CALL_MGMT_CAP_DATA_INTF     0x02 /**< Device can send/receive call management information over a Data Class interface. */
-/** @} */
-
-/**\anchor USB_CDC_LINECODE
- * \name Line coding structire bit fields
- * @{ */
-#define USB_CDC_1_STOP_BITS                 0x00
-#define USB_CDC_1_5_STOP_BITS               0x01
-#define USB_CDC_2_STOP_BITS                 0x02
-
-#define USB_CDC_NO_PARITY                   0x00
-#define USB_CDC_ODD_PARITY                  0x01
-#define USB_CDC_EVEN_PARITY                 0x02
-#define USB_CDC_MARK_PARITY                 0x03
-#define USB_CDC_SPACE_PARITY                0x04
-/** @} */
-
-/**\name SERIAL_STATE notification data values
- * @{ */
-#define USB_CDC_STATE_RX_CARRIER          0x0001 /**< State of receiver carrier detection mechanism of device. This signal corresponds to V.24 signal 109 and RS-232 signal DCD. */
-#define USB_CDC_STATE_TX_CARRIER          0x0002 /**< State of transmission carrier. This signal corresponds to V.24 signal 106 and RS-232 signal DSR. */
-#define USB_CDC_STATE_BREAK               0x0004 /**< State of break detection mechanism of the device. */
-#define USB_CDC_STATE_RING                0x0008 /**< State of ring signal detection of the device. */
-#define USB_CDC_STATE_FRAMING             0x0010 /**< A framing error has occurred. */
-#define USB_CDC_STATE_PARITY              0x0020 /**< A parity error has occurred. */
-#define USB_CDC_STATE_OVERRUN             0x0040 /**< Received data has been discarded due to overrun in the device */
-/** @} */
-
-/** \brief Header Functional Descriptor
- * \details Header Functional Descriptor marks the beginning of the concatenated set of functional descriptors for the interface. */
-
-struct usb_cdc_header_desc {
-    uint8_t     bFunctionLength;    /**< Size of this descriptor in bytes. */
-    uint8_t     bDescriptorType;    /**< CS_INTERFACE descriptor type. \see \ref USB_DTYPE_CS_INTERFACE */
-    uint8_t     bDescriptorSubType; /**< Header functional descriptor subtype \ref USB_DTYPE_CDC_HEADER */
-    uint16_t    bcdCDC;             /**< USB CDC Specification release number in binary-coded decimal. \see \ref VERSION_BCD macro */
-} __attribute__ ((packed));
-
-/** \brief Union Functional Descriptor
- * \details The Union functional descriptor describes the relationship between a group of interfaces that can be considered to form
- * a functional unit. It can only occur within the class-specific portion of an Interface descriptor. One of the interfaces in
- * the group is designated as a master or controlling interface for the group, and certain class-specific messages can be
- * sent to this interface to act upon the group as a whole.
- */
-struct usb_cdc_union_desc {
-    uint8_t     bFunctionLength;    /**< Size of this functional descriptor, in bytes. */
-    uint8_t     bDescriptorType;    /**< CS_INTERFACE descriptor type. \see \ref USB_DTYPE_CS_INTERFACE */
-    uint8_t     bDescriptorSubType; /**< Union Functional Descriptor. \ref USB_DTYPE_CDC_UNION */
-    uint8_t     bMasterInterface0;  /**< The interface number of the CDC interface, designated as the master or controlling interface for the union. */
-    uint8_t     bSlaveInterface0;   /**< Interface number of first slave or associated interface in the union. */
-    /* ... and there could be other slave interfaces */
-} __attribute__ ((packed));
-
-/** \brief Country Selection Functional Descriptor
- * \details The Country Selection functional descriptor identifies the countries in which the communication device is qualified to
- * operate. The parameters of the network connection often vary from one country to another, especially in Europe. Also
- * legal requirements impose certain restrictions on devices because of different regulations by the governing body of the
- * network to which the device must adhere. This descriptor can only occur within the class-specific portion of an
- * Interface descriptor and should only be provided to a master Communication Class interface of a union. The country
- * codes used in the Country Selection Functional Descriptor are not the same as the country codes used in dialing
- * international telephone calls. Implementers should refer to the ISO 3166 specification for more information.
- */
-struct usb_cdc_country_desc {
-    uint8_t     bFunctionLength;     /**< Size of this functional descriptor, in bytes. */
-    uint8_t     bDescriptorType;     /**< CS_INTERFACE descriptor type. \see \ref USB_DTYPE_CS_INTERFACE */
-    uint8_t     bDescriptorSubType;  /**< Country Selection Functional Descriptor \ref USB_DTYPE_CDC_COUNTRY */
-    uint8_t     iCountryCodeRelDate; /**< Index of a string giving the release date for the implemented ISO 3166 Country Codes. */
-    uint8_t     wCountyCode0;        /**< Country code in hexadecimal format as defined in ISO 3166, release date as specified
-                                      * in iCountryCodeRelDate for the first supported country. */
-    /* ... and there can be a lot of country codes */
-} __attribute__ ((packed));
-
-/** \brief Call Management Functional Descriptor.
- * \details The Call Management functional descriptor describes the processing of calls for the Communication Class interface. It
- * can only occur within the class-specific portion of an Interface descriptor.
- */
-struct usb_cdc_call_mgmt_desc {
-    uint8_t     bFunctionLength;    /**< Size of this functional descriptor, in bytes. */
-    uint8_t     bDescriptorType;    /**< CS_INTERFACE descriptor type. \see \ref USB_DTYPE_CS_INTERFACE */
-    uint8_t     bDescriptorSubType; /**< Call Management functional descriptor subtype \ref USB_DTYPE_CDC_CALL_MANAGEMENT */
-    uint8_t     bmCapabilities;     /**< The \ref USB_CDC_CALLMGMTCAP "capabilities" that this configuration supports */
-    uint8_t     bDataInterface;     /**< Interface number of Data Class interface optionally used for call management. */
-} __attribute__ ((packed));
-
-/** \brief Abstract Control Management Functional Descriptor
- * \details The Abstract Control Management functional descriptor describes the commands supported by the Communication
- * Class interface, as defined in Section 3.6.2, with the SubClass code of Abstract Control Model. It can only occur
- * within the class-specific portion of an Interface descriptor.
- */
-struct usb_cdc_acm_desc {
-    uint8_t     bFunctionLength;    /**< Size of this functional descriptor, in bytes. */
-    uint8_t     bDescriptorType;    /**< CS_INTERFACE descriptor type. \see \ref USB_DTYPE_CS_INTERFACE */
-    uint8_t     bDescriptorSubType; /**< Abstract Control Management functional descriptor subtype \ref USB_DTYPE_CDC_ACM */
-    uint8_t     bmCapabilities;     /**< The \ref USB_CDC_ACMGMNTCAP "capabilities" that this configuration supports */
-} __attribute__ ((packed));
-
-///\brief Notification structure from CDC
-struct usb_cdc_notification {
-    uint8_t     bmRequestType;
-    uint8_t     bNotificationType;
-    uint16_t    wValue;
-    uint16_t    wIndex;
-    uint16_t    wLength;
-    uint8_t     Data[];
-} __attribute__ ((packed));
-
-/**\brief Line Coding Structure
- * \details used in GET_LINE_CODING and SET_LINE_CODING requests
- */
-struct usb_cdc_line_coding {
-    uint32_t    dwDTERate;          /**< Data terminal rate, in bits per second. */
-    uint8_t     bCharFormat;        /**< Stop bits */
-    uint8_t     bParityType;        /**< Parity */
-    uint8_t     bDataBits;          /**< Data bits (5,6,7,8 or 16) */
-} __attribute__ ((packed));
-
-
-/** @} */
-
-
-#ifdef __cplusplus
-    }
-#endif
-
-#endif /* _USB_CDC_H_ */
+/* This file is the part of the LUS32 project
+ *
+ * Copyright ©2016 Dmitry Filimonchuk <dmitrystu[at]gmail[dot]com>
+ *
+ * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ * 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.
+ */
+#ifndef _USB_CDC_H_
+#define _USB_CDC_H_
+
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+/**\addtogroup USB_CDC USB CDC class
+ * \brief Generic USB CDC class definitions
+ * \details This module based on
+ * + Universal Serial Bus Class Definitions for Communications Devices Revision 1.2 (Errata 1)
+ * @{ */
+
+/**\name USB CDC Class codes
+ * @{ */
+#define USB_CLASS_CDC                       0x02 /**< Device/Interface belongs to the Communicational device class */
+#define USB_CLASS_CDC_DATA                  0x0A /**< Interface belongs to the Data Interface class */
+/** @} */
+
+/**\name USB CDC subclass codes
+ * @{ */
+#define USB_CDC_SUBCLASS_ACM                0x02 /**< Abstract Control Model */ 
+ /** @} */
+
+/**\name Communications Class Protocol Codes
+ * @{ */
+#define USB_CDC_PROTO_V25TER                0x01 /**< AT Commands: V.250 etc */
+ /** @} */
+
+
+/** \name Data Interface Class Protocol Codes 
+ * @{ */
+#define USB_CDC_PROTO_NTB                   0x01 /**< Network Transfer Block */ 
+#define USB_CDC_PROTO_HOST                  0xFD /**< Host based driver. \note This protocol code should only be used in messages between
+                                                  * host and device to identify the host driver portion of a protocol stack.*/
+#define USB_CDC_PROTO_CDCSPEC               0xFE /**< The protocol(s) are described using a Protocol Unit Functional Descriptors on Communication Class Interface.*/
+/** @} */
+
+/**\name USB CDC class-specified functional descriptors 
+ * @{ */
+#define USB_DTYPE_CDC_HEADER                0x00 /**< Header Functional Descriptor. \ref usb_cdc_header_desc */
+#define USB_DTYPE_CDC_CALL_MANAGEMENT       0x01 /**< Call Management Functional Descriptor. \ref usb_cdc_call_mgmt_desc */ 
+#define USB_DTYPE_CDC_ACM                   0x02 /**< Abstract Control Management Functional Descriptor. \ref usb_cdc_acm_desc */
+#define USB_DTYPE_CDC_UNION                 0x06 /**< Union Functional descriptor */
+#define USB_DTYPE_CDC_COUNTRY               0x07 /**< Country Selection Functional Descriptor */
+/** @} */
+
+
+
+/** \name USB CDC class-specific requests
+ * @{ */
+#define USB_CDC_SEND_ENCAPSULATED_CMD       0x00 /**< Used to issue a command in the format of the supported control protocol of the Communication Class interface. */
+#define USB_CDC_GET_ENCAPSULATED_RESP       0x01 /**< Used to request a response in the format of the supported control protocol of the Communication Class interface. */
+#define USB_CDC_SET_COMM_FEATURE            0x02 /**< Controls the settings for a particular communication feature of a particular target */
+#define USB_CDC_GET_COMM_FEATURE            0x03 /**< Returns the current settings for the communication feature as selected */
+#define USB_CDC_CLEAR_COMM_FEATURE          0x04 /**< Controls the settings for a particular communication feature of a particular 
+                                                  * target, setting the selected feature to its default state. */
+#define USB_CDC_SET_LINE_CODING             0x20 /**< Allows the host to specify typical asynchronous line-character formatting properties. */
+#define USB_CDC_GET_LINE_CODING             0x21 /**< Allows the host to find out the currently configured line coding. */
+#define USB_CDC_SET_CONTROL_LINE_STATE      0x22 /**< Generates RS-232/V.24 style control signals. */
+#define USB_CDC_SEND_BREAK                  0x23 /**< Sends special carrier modulation that generates an RS-232 style break. */
+/** @} */
+
+
+/**\name Generic CDC specific notifications
+ * @{ */
+#define USB_CDC_NTF_NETWORK_CONNECTION      0x00  /**< Allows the device to notify the host about network connection status. */
+#define USB_CDC_NTF_RESPONSE_AVAILABLE      0x01  /**< Allows the device to notify the host that a response is available. */
+#define USB_CDC_NTF_SERIAL_STATE            0x20  /**< Sends asynchronous notification of UART status. */ 
+#define USB_CDC_NTF_SPEED_CHANGE            0x2A  /**< allows the device to inform the host-networking driver that a change in either the uplink 
+                                                   * or the downlink bit rate of the connection has occurred. */
+/** @} */
+
+
+/**\anchor USB_CDC_ACMGMNTCAP
+ * \name USB CDC Abstract Control Management capabilities 
+ * @{ */
+#define USB_CDC_COMM_FEATURE                0x01 /**< Supports the request combination of Set_Comm_Feature, Clear_Comm_Feature, and Get_Comm_Feature. */
+#define USB_CDC_CAP_LINE                    0x02 /**< Supports the request combination of Set_Line_Coding, Set_Control_Line_State, Get_Line_Coding, and the notification Serial_State. */
+#define USB_CDC_CAP_BRK                     0x04 /**< Supports the request Send_Break */
+#define USB_CDC_CAP_NOTIFY                  0x08 /**< Supports notification Network_Connection. */
+/** @} */
+
+/**\anchor USB_CDC_CALLMGMTCAP
+ * \name USB CDC Call Management capabilities
+ * @{ */
+#define USB_CDC_CALL_MGMT_CAP_CALL_MGMT     0x01 /**< Device handles call management itself. */
+#define USB_CDC_CALL_MGMT_CAP_DATA_INTF     0x02 /**< Device can send/receive call management information over a Data Class interface. */
+/** @} */
+
+/**\anchor USB_CDC_LINECODE
+ * \name Line coding structire bit fields
+ * @{ */
+#define USB_CDC_1_STOP_BITS                 0x00
+#define USB_CDC_1_5_STOP_BITS               0x01
+#define USB_CDC_2_STOP_BITS                 0x02
+
+#define USB_CDC_NO_PARITY                   0x00
+#define USB_CDC_ODD_PARITY                  0x01
+#define USB_CDC_EVEN_PARITY                 0x02
+#define USB_CDC_MARK_PARITY                 0x03
+#define USB_CDC_SPACE_PARITY                0x04
+/** @} */
+
+/**\name SERIAL_STATE notification data values
+ * @{ */
+#define USB_CDC_STATE_RX_CARRIER          0x0001 /**< State of receiver carrier detection mechanism of device. This signal corresponds to V.24 signal 109 and RS-232 signal DCD. */
+#define USB_CDC_STATE_TX_CARRIER          0x0002 /**< State of transmission carrier. This signal corresponds to V.24 signal 106 and RS-232 signal DSR. */
+#define USB_CDC_STATE_BREAK               0x0004 /**< State of break detection mechanism of the device. */
+#define USB_CDC_STATE_RING                0x0008 /**< State of ring signal detection of the device. */
+#define USB_CDC_STATE_FRAMING             0x0010 /**< A framing error has occurred. */
+#define USB_CDC_STATE_PARITY              0x0020 /**< A parity error has occurred. */
+#define USB_CDC_STATE_OVERRUN             0x0040 /**< Received data has been discarded due to overrun in the device */
+/** @} */
+
+/** \brief Header Functional Descriptor
+ * \details Header Functional Descriptor marks the beginning of the concatenated set of functional descriptors for the interface. */
+
+struct usb_cdc_header_desc {
+    uint8_t     bFunctionLength;    /**< Size of this descriptor in bytes. */
+    uint8_t     bDescriptorType;    /**< CS_INTERFACE descriptor type. \see \ref USB_DTYPE_CS_INTERFACE */
+    uint8_t     bDescriptorSubType; /**< Header functional descriptor subtype \ref USB_DTYPE_CDC_HEADER */
+    uint16_t    bcdCDC;             /**< USB CDC Specification release number in binary-coded decimal. \see \ref VERSION_BCD macro */
+} __attribute__ ((packed));
+
+/** \brief Union Functional Descriptor
+ * \details The Union functional descriptor describes the relationship between a group of interfaces that can be considered to form
+ * a functional unit. It can only occur within the class-specific portion of an Interface descriptor. One of the interfaces in
+ * the group is designated as a master or controlling interface for the group, and certain class-specific messages can be
+ * sent to this interface to act upon the group as a whole.
+ */
+struct usb_cdc_union_desc {
+    uint8_t     bFunctionLength;    /**< Size of this functional descriptor, in bytes. */
+    uint8_t     bDescriptorType;    /**< CS_INTERFACE descriptor type. \see \ref USB_DTYPE_CS_INTERFACE */
+    uint8_t     bDescriptorSubType; /**< Union Functional Descriptor. \ref USB_DTYPE_CDC_UNION */
+    uint8_t     bMasterInterface0;  /**< The interface number of the CDC interface, designated as the master or controlling interface for the union. */
+    uint8_t     bSlaveInterface0;   /**< Interface number of first slave or associated interface in the union. */
+    /* ... and there could be other slave interfaces */
+} __attribute__ ((packed));
+
+/** \brief Country Selection Functional Descriptor
+ * \details The Country Selection functional descriptor identifies the countries in which the communication device is qualified to
+ * operate. The parameters of the network connection often vary from one country to another, especially in Europe. Also
+ * legal requirements impose certain restrictions on devices because of different regulations by the governing body of the
+ * network to which the device must adhere. This descriptor can only occur within the class-specific portion of an
+ * Interface descriptor and should only be provided to a master Communication Class interface of a union. The country
+ * codes used in the Country Selection Functional Descriptor are not the same as the country codes used in dialing
+ * international telephone calls. Implementers should refer to the ISO 3166 specification for more information.
+ */
+struct usb_cdc_country_desc {
+    uint8_t     bFunctionLength;     /**< Size of this functional descriptor, in bytes. */
+    uint8_t     bDescriptorType;     /**< CS_INTERFACE descriptor type. \see \ref USB_DTYPE_CS_INTERFACE */
+    uint8_t     bDescriptorSubType;  /**< Country Selection Functional Descriptor \ref USB_DTYPE_CDC_COUNTRY */
+    uint8_t     iCountryCodeRelDate; /**< Index of a string giving the release date for the implemented ISO 3166 Country Codes. */
+    uint8_t     wCountyCode0;        /**< Country code in hexadecimal format as defined in ISO 3166, release date as specified
+                                      * in iCountryCodeRelDate for the first supported country. */
+    /* ... and there can be a lot of country codes */
+} __attribute__ ((packed));
+
+/** \brief Call Management Functional Descriptor.
+ * \details The Call Management functional descriptor describes the processing of calls for the Communication Class interface. It
+ * can only occur within the class-specific portion of an Interface descriptor.
+ */
+struct usb_cdc_call_mgmt_desc {
+    uint8_t     bFunctionLength;    /**< Size of this functional descriptor, in bytes. */
+    uint8_t     bDescriptorType;    /**< CS_INTERFACE descriptor type. \see \ref USB_DTYPE_CS_INTERFACE */
+    uint8_t     bDescriptorSubType; /**< Call Management functional descriptor subtype \ref USB_DTYPE_CDC_CALL_MANAGEMENT */
+    uint8_t     bmCapabilities;     /**< The \ref USB_CDC_CALLMGMTCAP "capabilities" that this configuration supports */
+    uint8_t     bDataInterface;     /**< Interface number of Data Class interface optionally used for call management. */
+} __attribute__ ((packed));
+
+/** \brief Abstract Control Management Functional Descriptor
+ * \details The Abstract Control Management functional descriptor describes the commands supported by the Communication
+ * Class interface, as defined in Section 3.6.2, with the SubClass code of Abstract Control Model. It can only occur
+ * within the class-specific portion of an Interface descriptor.
+ */
+struct usb_cdc_acm_desc {
+    uint8_t     bFunctionLength;    /**< Size of this functional descriptor, in bytes. */
+    uint8_t     bDescriptorType;    /**< CS_INTERFACE descriptor type. \see \ref USB_DTYPE_CS_INTERFACE */
+    uint8_t     bDescriptorSubType; /**< Abstract Control Management functional descriptor subtype \ref USB_DTYPE_CDC_ACM */
+    uint8_t     bmCapabilities;     /**< The \ref USB_CDC_ACMGMNTCAP "capabilities" that this configuration supports */
+} __attribute__ ((packed));
+
+///\brief Notification structure from CDC
+struct usb_cdc_notification {
+    uint8_t     bmRequestType;
+    uint8_t     bNotificationType;
+    uint16_t    wValue;
+    uint16_t    wIndex;
+    uint16_t    wLength;
+    uint8_t     Data[];
+} __attribute__ ((packed));
+
+/**\brief Line Coding Structure
+ * \details used in GET_LINE_CODING and SET_LINE_CODING requests
+ */
+struct usb_cdc_line_coding {
+    uint32_t    dwDTERate;          /**< Data terminal rate, in bits per second. */
+    uint8_t     bCharFormat;        /**< Stop bits */
+    uint8_t     bParityType;        /**< Parity */
+    uint8_t     bDataBits;          /**< Data bits (5,6,7,8 or 16) */
+} __attribute__ ((packed));
+
+
+/** @} */
+
+
+#ifdef __cplusplus
+    }
+#endif
+
+#endif /* _USB_CDC_H_ */

+ 124 - 124
inc/usb_dfu.h

@@ -1,124 +1,124 @@
-/* This file is the part of the LUS32 project
- *
- * Copyright ©2016 Dmitry Filimonchuk <dmitrystu[at]gmail[dot]com>
- *
- * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
- * 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.
- */
-
-#ifndef _USB_DFU_H_
-#define _USB_DFU_H_
-
-#if defined(__cplusplus)
-    extern "C" {
-#endif
-
-/** \addtogroup USB_MODULE_DFU USB DFU class
- * \brief This module contains USB Device Firmware Upgrade class definitions.
- * \details This module based on
- * + [USB Device Firmware Upgrade Specification, Revision 1.1](http://www.usb.org/developers/docs/devclass_docs/DFU_1.1.pdf)
- * @{ */
-
-/**\name USB DFU class subclass and protocol definitions
- * @{ */
-#define USB_CLASS_DFU                   0xFE    /**< USB DFU class is an application-specified class */
-#define USB_DFU_SUBCLASS_DFU            0x01    /**< USB DFU subclass code */
-#define USB_DFU_PROTO_RUNTIME           0x01    /**< USB DFU runtime-mode protocol */
-#define USB_DFU_PROTO_DFU               0x02    /**< USB DFU DFU-mode protocol */
-/** @{ */
-
-/**\name USB DFU descriptor types */
-#define USB_DTYPE_DFU_FUNCTIONAL        0x21    /**< USB DFU functional descriptor type */
-
-/**\name USB DFU class-specific requests
- * @{ */
-#define USB_DFU_DETACH                  0x00    /**< Initiates a detach-attach sequence on the bus when it sees this request. */
-#define USB_DFU_DNLOAD                  0x01    /**< Initiates firmware image downloading */
-#define USB_DFU_UPLOAD                  0x02    /**< This request is employed by the host to solicit firmware from the device.*/
-#define USB_DFU_GETSTATUS               0x03    /**< The host employs this request to facilitate synchronization with the device. \see usb_dfu_status */
-#define USB_DFU_CLRSTATAUS              0x04    /**< This request resets DFU machine state to DFU_IDLE*/
-#define USB_DFU_GETSTATE                0x05    /**< This request solicits a report about the state of the device. */
-#define USB_DFU_ABORT                   0x06    /**< This request enables the host to exit from certain states and return to the DFU_IDLE state*/
-/** @} */
-
-/**\anchor USB_DFU_CAPAB
- * \name USB DFU capabilities
- * @{ */
-#define USB_DFU_ATTR_WILL_DETACH        0x08    /**< Device will perform a bus detach-attach sequence when it receives a DFU_DETACH request. */
-#define USB_DFU_ATTR_MANIF_TOL          0x04    /**< Device is able to communicate via USB after Manifestation phase. */
-#define USB_DFU_ATTR_CAN_UPLOAD         0x02    /**< Upload capable. */
-#define USB_DFU_ATTR_CAN_DNLOAD         0x01    /**< Download capable. */
-/** @} */
-
-/**\name USB DFU status codes
- * @{ */
-#define USB_DFU_STATUS_OK               0x00 /**< No error condition is present. */
-#define USB_DFU_STATUS_ERR_TARGET       0x01 /**< File is not targeted for use by this device. */
-#define USB_DFU_STATUS_ERR_FILE         0x02 /**< File is for this device but fails some vendor specific verification test. */
-#define USB_DFU_STATUS_ERR_WRITE        0x03 /**< Device is unable to write memory. */
-#define USB_DFU_STATUS_ERR_ERASE        0x04 /**< Memory erase function failed. */
-#define USB_DFU_STATUS_ERR_CHECK_ERASED 0x05 /**< Memory erase check failed. */
-#define USB_DFU_STATUS_ERR_PROG         0x06 /**< Program memory function failed. */
-#define USB_DFU_STATUS_ERR_VERIFY       0x07 /**< Programmed memory failed verification. */
-#define USB_DFU_STATUS_ERR_ADDRESS      0x08 /**< Cannot program memory due to received address that is out of range. */
-#define USB_DFU_STATUS_ERR_NOTDONE      0x09 /**< Received DFU_DNLOAD with wLength = 0, but device does not think it has all of the data yet. */
-#define USB_DFU_STATUS_ERR_FIRMWARE     0x0A /**< Device's firmware is corrupt.  It cannot return to run-time (non-DFU) operations. */
-#define USB_DFU_STATUS_ERR_VENDOR       0x0B /**< iString indicates a vendor-specific error. */
-#define USB_DFU_STATUS_ERR_USBR         0x0C /**< Device detected unexpected USB reset signaling. */
-#define USB_DFU_STATUS_ERR_POR          0x0D /**< Device detected unexpected power on reset. */
-#define USB_DFU_STATUS_ERR_UNKNOWN      0x0E /**< Something went wrong, but the device does not know what it was. */
-#define USB_DFU_STATUS_ERR_STALLEDPKT   0x0F /**< Device stalled an unexpected request. */
-/** @} */
-
-/**\name USB DFU state codes
- * @{ */
-#define USB_DFU_STATE_APP_IDLE          0x00 /**< Device is running its normal application. */
-#define USB_DFU_STATE_APP_DETACH        0x01 /**< Device is running its normal application, has received the DFU_DETACH request, and is waiting for a USB reset. */
-#define USB_DFU_STATE_DFU_IDLE          0x02 /**< Device is operating in the DFU mode and is waiting for requests. */
-#define USB_DFU_STATE_DFU_DNLOADSYNC    0x03 /**< Device has received a block and is waiting for the host to solicit the status via DFU_GETSTATUS. */
-#define USB_DFU_STATE_DFU_DNBUSY        0x04 /**< Device is programming a control-write block into its nonvolatile memories. */
-#define USB_DFU_STATE_DFU_DNLOADIDLE    0x05 /**< Device is processing a download operation.  Expecting DFU_DNLOAD requests. */
-#define USB_DFU_STATE_DFU_MANIFESTSYNC  0x06 /**< Device has received the final block of firmware from the host
-                                              * and is waiting for receipt of DFU_GETSTATUS to begin the Manifestation
-                                              * phase; or device has completed the Manifestation phase and is waiting
-                                              * for receipt of DFU_GETSTATUS.  (Devices that can enter this state
-                                              * after the Manifestation phase set bmAttributes bit bitManifestationTolerant to 1.) */
-#define USB_DFU_STATE_DFU_MANIFEST      0x07 /**< Device is in the Manifestation phase.  (Not all devices will be able to respond to DFU_GETSTATUS when in this state.) */
-#define USB_DFU_STATE_DFU_MANIFESTWR    0x08 /**< Device has programmed its memories and is waiting for a USB reset or a
-                                              * power on reset.  (Devices that must enter this state clear bitManifestationTolerant to 0.) */
-#define USB_DFU_STATE_DFU_UPLOADIDLE    0x09 /**< The device is processing an upload operation.  Expecting DFU_UPLOAD requests. */
-#define USB_DFU_STATE_DFU_ERROR         0x0A /**< An error has occurred. Awaiting the DFU_CLRSTATUS request. */
-/** @} */
-
-/** \brief USB DFU functional descriptor */
-struct usb_dfu_func_desc {
-    uint8_t     bLength;            /**< Descriptor length in bytes. */
-    uint8_t     bDescriptorType;    /**< Descriptor type, set it to \ref USB_DTYPE_DFU_FUNCTIONAL */
-    uint8_t     bmAttributes;       /**< Bitmap field of the \ref USB_DFU_CAPAB "USB DFU capabilities"*/
-    uint16_t    wDetachTimeout;     /**< USB DFU detach timeout in ms */
-    uint16_t    wTransferSize;      /**< USB DFU maximum transfer block size in bytes */
-    uint16_t    bcdDFUVersion;      /**< USB DFU version \ref VERSION_BCD utility macro */
-}__attribute__((packed));
-
-/** \brief Payload packet to response in DFU_GETSTATUS request */
-struct usb_dfu_status {
-    uint8_t     bStatus;            /**< An indication of the status resulting from the execution of the most recent request.*/
-    uint8_t     bPollTimeout;
-    uint16_t    wPollTimeout;       /**< Minimum time, (ms), that the host should wait before sending a subsequent \ref USB_DFU_GETSTATUS "DFU_GETSTATUS" request. */
-    uint8_t     bState;             /**< An indication of the state that the device is going to enter immediately following transmission of this response. */
-    uint8_t     iString;            /**< Index of the status \ref usb_string_descriptor "string descriptor". */
-};
-
-/** @} */
-
-#if defined(__cplusplus)
-    }
-#endif
-#endif /* _USB_DFU_H_ */
+/* This file is the part of the LUS32 project
+ *
+ * Copyright ©2016 Dmitry Filimonchuk <dmitrystu[at]gmail[dot]com>
+ *
+ * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ * 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.
+ */
+
+#ifndef _USB_DFU_H_
+#define _USB_DFU_H_
+
+#if defined(__cplusplus)
+    extern "C" {
+#endif
+
+/** \addtogroup USB_MODULE_DFU USB DFU class
+ * \brief This module contains USB Device Firmware Upgrade class definitions.
+ * \details This module based on
+ * + [USB Device Firmware Upgrade Specification, Revision 1.1](http://www.usb.org/developers/docs/devclass_docs/DFU_1.1.pdf)
+ * @{ */
+
+/**\name USB DFU class subclass and protocol definitions
+ * @{ */
+#define USB_CLASS_DFU                   0xFE    /**< USB DFU class is an application-specified class */
+#define USB_DFU_SUBCLASS_DFU            0x01    /**< USB DFU subclass code */
+#define USB_DFU_PROTO_RUNTIME           0x01    /**< USB DFU runtime-mode protocol */
+#define USB_DFU_PROTO_DFU               0x02    /**< USB DFU DFU-mode protocol */
+/** @{ */
+
+/**\name USB DFU descriptor types */
+#define USB_DTYPE_DFU_FUNCTIONAL        0x21    /**< USB DFU functional descriptor type */
+
+/**\name USB DFU class-specific requests
+ * @{ */
+#define USB_DFU_DETACH                  0x00    /**< Initiates a detach-attach sequence on the bus when it sees this request. */
+#define USB_DFU_DNLOAD                  0x01    /**< Initiates firmware image downloading */
+#define USB_DFU_UPLOAD                  0x02    /**< This request is employed by the host to solicit firmware from the device.*/
+#define USB_DFU_GETSTATUS               0x03    /**< The host employs this request to facilitate synchronization with the device. \see usb_dfu_status */
+#define USB_DFU_CLRSTATAUS              0x04    /**< This request resets DFU machine state to DFU_IDLE*/
+#define USB_DFU_GETSTATE                0x05    /**< This request solicits a report about the state of the device. */
+#define USB_DFU_ABORT                   0x06    /**< This request enables the host to exit from certain states and return to the DFU_IDLE state*/
+/** @} */
+
+/**\anchor USB_DFU_CAPAB
+ * \name USB DFU capabilities
+ * @{ */
+#define USB_DFU_ATTR_WILL_DETACH        0x08    /**< Device will perform a bus detach-attach sequence when it receives a DFU_DETACH request. */
+#define USB_DFU_ATTR_MANIF_TOL          0x04    /**< Device is able to communicate via USB after Manifestation phase. */
+#define USB_DFU_ATTR_CAN_UPLOAD         0x02    /**< Upload capable. */
+#define USB_DFU_ATTR_CAN_DNLOAD         0x01    /**< Download capable. */
+/** @} */
+
+/**\name USB DFU status codes
+ * @{ */
+#define USB_DFU_STATUS_OK               0x00 /**< No error condition is present. */
+#define USB_DFU_STATUS_ERR_TARGET       0x01 /**< File is not targeted for use by this device. */
+#define USB_DFU_STATUS_ERR_FILE         0x02 /**< File is for this device but fails some vendor specific verification test. */
+#define USB_DFU_STATUS_ERR_WRITE        0x03 /**< Device is unable to write memory. */
+#define USB_DFU_STATUS_ERR_ERASE        0x04 /**< Memory erase function failed. */
+#define USB_DFU_STATUS_ERR_CHECK_ERASED 0x05 /**< Memory erase check failed. */
+#define USB_DFU_STATUS_ERR_PROG         0x06 /**< Program memory function failed. */
+#define USB_DFU_STATUS_ERR_VERIFY       0x07 /**< Programmed memory failed verification. */
+#define USB_DFU_STATUS_ERR_ADDRESS      0x08 /**< Cannot program memory due to received address that is out of range. */
+#define USB_DFU_STATUS_ERR_NOTDONE      0x09 /**< Received DFU_DNLOAD with wLength = 0, but device does not think it has all of the data yet. */
+#define USB_DFU_STATUS_ERR_FIRMWARE     0x0A /**< Device's firmware is corrupt.  It cannot return to run-time (non-DFU) operations. */
+#define USB_DFU_STATUS_ERR_VENDOR       0x0B /**< iString indicates a vendor-specific error. */
+#define USB_DFU_STATUS_ERR_USBR         0x0C /**< Device detected unexpected USB reset signaling. */
+#define USB_DFU_STATUS_ERR_POR          0x0D /**< Device detected unexpected power on reset. */
+#define USB_DFU_STATUS_ERR_UNKNOWN      0x0E /**< Something went wrong, but the device does not know what it was. */
+#define USB_DFU_STATUS_ERR_STALLEDPKT   0x0F /**< Device stalled an unexpected request. */
+/** @} */
+
+/**\name USB DFU state codes
+ * @{ */
+#define USB_DFU_STATE_APP_IDLE          0x00 /**< Device is running its normal application. */
+#define USB_DFU_STATE_APP_DETACH        0x01 /**< Device is running its normal application, has received the DFU_DETACH request, and is waiting for a USB reset. */
+#define USB_DFU_STATE_DFU_IDLE          0x02 /**< Device is operating in the DFU mode and is waiting for requests. */
+#define USB_DFU_STATE_DFU_DNLOADSYNC    0x03 /**< Device has received a block and is waiting for the host to solicit the status via DFU_GETSTATUS. */
+#define USB_DFU_STATE_DFU_DNBUSY        0x04 /**< Device is programming a control-write block into its nonvolatile memories. */
+#define USB_DFU_STATE_DFU_DNLOADIDLE    0x05 /**< Device is processing a download operation.  Expecting DFU_DNLOAD requests. */
+#define USB_DFU_STATE_DFU_MANIFESTSYNC  0x06 /**< Device has received the final block of firmware from the host
+                                              * and is waiting for receipt of DFU_GETSTATUS to begin the Manifestation
+                                              * phase; or device has completed the Manifestation phase and is waiting
+                                              * for receipt of DFU_GETSTATUS.  (Devices that can enter this state
+                                              * after the Manifestation phase set bmAttributes bit bitManifestationTolerant to 1.) */
+#define USB_DFU_STATE_DFU_MANIFEST      0x07 /**< Device is in the Manifestation phase.  (Not all devices will be able to respond to DFU_GETSTATUS when in this state.) */
+#define USB_DFU_STATE_DFU_MANIFESTWR    0x08 /**< Device has programmed its memories and is waiting for a USB reset or a
+                                              * power on reset.  (Devices that must enter this state clear bitManifestationTolerant to 0.) */
+#define USB_DFU_STATE_DFU_UPLOADIDLE    0x09 /**< The device is processing an upload operation.  Expecting DFU_UPLOAD requests. */
+#define USB_DFU_STATE_DFU_ERROR         0x0A /**< An error has occurred. Awaiting the DFU_CLRSTATUS request. */
+/** @} */
+
+/** \brief USB DFU functional descriptor */
+struct usb_dfu_func_desc {
+    uint8_t     bLength;            /**< Descriptor length in bytes. */
+    uint8_t     bDescriptorType;    /**< Descriptor type, set it to \ref USB_DTYPE_DFU_FUNCTIONAL */
+    uint8_t     bmAttributes;       /**< Bitmap field of the \ref USB_DFU_CAPAB "USB DFU capabilities"*/
+    uint16_t    wDetachTimeout;     /**< USB DFU detach timeout in ms */
+    uint16_t    wTransferSize;      /**< USB DFU maximum transfer block size in bytes */
+    uint16_t    bcdDFUVersion;      /**< USB DFU version \ref VERSION_BCD utility macro */
+}__attribute__((packed));
+
+/** \brief Payload packet to response in DFU_GETSTATUS request */
+struct usb_dfu_status {
+    uint8_t     bStatus;            /**< An indication of the status resulting from the execution of the most recent request.*/
+    uint8_t     bPollTimeout;
+    uint16_t    wPollTimeout;       /**< Minimum time, (ms), that the host should wait before sending a subsequent \ref USB_DFU_GETSTATUS "DFU_GETSTATUS" request. */
+    uint8_t     bState;             /**< An indication of the state that the device is going to enter immediately following transmission of this response. */
+    uint8_t     iString;            /**< Index of the status \ref usb_string_descriptor "string descriptor". */
+};
+
+/** @} */
+
+#if defined(__cplusplus)
+    }
+#endif
+#endif /* _USB_DFU_H_ */

+ 212 - 212
inc/usb_hid.h

@@ -1,212 +1,212 @@
-/* This file is the part of the LUS32 project
- *
- * Copyright ©2016 Dmitry Filimonchuk <dmitrystu[at]gmail[dot]com>
- *
- * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
- * 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.
- */
-
-#ifndef _USB_HID_H_
-#define _USB_HID_H_
-#ifdef __cplusplus
-    extern "C" {
-#endif
-
-
-/**\addtogroup USB_HID USB HID class
- * \brief This module contains USB Human Interface Devices class definitions
- * \details This module based on
- * + [Device Class Definition for Human Interface Devices (HID) Version 1.11](http://www.usb.org/developers/hidpage/HID1_11.pdf)
- * + [LUFA - the Lightweight USB Framework for AVRs.](https://github.com/abcminiuser/lufa)
- * @{ */
-
-/**\name USB HID class code */
-#define USB_CLASS_HID               0x03 /**< Interface belongs to the Human Interface device class */
-
-/**\name USB HID subclass codes
- * @{ */
-#define USB_HID_SUBCLASS_NONBOOT    0x00
-#define USB_HID_SUBCLASS_BOOT       0x01
-/** @} */
-
-/**\name USB HID protocol codes
- * @{ */
-#define USB_HID_PROTO_NONBOOT       0x00
-#define USB_HID_PROTO_KEYBOARD      0x01
-#define USB_HID_PROTO_MOUSE         0x02
-/** @} */
-
-#define USB_HID_REPORT_IN           0 /**< \brief Indicates that the item is an IN report type. */
-#define USB_HID_REPORT_OUT          1 /**< \brief Indicates that the item is an OUT report type. */
-#define USB_HID_REPORT_FEATURE      2 /**< \brief Indicates that the item is a FEATURE report type. */
-
-
-/**\name USB HID class-specified requests
- * @{ */
-#define USB_HID_GETREPORT  			0x01 /**< Request to get the current HID report from the device. */
-#define USB_HID_GETIDLE    			0x02 /**< Request to get the current device idle count. */
-#define USB_HID_GETPROTOCOL			0x03 /**< Request to get the current HID report protocol mode. */
-#define USB_HID_SETREPORT  			0x09 /**< Request to set the current HID report to the device. */
-#define USB_HID_SETIDLE    			0x0A /**< Request to set the device's idle count. */
-#define USB_HID_SETPROTOCOL			0x0B /**< Request to set the current HID report protocol mode. */
-/** @} */
-
-/**\name USB HID class-specified descriptor types
- * @{ */
-#define	USB_DTYPE_HID           	0x21 /**< Descriptor header type value, to indicate a HID class HID descriptor. */
-#define	USB_DTYPE_HID_REPORT     	0x22 /**< Descriptor header type value, to indicate a HID class HID report descriptor. */
-/** @} */
-
-/**\name USB HID country codes
- * @{ */
-#define USB_HID_COUNTRY_NONE 		0 	/**< Not supported */
-#define USB_HID_COUNTRY_AR   		1 	/**< Arabic */
-#define USB_HID_COUNTRY_BE   		2 	/**< Belgian */
-#define USB_HID_COUNTRY_CA_BI		3 	/**< Canadian-Bilingual */
-#define USB_HID_COUNTRY_CA_FR		4 	/**< Canadian-French */
-#define USB_HID_COUNTRY_CZ   		5 	/**< Czech Republic */
-#define USB_HID_COUNTRY_DK   		6 	/**< Danish */
-#define USB_HID_COUNTRY_FI   		7 	/**< Finnish */
-#define USB_HID_COUNTRY_FR   		8 	/**< French */
-#define USB_HID_COUNTRY_DE   		9 	/**< German */
-#define USB_HID_COUNTRY_GR   		10	/**< Greek */
-#define USB_HID_COUNTRY_HEB  		11	/**< Hebrew */
-#define USB_HID_COUNTRY_HU   		12	/**< Hungary */
-#define USB_HID_COUNTRY_ISO  		13	/**< International (ISO) */
-#define USB_HID_COUNTRY_IT   		14	/**< Italian */
-#define USB_HID_COUNTRY_JP   		15	/**< Japan (Katakana) */
-#define USB_HID_COUNTRY_KR   		16	/**< Korean */
-#define USB_HID_COUNTRY_LAT  		17	/**< Latin American */
-#define USB_HID_COUNTRY_NL   		18	/**< Netherlands/Dutch */
-#define USB_HID_COUNTRY_NO   		19	/**< Norwegian */
-#define USB_HID_COUNTRY_PER  		20	/**< Persian (Farsi) */
-#define USB_HID_COUNTRY_PL   		21	/**< Poland */
-#define USB_HID_COUNTRY_PO   		22	/**< Portuguese */
-#define USB_HID_COUNTRY_RU   		23	/**< Russia */
-#define USB_HID_COUNTRY_SK   		24	/**< Slovakia */
-#define USB_HID_COUNTRY_ES   		25	/**< Spanish */
-#define USB_HID_COUNTRY_SE   		26	/**< Swedish */
-#define USB_HID_COUNTRY_CH_FR		26	/**< Swiss-French */
-#define USB_HID_COUNTRY_CH_DE		27	/**< Swiss-German */
-#define USB_HID_COUNTRY_CH   		29	/**< Switzerland */
-#define USB_HID_COUNTRY_TW   		30	/**< Taiwan */
-#define USB_HID_COUNTRY_TR_Q 		31	/**< Turkish-Q */
-#define USB_HID_COUNTRY_UK   		32	/**< UK */
-#define USB_HID_COUNTRY_US   		33	/**< US */
-#define USB_HID_COUNTRY_YU   		34	/**< Yugoslavia */
-#define USB_HID_COUNTRY_TR_F 		35	/**< Turkish-F */
-/** @} */
-
-/** \brief USB HID functional descriptor */
-struct usb_hid_descriptor {
-    uint8_t     bLength;            /**< Size of the descriptor, in bytes. */
-    uint8_t     bDescriptorType;    /**< Type of the descriptor, set to \ref USB_DTYPE_HID */
-	uint16_t    bcdHID;             /**< BCD encoded version that the HID descriptor and device complies to. \ref VERSION_BCD() */
-    uint8_t     bCountryCode;       /**< Country code of the localized device, or zero if universal. */
-	uint8_t     bNumDescriptors;    /**< Total number of HID report descriptors for the interface. */
-	uint8_t     bDescriptorType0;   /**< 1'st HID report descriptor type, set to \ref USB_DTYPE_HID_REPORT */
-	uint16_t    wDescriptorLength0; /**< 1'sr HID report descriptor length in bytes. */
-} __attribute__((packed));
-
-/**\brief USB HID report descriptor */
-struct usb_hid_report_descriptor {
-	uint8_t     bDescriptorType;   /**< Type of HID report, set to \ref USB_DTYPE_HID_REPORT */
-    uint16_t    wDescriptorLength; /**< Length of the associated HID report descriptor, in bytes. */
-} __attribute__((packed));
-
-
-	/* Private Interface - For use in library only: */
-	#if !defined(__DOXYGEN__)
-		/* Macros: */
-            #define CONCAT(x, y)            x ## y
-            #define CONCAT_EXPANDED(x, y)   CONCAT(x, y)
-
-			#define HID_RI_DATA_SIZE_MASK                   0x03
-			#define HID_RI_TYPE_MASK                        0x0C
-			#define HID_RI_TAG_MASK                         0xF0
-
-			#define HID_RI_TYPE_MAIN                        0x00
-			#define HID_RI_TYPE_GLOBAL                      0x04
-			#define HID_RI_TYPE_LOCAL                       0x08
-
-			#define HID_RI_DATA_BITS_0                      0x00
-			#define HID_RI_DATA_BITS_8                      0x01
-			#define HID_RI_DATA_BITS_16                     0x02
-			#define HID_RI_DATA_BITS_32                     0x03
-			#define HID_RI_DATA_BITS(DataBits)              CONCAT_EXPANDED(HID_RI_DATA_BITS_, DataBits)
-
-			#define _HID_RI_ENCODE_0(Data)
-			#define _HID_RI_ENCODE_8(Data)                  , (Data & 0xFF)
-			#define _HID_RI_ENCODE_16(Data)                 _HID_RI_ENCODE_8(Data)  _HID_RI_ENCODE_8(Data >> 8)
-			#define _HID_RI_ENCODE_32(Data)                 _HID_RI_ENCODE_16(Data) _HID_RI_ENCODE_16(Data >> 16)
-			#define _HID_RI_ENCODE(DataBits, ...)           CONCAT_EXPANDED(_HID_RI_ENCODE_, DataBits(__VA_ARGS__))
-
-			#define _HID_RI_ENTRY(Type, Tag, DataBits, ...) (Type | Tag | HID_RI_DATA_BITS(DataBits)) _HID_RI_ENCODE(DataBits, (__VA_ARGS__))
-	#endif
-
-	/* Public Interface - May be used in end-application: */
-		/* Macros: */
-		/** \name HID Input, Output and Feature Report Descriptor Item Flags */
-		//@{
-			#define HID_IOF_CONSTANT                        (1 << 0)
-			#define HID_IOF_DATA                            (0 << 0)
-			#define HID_IOF_VARIABLE                        (1 << 1)
-			#define HID_IOF_ARRAY                           (0 << 1)
-			#define HID_IOF_RELATIVE                        (1 << 2)
-			#define HID_IOF_ABSOLUTE                        (0 << 2)
-			#define HID_IOF_WRAP                            (1 << 3)
-			#define HID_IOF_NO_WRAP                         (0 << 3)
-			#define HID_IOF_NON_LINEAR                      (1 << 4)
-			#define HID_IOF_LINEAR                          (0 << 4)
-			#define HID_IOF_NO_PREFERRED_STATE              (1 << 5)
-			#define HID_IOF_PREFERRED_STATE                 (0 << 5)
-			#define HID_IOF_NULLSTATE                       (1 << 6)
-			#define HID_IOF_NO_NULL_POSITION                (0 << 6)
-			#define HID_IOF_VOLATILE                        (1 << 7)
-			#define HID_IOF_NON_VOLATILE                    (0 << 7)
-			#define HID_IOF_BUFFERED_BYTES                  (1 << 8)
-			#define HID_IOF_BITFIELD                        (0 << 8)
-		//@}
-
-		/** \name HID Report Descriptor Item Macros */
-		//@{
-			#define HID_RI_INPUT(DataBits, ...)             _HID_RI_ENTRY(HID_RI_TYPE_MAIN  , 0x80, DataBits, __VA_ARGS__)
-			#define HID_RI_OUTPUT(DataBits, ...)            _HID_RI_ENTRY(HID_RI_TYPE_MAIN  , 0x90, DataBits, __VA_ARGS__)
-			#define HID_RI_COLLECTION(DataBits, ...)        _HID_RI_ENTRY(HID_RI_TYPE_MAIN  , 0xA0, DataBits, __VA_ARGS__)
-			#define HID_RI_FEATURE(DataBits, ...)           _HID_RI_ENTRY(HID_RI_TYPE_MAIN  , 0xB0, DataBits, __VA_ARGS__)
-			#define HID_RI_END_COLLECTION(DataBits, ...)    _HID_RI_ENTRY(HID_RI_TYPE_MAIN  , 0xC0, DataBits, __VA_ARGS__)
-			#define HID_RI_USAGE_PAGE(DataBits, ...)        _HID_RI_ENTRY(HID_RI_TYPE_GLOBAL, 0x00, DataBits, __VA_ARGS__)
-			#define HID_RI_LOGICAL_MINIMUM(DataBits, ...)   _HID_RI_ENTRY(HID_RI_TYPE_GLOBAL, 0x10, DataBits, __VA_ARGS__)
-			#define HID_RI_LOGICAL_MAXIMUM(DataBits, ...)   _HID_RI_ENTRY(HID_RI_TYPE_GLOBAL, 0x20, DataBits, __VA_ARGS__)
-			#define HID_RI_PHYSICAL_MINIMUM(DataBits, ...)  _HID_RI_ENTRY(HID_RI_TYPE_GLOBAL, 0x30, DataBits, __VA_ARGS__)
-			#define HID_RI_PHYSICAL_MAXIMUM(DataBits, ...)  _HID_RI_ENTRY(HID_RI_TYPE_GLOBAL, 0x40, DataBits, __VA_ARGS__)
-			#define HID_RI_UNIT_EXPONENT(DataBits, ...)     _HID_RI_ENTRY(HID_RI_TYPE_GLOBAL, 0x50, DataBits, __VA_ARGS__)
-			#define HID_RI_UNIT(DataBits, ...)              _HID_RI_ENTRY(HID_RI_TYPE_GLOBAL, 0x60, DataBits, __VA_ARGS__)
-			#define HID_RI_REPORT_SIZE(DataBits, ...)       _HID_RI_ENTRY(HID_RI_TYPE_GLOBAL, 0x70, DataBits, __VA_ARGS__)
-			#define HID_RI_REPORT_ID(DataBits, ...)         _HID_RI_ENTRY(HID_RI_TYPE_GLOBAL, 0x80, DataBits, __VA_ARGS__)
-			#define HID_RI_REPORT_COUNT(DataBits, ...)      _HID_RI_ENTRY(HID_RI_TYPE_GLOBAL, 0x90, DataBits, __VA_ARGS__)
-			#define HID_RI_PUSH(DataBits, ...)              _HID_RI_ENTRY(HID_RI_TYPE_GLOBAL, 0xA0, DataBits, __VA_ARGS__)
-			#define HID_RI_POP(DataBits, ...)               _HID_RI_ENTRY(HID_RI_TYPE_GLOBAL, 0xB0, DataBits, __VA_ARGS__)
-			#define HID_RI_USAGE(DataBits, ...)             _HID_RI_ENTRY(HID_RI_TYPE_LOCAL , 0x00, DataBits, __VA_ARGS__)
-			#define HID_RI_USAGE_MINIMUM(DataBits, ...)     _HID_RI_ENTRY(HID_RI_TYPE_LOCAL , 0x10, DataBits, __VA_ARGS__)
-			#define HID_RI_USAGE_MAXIMUM(DataBits, ...)     _HID_RI_ENTRY(HID_RI_TYPE_LOCAL , 0x20, DataBits, __VA_ARGS__)
-		//@}
-
-
-
-
-/** @}  */
-
-#ifdef __cplusplus
-    }
-#endif
-
-#endif
-
+/* This file is the part of the LUS32 project
+ *
+ * Copyright ©2016 Dmitry Filimonchuk <dmitrystu[at]gmail[dot]com>
+ *
+ * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ * 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.
+ */
+
+#ifndef _USB_HID_H_
+#define _USB_HID_H_
+#ifdef __cplusplus
+    extern "C" {
+#endif
+
+
+/**\addtogroup USB_HID USB HID class
+ * \brief This module contains USB Human Interface Devices class definitions
+ * \details This module based on
+ * + [Device Class Definition for Human Interface Devices (HID) Version 1.11](http://www.usb.org/developers/hidpage/HID1_11.pdf)
+ * + [LUFA - the Lightweight USB Framework for AVRs.](https://github.com/abcminiuser/lufa)
+ * @{ */
+
+/**\name USB HID class code */
+#define USB_CLASS_HID               0x03 /**< Interface belongs to the Human Interface device class */
+
+/**\name USB HID subclass codes
+ * @{ */
+#define USB_HID_SUBCLASS_NONBOOT    0x00
+#define USB_HID_SUBCLASS_BOOT       0x01
+/** @} */
+
+/**\name USB HID protocol codes
+ * @{ */
+#define USB_HID_PROTO_NONBOOT       0x00
+#define USB_HID_PROTO_KEYBOARD      0x01
+#define USB_HID_PROTO_MOUSE         0x02
+/** @} */
+
+#define USB_HID_REPORT_IN           0 /**< \brief Indicates that the item is an IN report type. */
+#define USB_HID_REPORT_OUT          1 /**< \brief Indicates that the item is an OUT report type. */
+#define USB_HID_REPORT_FEATURE      2 /**< \brief Indicates that the item is a FEATURE report type. */
+
+
+/**\name USB HID class-specified requests
+ * @{ */
+#define USB_HID_GETREPORT  			0x01 /**< Request to get the current HID report from the device. */
+#define USB_HID_GETIDLE    			0x02 /**< Request to get the current device idle count. */
+#define USB_HID_GETPROTOCOL			0x03 /**< Request to get the current HID report protocol mode. */
+#define USB_HID_SETREPORT  			0x09 /**< Request to set the current HID report to the device. */
+#define USB_HID_SETIDLE    			0x0A /**< Request to set the device's idle count. */
+#define USB_HID_SETPROTOCOL			0x0B /**< Request to set the current HID report protocol mode. */
+/** @} */
+
+/**\name USB HID class-specified descriptor types
+ * @{ */
+#define	USB_DTYPE_HID           	0x21 /**< Descriptor header type value, to indicate a HID class HID descriptor. */
+#define	USB_DTYPE_HID_REPORT     	0x22 /**< Descriptor header type value, to indicate a HID class HID report descriptor. */
+/** @} */
+
+/**\name USB HID country codes
+ * @{ */
+#define USB_HID_COUNTRY_NONE 		0 	/**< Not supported */
+#define USB_HID_COUNTRY_AR   		1 	/**< Arabic */
+#define USB_HID_COUNTRY_BE   		2 	/**< Belgian */
+#define USB_HID_COUNTRY_CA_BI		3 	/**< Canadian-Bilingual */
+#define USB_HID_COUNTRY_CA_FR		4 	/**< Canadian-French */
+#define USB_HID_COUNTRY_CZ   		5 	/**< Czech Republic */
+#define USB_HID_COUNTRY_DK   		6 	/**< Danish */
+#define USB_HID_COUNTRY_FI   		7 	/**< Finnish */
+#define USB_HID_COUNTRY_FR   		8 	/**< French */
+#define USB_HID_COUNTRY_DE   		9 	/**< German */
+#define USB_HID_COUNTRY_GR   		10	/**< Greek */
+#define USB_HID_COUNTRY_HEB  		11	/**< Hebrew */
+#define USB_HID_COUNTRY_HU   		12	/**< Hungary */
+#define USB_HID_COUNTRY_ISO  		13	/**< International (ISO) */
+#define USB_HID_COUNTRY_IT   		14	/**< Italian */
+#define USB_HID_COUNTRY_JP   		15	/**< Japan (Katakana) */
+#define USB_HID_COUNTRY_KR   		16	/**< Korean */
+#define USB_HID_COUNTRY_LAT  		17	/**< Latin American */
+#define USB_HID_COUNTRY_NL   		18	/**< Netherlands/Dutch */
+#define USB_HID_COUNTRY_NO   		19	/**< Norwegian */
+#define USB_HID_COUNTRY_PER  		20	/**< Persian (Farsi) */
+#define USB_HID_COUNTRY_PL   		21	/**< Poland */
+#define USB_HID_COUNTRY_PO   		22	/**< Portuguese */
+#define USB_HID_COUNTRY_RU   		23	/**< Russia */
+#define USB_HID_COUNTRY_SK   		24	/**< Slovakia */
+#define USB_HID_COUNTRY_ES   		25	/**< Spanish */
+#define USB_HID_COUNTRY_SE   		26	/**< Swedish */
+#define USB_HID_COUNTRY_CH_FR		26	/**< Swiss-French */
+#define USB_HID_COUNTRY_CH_DE		27	/**< Swiss-German */
+#define USB_HID_COUNTRY_CH   		29	/**< Switzerland */
+#define USB_HID_COUNTRY_TW   		30	/**< Taiwan */
+#define USB_HID_COUNTRY_TR_Q 		31	/**< Turkish-Q */
+#define USB_HID_COUNTRY_UK   		32	/**< UK */
+#define USB_HID_COUNTRY_US   		33	/**< US */
+#define USB_HID_COUNTRY_YU   		34	/**< Yugoslavia */
+#define USB_HID_COUNTRY_TR_F 		35	/**< Turkish-F */
+/** @} */
+
+/** \brief USB HID functional descriptor */
+struct usb_hid_descriptor {
+    uint8_t     bLength;            /**< Size of the descriptor, in bytes. */
+    uint8_t     bDescriptorType;    /**< Type of the descriptor, set to \ref USB_DTYPE_HID */
+	uint16_t    bcdHID;             /**< BCD encoded version that the HID descriptor and device complies to. \ref VERSION_BCD() */
+    uint8_t     bCountryCode;       /**< Country code of the localized device, or zero if universal. */
+	uint8_t     bNumDescriptors;    /**< Total number of HID report descriptors for the interface. */
+	uint8_t     bDescriptorType0;   /**< 1'st HID report descriptor type, set to \ref USB_DTYPE_HID_REPORT */
+	uint16_t    wDescriptorLength0; /**< 1'sr HID report descriptor length in bytes. */
+} __attribute__((packed));
+
+/**\brief USB HID report descriptor */
+struct usb_hid_report_descriptor {
+	uint8_t     bDescriptorType;   /**< Type of HID report, set to \ref USB_DTYPE_HID_REPORT */
+    uint16_t    wDescriptorLength; /**< Length of the associated HID report descriptor, in bytes. */
+} __attribute__((packed));
+
+
+	/* Private Interface - For use in library only: */
+	#if !defined(__DOXYGEN__)
+		/* Macros: */
+            #define CONCAT(x, y)            x ## y
+            #define CONCAT_EXPANDED(x, y)   CONCAT(x, y)
+
+			#define HID_RI_DATA_SIZE_MASK                   0x03
+			#define HID_RI_TYPE_MASK                        0x0C
+			#define HID_RI_TAG_MASK                         0xF0
+
+			#define HID_RI_TYPE_MAIN                        0x00
+			#define HID_RI_TYPE_GLOBAL                      0x04
+			#define HID_RI_TYPE_LOCAL                       0x08
+
+			#define HID_RI_DATA_BITS_0                      0x00
+			#define HID_RI_DATA_BITS_8                      0x01
+			#define HID_RI_DATA_BITS_16                     0x02
+			#define HID_RI_DATA_BITS_32                     0x03
+			#define HID_RI_DATA_BITS(DataBits)              CONCAT_EXPANDED(HID_RI_DATA_BITS_, DataBits)
+
+			#define _HID_RI_ENCODE_0(Data)
+			#define _HID_RI_ENCODE_8(Data)                  , (Data & 0xFF)
+			#define _HID_RI_ENCODE_16(Data)                 _HID_RI_ENCODE_8(Data)  _HID_RI_ENCODE_8(Data >> 8)
+			#define _HID_RI_ENCODE_32(Data)                 _HID_RI_ENCODE_16(Data) _HID_RI_ENCODE_16(Data >> 16)
+			#define _HID_RI_ENCODE(DataBits, ...)           CONCAT_EXPANDED(_HID_RI_ENCODE_, DataBits(__VA_ARGS__))
+
+			#define _HID_RI_ENTRY(Type, Tag, DataBits, ...) (Type | Tag | HID_RI_DATA_BITS(DataBits)) _HID_RI_ENCODE(DataBits, (__VA_ARGS__))
+	#endif
+
+	/* Public Interface - May be used in end-application: */
+		/* Macros: */
+		/** \name HID Input, Output and Feature Report Descriptor Item Flags */
+		//@{
+			#define HID_IOF_CONSTANT                        (1 << 0)
+			#define HID_IOF_DATA                            (0 << 0)
+			#define HID_IOF_VARIABLE                        (1 << 1)
+			#define HID_IOF_ARRAY                           (0 << 1)
+			#define HID_IOF_RELATIVE                        (1 << 2)
+			#define HID_IOF_ABSOLUTE                        (0 << 2)
+			#define HID_IOF_WRAP                            (1 << 3)
+			#define HID_IOF_NO_WRAP                         (0 << 3)
+			#define HID_IOF_NON_LINEAR                      (1 << 4)
+			#define HID_IOF_LINEAR                          (0 << 4)
+			#define HID_IOF_NO_PREFERRED_STATE              (1 << 5)
+			#define HID_IOF_PREFERRED_STATE                 (0 << 5)
+			#define HID_IOF_NULLSTATE                       (1 << 6)
+			#define HID_IOF_NO_NULL_POSITION                (0 << 6)
+			#define HID_IOF_VOLATILE                        (1 << 7)
+			#define HID_IOF_NON_VOLATILE                    (0 << 7)
+			#define HID_IOF_BUFFERED_BYTES                  (1 << 8)
+			#define HID_IOF_BITFIELD                        (0 << 8)
+		//@}
+
+		/** \name HID Report Descriptor Item Macros */
+		//@{
+			#define HID_RI_INPUT(DataBits, ...)             _HID_RI_ENTRY(HID_RI_TYPE_MAIN  , 0x80, DataBits, __VA_ARGS__)
+			#define HID_RI_OUTPUT(DataBits, ...)            _HID_RI_ENTRY(HID_RI_TYPE_MAIN  , 0x90, DataBits, __VA_ARGS__)
+			#define HID_RI_COLLECTION(DataBits, ...)        _HID_RI_ENTRY(HID_RI_TYPE_MAIN  , 0xA0, DataBits, __VA_ARGS__)
+			#define HID_RI_FEATURE(DataBits, ...)           _HID_RI_ENTRY(HID_RI_TYPE_MAIN  , 0xB0, DataBits, __VA_ARGS__)
+			#define HID_RI_END_COLLECTION(DataBits, ...)    _HID_RI_ENTRY(HID_RI_TYPE_MAIN  , 0xC0, DataBits, __VA_ARGS__)
+			#define HID_RI_USAGE_PAGE(DataBits, ...)        _HID_RI_ENTRY(HID_RI_TYPE_GLOBAL, 0x00, DataBits, __VA_ARGS__)
+			#define HID_RI_LOGICAL_MINIMUM(DataBits, ...)   _HID_RI_ENTRY(HID_RI_TYPE_GLOBAL, 0x10, DataBits, __VA_ARGS__)
+			#define HID_RI_LOGICAL_MAXIMUM(DataBits, ...)   _HID_RI_ENTRY(HID_RI_TYPE_GLOBAL, 0x20, DataBits, __VA_ARGS__)
+			#define HID_RI_PHYSICAL_MINIMUM(DataBits, ...)  _HID_RI_ENTRY(HID_RI_TYPE_GLOBAL, 0x30, DataBits, __VA_ARGS__)
+			#define HID_RI_PHYSICAL_MAXIMUM(DataBits, ...)  _HID_RI_ENTRY(HID_RI_TYPE_GLOBAL, 0x40, DataBits, __VA_ARGS__)
+			#define HID_RI_UNIT_EXPONENT(DataBits, ...)     _HID_RI_ENTRY(HID_RI_TYPE_GLOBAL, 0x50, DataBits, __VA_ARGS__)
+			#define HID_RI_UNIT(DataBits, ...)              _HID_RI_ENTRY(HID_RI_TYPE_GLOBAL, 0x60, DataBits, __VA_ARGS__)
+			#define HID_RI_REPORT_SIZE(DataBits, ...)       _HID_RI_ENTRY(HID_RI_TYPE_GLOBAL, 0x70, DataBits, __VA_ARGS__)
+			#define HID_RI_REPORT_ID(DataBits, ...)         _HID_RI_ENTRY(HID_RI_TYPE_GLOBAL, 0x80, DataBits, __VA_ARGS__)
+			#define HID_RI_REPORT_COUNT(DataBits, ...)      _HID_RI_ENTRY(HID_RI_TYPE_GLOBAL, 0x90, DataBits, __VA_ARGS__)
+			#define HID_RI_PUSH(DataBits, ...)              _HID_RI_ENTRY(HID_RI_TYPE_GLOBAL, 0xA0, DataBits, __VA_ARGS__)
+			#define HID_RI_POP(DataBits, ...)               _HID_RI_ENTRY(HID_RI_TYPE_GLOBAL, 0xB0, DataBits, __VA_ARGS__)
+			#define HID_RI_USAGE(DataBits, ...)             _HID_RI_ENTRY(HID_RI_TYPE_LOCAL , 0x00, DataBits, __VA_ARGS__)
+			#define HID_RI_USAGE_MINIMUM(DataBits, ...)     _HID_RI_ENTRY(HID_RI_TYPE_LOCAL , 0x10, DataBits, __VA_ARGS__)
+			#define HID_RI_USAGE_MAXIMUM(DataBits, ...)     _HID_RI_ENTRY(HID_RI_TYPE_LOCAL , 0x20, DataBits, __VA_ARGS__)
+		//@}
+
+
+
+
+/** @}  */
+
+#ifdef __cplusplus
+    }
+#endif
+
+#endif
+

+ 419 - 419
inc/usb_std.h

@@ -1,419 +1,419 @@
-/* This file is the part of the LUS32 project
- *
- * Copyright ©2016 Dmitry Filimonchuk <dmitrystu[at]gmail[dot]com>
- *
- * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
- * 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.
- */
-
-#ifndef _USB_STD_H_
-#define _USB_STD_H_
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-/**\addtogroup USB_STD USB Standard
- * \brief This module contains generic USB device framework definitions
- * \details This module based on
- * + Chapter 9 of the [Universal Serial Bus Specification Revision 2.0](http://www.usb.org/developers/docs/usb20_docs/usb_20_080416.zip)
- * + [LUFA - the Lightweight USB Framework for AVRs.](https://github.com/abcminiuser/lufa)
- * @{
- *\name Utility functional macros
- * @{ */
-/** Macro to encode major/minor/version number into BCD code
- * \param maj Major version
- * \param min Minor version
- * \param rev Revision
- */
-#define VERSION_BCD(maj, min, rev)  (((maj & 0xFF) << 8) | ((min & 0x0F) << 4) | (rev & 0x0F))
-
-/** Macro to create \ref usb_string_descriptor from array of characters */
-#define USB_STRING_DESC(...)        {.bLength = 2 + sizeof((uint16_t[]){__VA_ARGS__}), .bDescriptorType = USB_DTYPE_STRING, .wString = {__VA_ARGS__}}
-
-/**\brief Macro to set мaximum power consumption field for the \ref usb_config_descriptor */
-#define USB_CFG_POWER_MA(mA)        ((mA) >> 1)
-/** @} */
-
-/**\name USB device configuration definitions
- * @{ */
-#define USB_CFG_ATTR_RESERVED       0x80
-#define USB_CFG_ATTR_SELFPOWERED    0x40
-/** @} */
-
-/** \anchor USB_ENDPOINT_DEF
- *  \name USB endpoint attributes definitions
- * @{ */
-#define USB_EPTYPE_CONTROL          0x00
-#define USB_EPTYPE_ISOCHRONUS       0x01
-#define USB_EPTYPE_BULK             0x02
-#define USB_EPTYPE_INTERRUPT        0x03
-#define USB_EPATTR_NO_SYNC          0x00
-#define USB_EPATTR_ASYNC            0x04
-#define USB_EPATTR_ADAPTIVE         0x08
-#define USB_EPATTR_SYNC             0x0C
-#define USB_EPUSAGE_DATA            0x00
-#define USB_EPUSAGE_FEEDBACK        0x10
-#define USB_EPUSAGE_IMP_FEEDBACK    0x20
-/** @} */
-
-/**\name Special string descriptor indexes
- * @{ */
-#define NO_DESCRIPTOR               0x00    /**< \brief Indicates that a given string descriptor doesn't exists in the device */
-#define INTSERIALNO_DESCRIPTOR      0xFE    /**< \brief Indicates that a given string descriptor is a internal serial number provided by hardware driver */
-/** @} */
-
-/**\name USB class definitions
- * @{ */
-#define USB_CLASS_PER_INTERFACE     0x00 /**< Class defined on interface level */
-#define USB_SUBCLASS_NONE           0x00
-#define USB_PROTO_NONE              0x00
-#define USB_CLASS_AUDIO             0x01 /**< Interface belongs to the Audio device class. */
-#define USB_CLASS_PHYSICAL          0x05 /**< Interface belongs to the Physical device class. */
-#define USB_CLASS_STILL_IMAGE       0x06 /**< Interface belongs to the Still Imaging device class. */
-#define USB_CLASS_PRINTER           0x07 /**< Interface belongs to the Printer device class. */
-#define USB_CLASS_MASS_STORAGE      0x08 /**< Interface belongs to the Mass Storage device class. */
-#define USB_CLASS_HUB               0x09 /**< Device belongs to the HUB device class. */
-#define USB_CLASS_CSCID             0x0B /**< Interface belongs to the Smart Card device class. */
-#define USB_CLASS_CONTENT_SEC       0x0D /**< Interface belongs to the Content Security device class. */
-#define USB_CLASS_VIDEO             0x0E /**< Interface belongs to the Video device class. */
-#define USB_CLASS_HEALTHCARE        0x0F /**< Interface belongs to the Personal Healthcare device class. */
-#define USB_CLASS_AV                0x10 /**< Interface belongs to the Audio/Video device class. */
-#define USB_CLASS_BILLBOARD         0x11 /**< Device belongs to the Billboard device class. */
-#define USB_CLASS_CBRIDGE           0x12 /**< Interface belongs to the USB Type-C Bridge device class. */
-#define USB_CLASS_DIAGNOSTIC        0xDC /**< Device/Interface belongs to the Diagnostic device class. */
-#define USB_CLASS_WIRELESS          0xE0 /**< Interface belongs to the Wireless controller class. */
-#define USB_CLASS_MISC              0xEF /**< Device/Interface belongs to the Miscellanious device class. */
-#define USB_CLASS_APP_SPEC          0xFE /**< Interface belongs to the Application Specific class. */
-#define USB_CLASS_VENDOR            0xFF /**< Device belongs to a vendor specific class. */
-#define USB_SUBCLASS_VENDOR         0xFF /**< Subclass belongs to a vendor specific subclass. */
-#define USB_PROTO_VENDOR            0xFF /**< Protocol belongs to a vendor specific protocol. */
-/** @} */
-
-/**\name USB Standard descriptor types
- * @{ */
-#define USB_DTYPE_DEVICE            0x01 /**< Indicates that the descriptor is a \ref usb_device_descriptor*/
-#define USB_DTYPE_CONFIGURATION     0x02 /**< Indicates that the descriptor is a \ref usb_config_descriptor */
-#define USB_DTYPE_STRING            0x03 /**< Indicates that the descriptor is a \ref usb_string_descriptor */
-#define USB_DTYPE_INTERFACE         0x04 /**< Indicates that the descriptor is a \ref usb_interface_descriptor */
-#define USB_DTYPE_ENDPOINT          0x05 /**< Indicates that the descriptor is an endpoint descriptor. */
-#define USB_DTYPE_QUALIFIER         0x06 /**< Indicates that the descriptor is a \ref usb_qualifier_descriptor */
-#define USB_DTYPE_OTHER             0x07 /**< Indicates that the descriptor is of other type. */
-#define USB_DTYPE_INTERFACEPOWER    0x08 /**< Indicates that the descriptor is an interface power descriptor. */
-#define USB_DTYPE_OTG               0x09 /**< Indicates that the descroptor is an OTG descriptor */
-#define USB_DTYPE_DEBUG             0x0A /**< Indicates that the descriptor is a Debug descriptor */
-#define USB_DTYPE_INTERFASEASSOC    0x0B /**< Indicates that the descriptor is an interface association descriptor. */
-#define USB_DTYPE_CS_INTERFACE      0x24 /**< Indicates that the descriptor is a class specific interface descriptor. */
-#define USB_DTYPE_CS_ENDPOINT       0x25 /**< Indicates that the descriptor is a class specific endpoint descriptor. */
-/** @} */
-
-/**\name USB Standard requests
- * @{ */
-#define USB_STD_GET_STATUS          0x00 /**< This request returns status for the specified recipient */
-#define USB_STD_CLEAR_FEATURE       0x01 /**< This request is used to clear or disable a specific feature */
-#define USB_STD_SET_FEATURE         0x03 /**< This request is used to set or enable a specific feature */
-#define USB_STD_SET_ADDRESS         0x05 /**< This request sets the device address for all future device accesses */
-#define USB_STD_GET_DESCRIPTOR      0x06 /**< This request returns the specified descriptor if the descriptor exists */
-#define USB_STD_SET_DESCRIPTOR      0x07 /**< This request is optional and may be used to update existing descriptors or new descriptors may be added */
-#define USB_STD_GET_CONFIG          0x08 /**< This request returns the current device configuration value */
-#define USB_STD_SET_CONFIG          0x09 /**< This request sets the device configuration */
-#define USB_STD_GET_INTERFACE       0x0A /**< This request returns the selected alternate setting for the specified interface */
-#define USB_STD_SET_INTERFACE       0x0B /**< This request allows the host to select an alternate setting for the specified interface */
-#define USB_STD_SYNCH_FRAME         0x0C /**< This request is used to set and then report an endpoint's synchronization frame */
-/** @} */
-
-/**\name USB Feature selector
- * @{ */
-#define USB_FEAT_ENDPOINT_HALT      0x00
-#define USB_FEAT_REMOTE_WKUP        0x01
-#define USB_FEAT_TEST_MODE          0x02
-#define USB_FEAT_DEBUG_MODE         0x06
-/** @} */
-
-/**\name USB Test mode Selectors
- * @{ */
-#define USB_TEST_J                  0x01
-#define USB_TEST_K                  0x02
-#define USB_TEST_SE0_NAK            0x03
-#define USB_TEST_PACKET             0x04
-#define USB_TEST_FOECR_ENABLE       0x05
-/** @} */
-
-/** \addtogroup USB_STD_LANGID USB standard LANGID codes
- * @{ */
-#define USB_LANGID_AFR          0x0436   /**< Afrikaans */
-#define USB_LANGID_SQI          0x041c   /**< Albanian */
-#define USB_LANGID_ARA_SA       0x0401   /**< Arabic (Saudi Arabia) */
-#define USB_LANGID_ARA_IQ       0x0801   /**< Arabic (Iraq) */
-#define USB_LANGID_ARA_EG       0x0c01   /**< Arabic (Egypt) */
-#define USB_LANGID_ARA_LY       0x1001   /**< Arabic (Libya) */
-#define USB_LANGID_ARA_DZ       0x1401   /**< Arabic (Algeria) */
-#define USB_LANGID_ARA_MA       0x1801   /**< Arabic (Morocco) */
-#define USB_LANGID_ARA_TN       0x1c01   /**< Arabic (Tunisia) */
-#define USB_LANGID_ARA_OM       0x2001   /**< Arabic (Oman) */
-#define USB_LANGID_ARA_YE       0x2401   /**< Arabic (Yemen) */
-#define USB_LANGID_ARA_SY       0x2801   /**< Arabic (Syria) */
-#define USB_LANGID_ARA_JO       0x2c01   /**< Arabic (Jordan) */
-#define USB_LANGID_ARA_LB       0x3001   /**< Arabic (Lebanon) */
-#define USB_LANGID_ARA_KW       0x3401   /**< Arabic (Kuwait) */
-#define USB_LANGID_ARA_AE       0x3801   /**< Arabic (U.A.E.) */
-#define USB_LANGID_ARA_BH       0x3c01   /**< Arabic (Bahrain) */
-#define USB_LANGID_ARA_QA       0x4001   /**< Arabic (Qatar) */
-#define USB_LANGID_HYE          0x042b   /**< Armenian */
-#define USB_LANGID_ASM          0x044d   /**< Assamese */
-#define USB_LANGID_AZE_LAT      0x042c   /**< Azeri (Latin) */
-#define USB_LANGID_AZE_CYR      0x082c   /**< Azeri (Cyrillic) */
-#define USB_LANGID_EUS          0x042d   /**< Basque */
-#define USB_LANGID_BEL          0x0423   /**< Belarussian */
-#define USB_LANGID_BEN          0x0445   /**< Bengali */
-#define USB_LANGID_BUL          0x0402   /**< Bulgarian */
-#define USB_LANGID_MYA          0x0455   /**< Burmese */
-#define USB_LANGID_CAT          0x0403   /**< Catalan */
-#define USB_LANGID_ZHO_TW       0x0404   /**< Chinese (Taiwan) */
-#define USB_LANGID_ZHO_CN       0x0804   /**< Chinese (PRC) */
-#define USB_LANGID_ZHO_HK       0x0c04   /**< Chinese (Hong Kong SAR, PRC) */
-#define USB_LANGID_ZHO_SG       0x1004   /**< Chinese (Singapore) */
-#define USB_LANGID_ZHO_MO       0x1404   /**< Chinese (Macau SAR) */
-#define USB_LANGID_HRV          0x041a   /**< Croatian */
-#define USB_LANGID_CZE          0x0405   /**< Czech */
-#define USB_LANGID_DAN          0x0406   /**< Danish */
-#define USB_LANGID_NLD_NL       0x0413   /**< Dutch (Netherlands) */
-#define USB_LANGID_NLD_BE       0x0813   /**< Dutch (Belgium) */
-#define USB_LANGID_ENG_US       0x0409   /**< English (United States) */
-#define USB_LANGID_ENG_UK       0x0809   /**< English (United Kingdom) */
-#define USB_LANGID_ENG_AU       0x0c09   /**< English (Australian) */
-#define USB_LANGID_ENG_CA       0x1009   /**< English (Canadian) */
-#define USB_LANGID_ENG_NZ       0x1409   /**< English (New Zealand) */
-#define USB_LANGID_ENG_IE       0x1809   /**< English (Ireland) */
-#define USB_LANGID_ENG_ZA       0x1c09   /**< English (South Africa) */
-#define USB_LANGID_ENG_JM       0x2009   /**< English (Jamaica) */
-#define USB_LANGID_ENG_CAR      0x2409   /**< English (Caribbean) */
-#define USB_LANGID_ENG_BZ       0x2809   /**< English (Belize) */
-#define USB_LANGID_ENG_TH       0x2c09   /**< English (Trinidad) */
-#define USB_LANGID_ENG_ZW       0x3009   /**< English (Zimbabwe) */
-#define USB_LANGID_ENG_PH       0x3409   /**< English (Philippines) */
-#define USB_LANGID_EST          0x0425   /**< Estonian */
-#define USB_LANGID_FAO          0x0438   /**< Faeroese */
-#define USB_LANGID_FAS          0x0429   /**< Farsi */
-#define USB_LANGID_FIN          0x040b   /**< Finnish */
-#define USB_LANGID_FRA          0x040c   /**< French (Standard) */
-#define USB_LANGID_FRA_BE       0x080c   /**< French (Belgian) */
-#define USB_LANGID_FRA_CA       0x0c0c   /**< French (Canadian) */
-#define USB_LANGID_FRA_SZ       0x100c   /**< French (Switzerland) */
-#define USB_LANGID_FRA_LU       0x140c   /**< French (Luxembourg) */
-#define USB_LANGID_FRA_MC       0x180c   /**< French (Monaco) */
-#define USB_LANGID_KAT          0x0437   /**< Georgian */
-#define USB_LANGID_DEU          0x0407   /**< German (Standard) */
-#define USB_LANGID_DEU_SZ       0x0807   /**< German (Switzerland) */
-#define USB_LANGID_DEU_AT       0x0c07   /**< German (Austria) */
-#define USB_LANGID_DEU_LU       0x1007   /**< German (Luxembourg) */
-#define USB_LANGID_DEU_LI       0x1407   /**< German (Liechtenstein) */
-#define USB_LANGID_ELL          0x0408   /**< Greek */
-#define USB_LANGID_GUJ          0x0447   /**< Gujarati */
-#define USB_LANGID_HEB          0x040d   /**< Hebrew */
-#define USB_LANGID_HIN          0x0439   /**< Hindi */
-#define USB_LANGID_HUN          0x040e   /**< Hungarian */
-#define USB_LANGID_ISL          0x040f   /**< Icelandic */
-#define USB_LANGID_IND          0x0421   /**< Indonesian */
-#define USB_LANGID_ITA          0x0410   /**< Italian (Standard) */
-#define USB_LANGID_ITA_SZ       0x0810   /**< Italian (Switzerland) */
-#define USB_LANGID_JPN          0x0411   /**< Japanese */
-#define USB_LANGID_KAN          0x044b   /**< Kannada */
-#define USB_LANGID_KAS          0x0860   /**< Kashmiri (India) */
-#define USB_LANGID_KAZ          0x043f   /**< Kazakh */
-#define USB_LANGID_KOK          0x0457   /**< Konkani */
-#define USB_LANGID_KOR          0x0412   /**< Korean */
-#define USB_LANGID_KOR_JOH      0x0812   /**< Korean (Johab) */
-#define USB_LANGID_LAV          0x0426   /**< Latvian */
-#define USB_LANGID_LIT          0x0427   /**< Lithuanian */
-#define USB_LANGID_LIT_CLS      0x0827   /**< Lithuanian (Classic) */
-#define USB_LANGID_MKD          0x042f   /**< Macedonian */
-#define USB_LANGID_MSA          0x043e   /**< Malay (Malaysian) */
-#define USB_LANGID_MSA_BN       0x083e   /**< Malay (Brunei Darussalam) */
-#define USB_LANGID_MAL          0x044c   /**< Malayalam */
-#define USB_LANGID_MNI          0x0458   /**< Manipuri */
-#define USB_LANGID_MAR          0x044e   /**< Marathi */
-#define USB_LANGID_NEP          0x0861   /**< Nepali (India) */
-#define USB_LANGID_NOB          0x0414   /**< Norwegian (Bokmal) */
-#define USB_LANGID_NNO          0x0814   /**< Norwegian (Nynorsk) */
-#define USB_LANGID_ORI          0x0448   /**< Oriya */
-#define USB_LANGID_POL          0x0415   /**< Polish */
-#define USB_LANGID_POR_BR       0x0416   /**< Portuguese (Brazil) */
-#define USB_LANGID_POR          0x0816   /**< Portuguese (Standard) */
-#define USB_LANGID_PAN          0x0446   /**< Punjabi */
-#define USB_LANGID_RON          0x0418   /**< Romanian */
-#define USB_LANGID_RUS          0x0419   /**< Russian */
-#define USB_LANGID_SAN          0x044f   /**< Sanskrit */
-#define USB_LANGID_SRB_CYR      0x0c1a   /**< Serbian (Cyrillic) */
-#define USB_LANGID_SRB_LAT      0x081a   /**< Serbian (Latin) */
-#define USB_LANGID_SND          0x0459   /**< Sindhi */
-#define USB_LANGID_SLK          0x041b   /**< Slovak */
-#define USB_LANGID_SLV          0x0424   /**< Slovenian */
-#define USB_LANGID_SPA          0x040a   /**< Spanish (Traditional Sort) */
-#define USB_LANGID_SPA_MX       0x080a   /**< Spanish (Mexican) */
-#define USB_LANGID_SPA_MDN      0x0c0a   /**< Spanish (Modern Sort) */
-#define USB_LANGID_SPA_GT       0x100a   /**< Spanish (Guatemala) */
-#define USB_LANGID_SPA_CR       0x140a   /**< Spanish (Costa Rica) */
-#define USB_LANGID_SPA_PA       0x180a   /**< Spanish (Panama) */
-#define USB_LANGID_SPA_DO       0x1c0a   /**< Spanish (Dominican Republic) */
-#define USB_LANGID_SPA_VE       0x200a   /**< Spanish (Venezuela) */
-#define USB_LANGID_SPA_CO       0x240a   /**< Spanish (Colombia) */
-#define USB_LANGID_SPA_PE       0x280a   /**< Spanish (Peru) */
-#define USB_LANGID_SPA_AR       0x2c0a   /**< Spanish (Argentina) */
-#define USB_LANGID_SPA_EC       0x300a   /**< Spanish (Ecuador) */
-#define USB_LANGID_SPA_CL       0x340a   /**< Spanish (Chile) */
-#define USB_LANGID_SPA_UY       0x380a   /**< Spanish (Uruguay) */
-#define USB_LANGID_SPA_PY       0x3c0a   /**< Spanish (Paraguay) */
-#define USB_LANGID_SPA_BO       0x400a   /**< Spanish (Bolivia) */
-#define USB_LANGID_SPA_SV       0x440a   /**< Spanish (El Salvador) */
-#define USB_LANGID_SPA_HN       0x480a   /**< Spanish (Honduras) */
-#define USB_LANGID_SPA_NI       0x4c0a   /**< Spanish (Nicaragua) */
-#define USB_LANGID_SPA_PR       0x500a   /**< Spanish (Puerto Rico) */
-#define USB_LANGID_NSO          0x0430   /**< Sutu, Sotho. */
-#define USB_LANGID_SWA          0x0441   /**< Swahili (Kenya) */
-#define USB_LANGID_SWE          0x041d   /**< Swedish */
-#define USB_LANGID_SWE_FI       0x081d   /**< Swedish (Finland) */
-#define USB_LANGID_TAM          0x0449   /**< Tamil */
-#define USB_LANGID_TAT          0x0444   /**< Tatar (Tatarstan) */
-#define USB_LANGID_TEL          0x044a   /**< Telugu */
-#define USB_LANGID_THA          0x041e   /**< Thai */
-#define USB_LANGID_TUR          0x041f   /**< Turkish */
-#define USB_LANGIG_UKR          0x0422   /**< Ukrainian */
-#define USB_LANGID_URD_PK       0x0420   /**< Urdu (Pakistan) */
-#define USB_LANGID_URD_IN       0x0820   /**< Urdu (India) */
-#define USB_LANGID_UZB_LAT      0x0443   /**< Uzbek (Latin) */
-#define USB_LANGID_UZB_CYR      0x0843   /**< Uzbek (Cyrillic) */
-#define USB_LANGID_VIE          0x042a   /**< Vietnamese. */
-/** @} */
-
-/** \brief common USB descriptor header */
-struct usb_header_descriptor {
-    uint8_t bLength;                /**< Size of the descriptor, in bytes. */
-    uint8_t bDescriptorType;        /**< Type of the descriptor. */
-} __attribute__((packed));
-
-/** \brief Represents a USB device descriptor
- *  \details A device descriptor describes general information about a USB device. It includes information that applies
- *           globally to the device and all of the device’s configurations. A USB device has only one device descriptor.
- *           A high-speed capable device that has different device information for full-speed and high-speed must also
- *           have a \ref usb_qualifier_descriptor
- */
-struct usb_device_descriptor {
-    uint8_t  bLength;               /**< Size of the descriptor, in bytes. */
-    uint8_t  bDescriptorType;       /**< Type of the descriptor, must be a \ref USB_DTYPE_DEVICE. */
-    uint16_t bcdUSB;                /**< BCD of the supported USB specification. \ref VERSION_BCD utility macro. */
-    uint8_t  bDeviceClass;          /**< USB device class. */
-    uint8_t  bDeviceSubClass;       /**< USB device subclass. */
-    uint8_t  bDeviceProtocol;       /**< USB device protocol. */
-    uint8_t  bMaxPacketSize0;       /**< Size of the control (address 0) endpoint's bank in bytes. */
-    uint16_t idVendor;              /**< Vendor ID for the USB product. */
-    uint16_t idProduct;             /**< Unique product ID for the USB product. */
-    uint16_t bcdDevice;             /**< Product release (version) number. \ref VERSION_BCD utility macro. */
-    uint8_t  iManufacturer;         /**< String index for the manufacturer's name. */
-    uint8_t  iProduct;              /**< String index for the product name/details. */
-    uint8_t  iSerialNumber;         /**< String index for the product serial number, \ref INTSERIALNO_DESCRIPTOR can be used*/
-    uint8_t  bNumConfigurations;    /**< Total number of configurations supported by the device. */
-} __attribute__((packed));
-
-/** \brief USB device qualifier descriptor
- *  \details The device_qualifier descriptor describes information about a high-speed capable device that would
- *           change if the device were operating at the other speed. For example, if the device is currently operating
- *           at full-speed, the device qualifier returns information about how it would operate at high-speed and vice-versa.
- */
-struct usb_qualifier_descriptor {
-    uint8_t  bLength;               /**< Size of the descriptor, in bytes. */
-    uint8_t  bDescriptorType;       /**< Type of the descriptor, must be a \ref USB_DTYPE_QUALIFIER. */
-    uint16_t bcdUSB;                /**< BCD of the supported USB specification. \ref VERSION_BCD utility macro. */
-    uint8_t  bDeviceClass;          /**< USB device class. */
-    uint8_t  bDeviceSubClass;       /**< USB device subclass. */
-    uint8_t  bDeviceProtocol;       /**< USB device protocol. */
-    uint8_t  bMaxPacketSize0;       /**< Size of the control (address 0) endpoint's bank in bytes. */
-    uint8_t  bNumConfigurations;    /**< Total number of configurations supported by the device. */
-    uint8_t  bReserved;             /**< Reserved for future use, must be 0. */
-} __attribute__((packed));
-/** \brief USB device configuration descriptor
- *  \details The configuration descriptor describes information about a specific device configuration. The descriptor
- *           contains a bConfigurationValue field with a value that, when used as a parameter to the SetConfiguration()
- *           request, causes the device to assume the described configuration.
- */
-struct usb_config_descriptor {
-    uint8_t  bLength;               /**< Size of the descriptor, in bytes. */
-    uint8_t  bDescriptorType;       /**< Type of the descriptor, must be a \ref USB_DTYPE_CONFIGURATION. */
-    uint16_t wTotalLength;          /**< Size of the configuration descriptor header, and all sub descriptors inside the configuration. */
-    uint8_t  bNumInterfaces;        /**< Total number of interfaces in the configuration. */
-    uint8_t  bConfigurationValue;   /**< Configuration index of the current configuration. */
-    uint8_t  iConfiguration;        /**< Index of a string descriptor describing the configuration. */
-    uint8_t  bmAttributes;          /**< Configuration attributes, comprised of a mask of \c USB_CONFIG_ATTR_* masks. On all devices, this should include USB_CONFIG_ATTR_RESERVED at a minimum. */
-    uint8_t  bMaxPower;             /**< Maximum power consumption of the device while in the current configuration, calculated by the \ref USB_CFG_POWER_MA() macro. */
-} __attribute__((packed));
-/** \brief USB interface descriptor
- *  \details The interface descriptor describes a specific interface within a configuration. A configuration provides one or more interfaces,
- *           each with zero or more endpoint descriptors describing a unique set of endpoints within the configuration.
- */
-struct usb_interface_descriptor {
-    uint8_t bLength;                /**< Size of the descriptor, in bytes. */
-    uint8_t bDescriptorType;        /**< Type of the descriptor, must be \ref USB_DTYPE_INTERFACE */
-    uint8_t bInterfaceNumber;       /**< Index of the interface in the current configuration. */
-    uint8_t bAlternateSetting;      /**< Alternate setting for the interface number. */
-    uint8_t bNumEndpoints;          /**< Total number of endpoints in the interface. */
-    uint8_t bInterfaceClass;        /**< Interface class ID. */
-    uint8_t bInterfaceSubClass;     /**< Interface subclass ID. */
-    uint8_t bInterfaceProtocol;     /**< Interface protocol ID. */
-    uint8_t iInterface;             /**< Index of the string descriptor describing the interface. */
-} __attribute__((packed));
-struct usb_iad_descriptor {
-    uint8_t bLength;                /**< Size of the descriptor, in bytes. */
-    uint8_t bDescriptorType;        /**< Type of the descriptor, either a value in */
-    uint8_t bFirstInterface;        /**< Index of the first associated interface. */
-    uint8_t bInterfaceCount;        /**< Total number of associated interfaces. */
-    uint8_t bFunctionClass;         /**< Interface class ID. */
-    uint8_t bFunctionSubClass;      /**< Interface subclass ID. */
-    uint8_t bFunctionProtocol;      /**< Interface protocol ID. */
-    uint8_t iFunction;              /**< Index of the string descriptor describing the interface association. */
-} __attribute__((packed));
-/** \brief USB endpoint descriptor
- *  \details This descriptor contains the information required by the host to determine the bandwidth requirements of each endpoint.
- */
-struct usb_endpoint_descriptor {
-    uint8_t  bLength;               /**< Size of the descriptor, in bytes. */
-    uint8_t  bDescriptorType;       /**< Type of the descriptor, must be \ref USB_DTYPE_ENDPOINT */
-    uint8_t  bEndpointAddress;      /**< Logical address of the endpoint within the device for the current configuration, including direction mask. */
-    uint8_t  bmAttributes;          /**< Endpoint attributes, \ref USB_ENDPOINT_DEF. */
-    uint16_t wMaxPacketSize;        /**< Size of the endpoint bank, in bytes. This indicates the maximum packet size that the endpoint can receive at a time. */
-    uint8_t  bInterval;             /**< Polling interval in milliseconds for the endpoint if it is an INTERRUPT or ISOCHRONOUS type. */
-} __attribute__((packed));
-/** \brief USB string descriptor
- *  \details String descriptors are referenced by their one-based index number. A string descriptor contains one or more not NULL-terminated Unicode strings.
- *  \note String descriptors are optional. if a device does not support string descriptors, all references to string descriptors within device, configuration,
- *        and interface descriptors must be reset to zero.
- */
-struct usb_string_descriptor {
-    uint8_t  bLength;               /**< Size of the descriptor, in bytes. */
-    uint8_t  bDescriptorType;       /**< Type of the descriptor, must be \ref USB_DTYPE_STRING */
-    uint16_t wString[];             /**< String data, as unicode characters (for zero-indexed descriptor, array of \ref USB_STD_LANGID ). */
-} __attribute__((packed));
-/** \brief USB debug descriptor
- *  \details This descriptor is used to describe certain characteristics of the device that the host debug port driver needs to know
- *           to communicate with the device. Specifically, the debug descriptor lists the addresses of the endpoints that comprise the
- *           Debug Pipe. The endpoints are identified by endpoint number.
- */
-struct usb_debug_descriptor {
-    uint8_t  bLength;               /**< Size of the descriptor, in bytes. */
-    uint8_t  bDescriptorType;       /**< Type ot the descriptor, must be \ref USB_DTYPE_DEBUG */
-    uint8_t  bDebugInEndpoint;      /**< Endpoint number of the Debug Data IN endpoint. This is a Bulk-type endpoint with a maximum packet size of 8 bytes.  */
-    uint8_t  bDebugOutEndpoint;     /**< Endpoint number of the Debug Data OUTendpoint. This is a Bulk-type endpoint with a maximum packet size of 8 bytes.  */
-} __attribute__((packed));
-
-
-/** @} */
-
-#if defined (__cplusplus)
-}
-#endif
-#endif //_USB_STD_H_
+/* This file is the part of the LUS32 project
+ *
+ * Copyright ©2016 Dmitry Filimonchuk <dmitrystu[at]gmail[dot]com>
+ *
+ * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ * 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.
+ */
+
+#ifndef _USB_STD_H_
+#define _USB_STD_H_
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/**\addtogroup USB_STD USB Standard
+ * \brief This module contains generic USB device framework definitions
+ * \details This module based on
+ * + Chapter 9 of the [Universal Serial Bus Specification Revision 2.0](http://www.usb.org/developers/docs/usb20_docs/usb_20_080416.zip)
+ * + [LUFA - the Lightweight USB Framework for AVRs.](https://github.com/abcminiuser/lufa)
+ * @{
+ *\name Utility functional macros
+ * @{ */
+/** Macro to encode major/minor/version number into BCD code
+ * \param maj Major version
+ * \param min Minor version
+ * \param rev Revision
+ */
+#define VERSION_BCD(maj, min, rev)  (((maj & 0xFF) << 8) | ((min & 0x0F) << 4) | (rev & 0x0F))
+
+/** Macro to create \ref usb_string_descriptor from array of characters */
+#define USB_STRING_DESC(...)        {.bLength = 2 + sizeof((uint16_t[]){__VA_ARGS__}), .bDescriptorType = USB_DTYPE_STRING, .wString = {__VA_ARGS__}}
+
+/**\brief Macro to set мaximum power consumption field for the \ref usb_config_descriptor */
+#define USB_CFG_POWER_MA(mA)        ((mA) >> 1)
+/** @} */
+
+/**\name USB device configuration definitions
+ * @{ */
+#define USB_CFG_ATTR_RESERVED       0x80
+#define USB_CFG_ATTR_SELFPOWERED    0x40
+/** @} */
+
+/** \anchor USB_ENDPOINT_DEF
+ *  \name USB endpoint attributes definitions
+ * @{ */
+#define USB_EPTYPE_CONTROL          0x00
+#define USB_EPTYPE_ISOCHRONUS       0x01
+#define USB_EPTYPE_BULK             0x02
+#define USB_EPTYPE_INTERRUPT        0x03
+#define USB_EPATTR_NO_SYNC          0x00
+#define USB_EPATTR_ASYNC            0x04
+#define USB_EPATTR_ADAPTIVE         0x08
+#define USB_EPATTR_SYNC             0x0C
+#define USB_EPUSAGE_DATA            0x00
+#define USB_EPUSAGE_FEEDBACK        0x10
+#define USB_EPUSAGE_IMP_FEEDBACK    0x20
+/** @} */
+
+/**\name Special string descriptor indexes
+ * @{ */
+#define NO_DESCRIPTOR               0x00    /**< \brief Indicates that a given string descriptor doesn't exists in the device */
+#define INTSERIALNO_DESCRIPTOR      0xFE    /**< \brief Indicates that a given string descriptor is a internal serial number provided by hardware driver */
+/** @} */
+
+/**\name USB class definitions
+ * @{ */
+#define USB_CLASS_PER_INTERFACE     0x00 /**< Class defined on interface level */
+#define USB_SUBCLASS_NONE           0x00
+#define USB_PROTO_NONE              0x00
+#define USB_CLASS_AUDIO             0x01 /**< Interface belongs to the Audio device class. */
+#define USB_CLASS_PHYSICAL          0x05 /**< Interface belongs to the Physical device class. */
+#define USB_CLASS_STILL_IMAGE       0x06 /**< Interface belongs to the Still Imaging device class. */
+#define USB_CLASS_PRINTER           0x07 /**< Interface belongs to the Printer device class. */
+#define USB_CLASS_MASS_STORAGE      0x08 /**< Interface belongs to the Mass Storage device class. */
+#define USB_CLASS_HUB               0x09 /**< Device belongs to the HUB device class. */
+#define USB_CLASS_CSCID             0x0B /**< Interface belongs to the Smart Card device class. */
+#define USB_CLASS_CONTENT_SEC       0x0D /**< Interface belongs to the Content Security device class. */
+#define USB_CLASS_VIDEO             0x0E /**< Interface belongs to the Video device class. */
+#define USB_CLASS_HEALTHCARE        0x0F /**< Interface belongs to the Personal Healthcare device class. */
+#define USB_CLASS_AV                0x10 /**< Interface belongs to the Audio/Video device class. */
+#define USB_CLASS_BILLBOARD         0x11 /**< Device belongs to the Billboard device class. */
+#define USB_CLASS_CBRIDGE           0x12 /**< Interface belongs to the USB Type-C Bridge device class. */
+#define USB_CLASS_DIAGNOSTIC        0xDC /**< Device/Interface belongs to the Diagnostic device class. */
+#define USB_CLASS_WIRELESS          0xE0 /**< Interface belongs to the Wireless controller class. */
+#define USB_CLASS_MISC              0xEF /**< Device/Interface belongs to the Miscellanious device class. */
+#define USB_CLASS_APP_SPEC          0xFE /**< Interface belongs to the Application Specific class. */
+#define USB_CLASS_VENDOR            0xFF /**< Device belongs to a vendor specific class. */
+#define USB_SUBCLASS_VENDOR         0xFF /**< Subclass belongs to a vendor specific subclass. */
+#define USB_PROTO_VENDOR            0xFF /**< Protocol belongs to a vendor specific protocol. */
+/** @} */
+
+/**\name USB Standard descriptor types
+ * @{ */
+#define USB_DTYPE_DEVICE            0x01 /**< Indicates that the descriptor is a \ref usb_device_descriptor*/
+#define USB_DTYPE_CONFIGURATION     0x02 /**< Indicates that the descriptor is a \ref usb_config_descriptor */
+#define USB_DTYPE_STRING            0x03 /**< Indicates that the descriptor is a \ref usb_string_descriptor */
+#define USB_DTYPE_INTERFACE         0x04 /**< Indicates that the descriptor is a \ref usb_interface_descriptor */
+#define USB_DTYPE_ENDPOINT          0x05 /**< Indicates that the descriptor is an endpoint descriptor. */
+#define USB_DTYPE_QUALIFIER         0x06 /**< Indicates that the descriptor is a \ref usb_qualifier_descriptor */
+#define USB_DTYPE_OTHER             0x07 /**< Indicates that the descriptor is of other type. */
+#define USB_DTYPE_INTERFACEPOWER    0x08 /**< Indicates that the descriptor is an interface power descriptor. */
+#define USB_DTYPE_OTG               0x09 /**< Indicates that the descroptor is an OTG descriptor */
+#define USB_DTYPE_DEBUG             0x0A /**< Indicates that the descriptor is a Debug descriptor */
+#define USB_DTYPE_INTERFASEASSOC    0x0B /**< Indicates that the descriptor is an interface association descriptor. */
+#define USB_DTYPE_CS_INTERFACE      0x24 /**< Indicates that the descriptor is a class specific interface descriptor. */
+#define USB_DTYPE_CS_ENDPOINT       0x25 /**< Indicates that the descriptor is a class specific endpoint descriptor. */
+/** @} */
+
+/**\name USB Standard requests
+ * @{ */
+#define USB_STD_GET_STATUS          0x00 /**< This request returns status for the specified recipient */
+#define USB_STD_CLEAR_FEATURE       0x01 /**< This request is used to clear or disable a specific feature */
+#define USB_STD_SET_FEATURE         0x03 /**< This request is used to set or enable a specific feature */
+#define USB_STD_SET_ADDRESS         0x05 /**< This request sets the device address for all future device accesses */
+#define USB_STD_GET_DESCRIPTOR      0x06 /**< This request returns the specified descriptor if the descriptor exists */
+#define USB_STD_SET_DESCRIPTOR      0x07 /**< This request is optional and may be used to update existing descriptors or new descriptors may be added */
+#define USB_STD_GET_CONFIG          0x08 /**< This request returns the current device configuration value */
+#define USB_STD_SET_CONFIG          0x09 /**< This request sets the device configuration */
+#define USB_STD_GET_INTERFACE       0x0A /**< This request returns the selected alternate setting for the specified interface */
+#define USB_STD_SET_INTERFACE       0x0B /**< This request allows the host to select an alternate setting for the specified interface */
+#define USB_STD_SYNCH_FRAME         0x0C /**< This request is used to set and then report an endpoint's synchronization frame */
+/** @} */
+
+/**\name USB Feature selector
+ * @{ */
+#define USB_FEAT_ENDPOINT_HALT      0x00
+#define USB_FEAT_REMOTE_WKUP        0x01
+#define USB_FEAT_TEST_MODE          0x02
+#define USB_FEAT_DEBUG_MODE         0x06
+/** @} */
+
+/**\name USB Test mode Selectors
+ * @{ */
+#define USB_TEST_J                  0x01
+#define USB_TEST_K                  0x02
+#define USB_TEST_SE0_NAK            0x03
+#define USB_TEST_PACKET             0x04
+#define USB_TEST_FOECR_ENABLE       0x05
+/** @} */
+
+/** \addtogroup USB_STD_LANGID USB standard LANGID codes
+ * @{ */
+#define USB_LANGID_AFR          0x0436   /**< Afrikaans */
+#define USB_LANGID_SQI          0x041c   /**< Albanian */
+#define USB_LANGID_ARA_SA       0x0401   /**< Arabic (Saudi Arabia) */
+#define USB_LANGID_ARA_IQ       0x0801   /**< Arabic (Iraq) */
+#define USB_LANGID_ARA_EG       0x0c01   /**< Arabic (Egypt) */
+#define USB_LANGID_ARA_LY       0x1001   /**< Arabic (Libya) */
+#define USB_LANGID_ARA_DZ       0x1401   /**< Arabic (Algeria) */
+#define USB_LANGID_ARA_MA       0x1801   /**< Arabic (Morocco) */
+#define USB_LANGID_ARA_TN       0x1c01   /**< Arabic (Tunisia) */
+#define USB_LANGID_ARA_OM       0x2001   /**< Arabic (Oman) */
+#define USB_LANGID_ARA_YE       0x2401   /**< Arabic (Yemen) */
+#define USB_LANGID_ARA_SY       0x2801   /**< Arabic (Syria) */
+#define USB_LANGID_ARA_JO       0x2c01   /**< Arabic (Jordan) */
+#define USB_LANGID_ARA_LB       0x3001   /**< Arabic (Lebanon) */
+#define USB_LANGID_ARA_KW       0x3401   /**< Arabic (Kuwait) */
+#define USB_LANGID_ARA_AE       0x3801   /**< Arabic (U.A.E.) */
+#define USB_LANGID_ARA_BH       0x3c01   /**< Arabic (Bahrain) */
+#define USB_LANGID_ARA_QA       0x4001   /**< Arabic (Qatar) */
+#define USB_LANGID_HYE          0x042b   /**< Armenian */
+#define USB_LANGID_ASM          0x044d   /**< Assamese */
+#define USB_LANGID_AZE_LAT      0x042c   /**< Azeri (Latin) */
+#define USB_LANGID_AZE_CYR      0x082c   /**< Azeri (Cyrillic) */
+#define USB_LANGID_EUS          0x042d   /**< Basque */
+#define USB_LANGID_BEL          0x0423   /**< Belarussian */
+#define USB_LANGID_BEN          0x0445   /**< Bengali */
+#define USB_LANGID_BUL          0x0402   /**< Bulgarian */
+#define USB_LANGID_MYA          0x0455   /**< Burmese */
+#define USB_LANGID_CAT          0x0403   /**< Catalan */
+#define USB_LANGID_ZHO_TW       0x0404   /**< Chinese (Taiwan) */
+#define USB_LANGID_ZHO_CN       0x0804   /**< Chinese (PRC) */
+#define USB_LANGID_ZHO_HK       0x0c04   /**< Chinese (Hong Kong SAR, PRC) */
+#define USB_LANGID_ZHO_SG       0x1004   /**< Chinese (Singapore) */
+#define USB_LANGID_ZHO_MO       0x1404   /**< Chinese (Macau SAR) */
+#define USB_LANGID_HRV          0x041a   /**< Croatian */
+#define USB_LANGID_CZE          0x0405   /**< Czech */
+#define USB_LANGID_DAN          0x0406   /**< Danish */
+#define USB_LANGID_NLD_NL       0x0413   /**< Dutch (Netherlands) */
+#define USB_LANGID_NLD_BE       0x0813   /**< Dutch (Belgium) */
+#define USB_LANGID_ENG_US       0x0409   /**< English (United States) */
+#define USB_LANGID_ENG_UK       0x0809   /**< English (United Kingdom) */
+#define USB_LANGID_ENG_AU       0x0c09   /**< English (Australian) */
+#define USB_LANGID_ENG_CA       0x1009   /**< English (Canadian) */
+#define USB_LANGID_ENG_NZ       0x1409   /**< English (New Zealand) */
+#define USB_LANGID_ENG_IE       0x1809   /**< English (Ireland) */
+#define USB_LANGID_ENG_ZA       0x1c09   /**< English (South Africa) */
+#define USB_LANGID_ENG_JM       0x2009   /**< English (Jamaica) */
+#define USB_LANGID_ENG_CAR      0x2409   /**< English (Caribbean) */
+#define USB_LANGID_ENG_BZ       0x2809   /**< English (Belize) */
+#define USB_LANGID_ENG_TH       0x2c09   /**< English (Trinidad) */
+#define USB_LANGID_ENG_ZW       0x3009   /**< English (Zimbabwe) */
+#define USB_LANGID_ENG_PH       0x3409   /**< English (Philippines) */
+#define USB_LANGID_EST          0x0425   /**< Estonian */
+#define USB_LANGID_FAO          0x0438   /**< Faeroese */
+#define USB_LANGID_FAS          0x0429   /**< Farsi */
+#define USB_LANGID_FIN          0x040b   /**< Finnish */
+#define USB_LANGID_FRA          0x040c   /**< French (Standard) */
+#define USB_LANGID_FRA_BE       0x080c   /**< French (Belgian) */
+#define USB_LANGID_FRA_CA       0x0c0c   /**< French (Canadian) */
+#define USB_LANGID_FRA_SZ       0x100c   /**< French (Switzerland) */
+#define USB_LANGID_FRA_LU       0x140c   /**< French (Luxembourg) */
+#define USB_LANGID_FRA_MC       0x180c   /**< French (Monaco) */
+#define USB_LANGID_KAT          0x0437   /**< Georgian */
+#define USB_LANGID_DEU          0x0407   /**< German (Standard) */
+#define USB_LANGID_DEU_SZ       0x0807   /**< German (Switzerland) */
+#define USB_LANGID_DEU_AT       0x0c07   /**< German (Austria) */
+#define USB_LANGID_DEU_LU       0x1007   /**< German (Luxembourg) */
+#define USB_LANGID_DEU_LI       0x1407   /**< German (Liechtenstein) */
+#define USB_LANGID_ELL          0x0408   /**< Greek */
+#define USB_LANGID_GUJ          0x0447   /**< Gujarati */
+#define USB_LANGID_HEB          0x040d   /**< Hebrew */
+#define USB_LANGID_HIN          0x0439   /**< Hindi */
+#define USB_LANGID_HUN          0x040e   /**< Hungarian */
+#define USB_LANGID_ISL          0x040f   /**< Icelandic */
+#define USB_LANGID_IND          0x0421   /**< Indonesian */
+#define USB_LANGID_ITA          0x0410   /**< Italian (Standard) */
+#define USB_LANGID_ITA_SZ       0x0810   /**< Italian (Switzerland) */
+#define USB_LANGID_JPN          0x0411   /**< Japanese */
+#define USB_LANGID_KAN          0x044b   /**< Kannada */
+#define USB_LANGID_KAS          0x0860   /**< Kashmiri (India) */
+#define USB_LANGID_KAZ          0x043f   /**< Kazakh */
+#define USB_LANGID_KOK          0x0457   /**< Konkani */
+#define USB_LANGID_KOR          0x0412   /**< Korean */
+#define USB_LANGID_KOR_JOH      0x0812   /**< Korean (Johab) */
+#define USB_LANGID_LAV          0x0426   /**< Latvian */
+#define USB_LANGID_LIT          0x0427   /**< Lithuanian */
+#define USB_LANGID_LIT_CLS      0x0827   /**< Lithuanian (Classic) */
+#define USB_LANGID_MKD          0x042f   /**< Macedonian */
+#define USB_LANGID_MSA          0x043e   /**< Malay (Malaysian) */
+#define USB_LANGID_MSA_BN       0x083e   /**< Malay (Brunei Darussalam) */
+#define USB_LANGID_MAL          0x044c   /**< Malayalam */
+#define USB_LANGID_MNI          0x0458   /**< Manipuri */
+#define USB_LANGID_MAR          0x044e   /**< Marathi */
+#define USB_LANGID_NEP          0x0861   /**< Nepali (India) */
+#define USB_LANGID_NOB          0x0414   /**< Norwegian (Bokmal) */
+#define USB_LANGID_NNO          0x0814   /**< Norwegian (Nynorsk) */
+#define USB_LANGID_ORI          0x0448   /**< Oriya */
+#define USB_LANGID_POL          0x0415   /**< Polish */
+#define USB_LANGID_POR_BR       0x0416   /**< Portuguese (Brazil) */
+#define USB_LANGID_POR          0x0816   /**< Portuguese (Standard) */
+#define USB_LANGID_PAN          0x0446   /**< Punjabi */
+#define USB_LANGID_RON          0x0418   /**< Romanian */
+#define USB_LANGID_RUS          0x0419   /**< Russian */
+#define USB_LANGID_SAN          0x044f   /**< Sanskrit */
+#define USB_LANGID_SRB_CYR      0x0c1a   /**< Serbian (Cyrillic) */
+#define USB_LANGID_SRB_LAT      0x081a   /**< Serbian (Latin) */
+#define USB_LANGID_SND          0x0459   /**< Sindhi */
+#define USB_LANGID_SLK          0x041b   /**< Slovak */
+#define USB_LANGID_SLV          0x0424   /**< Slovenian */
+#define USB_LANGID_SPA          0x040a   /**< Spanish (Traditional Sort) */
+#define USB_LANGID_SPA_MX       0x080a   /**< Spanish (Mexican) */
+#define USB_LANGID_SPA_MDN      0x0c0a   /**< Spanish (Modern Sort) */
+#define USB_LANGID_SPA_GT       0x100a   /**< Spanish (Guatemala) */
+#define USB_LANGID_SPA_CR       0x140a   /**< Spanish (Costa Rica) */
+#define USB_LANGID_SPA_PA       0x180a   /**< Spanish (Panama) */
+#define USB_LANGID_SPA_DO       0x1c0a   /**< Spanish (Dominican Republic) */
+#define USB_LANGID_SPA_VE       0x200a   /**< Spanish (Venezuela) */
+#define USB_LANGID_SPA_CO       0x240a   /**< Spanish (Colombia) */
+#define USB_LANGID_SPA_PE       0x280a   /**< Spanish (Peru) */
+#define USB_LANGID_SPA_AR       0x2c0a   /**< Spanish (Argentina) */
+#define USB_LANGID_SPA_EC       0x300a   /**< Spanish (Ecuador) */
+#define USB_LANGID_SPA_CL       0x340a   /**< Spanish (Chile) */
+#define USB_LANGID_SPA_UY       0x380a   /**< Spanish (Uruguay) */
+#define USB_LANGID_SPA_PY       0x3c0a   /**< Spanish (Paraguay) */
+#define USB_LANGID_SPA_BO       0x400a   /**< Spanish (Bolivia) */
+#define USB_LANGID_SPA_SV       0x440a   /**< Spanish (El Salvador) */
+#define USB_LANGID_SPA_HN       0x480a   /**< Spanish (Honduras) */
+#define USB_LANGID_SPA_NI       0x4c0a   /**< Spanish (Nicaragua) */
+#define USB_LANGID_SPA_PR       0x500a   /**< Spanish (Puerto Rico) */
+#define USB_LANGID_NSO          0x0430   /**< Sutu, Sotho. */
+#define USB_LANGID_SWA          0x0441   /**< Swahili (Kenya) */
+#define USB_LANGID_SWE          0x041d   /**< Swedish */
+#define USB_LANGID_SWE_FI       0x081d   /**< Swedish (Finland) */
+#define USB_LANGID_TAM          0x0449   /**< Tamil */
+#define USB_LANGID_TAT          0x0444   /**< Tatar (Tatarstan) */
+#define USB_LANGID_TEL          0x044a   /**< Telugu */
+#define USB_LANGID_THA          0x041e   /**< Thai */
+#define USB_LANGID_TUR          0x041f   /**< Turkish */
+#define USB_LANGIG_UKR          0x0422   /**< Ukrainian */
+#define USB_LANGID_URD_PK       0x0420   /**< Urdu (Pakistan) */
+#define USB_LANGID_URD_IN       0x0820   /**< Urdu (India) */
+#define USB_LANGID_UZB_LAT      0x0443   /**< Uzbek (Latin) */
+#define USB_LANGID_UZB_CYR      0x0843   /**< Uzbek (Cyrillic) */
+#define USB_LANGID_VIE          0x042a   /**< Vietnamese. */
+/** @} */
+
+/** \brief common USB descriptor header */
+struct usb_header_descriptor {
+    uint8_t bLength;                /**< Size of the descriptor, in bytes. */
+    uint8_t bDescriptorType;        /**< Type of the descriptor. */
+} __attribute__((packed));
+
+/** \brief Represents a USB device descriptor
+ *  \details A device descriptor describes general information about a USB device. It includes information that applies
+ *           globally to the device and all of the device’s configurations. A USB device has only one device descriptor.
+ *           A high-speed capable device that has different device information for full-speed and high-speed must also
+ *           have a \ref usb_qualifier_descriptor
+ */
+struct usb_device_descriptor {
+    uint8_t  bLength;               /**< Size of the descriptor, in bytes. */
+    uint8_t  bDescriptorType;       /**< Type of the descriptor, must be a \ref USB_DTYPE_DEVICE. */
+    uint16_t bcdUSB;                /**< BCD of the supported USB specification. \ref VERSION_BCD utility macro. */
+    uint8_t  bDeviceClass;          /**< USB device class. */
+    uint8_t  bDeviceSubClass;       /**< USB device subclass. */
+    uint8_t  bDeviceProtocol;       /**< USB device protocol. */
+    uint8_t  bMaxPacketSize0;       /**< Size of the control (address 0) endpoint's bank in bytes. */
+    uint16_t idVendor;              /**< Vendor ID for the USB product. */
+    uint16_t idProduct;             /**< Unique product ID for the USB product. */
+    uint16_t bcdDevice;             /**< Product release (version) number. \ref VERSION_BCD utility macro. */
+    uint8_t  iManufacturer;         /**< String index for the manufacturer's name. */
+    uint8_t  iProduct;              /**< String index for the product name/details. */
+    uint8_t  iSerialNumber;         /**< String index for the product serial number, \ref INTSERIALNO_DESCRIPTOR can be used*/
+    uint8_t  bNumConfigurations;    /**< Total number of configurations supported by the device. */
+} __attribute__((packed));
+
+/** \brief USB device qualifier descriptor
+ *  \details The device_qualifier descriptor describes information about a high-speed capable device that would
+ *           change if the device were operating at the other speed. For example, if the device is currently operating
+ *           at full-speed, the device qualifier returns information about how it would operate at high-speed and vice-versa.
+ */
+struct usb_qualifier_descriptor {
+    uint8_t  bLength;               /**< Size of the descriptor, in bytes. */
+    uint8_t  bDescriptorType;       /**< Type of the descriptor, must be a \ref USB_DTYPE_QUALIFIER. */
+    uint16_t bcdUSB;                /**< BCD of the supported USB specification. \ref VERSION_BCD utility macro. */
+    uint8_t  bDeviceClass;          /**< USB device class. */
+    uint8_t  bDeviceSubClass;       /**< USB device subclass. */
+    uint8_t  bDeviceProtocol;       /**< USB device protocol. */
+    uint8_t  bMaxPacketSize0;       /**< Size of the control (address 0) endpoint's bank in bytes. */
+    uint8_t  bNumConfigurations;    /**< Total number of configurations supported by the device. */
+    uint8_t  bReserved;             /**< Reserved for future use, must be 0. */
+} __attribute__((packed));
+/** \brief USB device configuration descriptor
+ *  \details The configuration descriptor describes information about a specific device configuration. The descriptor
+ *           contains a bConfigurationValue field with a value that, when used as a parameter to the SetConfiguration()
+ *           request, causes the device to assume the described configuration.
+ */
+struct usb_config_descriptor {
+    uint8_t  bLength;               /**< Size of the descriptor, in bytes. */
+    uint8_t  bDescriptorType;       /**< Type of the descriptor, must be a \ref USB_DTYPE_CONFIGURATION. */
+    uint16_t wTotalLength;          /**< Size of the configuration descriptor header, and all sub descriptors inside the configuration. */
+    uint8_t  bNumInterfaces;        /**< Total number of interfaces in the configuration. */
+    uint8_t  bConfigurationValue;   /**< Configuration index of the current configuration. */
+    uint8_t  iConfiguration;        /**< Index of a string descriptor describing the configuration. */
+    uint8_t  bmAttributes;          /**< Configuration attributes, comprised of a mask of \c USB_CONFIG_ATTR_* masks. On all devices, this should include USB_CONFIG_ATTR_RESERVED at a minimum. */
+    uint8_t  bMaxPower;             /**< Maximum power consumption of the device while in the current configuration, calculated by the \ref USB_CFG_POWER_MA() macro. */
+} __attribute__((packed));
+/** \brief USB interface descriptor
+ *  \details The interface descriptor describes a specific interface within a configuration. A configuration provides one or more interfaces,
+ *           each with zero or more endpoint descriptors describing a unique set of endpoints within the configuration.
+ */
+struct usb_interface_descriptor {
+    uint8_t bLength;                /**< Size of the descriptor, in bytes. */
+    uint8_t bDescriptorType;        /**< Type of the descriptor, must be \ref USB_DTYPE_INTERFACE */
+    uint8_t bInterfaceNumber;       /**< Index of the interface in the current configuration. */
+    uint8_t bAlternateSetting;      /**< Alternate setting for the interface number. */
+    uint8_t bNumEndpoints;          /**< Total number of endpoints in the interface. */
+    uint8_t bInterfaceClass;        /**< Interface class ID. */
+    uint8_t bInterfaceSubClass;     /**< Interface subclass ID. */
+    uint8_t bInterfaceProtocol;     /**< Interface protocol ID. */
+    uint8_t iInterface;             /**< Index of the string descriptor describing the interface. */
+} __attribute__((packed));
+struct usb_iad_descriptor {
+    uint8_t bLength;                /**< Size of the descriptor, in bytes. */
+    uint8_t bDescriptorType;        /**< Type of the descriptor, either a value in */
+    uint8_t bFirstInterface;        /**< Index of the first associated interface. */
+    uint8_t bInterfaceCount;        /**< Total number of associated interfaces. */
+    uint8_t bFunctionClass;         /**< Interface class ID. */
+    uint8_t bFunctionSubClass;      /**< Interface subclass ID. */
+    uint8_t bFunctionProtocol;      /**< Interface protocol ID. */
+    uint8_t iFunction;              /**< Index of the string descriptor describing the interface association. */
+} __attribute__((packed));
+/** \brief USB endpoint descriptor
+ *  \details This descriptor contains the information required by the host to determine the bandwidth requirements of each endpoint.
+ */
+struct usb_endpoint_descriptor {
+    uint8_t  bLength;               /**< Size of the descriptor, in bytes. */
+    uint8_t  bDescriptorType;       /**< Type of the descriptor, must be \ref USB_DTYPE_ENDPOINT */
+    uint8_t  bEndpointAddress;      /**< Logical address of the endpoint within the device for the current configuration, including direction mask. */
+    uint8_t  bmAttributes;          /**< Endpoint attributes, \ref USB_ENDPOINT_DEF. */
+    uint16_t wMaxPacketSize;        /**< Size of the endpoint bank, in bytes. This indicates the maximum packet size that the endpoint can receive at a time. */
+    uint8_t  bInterval;             /**< Polling interval in milliseconds for the endpoint if it is an INTERRUPT or ISOCHRONOUS type. */
+} __attribute__((packed));
+/** \brief USB string descriptor
+ *  \details String descriptors are referenced by their one-based index number. A string descriptor contains one or more not NULL-terminated Unicode strings.
+ *  \note String descriptors are optional. if a device does not support string descriptors, all references to string descriptors within device, configuration,
+ *        and interface descriptors must be reset to zero.
+ */
+struct usb_string_descriptor {
+    uint8_t  bLength;               /**< Size of the descriptor, in bytes. */
+    uint8_t  bDescriptorType;       /**< Type of the descriptor, must be \ref USB_DTYPE_STRING */
+    uint16_t wString[];             /**< String data, as unicode characters (for zero-indexed descriptor, array of \ref USB_STD_LANGID ). */
+} __attribute__((packed));
+/** \brief USB debug descriptor
+ *  \details This descriptor is used to describe certain characteristics of the device that the host debug port driver needs to know
+ *           to communicate with the device. Specifically, the debug descriptor lists the addresses of the endpoints that comprise the
+ *           Debug Pipe. The endpoints are identified by endpoint number.
+ */
+struct usb_debug_descriptor {
+    uint8_t  bLength;               /**< Size of the descriptor, in bytes. */
+    uint8_t  bDescriptorType;       /**< Type ot the descriptor, must be \ref USB_DTYPE_DEBUG */
+    uint8_t  bDebugInEndpoint;      /**< Endpoint number of the Debug Data IN endpoint. This is a Bulk-type endpoint with a maximum packet size of 8 bytes.  */
+    uint8_t  bDebugOutEndpoint;     /**< Endpoint number of the Debug Data OUTendpoint. This is a Bulk-type endpoint with a maximum packet size of 8 bytes.  */
+} __attribute__((packed));
+
+
+/** @} */
+
+#if defined (__cplusplus)
+}
+#endif
+#endif //_USB_STD_H_

+ 441 - 441
inc/usbd_core.h

@@ -1,441 +1,441 @@
-/* This file is the part of the LUS32 project
- *
- * Copyright ©2016 Dmitry Filimonchuk <dmitrystu[at]gmail[dot]com>
- *
- * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
- * 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.
- */
-
-/** \file usbd_core.h
- * \brief Core and hardware driver framework.
- * \author Dmitry Filimonchuk <dmitrystu[at]gmail[dot]com>
- * \version 1.0
- * \copyright Apache License, Version 2.0
- */
-
-#ifndef _USBD_CORE_H_
-#define _USBD_CORE_H_
-#if defined(__cplusplus)
-    extern "C" {
-#endif
-
-
-/** \addtogroup USBD_CORE USB device core
- * \brief Contains core and hardware driver framework definitions
- * @{ */
-#define USB_EPTYPE_DBLBUF       0x04        /**< indicates a doublebuffered endpoint (bulk endpoint only) */
-#define USB_EPDIR_IN            0x00        /**< indicates host-to-device endpoint direction  */
-#define USB_EPDIR_OUT           0x80        /**< indicates device-to-host endpoint direction */
-
-
-/** \name bmRequestType bitmapped field
- * @{ */
-#define USB_REQ_DIRECTION       (1 << 7)
-#define USB_REQ_HOSTTODEV       (0 << 7)
-#define USB_REQ_DEVTOHOST       (1 << 7)
-#define USB_REQ_TYPE            (3 << 5)
-#define USB_REQ_STANDARD        (0 << 5)
-#define USB_REQ_CLASS           (1 << 5)
-#define USB_REQ_VENDOR          (2 << 5)
-#define USB_REQ_RECIPIENT       (3 << 0)
-#define USB_REQ_DEVICE          (0 << 0)
-#define USB_REQ_INTERFACE       (1 << 0)
-#define USB_REQ_ENDPOINT        (2 << 0)
-#define USB_REQ_OTHER           (3 << 0)
-/** @} */
-
-
-#if defined(__ASSEMBLER__)
-    #define usbd_evt_reset      0
-    #define usbd_evt_sof        1
-    #define usbd_evt_susp       2
-    #define usbd_evt_wkup       3
-    #define usbd_evt_eptx       4
-    #define usbd_evt_eprx       5
-    #define usbd_evt_epsetup    6
-    #define usbd_evt_error      7
-    #define usbd_evt_esof       8
-#else
-
-
-/** USB device events */
-enum usbd_evt {
-    usbd_evt_reset,             /**< Reset */
-    usbd_evt_sof,               /**< Start Of Frame */
-    usbd_evt_susp,              /**< Suspend */
-    usbd_evt_wkup,              /**< Wakeup */
-    usbd_evt_eptx,              /**< Transmit completed */
-    usbd_evt_eprx,              /**< Data packet received */
-    usbd_evt_epsetup,           /**< Setup packet received */
-    usbd_evt_error,             /**< Data error */
-    usbd_evt_esof,              /**< Missed SOF */
-    usbd_evt_count, /* this is trick to count qty */
-};
-
-/** USB device machine state */
-enum usbd_machine_state {
-    usbd_state_disabled,
-    usbd_state_disconnected,
-    usbd_state_default,         /**< Default */
-    usbd_state_addressed,       /**< Addressed */
-    usbd_state_configured,      /**< Configured */
-};
-
-/** USB device control endpoint machine state */
-enum usbd_ctl_state {
-    usbd_ctl_idle,              /**< Idle. Awaiting for SETUP packet */
-    usbd_ctl_rxdata,            /**< RX. Receiving DATA-OUT payload */
-    usbd_ctl_txdata,            /**< TX. Transmitting DATA-IN payload */
-    usbd_ctl_ztxdata,           /**< TX. Transmitting DATA-IN payload. Zero length packet maybe required. */
-    usbd_ctl_lastdata,          /**< TX. Last DATA-IN packed passed to buffer. Awaiting for the TX completion */
-    usbd_ctl_statusin,          /**< STATUS-IN stage */
-    usbd_ctl_statusout,         /**< STATUS-OUT stage */
-};
-
-/** Asynchronous device control commands  */
-enum usbd_commands {
-    usbd_cmd_enable,            /**< Enables device */
-    usbd_cmd_disable,           /**< Disables device */
-    usbd_cmd_connect,           /**< Connects device to host */
-    usbd_cmd_disconnect,        /**< Disconnects device from host */
-    usbd_cmd_reset,             /**< Resets device */
-};
-
-/* Reporting status results */
-typedef enum _usbd_respond {
-    usbd_fail,                  /**< Function has an error, STALLPID will be issued */
-    usbd_ack,                   /**< Function completes request accepted ZLP or data will be send */
-    usbd_nak,                   /**< Function is busy. NAK handshake */
-} usbd_respond;
-
-typedef struct _usbd_device usbd_device;
-typedef struct _usbd_ctlreq usbd_ctlreq;
-typedef struct _usbd_status usbd_status;
-
-/** \addtogroup USB_CORE_API Core API functions
- * @{ */
- /** Generic USB device event callback for events and endpoints processing
-  * \param[in] dev pointer to USB device
-  * \param event \ref usbd_evt "USB event"
-  * \param ep active endpoint number
-  * \note endpoints with same indexes i.e. 0x01 and 0x81 shares same callback.
-  */
-typedef void (*usbd_evt_callback)(usbd_device *dev, uint8_t event, uint8_t ep);
-
-/** USB control transfer completed callback function typedef.
- * \param[in] dev pointer to USB device
- * \param[in] req pointer to usb request structure
- * \note When this callback will be completed usbd_device#complete_callback will be reseted to NULL
- */
-typedef void (*usbd_ctl_complete)(usbd_device *dev, usbd_ctlreq *req);
-
-/** USB control callback function typedef.
- * \details Uses for the control request processing.
- *          Some requests will be handled by core if callback don't process it (returns FALSE). If request was not processed STALL PID will be issued.
- *          - GET_CONFIGURATION
- *          - SET_CONFIGURATION (passes to \ref usbd_cfg_callback)
- *          - GET_DESCRIPTOR (passes to \ref usbd_dsc_callback)
- *          - GET_STATUS
- *          - SET_FEATURE, CLEAR_FEATURE (endpoints only)
- *          - SET_ADDRESS
- * \param[in] dev points to USB device
- * \param[in] req points to usb control request
- * \param[out] *callback \ref usbd_ctl_complete "pointer to USB control transfer completed callback", default is NULL (no callback)
- * \return usbd_respond status.
- */
-typedef usbd_respond (*usbd_ctl_callback)(usbd_device *dev, usbd_ctlreq *req, usbd_ctl_complete *callback);
-
-/** USB get descriptor callback function typedef
- * \details Called when GET_DESCRIPTOR request issued
- * \param[in] req pointer to usb control request structure
- * \param[in,out] address pointer to the descriptor in memory. Points to req->data by default. You can use this buffer.
- * \param[in,out] dsize descriptor size. req->data buffer size by default.
- * \return TRUE if you passed the correct descriptor, FALSE otherwise.
- */
-typedef bool (*usbd_dsc_callback)(usbd_ctlreq *req, void **address, uint16_t *dsize);
-
-/** USB set configuration callback function typedef
- * \details called when SET_CONFIGURATION request issued
- * \param[in] dev pointer to USB device
- * \param[in] cfg configuration number.
- * \note if config is 0 device endpoints should be de-configured
- * \return TRUE if success
- */
-typedef bool (*usbd_cfg_callback)(usbd_device *dev, uint8_t cfg);
-
-/** @} */
-
-/**\addtogroup USB_HW_API Hardware driver API functions 
- * @{ */
-
-/** Enables or disables USB hardware
- * \param enable Enables USB when TRUE disables otherwise
- */
-typedef void (*usbd_hw_enable)(bool enable);
-
-/** Resets USB hardware */
-typedef void (*usbd_hw_reset)(void);
-
-/** Connects or disconnects USB hardware to/from usb host
- * \param connect Connects USB to host if TRUE, disconnects otherwise
- */
-typedef void (*usbd_hw_connect)(bool connect);
-
-/** Sets USB hardware address
- * \param address USB address
- */
-typedef void (*usbd_hw_setaddr)(uint8_t address);
-
-/** Configures endpoint
- * \param ep endpoint address. Use USB_EPDIR_ macros to set endpoint direction
- * \param eptype endpoint type. Use USB_EPTYPE_* macros.
- * \param epsize endpoint size in bytes
- * \return TRUE if success
- */
-typedef bool (*usbd_hw_ep_config)(uint8_t ep, uint8_t eptype, uint16_t epsize);
-
-/** De-configures, cleans and disables endpoint
- * \param ep endpoint index
- * \note if you have two one-direction single-buffered endpoints with same index (i.e. 0x02 and 0x82) both will be deconfigured.
- */
-typedef void (*usbd_hw_ep_deconfig)(uint8_t ep);
-
-/** Reads data from OUT or control endpoint
- * \param ep endpoint index, should belong to OUT or CONTROL endpoint.
- * \param buf pointer to read buffer
- * \param blen size of the read buffer in bytes
- * \return size of the actually received data
- */
-typedef uint16_t (*usbd_hw_ep_read)(uint8_t ep, void *buf, uint16_t blen);
-
-/** Writes data to IN or control endpoint
- * \param ep endpoint index, hould belong to IN or CONTROL endpoint
- * \param buf pointer to data buffer
- * \param blen size of data will be written
- * \return number of written bytes
- */
-typedef uint16_t (*usbd_hw_ep_write)(uint8_t ep, void *buf, uint16_t blen);
-
-/** Stalls and unstalls endpoint
- * \param ep endpoint address
- * \param stall endpoint will be stalled if TRUE and unstalled otherwise.
- * \note Has no effect on inactive endpoints.
- */
-typedef void (*usbd_hw_ep_setstall)(uint8_t ep, bool stall);
-
-/** Checks endpoint for stalled state
- * \param ep endpoint address
- * \return TRUE if endpoint is stalled
- */
-typedef bool (*usbd_hw_ep_isstalled)(uint8_t ep);
-
-/** Polls USB hardware for the events
- * \param[in] dev pointer to usb device structure
- * \param drv_callback callback to event processing subroutine
- */
-typedef void (*usbd_hw_poll)(usbd_device *dev, usbd_evt_callback drv_callback);
-
-/** Gets frame number from usb hardware
- */
-typedef uint16_t (*usbd_hw_get_frameno)(void);
-
-
-/** Makes a string descriptor contains unique serial number from hardware ID's
- * \param[in] buffer pointer to buffer for the descriptor
- * \return of the descriptor in bytes
- */
-typedef uint16_t (*usbd_hw_get_serialno)(void *buffer);
-
-/** @} */
-
-/** Represents generic USB control request */
-struct _usbd_ctlreq {
-    uint8_t     bmRequestType;  /**< This bitmapped field identifies the characteristics of the specific request. */
-    uint8_t     bRequest;       /**< This field specifies the particular request. */
-    uint16_t    wValue;         /**< It is used to pass a parameter to the device, specific to the request. */
-    uint16_t    wIndex;         /**< It is used to pass a parameter to the device, specific to the request. */
-    uint16_t    wLength;        /**< This field specifies the length of the data transferred during the second phase of the control transfer */
-    uint8_t     data[];         /**< Request data payload */
-};
-
-
-/** USB device status data for control endpoint */
-struct _usbd_status {
-    void        *data_buf;
-    void        *data_ptr;      /**< Pointer to control endpoint current data buffer */
-    uint16_t    data_count;     /**< Control endpoint data counter */
-    uint16_t    data_maxsize;   /**< Size of the data buffer for control endpoint */
-    uint8_t     ep0size;        /**< Size of the control endpoint */
-    uint8_t     device_cfg;     /**< Current device configuration ID */
-    uint8_t     device_state;   /**< Current \ref usbd_machine_state */
-    uint8_t     control_state;  /**< Current \ref usbd_ctl_state */
-};
-
-/** Structure represents a hardware USB driver call table */
-struct usbd_driver {
-    usbd_hw_enable          enable;
-    usbd_hw_reset           reset;
-    usbd_hw_connect         connect;
-    usbd_hw_setaddr         setaddr;
-    usbd_hw_ep_config       ep_config;
-    usbd_hw_ep_deconfig     ep_deconfig;
-    usbd_hw_ep_read         ep_read;
-    usbd_hw_ep_write        ep_write;
-    usbd_hw_ep_setstall     ep_setstall;
-    usbd_hw_ep_isstalled    ep_isstalled;
-    usbd_hw_poll            poll;
-    usbd_hw_get_frameno     frame_no;
-    usbd_hw_get_serialno    get_serialno_desc;
-};
-
-/** Structure represents a USB device data. No other data used by USB core and driver
- *  \note use helper \ref usbd_device typedef
- *  \note structure must be aligned
- */
-struct _usbd_device {
-    const struct usbd_driver    *driver;
-    usbd_ctl_callback           control_callback;
-    usbd_ctl_complete           complete_callback;
-    usbd_cfg_callback           config_callback;
-    usbd_dsc_callback           descriptor_callback;
-    usbd_evt_callback           events[usbd_evt_count];     /**< events callbacks array */
-    usbd_evt_callback           endpoint[8];                /**< endpoint callbacks array for tx, rx and setup events */
-    usbd_status                 status;
-};
-
-/** \addtogroup USB_CORE_API
- * @{ */
-
-/** Initializes device structure
- * \param dev USB device that will be initialized
- * \param drv Pointer to hardware driver
- * \param ep0size Control endpoint 0 size
- * \param buffer Pointer to control request data buffer (32-bit aligned)
- * \param bsize Size of the data buffer
- */
-inline static void usbd_init(usbd_device *dev, const struct usbd_driver *drv, const uint8_t ep0size, uint32_t *buffer, const uint16_t bsize) {
-    dev->driver = drv;
-    dev->status.ep0size = ep0size;
-    dev->status.data_ptr = buffer;
-    dev->status.data_buf = buffer;
-    dev->status.data_maxsize = bsize - __builtin_offsetof(usbd_ctlreq, data);
-}
-
-/** Polls USB for events
- * \param dev Pointer to device structure
- * \note can be called as from main routine as from USB interrupt
- */
-void usbd_poll(usbd_device *dev);
-
-/** Asynchronous device control
- * \param dev USB device
- * \param cmd control command
- */
-void usbd_control(usbd_device *dev, enum usbd_commands cmd);
-
-/** Register callback for all control requests
- * \param dev pointer to \ref usbd_device structure
- * \param cb pointer to user \ref usbd_ctl_callback
- */
-inline static void usbd_reg_control(usbd_device *dev, usbd_ctl_callback callback) {
-    dev->control_callback = callback;
-}
-
-/** Register callback for SET_CONFIG control request
- * \param dev pointer to \ref usbd_device structure
- * \param cb pointer to user \ref usbd_cfg_callback
- */
-inline static void usbd_reg_config(usbd_device *dev, usbd_cfg_callback callback) {
-    dev->config_callback = callback;
-}
-
-/** Register callback for GET_DESCRIPTOR control request
- * \param dev pointer to \ref usbd_device structure
- * \param cb pointer to user \ref usbd_ctl_callback
- */
-inline static void usbd_reg_descr(usbd_device *dev, usbd_dsc_callback callback) {
-    dev->descriptor_callback = callback;
-}
-
-/** Configure endpoint
- * \param dev pointer to \ref usbd_device structure
- * \copydetails usbd_hw_ep_config
- */
-inline static bool usbd_ep_config(usbd_device *dev, uint8_t ep, uint8_t eptype, uint16_t epsize) {
-    return dev->driver->ep_config(ep, eptype, epsize);
-}
-
-/** Deconfigure endpoint
- * \param dev pointer to \ref usbd_device structure
- * \copydetails usbd_hw_ep_deconfig
- */
-inline static void usbd_ep_deconfig(usbd_device *dev, uint8_t ep) {
-    dev->driver->ep_deconfig(ep);
-}
-
-/** Register endpoint callback
- * \param dev pointer to \ref usbd_device structure
- * \param ep endpoint index
- * \param cb pointer to user \ref usbd_evt_callback callback for endpoint events
- */
-inline static void usbd_reg_endpoint(usbd_device *dev, uint8_t ep, usbd_evt_callback callback) {
-    dev->endpoint[ep & 0x07] = callback;
-}
-
-/** Registers event callback
- * \param dev pointer to \ref usbd_device structure
- * \param evt device \ref usbd_evt "event" wants to be registered
- * \param cb pointer to user \ref usbd_evt_callback for this event
- */
-inline static void usbd_reg_event(usbd_device *dev, enum usbd_evt evt, usbd_evt_callback callback) {
-    dev->events[evt] = callback;
-}
-
-/** Write data to endpoint
- * \param dev pointer to \ref usbd_device structure
- * \copydetails usbd_hw_ep_write
- */
-inline static uint16_t usbd_ep_write(usbd_device *dev, uint8_t ep, void *buf, uint16_t blen) {
-    return dev->driver->ep_write(ep, buf, blen);
-}
-
-/** Read data from endpoint
- * \param dev pointer to \ref usbd_device structure
- * \copydetails usbd_hw_ep_read
- */
-inline static uint16_t usbd_ep_read(usbd_device *dev, uint8_t ep, void *buf, uint16_t blen) {
-    return dev->driver->ep_read(ep, buf, blen);
-}
-
-/** Stall endpoint
- * \param dev pointer to \ref usbd_device structure
- * \param ep endpoint address
- */
-inline static void usbd_ep_stall(usbd_device *dev, uint8_t ep) {
-    dev->driver->ep_setstall(ep, 1);
-}
-
-/** Unstall endpoint
- * \param dev pointer to \ref usbd_device structure
- * \param ep endpoint address
- */
-inline static void usbd_ep_unstall(usbd_device *dev, uint8_t ep) {
-    dev->driver->ep_setstall(ep, 0);
-}
-
-#endif //(__ASSEMBLER__)
-/** @} */
-/** @} */
-
-
-#if defined(__cplusplus)
-    }
-#endif
-#endif //_USBD_STD_H_
+/* This file is the part of the LUS32 project
+ *
+ * Copyright ©2016 Dmitry Filimonchuk <dmitrystu[at]gmail[dot]com>
+ *
+ * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ * 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.
+ */
+
+/** \file usbd_core.h
+ * \brief Core and hardware driver framework.
+ * \author Dmitry Filimonchuk <dmitrystu[at]gmail[dot]com>
+ * \version 1.0
+ * \copyright Apache License, Version 2.0
+ */
+
+#ifndef _USBD_CORE_H_
+#define _USBD_CORE_H_
+#if defined(__cplusplus)
+    extern "C" {
+#endif
+
+
+/** \addtogroup USBD_CORE USB device core
+ * \brief Contains core and hardware driver framework definitions
+ * @{ */
+#define USB_EPTYPE_DBLBUF       0x04        /**< indicates a doublebuffered endpoint (bulk endpoint only) */
+#define USB_EPDIR_IN            0x00        /**< indicates host-to-device endpoint direction  */
+#define USB_EPDIR_OUT           0x80        /**< indicates device-to-host endpoint direction */
+
+
+/** \name bmRequestType bitmapped field
+ * @{ */
+#define USB_REQ_DIRECTION       (1 << 7)
+#define USB_REQ_HOSTTODEV       (0 << 7)
+#define USB_REQ_DEVTOHOST       (1 << 7)
+#define USB_REQ_TYPE            (3 << 5)
+#define USB_REQ_STANDARD        (0 << 5)
+#define USB_REQ_CLASS           (1 << 5)
+#define USB_REQ_VENDOR          (2 << 5)
+#define USB_REQ_RECIPIENT       (3 << 0)
+#define USB_REQ_DEVICE          (0 << 0)
+#define USB_REQ_INTERFACE       (1 << 0)
+#define USB_REQ_ENDPOINT        (2 << 0)
+#define USB_REQ_OTHER           (3 << 0)
+/** @} */
+
+
+#if defined(__ASSEMBLER__)
+    #define usbd_evt_reset      0
+    #define usbd_evt_sof        1
+    #define usbd_evt_susp       2
+    #define usbd_evt_wkup       3
+    #define usbd_evt_eptx       4
+    #define usbd_evt_eprx       5
+    #define usbd_evt_epsetup    6
+    #define usbd_evt_error      7
+    #define usbd_evt_esof       8
+#else
+
+
+/** USB device events */
+enum usbd_evt {
+    usbd_evt_reset,             /**< Reset */
+    usbd_evt_sof,               /**< Start Of Frame */
+    usbd_evt_susp,              /**< Suspend */
+    usbd_evt_wkup,              /**< Wakeup */
+    usbd_evt_eptx,              /**< Transmit completed */
+    usbd_evt_eprx,              /**< Data packet received */
+    usbd_evt_epsetup,           /**< Setup packet received */
+    usbd_evt_error,             /**< Data error */
+    usbd_evt_esof,              /**< Missed SOF */
+    usbd_evt_count, /* this is trick to count qty */
+};
+
+/** USB device machine state */
+enum usbd_machine_state {
+    usbd_state_disabled,
+    usbd_state_disconnected,
+    usbd_state_default,         /**< Default */
+    usbd_state_addressed,       /**< Addressed */
+    usbd_state_configured,      /**< Configured */
+};
+
+/** USB device control endpoint machine state */
+enum usbd_ctl_state {
+    usbd_ctl_idle,              /**< Idle. Awaiting for SETUP packet */
+    usbd_ctl_rxdata,            /**< RX. Receiving DATA-OUT payload */
+    usbd_ctl_txdata,            /**< TX. Transmitting DATA-IN payload */
+    usbd_ctl_ztxdata,           /**< TX. Transmitting DATA-IN payload. Zero length packet maybe required. */
+    usbd_ctl_lastdata,          /**< TX. Last DATA-IN packed passed to buffer. Awaiting for the TX completion */
+    usbd_ctl_statusin,          /**< STATUS-IN stage */
+    usbd_ctl_statusout,         /**< STATUS-OUT stage */
+};
+
+/** Asynchronous device control commands  */
+enum usbd_commands {
+    usbd_cmd_enable,            /**< Enables device */
+    usbd_cmd_disable,           /**< Disables device */
+    usbd_cmd_connect,           /**< Connects device to host */
+    usbd_cmd_disconnect,        /**< Disconnects device from host */
+    usbd_cmd_reset,             /**< Resets device */
+};
+
+/* Reporting status results */
+typedef enum _usbd_respond {
+    usbd_fail,                  /**< Function has an error, STALLPID will be issued */
+    usbd_ack,                   /**< Function completes request accepted ZLP or data will be send */
+    usbd_nak,                   /**< Function is busy. NAK handshake */
+} usbd_respond;
+
+typedef struct _usbd_device usbd_device;
+typedef struct _usbd_ctlreq usbd_ctlreq;
+typedef struct _usbd_status usbd_status;
+
+/** \addtogroup USB_CORE_API Core API functions
+ * @{ */
+ /** Generic USB device event callback for events and endpoints processing
+  * \param[in] dev pointer to USB device
+  * \param event \ref usbd_evt "USB event"
+  * \param ep active endpoint number
+  * \note endpoints with same indexes i.e. 0x01 and 0x81 shares same callback.
+  */
+typedef void (*usbd_evt_callback)(usbd_device *dev, uint8_t event, uint8_t ep);
+
+/** USB control transfer completed callback function typedef.
+ * \param[in] dev pointer to USB device
+ * \param[in] req pointer to usb request structure
+ * \note When this callback will be completed usbd_device#complete_callback will be reseted to NULL
+ */
+typedef void (*usbd_ctl_complete)(usbd_device *dev, usbd_ctlreq *req);
+
+/** USB control callback function typedef.
+ * \details Uses for the control request processing.
+ *          Some requests will be handled by core if callback don't process it (returns FALSE). If request was not processed STALL PID will be issued.
+ *          - GET_CONFIGURATION
+ *          - SET_CONFIGURATION (passes to \ref usbd_cfg_callback)
+ *          - GET_DESCRIPTOR (passes to \ref usbd_dsc_callback)
+ *          - GET_STATUS
+ *          - SET_FEATURE, CLEAR_FEATURE (endpoints only)
+ *          - SET_ADDRESS
+ * \param[in] dev points to USB device
+ * \param[in] req points to usb control request
+ * \param[out] *callback \ref usbd_ctl_complete "pointer to USB control transfer completed callback", default is NULL (no callback)
+ * \return usbd_respond status.
+ */
+typedef usbd_respond (*usbd_ctl_callback)(usbd_device *dev, usbd_ctlreq *req, usbd_ctl_complete *callback);
+
+/** USB get descriptor callback function typedef
+ * \details Called when GET_DESCRIPTOR request issued
+ * \param[in] req pointer to usb control request structure
+ * \param[in,out] address pointer to the descriptor in memory. Points to req->data by default. You can use this buffer.
+ * \param[in,out] dsize descriptor size. req->data buffer size by default.
+ * \return TRUE if you passed the correct descriptor, FALSE otherwise.
+ */
+typedef bool (*usbd_dsc_callback)(usbd_ctlreq *req, void **address, uint16_t *dsize);
+
+/** USB set configuration callback function typedef
+ * \details called when SET_CONFIGURATION request issued
+ * \param[in] dev pointer to USB device
+ * \param[in] cfg configuration number.
+ * \note if config is 0 device endpoints should be de-configured
+ * \return TRUE if success
+ */
+typedef bool (*usbd_cfg_callback)(usbd_device *dev, uint8_t cfg);
+
+/** @} */
+
+/**\addtogroup USB_HW_API Hardware driver API functions 
+ * @{ */
+
+/** Enables or disables USB hardware
+ * \param enable Enables USB when TRUE disables otherwise
+ */
+typedef void (*usbd_hw_enable)(bool enable);
+
+/** Resets USB hardware */
+typedef void (*usbd_hw_reset)(void);
+
+/** Connects or disconnects USB hardware to/from usb host
+ * \param connect Connects USB to host if TRUE, disconnects otherwise
+ */
+typedef void (*usbd_hw_connect)(bool connect);
+
+/** Sets USB hardware address
+ * \param address USB address
+ */
+typedef void (*usbd_hw_setaddr)(uint8_t address);
+
+/** Configures endpoint
+ * \param ep endpoint address. Use USB_EPDIR_ macros to set endpoint direction
+ * \param eptype endpoint type. Use USB_EPTYPE_* macros.
+ * \param epsize endpoint size in bytes
+ * \return TRUE if success
+ */
+typedef bool (*usbd_hw_ep_config)(uint8_t ep, uint8_t eptype, uint16_t epsize);
+
+/** De-configures, cleans and disables endpoint
+ * \param ep endpoint index
+ * \note if you have two one-direction single-buffered endpoints with same index (i.e. 0x02 and 0x82) both will be deconfigured.
+ */
+typedef void (*usbd_hw_ep_deconfig)(uint8_t ep);
+
+/** Reads data from OUT or control endpoint
+ * \param ep endpoint index, should belong to OUT or CONTROL endpoint.
+ * \param buf pointer to read buffer
+ * \param blen size of the read buffer in bytes
+ * \return size of the actually received data
+ */
+typedef uint16_t (*usbd_hw_ep_read)(uint8_t ep, void *buf, uint16_t blen);
+
+/** Writes data to IN or control endpoint
+ * \param ep endpoint index, hould belong to IN or CONTROL endpoint
+ * \param buf pointer to data buffer
+ * \param blen size of data will be written
+ * \return number of written bytes
+ */
+typedef uint16_t (*usbd_hw_ep_write)(uint8_t ep, void *buf, uint16_t blen);
+
+/** Stalls and unstalls endpoint
+ * \param ep endpoint address
+ * \param stall endpoint will be stalled if TRUE and unstalled otherwise.
+ * \note Has no effect on inactive endpoints.
+ */
+typedef void (*usbd_hw_ep_setstall)(uint8_t ep, bool stall);
+
+/** Checks endpoint for stalled state
+ * \param ep endpoint address
+ * \return TRUE if endpoint is stalled
+ */
+typedef bool (*usbd_hw_ep_isstalled)(uint8_t ep);
+
+/** Polls USB hardware for the events
+ * \param[in] dev pointer to usb device structure
+ * \param drv_callback callback to event processing subroutine
+ */
+typedef void (*usbd_hw_poll)(usbd_device *dev, usbd_evt_callback drv_callback);
+
+/** Gets frame number from usb hardware
+ */
+typedef uint16_t (*usbd_hw_get_frameno)(void);
+
+
+/** Makes a string descriptor contains unique serial number from hardware ID's
+ * \param[in] buffer pointer to buffer for the descriptor
+ * \return of the descriptor in bytes
+ */
+typedef uint16_t (*usbd_hw_get_serialno)(void *buffer);
+
+/** @} */
+
+/** Represents generic USB control request */
+struct _usbd_ctlreq {
+    uint8_t     bmRequestType;  /**< This bitmapped field identifies the characteristics of the specific request. */
+    uint8_t     bRequest;       /**< This field specifies the particular request. */
+    uint16_t    wValue;         /**< It is used to pass a parameter to the device, specific to the request. */
+    uint16_t    wIndex;         /**< It is used to pass a parameter to the device, specific to the request. */
+    uint16_t    wLength;        /**< This field specifies the length of the data transferred during the second phase of the control transfer */
+    uint8_t     data[];         /**< Request data payload */
+};
+
+
+/** USB device status data for control endpoint */
+struct _usbd_status {
+    void        *data_buf;
+    void        *data_ptr;      /**< Pointer to control endpoint current data buffer */
+    uint16_t    data_count;     /**< Control endpoint data counter */
+    uint16_t    data_maxsize;   /**< Size of the data buffer for control endpoint */
+    uint8_t     ep0size;        /**< Size of the control endpoint */
+    uint8_t     device_cfg;     /**< Current device configuration ID */
+    uint8_t     device_state;   /**< Current \ref usbd_machine_state */
+    uint8_t     control_state;  /**< Current \ref usbd_ctl_state */
+};
+
+/** Structure represents a hardware USB driver call table */
+struct usbd_driver {
+    usbd_hw_enable          enable;
+    usbd_hw_reset           reset;
+    usbd_hw_connect         connect;
+    usbd_hw_setaddr         setaddr;
+    usbd_hw_ep_config       ep_config;
+    usbd_hw_ep_deconfig     ep_deconfig;
+    usbd_hw_ep_read         ep_read;
+    usbd_hw_ep_write        ep_write;
+    usbd_hw_ep_setstall     ep_setstall;
+    usbd_hw_ep_isstalled    ep_isstalled;
+    usbd_hw_poll            poll;
+    usbd_hw_get_frameno     frame_no;
+    usbd_hw_get_serialno    get_serialno_desc;
+};
+
+/** Structure represents a USB device data. No other data used by USB core and driver
+ *  \note use helper \ref usbd_device typedef
+ *  \note structure must be aligned
+ */
+struct _usbd_device {
+    const struct usbd_driver    *driver;
+    usbd_ctl_callback           control_callback;
+    usbd_ctl_complete           complete_callback;
+    usbd_cfg_callback           config_callback;
+    usbd_dsc_callback           descriptor_callback;
+    usbd_evt_callback           events[usbd_evt_count];     /**< events callbacks array */
+    usbd_evt_callback           endpoint[8];                /**< endpoint callbacks array for tx, rx and setup events */
+    usbd_status                 status;
+};
+
+/** \addtogroup USB_CORE_API
+ * @{ */
+
+/** Initializes device structure
+ * \param dev USB device that will be initialized
+ * \param drv Pointer to hardware driver
+ * \param ep0size Control endpoint 0 size
+ * \param buffer Pointer to control request data buffer (32-bit aligned)
+ * \param bsize Size of the data buffer
+ */
+inline static void usbd_init(usbd_device *dev, const struct usbd_driver *drv, const uint8_t ep0size, uint32_t *buffer, const uint16_t bsize) {
+    dev->driver = drv;
+    dev->status.ep0size = ep0size;
+    dev->status.data_ptr = buffer;
+    dev->status.data_buf = buffer;
+    dev->status.data_maxsize = bsize - __builtin_offsetof(usbd_ctlreq, data);
+}
+
+/** Polls USB for events
+ * \param dev Pointer to device structure
+ * \note can be called as from main routine as from USB interrupt
+ */
+void usbd_poll(usbd_device *dev);
+
+/** Asynchronous device control
+ * \param dev USB device
+ * \param cmd control command
+ */
+void usbd_control(usbd_device *dev, enum usbd_commands cmd);
+
+/** Register callback for all control requests
+ * \param dev pointer to \ref usbd_device structure
+ * \param cb pointer to user \ref usbd_ctl_callback
+ */
+inline static void usbd_reg_control(usbd_device *dev, usbd_ctl_callback callback) {
+    dev->control_callback = callback;
+}
+
+/** Register callback for SET_CONFIG control request
+ * \param dev pointer to \ref usbd_device structure
+ * \param cb pointer to user \ref usbd_cfg_callback
+ */
+inline static void usbd_reg_config(usbd_device *dev, usbd_cfg_callback callback) {
+    dev->config_callback = callback;
+}
+
+/** Register callback for GET_DESCRIPTOR control request
+ * \param dev pointer to \ref usbd_device structure
+ * \param cb pointer to user \ref usbd_ctl_callback
+ */
+inline static void usbd_reg_descr(usbd_device *dev, usbd_dsc_callback callback) {
+    dev->descriptor_callback = callback;
+}
+
+/** Configure endpoint
+ * \param dev pointer to \ref usbd_device structure
+ * \copydetails usbd_hw_ep_config
+ */
+inline static bool usbd_ep_config(usbd_device *dev, uint8_t ep, uint8_t eptype, uint16_t epsize) {
+    return dev->driver->ep_config(ep, eptype, epsize);
+}
+
+/** Deconfigure endpoint
+ * \param dev pointer to \ref usbd_device structure
+ * \copydetails usbd_hw_ep_deconfig
+ */
+inline static void usbd_ep_deconfig(usbd_device *dev, uint8_t ep) {
+    dev->driver->ep_deconfig(ep);
+}
+
+/** Register endpoint callback
+ * \param dev pointer to \ref usbd_device structure
+ * \param ep endpoint index
+ * \param cb pointer to user \ref usbd_evt_callback callback for endpoint events
+ */
+inline static void usbd_reg_endpoint(usbd_device *dev, uint8_t ep, usbd_evt_callback callback) {
+    dev->endpoint[ep & 0x07] = callback;
+}
+
+/** Registers event callback
+ * \param dev pointer to \ref usbd_device structure
+ * \param evt device \ref usbd_evt "event" wants to be registered
+ * \param cb pointer to user \ref usbd_evt_callback for this event
+ */
+inline static void usbd_reg_event(usbd_device *dev, enum usbd_evt evt, usbd_evt_callback callback) {
+    dev->events[evt] = callback;
+}
+
+/** Write data to endpoint
+ * \param dev pointer to \ref usbd_device structure
+ * \copydetails usbd_hw_ep_write
+ */
+inline static uint16_t usbd_ep_write(usbd_device *dev, uint8_t ep, void *buf, uint16_t blen) {
+    return dev->driver->ep_write(ep, buf, blen);
+}
+
+/** Read data from endpoint
+ * \param dev pointer to \ref usbd_device structure
+ * \copydetails usbd_hw_ep_read
+ */
+inline static uint16_t usbd_ep_read(usbd_device *dev, uint8_t ep, void *buf, uint16_t blen) {
+    return dev->driver->ep_read(ep, buf, blen);
+}
+
+/** Stall endpoint
+ * \param dev pointer to \ref usbd_device structure
+ * \param ep endpoint address
+ */
+inline static void usbd_ep_stall(usbd_device *dev, uint8_t ep) {
+    dev->driver->ep_setstall(ep, 1);
+}
+
+/** Unstall endpoint
+ * \param dev pointer to \ref usbd_device structure
+ * \param ep endpoint address
+ */
+inline static void usbd_ep_unstall(usbd_device *dev, uint8_t ep) {
+    dev->driver->ep_setstall(ep, 0);
+}
+
+#endif //(__ASSEMBLER__)
+/** @} */
+/** @} */
+
+
+#if defined(__cplusplus)
+    }
+#endif
+#endif //_USBD_STD_H_

+ 43 - 43
readme.md

@@ -1,43 +1,43 @@
-### Lightweight USB Device Stack ###
-
-+ Lightweight and fast
-+ Event-driven process workflow
-+ Completely separated USB hardware driver and middleware
-+ Easy to use.
-
-### Supported hardware ###
-
-| MCU series   | Driver Name | Written on | Endpoints (1) | Internal S/N | Doublebuffered transfer   |
-| ------------ | ----------- | ---------- | ------------- |------------- | ------------------------- |
-| STM32L052    | usb_stmv0a  | GCC ASM    |             8 | FNV1A 32bit  | ISO, BULK OUT, BULK IN (2)|
-| STM32L052    | usb_stmv0   | C          |             8 | FNV1A 32bit  | ISO, BULK OUT, BULK IN (2)|
-| STM32L053(3) | usb_stmv0   | C          |             8 | FNV1A 32bit  | ISO, BULK OUT, BULK IN (2)|
-| STM32F042(3) | usb_stmv0   | C          |             8 | FNV1A 32bit  | ISO, BULK OUT, BULK IN (2)|
-| STM32F072(3) | usb_stmv0   | C          |             8 | FNV1A 32bit  | ISO, BULK OUT, BULK IN (2)|
-| STM32L1xx    | usb_stmv1a  | GCC ASM    |             8 | FNV1A 32bit  | ISO, BULK OUT, BULK IN (2)|
-| STM32L1xx    | usb_stmv1   | C          |             8 | FNV1A 32bit  | ISO, BULK OUT, BULK IN (2)|
-| STM32L432(3) | usb_stmv0   | C          |             8 | FNV1A 32bit  | ISO, BULK OUT, BULK IN (2)|
-| STM32L433(3) | usb_stmv0   | C          |             8 | FNV1A 32bit  | ISO, BULK OUT, BULK IN (2)|
-| STM32L442(3) | usb_stmv0   | C          |             8 | FNV1A 32bit  | ISO, BULK OUT, BULK IN (2)|
-| STM32L443(3) | usb_stmv0   | C          |             8 | FNV1A 32bit  | ISO, BULK OUT, BULK IN (2)|
-
-
-1. Single physicsl endpoint can be used to implement
-  + one bi-directional/single-buffer logical endpoint (CONTROL)
-  + one mono-directional/double-buffer logical endpoint (BULK OR ISOCHRONOUS)
-  + two mono-directional/single-buffer logical endpoints (BULK OR INTERRUPT)
-
-2. At this moment BULK IN endpoint can use both buffers, but it is not **real** doublebuffered.
-
-3. **Not tested**
-
-### Implemented definitions for classes ###
-1. USB HID based on [Device Class Definition for Human Interface Devices (HID) Version 1.11](http://www.usb.org/developers/hidpage/HID1_11.pdf)
-2. USB DFU based on [USB Device Firmware Upgrade Specification, Revision 1.1] (http://www.usb.org/developers/docs/devclass_docs/DFU_1.1.pdf)
-3. USB CDC based on [Class definitions for Communication Devices 1.2] (http://www.usb.org/developers/docs/devclass_docs/CDC1.2_WMC1.1_012011.zip)
-
-### Useful Recources ###
-1. [USB Implementers Forum official site] (http://www.usb.org/home)
-2. [USB Made Simple] (http://www.usbmadesimple.co.uk/)
-3. [LUFA - the Lightweight USB Framework for AVRs.] (https://github.com/abcminiuser/lufa)
-4. [Open Source ARM cortex m microcontroller library] (https://github.com/libopencm3/libopencm3)
+### Lightweight USB Device Stack ###
+
++ Lightweight and fast
++ Event-driven process workflow
++ Completely separated USB hardware driver and middleware
++ Easy to use.
+
+### Supported hardware ###
+
+| MCU series   | Driver Name | Written on | Endpoints (1) | Internal S/N | Doublebuffered transfer   |
+| ------------ | ----------- | ---------- | ------------- |------------- | ------------------------- |
+| STM32L052    | usb_stmv0a  | GCC ASM    |             8 | FNV1A 32bit  | ISO, BULK OUT, BULK IN (2)|
+| STM32L052    | usb_stmv0   | C          |             8 | FNV1A 32bit  | ISO, BULK OUT, BULK IN (2)|
+| STM32L053(3) | usb_stmv0   | C          |             8 | FNV1A 32bit  | ISO, BULK OUT, BULK IN (2)|
+| STM32F042(3) | usb_stmv0   | C          |             8 | FNV1A 32bit  | ISO, BULK OUT, BULK IN (2)|
+| STM32F072(3) | usb_stmv0   | C          |             8 | FNV1A 32bit  | ISO, BULK OUT, BULK IN (2)|
+| STM32L1xx    | usb_stmv1a  | GCC ASM    |             8 | FNV1A 32bit  | ISO, BULK OUT, BULK IN (2)|
+| STM32L1xx    | usb_stmv1   | C          |             8 | FNV1A 32bit  | ISO, BULK OUT, BULK IN (2)|
+| STM32L432(3) | usb_stmv0   | C          |             8 | FNV1A 32bit  | ISO, BULK OUT, BULK IN (2)|
+| STM32L433(3) | usb_stmv0   | C          |             8 | FNV1A 32bit  | ISO, BULK OUT, BULK IN (2)|
+| STM32L442(3) | usb_stmv0   | C          |             8 | FNV1A 32bit  | ISO, BULK OUT, BULK IN (2)|
+| STM32L443(3) | usb_stmv0   | C          |             8 | FNV1A 32bit  | ISO, BULK OUT, BULK IN (2)|
+
+
+1. Single physicsl endpoint can be used to implement
+  + one bi-directional/single-buffer logical endpoint (CONTROL)
+  + one mono-directional/double-buffer logical endpoint (BULK OR ISOCHRONOUS)
+  + two mono-directional/single-buffer logical endpoints (BULK OR INTERRUPT)
+
+2. At this moment BULK IN endpoint can use both buffers, but it is not **real** doublebuffered.
+
+3. **Not tested**
+
+### Implemented definitions for classes ###
+1. USB HID based on [Device Class Definition for Human Interface Devices (HID) Version 1.11](http://www.usb.org/developers/hidpage/HID1_11.pdf)
+2. USB DFU based on [USB Device Firmware Upgrade Specification, Revision 1.1] (http://www.usb.org/developers/docs/devclass_docs/DFU_1.1.pdf)
+3. USB CDC based on [Class definitions for Communication Devices 1.2] (http://www.usb.org/developers/docs/devclass_docs/CDC1.2_WMC1.1_012011.zip)
+
+### Useful Recources ###
+1. [USB Implementers Forum official site] (http://www.usb.org/home)
+2. [USB Made Simple] (http://www.usbmadesimple.co.uk/)
+3. [LUFA - the Lightweight USB Framework for AVRs.] (https://github.com/abcminiuser/lufa)
+4. [Open Source ARM cortex m microcontroller library] (https://github.com/libopencm3/libopencm3)

+ 8 - 8
src/memmap.inc

@@ -5,15 +5,15 @@
     #define USB_CNTR        0x00
     #define USB_ISTR        0x04
     #define USB_FNR         0x08
-    #define USB_DADDR       0x0C
+    #define USB_DADDR       0x0C
     #define USB_BTABLE      0x10
     #define USB_BCDR        0x18
-    #define USB_PMABASE     0x40006000
+    #define USB_PMABASE     0x40006000
+
+    #define RCC_BASE        0x40021000
+    #define RCC_APB1RSTR    0x28
+    #define RCC_APB1ENR     0x38
 
-    #define RCC_BASE        0x40021000
-    #define RCC_APB1RSTR    0x28
-    #define RCC_APB1ENR     0x38
-
 
     #define UID_BASE        0x1FF80050
 
@@ -23,7 +23,7 @@
 
 
 #elif defined(STM32L1)
-/* common definitions for STM31L100xx STM32L151xx STM32L152xx STM32L162xx */
+/* common definitions for STM31L100xx STM32L151xx STM32L152xx STM32L162xx */
     #define USB_EPBASE      0x40005C00
     #define USB_REGBASE     0x40005C40
     #define USB_CNTR        0x00
@@ -34,7 +34,7 @@
     #define USB_PMABASE     0x40006000
 
     #define SYSCFG_BASE     0x40010000
-    #define SYSCFG_PMC      0x04
+    #define SYSCFG_PMC      0x04
 
     #define RCC_BASE        0x40023800
     #define RCC_APB1ENR     0x24

+ 457 - 457
src/usb_32v0.c

@@ -1,457 +1,457 @@
-#include <stdint.h>
-#include <stdbool.h>
-#include "stm32.h"
-#include "../usb.h"
-
-#if defined(USE_STMV0_DRIVER)
-
-#ifndef USB_PMASIZE
-    #warning PMA memory size is not defined. Use 1k by default
-    #define USB_PMASIZE 0x400
-#endif
-
-#define USB_EP_SWBUF_TX     USB_EP_DTOG_RX
-#define USB_EP_SWBUF_RX     USB_EP_DTOG_TX
-
-
-#define EP_TOGGLE_SET(epr, bits, mask) *(epr) = (*(epr) ^ (bits)) & (USB_EPREG_MASK | (mask))
-
-#define EP_TX_STALL(epr)    EP_TOGGLE_SET((epr), USB_EP_TX_STALL,                   USB_EPTX_STAT)
-#define EP_RX_STALL(epr)    EP_TOGGLE_SET((epr), USB_EP_RX_STALL,                   USB_EPRX_STAT)
-#define EP_TX_UNSTALL(epr)  EP_TOGGLE_SET((epr), USB_EP_TX_NAK,                     USB_EPTX_STAT | USB_EP_DTOG_TX)
-#define EP_RX_UNSTALL(epr)  EP_TOGGLE_SET((epr), USB_EP_RX_VALID,                   USB_EPRX_STAT | USB_EP_DTOG_RX)
-#define EP_DTX_UNSTALL(epr) EP_TOGGLE_SET((epr), USB_EP_TX_VALID,                   USB_EPTX_STAT | USB_EP_DTOG_TX | USB_EP_SWBUF_TX)
-#define EP_DRX_UNSTALL(epr) EP_TOGGLE_SET((epr), USB_EP_RX_VALID | USB_EP_SWBUF_RX, USB_EPRX_STAT | USB_EP_DTOG_RX | USB_EP_SWBUF_RX)
-#define EP_TX_VALID(epr)    EP_TOGGLE_SET((epr), USB_EP_TX_VALID,                   USB_EPTX_STAT)
-#define EP_RX_VALID(epr)    EP_TOGGLE_SET((epr), USB_EP_RX_VALID,                   USB_EPRX_STAT)
-
-
-
-typedef union pma_table {
-    struct {
-    uint16_t    txadr;
-    uint16_t    txcnt;
-    uint16_t    rxadr;
-    uint16_t    rxcnt;
-    };
-    struct {
-    uint16_t    txadr0;
-    uint16_t    txcnt0;
-    uint16_t    txadr1;
-    uint16_t    txcnt1;
-    };
-    struct {
-    uint16_t    rxadr0;
-    uint16_t    rxcnt0;
-    uint16_t    rxadr1;
-    uint16_t    rxcnt1;
-    };
-} pma_table;
-
-
-/** \brief Helper function. Returns pointer to the buffer descriptor table.
- */
-inline static pma_table *EPT(uint8_t ep) {
-    return (pma_table*)((ep & 0x07) * 8 + USB_PMAADDR);
-
-}
-
-/** \brief Helper function. Returns pointer to the endpoint control register.
- */
-inline static volatile uint16_t *EPR(uint8_t ep) {
-    return (uint16_t*)((ep & 0x07) * 4 + USB_BASE);
-}
-
-
-/** \brief Helper function. Returns next available PMA buffer.
- *
- * \param sz uint16_t Requested buffer size.
- * \return uint16_t Buffer address for PMA table.
- * \note PMA buffers grown from top to bottom like stack.
- */
-static uint16_t get_next_pma(uint16_t sz) {
-    unsigned _result = USB_PMASIZE;
-    for (int i = 0; i < 8; i++) {
-        pma_table *tbl = EPT(i);
-        if ((tbl->rxadr) && (tbl->rxadr < _result)) _result = tbl->rxadr;
-        if ((tbl->txadr) && (tbl->txadr < _result)) _result = tbl->txadr;
-    }
-    if ( _result < (8 * sizeof(pma_table) + sz)) {
-        return 0;
-    } else {
-        return _result - sz;
-    }
-}
-
-void ep_setstall(uint8_t ep, bool stall) {
-    volatile uint16_t *reg = EPR(ep);
-    /* ISOCHRONOUS endpoint can't be stalled or unstalled */
-    if (USB_EP_ISOCHRONOUS == (*reg & USB_EP_T_FIELD)) return;
-    /* If it's an IN endpoint */
-    if (ep & 0x80) {
-        /* DISABLED endpoint can't be stalled or unstalled */
-        if (USB_EP_TX_DIS == (*reg & USB_EPTX_STAT)) return;
-        if (stall) {
-            EP_TX_STALL(reg);
-        } else {
-            /* if it's a doublebuffered endpoint */
-            if ((USB_EP_KIND | USB_EP_BULK) == (*reg & (USB_EP_T_FIELD | USB_EP_KIND))) {
-                /* set endpoint to VALID and clear DTOG_TX & SWBUF_TX */
-                EP_DTX_UNSTALL(reg);
-            } else {
-                /* set endpoint to NAKED and clear DTOG_TX */
-                EP_TX_UNSTALL(reg);
-            }
-        }
-    } else {
-        if (USB_EP_RX_DIS == (*reg & USB_EPRX_STAT)) return;
-        if (stall) {
-            EP_RX_STALL(reg);
-        } else {
-            /* if it's a doublebuffered endpoint */
-            if ((USB_EP_KIND | USB_EP_BULK) == (*reg & (USB_EP_T_FIELD | USB_EP_KIND))) {
-                /* set endpoint to VALID, clear DTOG_RX, set SWBUF_RX */
-                EP_DRX_UNSTALL(reg);
-            } else {
-                /* set endpoint to VALID and clear DTOG_RX */
-                EP_RX_UNSTALL(reg);
-            }
-        }
-    }
-}
-
-bool ep_isstalled(uint8_t ep) {
-    if (ep & 0x80) {
-        return (USB_EP_TX_STALL == (USB_EPTX_STAT & *EPR(ep)));
-    } else {
-        return (USB_EP_RX_STALL == (USB_EPRX_STAT & *EPR(ep)));
-    }
-}
-
-void enable(bool enable) {
-    if (enable) {
-        RCC->APB1ENR  |=  RCC_APB1ENR_USBEN;
-        RCC->APB1RSTR |= RCC_APB1RSTR_USBRST;
-        RCC->APB1RSTR &= ~RCC_APB1RSTR_USBRST;
-        USB->CNTR = USB_CNTR_CTRM | USB_CNTR_RESETM | USB_CNTR_SOFM | USB_CNTR_ESOFM | USB_CNTR_ERRM | USB_CNTR_SUSPM | USB_CNTR_WKUPM;
-    } else if (RCC->APB1ENR & RCC_APB1ENR_USBEN) {
-        USB->BCDR = 0;
-        RCC->APB1RSTR |= RCC_APB1RSTR_USBRST;
-        RCC->APB1ENR &= ~RCC_APB1ENR_USBEN;
-    }
-}
-
-void reset (void) {
-    USB->CNTR |= USB_CNTR_FRES;
-    USB->CNTR &= ~USB_CNTR_FRES;
-}
-
-void connect(bool connect) {
-    USB->BCDR = (connect) ? USB_BCDR_DPPU : 0;
-}
-
-void setaddr (uint8_t addr) {
-    USB->DADDR = USB_DADDR_EF | addr;
-}
-
-
-bool ep_config(uint8_t ep, uint8_t eptype, uint16_t epsize) {
-    volatile uint16_t *reg = EPR(ep);
-    pma_table *tbl = EPT(ep);
-    /* epsize should be 16-bit aligned */
-    if (epsize & 0x01) epsize++;
-
-    switch (eptype) {
-    case USB_EPTYPE_CONTROL:
-        *reg = USB_EP_CONTROL | (ep & 0x07);
-        break;
-    case USB_EPTYPE_ISOCHRONUS:
-        *reg = USB_EP_ISOCHRONOUS | (ep & 0x07);
-        break;
-    case USB_EPTYPE_BULK:
-        *reg = USB_EP_BULK | (ep & 0x07);
-        break;
-    case USB_EPTYPE_BULK | USB_EPTYPE_DBLBUF:
-        *reg = USB_EP_BULK | USB_EP_KIND | (ep & 0x07);
-        break;
-    default:
-        *reg = USB_EP_INTERRUPT | (ep & 0x07);
-        break;
-    }
-    /* if it TX or CONTROL endpoint */
-    if ((ep & 0x80) || (eptype == USB_EPTYPE_CONTROL)) {
-        uint16_t _pma;
-        _pma = get_next_pma(epsize);
-        if (_pma == 0) return false;
-        if ((eptype == USB_EPTYPE_ISOCHRONUS) ||
-            (eptype == (USB_EPTYPE_BULK | USB_EPTYPE_DBLBUF))) {
-            tbl->txadr0 = _pma;
-            _pma = get_next_pma(epsize);
-            if (_pma == 0) return false;
-            tbl->txadr1 = _pma;
-            tbl->txcnt0 = 0;
-            tbl->txcnt1 = 0;
-            EP_DTX_UNSTALL(reg);
-        } else {
-            tbl->txadr = _pma;
-            tbl->txcnt = 0;
-            EP_TX_UNSTALL(reg);
-        }
-    }
-    if (!(ep & 0x80)) {
-        uint16_t _rxcnt;
-        uint16_t _pma;
-        if (epsize > 62) {
-            if (epsize & 0x1F) {
-                epsize &= 0x1F;
-            } else {
-                epsize -= 0x20;
-            }
-            _rxcnt = 0x8000 | (epsize << 5);
-            epsize += 0x20;
-        } else {
-            _rxcnt = epsize << 9;
-        }
-        _pma = get_next_pma(epsize);
-        if (_pma == 0) return false;
-        if ((eptype == USB_EPTYPE_ISOCHRONUS) ||
-            (eptype == (USB_EPTYPE_BULK | USB_EPTYPE_DBLBUF))) {
-            tbl->rxadr0 = _pma;
-            _pma = get_next_pma(epsize);
-            if (_pma == 0) return false;
-            tbl->rxadr1 = _pma;
-            tbl->rxcnt0 = _rxcnt;
-            tbl->rxcnt1 = _rxcnt;
-            EP_DRX_UNSTALL(reg);
-        } else {
-            tbl->rxadr = _pma;
-            tbl->rxcnt = _rxcnt;
-            EP_RX_UNSTALL(reg);
-        }
-    }
-    return true;
-}
-
-static void ep_deconfig(uint8_t ep) {
-    pma_table *ept = EPT(ep);
-    *EPR(ep) &= ~USB_EPREG_MASK;
-    ept->rxadr = 0;
-    ept->rxcnt = 0;
-    ept->txadr = 0;
-    ept->txcnt = 0;
-}
-
-
-
-static void pma_write(const uint16_t txadr, const uint8_t *buf, uint16_t blen) {
-    uint16_t *pma = (void*)(USB_PMAADDR + txadr);
-    while (blen > 1) {
-        *pma++ = buf[1] << 8 | buf[0];
-        buf += 2;
-        blen -= 2;
-    }
-    if (blen) *pma = *buf;
-}
-
-static void pma_read (const uint16_t rxadr, uint8_t *buf, uint16_t blen, uint16_t rxlen) {
-    uint16_t *pma = (void*)(USB_PMAADDR + rxadr);
-    if (blen > rxlen) blen = rxlen;
-    while (blen) {
-        uint16_t _t = *pma;
-        *buf++ = _t & 0xFF;
-        if (--blen) {
-            *buf++ = _t >> 8;
-            pma++;
-            blen--;
-        } else break;
-    }
-}
-
-uint16_t ep_read(uint8_t ep, void *buf, uint16_t blen) {
-    pma_table *tbl = EPT(ep);
-    volatile uint16_t *reg = EPR(ep);
-    uint16_t rxlen, rxbuf;
-
-    switch (*reg & (USB_EP_T_FIELD | USB_EP_KIND)) {
-    case (USB_EP_BULK | USB_EP_KIND):
-        if (*reg & USB_EP_SWBUF_RX) {
-            rxbuf = tbl->rxadr1;
-            rxlen = tbl->rxcnt1 & 0x03FF;
-        } else {
-            rxbuf = tbl->rxadr0;
-            rxlen = tbl->rxcnt0 & 0x03FF;
-        }
-        pma_read(rxbuf, buf, blen, rxlen);
-        break;
-    case USB_EP_ISOCHRONOUS:
-        if (*reg & USB_EP_DTOG_RX) {
-            rxbuf = tbl->rxadr0;
-            rxlen = tbl->rxcnt0 & 0x03FF;
-        } else {
-            rxbuf = tbl->rxadr1;
-            rxlen = tbl->rxcnt1 & 0x03FF;
-        }
-        pma_read(rxbuf, buf, blen, rxlen);
-        break;
-    default:
-        rxbuf = tbl->rxadr;
-        rxlen = tbl->rxcnt & 0x03FF;
-        pma_read(rxbuf, buf, blen, rxlen);
-        /* setting endpoint to VALID state */
-        EP_RX_VALID(reg);
-        break;
-    }
-    return rxlen;
-}
-
-
-
-uint16_t ep_write(uint8_t ep, void *buf, uint16_t blen) {
-    pma_table *tbl = EPT(ep);
-    volatile uint16_t *reg = EPR(ep);
-    uint16_t txbuf;
-    switch (*reg & (USB_EP_T_FIELD | USB_EP_KIND)) {
-    case (USB_EP_BULK | USB_EP_KIND):
-        if (*reg & USB_EP_SWBUF_TX) {
-            tbl->txcnt1 = blen;
-            txbuf = tbl->txadr1;
-        } else {
-            tbl->txcnt0 = blen;
-            txbuf = tbl->txadr0;
-        }
-        break;
-    case USB_EP_ISOCHRONOUS:
-        if (*reg & USB_EP_DTOG_TX) {
-            tbl->txcnt0 = blen;
-            txbuf = tbl->txadr0;
-        } else {
-            tbl->txcnt1 = blen;
-            txbuf = tbl->txadr1;
-        }
-        break;
-    default:
-        tbl->txcnt = blen;
-        txbuf = tbl->txadr;
-        break;
-    }
-    pma_write(txbuf, buf, blen);
-
-    switch (*reg & (USB_EP_T_FIELD | USB_EP_KIND)) {
-    case (USB_EP_BULK | USB_EP_KIND):
-        /* switching buffer if doublebuffered bulk endpoint */
-        *reg = (*reg & USB_EPREG_MASK) | USB_EP_SWBUF_TX;
-        break;
-    case USB_EP_ISOCHRONOUS:
-        break;
-    default:
-        /* set TX valid to start transfer */
-        EP_TX_VALID(reg);
-    }
-    return blen;
-
-}
-
-uint16_t get_frame (void) {
-    return USB->FNR & USB_FNR_FN;
-}
-
-
-
-void evt_poll(usbd_device *dev, usbd_evt_callback callback) {
-    uint8_t _ev, _ep;
-    uint16_t _istr = USB->ISTR;
-    _ep = _istr & USB_ISTR_EP_ID;
-
-    if (_istr & USB_ISTR_CTR) {
-        volatile uint16_t *reg = EPR(_ep);
-        if (*reg & USB_EP_CTR_TX) {
-            *reg &= (USB_EPREG_MASK ^ USB_EP_CTR_TX);
-            _ep |= 0x80;
-            _ev = usbd_evt_eptx;
-        } else {
-            /* clearing CTR */
-            if ((*reg & (USB_EP_T_FIELD | USB_EP_KIND)) == (USB_EP_BULK | USB_EP_KIND)) {
-                /* switching RX buffer and if doublebuffered bulk endpoint */
-                *reg = (*reg & (USB_EPREG_MASK ^ USB_EP_CTR_RX)) | USB_EP_SWBUF_RX;
-            } else {
-                *reg &= (USB_EPREG_MASK ^ USB_EP_CTR_RX);
-            }
-            _ev = (*reg & USB_EP_SETUP) ? usbd_evt_epsetup : usbd_evt_eprx;
-        }
-    } else if (_istr & USB_ISTR_RESET) {
-        USB->ISTR &= ~USB_ISTR_RESET;
-        USB->BTABLE = 0;
-        for (int i = 0; i < 8; i++) {
-            ep_deconfig(i);
-        }
-        _ev = usbd_evt_reset;
-    } else if (_istr & USB_ISTR_SOF) {
-        _ev = usbd_evt_sof;
-        USB->ISTR &= ~USB_ISTR_SOF;
-    } else if (_istr & USB_ISTR_WKUP) {
-        _ev = usbd_evt_wkup;
-        USB->CNTR &= ~USB_CNTR_FSUSP;
-        USB->ISTR &= ~USB_ISTR_WKUP;
-    } else if (_istr & USB_ISTR_SUSP) {
-        _ev = usbd_evt_susp;
-        USB->CNTR |= USB_CNTR_FSUSP;
-        USB->ISTR &= ~USB_ISTR_SUSP;
-    } else if (_istr & USB_ISTR_ESOF) {
-        USB->ISTR &= ~USB_ISTR_ESOF;
-        _ev = usbd_evt_esof;
-    } else if (_istr & USB_ISTR_ERR) {
-        USB->ISTR &= ~USB_ISTR_ERR;
-        _ev = usbd_evt_error;
-    } else {
-        return;
-    }
-    callback(dev, _ev, _ep);
-}
-
-static uint32_t fnv1a32_turn (uint32_t fnv, uint32_t data ) {
-    for (int i = 0; i < 4 ; i++) {
-        fnv ^= (data & 0xFF);
-        fnv *= 16777619;
-        data >>= 8;
-    }
-    return fnv;
-}
-
-static uint16_t get_serialno_desc(void *buffer) {
-    struct  usb_string_descriptor *dsc = buffer;
-    uint16_t *str = dsc->wString;
-    uint32_t fnv = 2166136261;
-    fnv = fnv1a32_turn(fnv, *(uint32_t*)(UID_BASE + 0x00));
-    fnv = fnv1a32_turn(fnv, *(uint32_t*)(UID_BASE + 0x04));
-    fnv = fnv1a32_turn(fnv, *(uint32_t*)(UID_BASE + 0x14));
-    for (int i = 28; i >= 0; i -= 4 ) {
-        uint16_t c = (fnv >> i) & 0x0F;
-        c += (c < 10) ? '0' : ('A' - 10);
-        *str++ = c;
-    }
-    dsc->bDescriptorType = USB_DTYPE_STRING;
-    dsc->bLength = 18;
-    return 18;
-}
-
-
-
-
-
-const struct usbd_driver usb_stmv0 = {
-    enable,
-    reset,
-    connect,
-    setaddr,
-    ep_config,
-    ep_deconfig,
-    ep_read,
-    ep_write,
-    ep_setstall,
-    ep_isstalled,
-    evt_poll,
-    get_frame,
-    get_serialno_desc,
-};
-
-#endif //USE_STM32V0_DRIVER
+#include <stdint.h>
+#include <stdbool.h>
+#include "stm32.h"
+#include "../usb.h"
+
+#if defined(USE_STMV0_DRIVER)
+
+#ifndef USB_PMASIZE
+    #warning PMA memory size is not defined. Use 1k by default
+    #define USB_PMASIZE 0x400
+#endif
+
+#define USB_EP_SWBUF_TX     USB_EP_DTOG_RX
+#define USB_EP_SWBUF_RX     USB_EP_DTOG_TX
+
+
+#define EP_TOGGLE_SET(epr, bits, mask) *(epr) = (*(epr) ^ (bits)) & (USB_EPREG_MASK | (mask))
+
+#define EP_TX_STALL(epr)    EP_TOGGLE_SET((epr), USB_EP_TX_STALL,                   USB_EPTX_STAT)
+#define EP_RX_STALL(epr)    EP_TOGGLE_SET((epr), USB_EP_RX_STALL,                   USB_EPRX_STAT)
+#define EP_TX_UNSTALL(epr)  EP_TOGGLE_SET((epr), USB_EP_TX_NAK,                     USB_EPTX_STAT | USB_EP_DTOG_TX)
+#define EP_RX_UNSTALL(epr)  EP_TOGGLE_SET((epr), USB_EP_RX_VALID,                   USB_EPRX_STAT | USB_EP_DTOG_RX)
+#define EP_DTX_UNSTALL(epr) EP_TOGGLE_SET((epr), USB_EP_TX_VALID,                   USB_EPTX_STAT | USB_EP_DTOG_TX | USB_EP_SWBUF_TX)
+#define EP_DRX_UNSTALL(epr) EP_TOGGLE_SET((epr), USB_EP_RX_VALID | USB_EP_SWBUF_RX, USB_EPRX_STAT | USB_EP_DTOG_RX | USB_EP_SWBUF_RX)
+#define EP_TX_VALID(epr)    EP_TOGGLE_SET((epr), USB_EP_TX_VALID,                   USB_EPTX_STAT)
+#define EP_RX_VALID(epr)    EP_TOGGLE_SET((epr), USB_EP_RX_VALID,                   USB_EPRX_STAT)
+
+
+
+typedef union pma_table {
+    struct {
+    uint16_t    txadr;
+    uint16_t    txcnt;
+    uint16_t    rxadr;
+    uint16_t    rxcnt;
+    };
+    struct {
+    uint16_t    txadr0;
+    uint16_t    txcnt0;
+    uint16_t    txadr1;
+    uint16_t    txcnt1;
+    };
+    struct {
+    uint16_t    rxadr0;
+    uint16_t    rxcnt0;
+    uint16_t    rxadr1;
+    uint16_t    rxcnt1;
+    };
+} pma_table;
+
+
+/** \brief Helper function. Returns pointer to the buffer descriptor table.
+ */
+inline static pma_table *EPT(uint8_t ep) {
+    return (pma_table*)((ep & 0x07) * 8 + USB_PMAADDR);
+
+}
+
+/** \brief Helper function. Returns pointer to the endpoint control register.
+ */
+inline static volatile uint16_t *EPR(uint8_t ep) {
+    return (uint16_t*)((ep & 0x07) * 4 + USB_BASE);
+}
+
+
+/** \brief Helper function. Returns next available PMA buffer.
+ *
+ * \param sz uint16_t Requested buffer size.
+ * \return uint16_t Buffer address for PMA table.
+ * \note PMA buffers grown from top to bottom like stack.
+ */
+static uint16_t get_next_pma(uint16_t sz) {
+    unsigned _result = USB_PMASIZE;
+    for (int i = 0; i < 8; i++) {
+        pma_table *tbl = EPT(i);
+        if ((tbl->rxadr) && (tbl->rxadr < _result)) _result = tbl->rxadr;
+        if ((tbl->txadr) && (tbl->txadr < _result)) _result = tbl->txadr;
+    }
+    if ( _result < (8 * sizeof(pma_table) + sz)) {
+        return 0;
+    } else {
+        return _result - sz;
+    }
+}
+
+void ep_setstall(uint8_t ep, bool stall) {
+    volatile uint16_t *reg = EPR(ep);
+    /* ISOCHRONOUS endpoint can't be stalled or unstalled */
+    if (USB_EP_ISOCHRONOUS == (*reg & USB_EP_T_FIELD)) return;
+    /* If it's an IN endpoint */
+    if (ep & 0x80) {
+        /* DISABLED endpoint can't be stalled or unstalled */
+        if (USB_EP_TX_DIS == (*reg & USB_EPTX_STAT)) return;
+        if (stall) {
+            EP_TX_STALL(reg);
+        } else {
+            /* if it's a doublebuffered endpoint */
+            if ((USB_EP_KIND | USB_EP_BULK) == (*reg & (USB_EP_T_FIELD | USB_EP_KIND))) {
+                /* set endpoint to VALID and clear DTOG_TX & SWBUF_TX */
+                EP_DTX_UNSTALL(reg);
+            } else {
+                /* set endpoint to NAKED and clear DTOG_TX */
+                EP_TX_UNSTALL(reg);
+            }
+        }
+    } else {
+        if (USB_EP_RX_DIS == (*reg & USB_EPRX_STAT)) return;
+        if (stall) {
+            EP_RX_STALL(reg);
+        } else {
+            /* if it's a doublebuffered endpoint */
+            if ((USB_EP_KIND | USB_EP_BULK) == (*reg & (USB_EP_T_FIELD | USB_EP_KIND))) {
+                /* set endpoint to VALID, clear DTOG_RX, set SWBUF_RX */
+                EP_DRX_UNSTALL(reg);
+            } else {
+                /* set endpoint to VALID and clear DTOG_RX */
+                EP_RX_UNSTALL(reg);
+            }
+        }
+    }
+}
+
+bool ep_isstalled(uint8_t ep) {
+    if (ep & 0x80) {
+        return (USB_EP_TX_STALL == (USB_EPTX_STAT & *EPR(ep)));
+    } else {
+        return (USB_EP_RX_STALL == (USB_EPRX_STAT & *EPR(ep)));
+    }
+}
+
+void enable(bool enable) {
+    if (enable) {
+        RCC->APB1ENR  |=  RCC_APB1ENR_USBEN;
+        RCC->APB1RSTR |= RCC_APB1RSTR_USBRST;
+        RCC->APB1RSTR &= ~RCC_APB1RSTR_USBRST;
+        USB->CNTR = USB_CNTR_CTRM | USB_CNTR_RESETM | USB_CNTR_SOFM | USB_CNTR_ESOFM | USB_CNTR_ERRM | USB_CNTR_SUSPM | USB_CNTR_WKUPM;
+    } else if (RCC->APB1ENR & RCC_APB1ENR_USBEN) {
+        USB->BCDR = 0;
+        RCC->APB1RSTR |= RCC_APB1RSTR_USBRST;
+        RCC->APB1ENR &= ~RCC_APB1ENR_USBEN;
+    }
+}
+
+void reset (void) {
+    USB->CNTR |= USB_CNTR_FRES;
+    USB->CNTR &= ~USB_CNTR_FRES;
+}
+
+void connect(bool connect) {
+    USB->BCDR = (connect) ? USB_BCDR_DPPU : 0;
+}
+
+void setaddr (uint8_t addr) {
+    USB->DADDR = USB_DADDR_EF | addr;
+}
+
+
+bool ep_config(uint8_t ep, uint8_t eptype, uint16_t epsize) {
+    volatile uint16_t *reg = EPR(ep);
+    pma_table *tbl = EPT(ep);
+    /* epsize should be 16-bit aligned */
+    if (epsize & 0x01) epsize++;
+
+    switch (eptype) {
+    case USB_EPTYPE_CONTROL:
+        *reg = USB_EP_CONTROL | (ep & 0x07);
+        break;
+    case USB_EPTYPE_ISOCHRONUS:
+        *reg = USB_EP_ISOCHRONOUS | (ep & 0x07);
+        break;
+    case USB_EPTYPE_BULK:
+        *reg = USB_EP_BULK | (ep & 0x07);
+        break;
+    case USB_EPTYPE_BULK | USB_EPTYPE_DBLBUF:
+        *reg = USB_EP_BULK | USB_EP_KIND | (ep & 0x07);
+        break;
+    default:
+        *reg = USB_EP_INTERRUPT | (ep & 0x07);
+        break;
+    }
+    /* if it TX or CONTROL endpoint */
+    if ((ep & 0x80) || (eptype == USB_EPTYPE_CONTROL)) {
+        uint16_t _pma;
+        _pma = get_next_pma(epsize);
+        if (_pma == 0) return false;
+        if ((eptype == USB_EPTYPE_ISOCHRONUS) ||
+            (eptype == (USB_EPTYPE_BULK | USB_EPTYPE_DBLBUF))) {
+            tbl->txadr0 = _pma;
+            _pma = get_next_pma(epsize);
+            if (_pma == 0) return false;
+            tbl->txadr1 = _pma;
+            tbl->txcnt0 = 0;
+            tbl->txcnt1 = 0;
+            EP_DTX_UNSTALL(reg);
+        } else {
+            tbl->txadr = _pma;
+            tbl->txcnt = 0;
+            EP_TX_UNSTALL(reg);
+        }
+    }
+    if (!(ep & 0x80)) {
+        uint16_t _rxcnt;
+        uint16_t _pma;
+        if (epsize > 62) {
+            if (epsize & 0x1F) {
+                epsize &= 0x1F;
+            } else {
+                epsize -= 0x20;
+            }
+            _rxcnt = 0x8000 | (epsize << 5);
+            epsize += 0x20;
+        } else {
+            _rxcnt = epsize << 9;
+        }
+        _pma = get_next_pma(epsize);
+        if (_pma == 0) return false;
+        if ((eptype == USB_EPTYPE_ISOCHRONUS) ||
+            (eptype == (USB_EPTYPE_BULK | USB_EPTYPE_DBLBUF))) {
+            tbl->rxadr0 = _pma;
+            _pma = get_next_pma(epsize);
+            if (_pma == 0) return false;
+            tbl->rxadr1 = _pma;
+            tbl->rxcnt0 = _rxcnt;
+            tbl->rxcnt1 = _rxcnt;
+            EP_DRX_UNSTALL(reg);
+        } else {
+            tbl->rxadr = _pma;
+            tbl->rxcnt = _rxcnt;
+            EP_RX_UNSTALL(reg);
+        }
+    }
+    return true;
+}
+
+static void ep_deconfig(uint8_t ep) {
+    pma_table *ept = EPT(ep);
+    *EPR(ep) &= ~USB_EPREG_MASK;
+    ept->rxadr = 0;
+    ept->rxcnt = 0;
+    ept->txadr = 0;
+    ept->txcnt = 0;
+}
+
+
+
+static void pma_write(const uint16_t txadr, const uint8_t *buf, uint16_t blen) {
+    uint16_t *pma = (void*)(USB_PMAADDR + txadr);
+    while (blen > 1) {
+        *pma++ = buf[1] << 8 | buf[0];
+        buf += 2;
+        blen -= 2;
+    }
+    if (blen) *pma = *buf;
+}
+
+static void pma_read (const uint16_t rxadr, uint8_t *buf, uint16_t blen, uint16_t rxlen) {
+    uint16_t *pma = (void*)(USB_PMAADDR + rxadr);
+    if (blen > rxlen) blen = rxlen;
+    while (blen) {
+        uint16_t _t = *pma;
+        *buf++ = _t & 0xFF;
+        if (--blen) {
+            *buf++ = _t >> 8;
+            pma++;
+            blen--;
+        } else break;
+    }
+}
+
+uint16_t ep_read(uint8_t ep, void *buf, uint16_t blen) {
+    pma_table *tbl = EPT(ep);
+    volatile uint16_t *reg = EPR(ep);
+    uint16_t rxlen, rxbuf;
+
+    switch (*reg & (USB_EP_T_FIELD | USB_EP_KIND)) {
+    case (USB_EP_BULK | USB_EP_KIND):
+        if (*reg & USB_EP_SWBUF_RX) {
+            rxbuf = tbl->rxadr1;
+            rxlen = tbl->rxcnt1 & 0x03FF;
+        } else {
+            rxbuf = tbl->rxadr0;
+            rxlen = tbl->rxcnt0 & 0x03FF;
+        }
+        pma_read(rxbuf, buf, blen, rxlen);
+        break;
+    case USB_EP_ISOCHRONOUS:
+        if (*reg & USB_EP_DTOG_RX) {
+            rxbuf = tbl->rxadr0;
+            rxlen = tbl->rxcnt0 & 0x03FF;
+        } else {
+            rxbuf = tbl->rxadr1;
+            rxlen = tbl->rxcnt1 & 0x03FF;
+        }
+        pma_read(rxbuf, buf, blen, rxlen);
+        break;
+    default:
+        rxbuf = tbl->rxadr;
+        rxlen = tbl->rxcnt & 0x03FF;
+        pma_read(rxbuf, buf, blen, rxlen);
+        /* setting endpoint to VALID state */
+        EP_RX_VALID(reg);
+        break;
+    }
+    return rxlen;
+}
+
+
+
+uint16_t ep_write(uint8_t ep, void *buf, uint16_t blen) {
+    pma_table *tbl = EPT(ep);
+    volatile uint16_t *reg = EPR(ep);
+    uint16_t txbuf;
+    switch (*reg & (USB_EP_T_FIELD | USB_EP_KIND)) {
+    case (USB_EP_BULK | USB_EP_KIND):
+        if (*reg & USB_EP_SWBUF_TX) {
+            tbl->txcnt1 = blen;
+            txbuf = tbl->txadr1;
+        } else {
+            tbl->txcnt0 = blen;
+            txbuf = tbl->txadr0;
+        }
+        break;
+    case USB_EP_ISOCHRONOUS:
+        if (*reg & USB_EP_DTOG_TX) {
+            tbl->txcnt0 = blen;
+            txbuf = tbl->txadr0;
+        } else {
+            tbl->txcnt1 = blen;
+            txbuf = tbl->txadr1;
+        }
+        break;
+    default:
+        tbl->txcnt = blen;
+        txbuf = tbl->txadr;
+        break;
+    }
+    pma_write(txbuf, buf, blen);
+
+    switch (*reg & (USB_EP_T_FIELD | USB_EP_KIND)) {
+    case (USB_EP_BULK | USB_EP_KIND):
+        /* switching buffer if doublebuffered bulk endpoint */
+        *reg = (*reg & USB_EPREG_MASK) | USB_EP_SWBUF_TX;
+        break;
+    case USB_EP_ISOCHRONOUS:
+        break;
+    default:
+        /* set TX valid to start transfer */
+        EP_TX_VALID(reg);
+    }
+    return blen;
+
+}
+
+uint16_t get_frame (void) {
+    return USB->FNR & USB_FNR_FN;
+}
+
+
+
+void evt_poll(usbd_device *dev, usbd_evt_callback callback) {
+    uint8_t _ev, _ep;
+    uint16_t _istr = USB->ISTR;
+    _ep = _istr & USB_ISTR_EP_ID;
+
+    if (_istr & USB_ISTR_CTR) {
+        volatile uint16_t *reg = EPR(_ep);
+        if (*reg & USB_EP_CTR_TX) {
+            *reg &= (USB_EPREG_MASK ^ USB_EP_CTR_TX);
+            _ep |= 0x80;
+            _ev = usbd_evt_eptx;
+        } else {
+            /* clearing CTR */
+            if ((*reg & (USB_EP_T_FIELD | USB_EP_KIND)) == (USB_EP_BULK | USB_EP_KIND)) {
+                /* switching RX buffer and if doublebuffered bulk endpoint */
+                *reg = (*reg & (USB_EPREG_MASK ^ USB_EP_CTR_RX)) | USB_EP_SWBUF_RX;
+            } else {
+                *reg &= (USB_EPREG_MASK ^ USB_EP_CTR_RX);
+            }
+            _ev = (*reg & USB_EP_SETUP) ? usbd_evt_epsetup : usbd_evt_eprx;
+        }
+    } else if (_istr & USB_ISTR_RESET) {
+        USB->ISTR &= ~USB_ISTR_RESET;
+        USB->BTABLE = 0;
+        for (int i = 0; i < 8; i++) {
+            ep_deconfig(i);
+        }
+        _ev = usbd_evt_reset;
+    } else if (_istr & USB_ISTR_SOF) {
+        _ev = usbd_evt_sof;
+        USB->ISTR &= ~USB_ISTR_SOF;
+    } else if (_istr & USB_ISTR_WKUP) {
+        _ev = usbd_evt_wkup;
+        USB->CNTR &= ~USB_CNTR_FSUSP;
+        USB->ISTR &= ~USB_ISTR_WKUP;
+    } else if (_istr & USB_ISTR_SUSP) {
+        _ev = usbd_evt_susp;
+        USB->CNTR |= USB_CNTR_FSUSP;
+        USB->ISTR &= ~USB_ISTR_SUSP;
+    } else if (_istr & USB_ISTR_ESOF) {
+        USB->ISTR &= ~USB_ISTR_ESOF;
+        _ev = usbd_evt_esof;
+    } else if (_istr & USB_ISTR_ERR) {
+        USB->ISTR &= ~USB_ISTR_ERR;
+        _ev = usbd_evt_error;
+    } else {
+        return;
+    }
+    callback(dev, _ev, _ep);
+}
+
+static uint32_t fnv1a32_turn (uint32_t fnv, uint32_t data ) {
+    for (int i = 0; i < 4 ; i++) {
+        fnv ^= (data & 0xFF);
+        fnv *= 16777619;
+        data >>= 8;
+    }
+    return fnv;
+}
+
+static uint16_t get_serialno_desc(void *buffer) {
+    struct  usb_string_descriptor *dsc = buffer;
+    uint16_t *str = dsc->wString;
+    uint32_t fnv = 2166136261;
+    fnv = fnv1a32_turn(fnv, *(uint32_t*)(UID_BASE + 0x00));
+    fnv = fnv1a32_turn(fnv, *(uint32_t*)(UID_BASE + 0x04));
+    fnv = fnv1a32_turn(fnv, *(uint32_t*)(UID_BASE + 0x14));
+    for (int i = 28; i >= 0; i -= 4 ) {
+        uint16_t c = (fnv >> i) & 0x0F;
+        c += (c < 10) ? '0' : ('A' - 10);
+        *str++ = c;
+    }
+    dsc->bDescriptorType = USB_DTYPE_STRING;
+    dsc->bLength = 18;
+    return 18;
+}
+
+
+
+
+
+const struct usbd_driver usb_stmv0 = {
+    enable,
+    reset,
+    connect,
+    setaddr,
+    ep_config,
+    ep_deconfig,
+    ep_read,
+    ep_write,
+    ep_setstall,
+    ep_isstalled,
+    evt_poll,
+    get_frame,
+    get_serialno_desc,
+};
+
+#endif //USE_STM32V0_DRIVER

+ 813 - 813
src/usb_32v0A.S

@@ -1,813 +1,813 @@
-/* This file is the part of the LUS32 project
- *
- * Copyright ©2016 Dmitry Filimonchuk <dmitrystu[at]gmail[dot]com>
- *
- * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
- * 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.
- */
-
-#if !defined (__ASSEMBLER__)
-    #define __ASSEMBLER__
-#endif
-
-#include "../usb.h"
-#include "memmap.inc"
-#if defined(USE_STMV0A_DRIVER)
-
-#define EP_SETUP    0x0800
-#define EP_TYPE     0x0600
-#define EP_KIND     0x0100
-#define EP_ADDR     0x000F
-
-#define EP_RX_CTR   0x8000
-#define EP_RX_DTOG  0x4000
-#define EP_RX_STAT  0x3000
-#define EP_RX_SWBUF 0x0040
-
-#define EP_RX_DIS   0x0000
-#define EP_RX_STAL  0x1000
-#define EP_RX_NAK   0x2000
-#define EP_RX_VAL   0x3000
-
-#define EP_TX_CTR   0x0080
-#define EP_TX_DTOG  0x0040
-#define EP_TX_STAT  0x0030
-#define EP_TX_SWBUF 0x4000
-
-#define EP_TX_DIS   0x0000
-#define EP_TX_STAL  0x0010
-#define EP_TX_NAK   0x0020
-#define EP_TX_VAL   0x0030
-
-#define RXADDR0     0x00
-#define RXCOUNT0    0x02
-#define RXADDR1     0x04
-#define RXCOUNT1    0x08
-
-#define TXADDR0     0x00
-#define TXCOUNT0    0x02
-#define TXADDR1     0x04
-#define TXCOUNT1    0x08
-
-#define TXADDR      0x00
-#define TXCOUNT     0x02
-#define RXADDR      0x04
-#define RXCOUNT     0x08
-
-
-#define EP_NOTOG    (EP_RX_CTR | EP_TX_CTR | EP_SETUP | EP_TYPE | EP_KIND | EP_ADDR)
-
-#define TGL_SET(mask, bits)  ((EP_NOTOG | (mask))<<16 | (bits))
-
-#define TX_STALL    TGL_SET(EP_TX_STAT,                            EP_TX_STAL)
-#define RX_STALL    TGL_SET(EP_RX_STAT,                            EP_RX_STAL)
-#define TX_USTALL   TGL_SET(EP_TX_STAT | EP_TX_DTOG,               EP_TX_NAK)
-#define RX_USTALL   TGL_SET(EP_RX_STAT | EP_RX_DTOG,               EP_RX_VAL)
-#define DTX_USTALL  TGL_SET(EP_TX_STAT | EP_TX_DTOG | EP_TX_SWBUF, EP_TX_VAL)
-#define DRX_USTALL  TGL_SET(EP_RX_STAT | EP_RX_DTOG | EP_RX_SWBUF, EP_RX_VAL | EP_RX_SWBUF)
-
-
-    .syntax unified
-    .cpu cortex-m0plus
-    .text
-    .thumb
-
-
-    .globl  usb_stmv0a
-    .align  2
-usb_stmv0a:
-    .long   _enable
-    .long   _reset
-    .long   _connect
-    .long   _setaddr
-    .long   _ep_config
-    .long   _ep_deconfig
-    .long   _ep_read
-    .long   _ep_write
-    .long   _ep_setstall
-    .long   _ep_isstalled
-    .long   _evt_poll
-    .long   _get_frame
-    .long   _get_serial_desc
-    .size   usb_stmv0a, . - usb_stmv0a
-
-
-    .thumb_func
-    .type _get_serial_desc, %function
-
-/*  uint16_t get_serial_desc (void *buffer)
- *  R0 <- buffer for the string descriptor
- *  descrpitor size -> R0
- */
-_get_serial_desc:
-    push    {r4, r5, lr}
-    movs    r1,18               //descriptor size 18 bytes
-    strb    r1,[r0]
-    movs    r1, #0x03           //DTYPE_STRING
-    strb    r1,[r0, #0x01]
-    ldr     r5, .L_uid_base     //UID3 this is the serial number
-    ldr     r4, .L_fnv1a_offset //FNV1A offset
-    ldr     r2, [r5, 0x00]      //UID0
-    bl      .L_fnv1a
-    ldr     r2, [r5, 0x04]      //UID1
-    bl      .L_fnv1a
-    ldr     r2, [r5, 0x14]      //UID2
-    bl      .L_fnv1a
-    movs    r3, #28
-.L_gsn_loop:
-    movs    r1, r4
-    lsrs    r1, r3
-    lsls    r1, #28
-    lsrs    r1, #28
-    adds    r1, #0x30           //'0'
-    cmp     r1, #0x3A
-    blo     .L_gsn_store
-    adds    r1, #0x07           //'A' - '0'
-.L_gsn_store:
-    adds    r0, #0x02
-    strb    r1, [r0]
-    lsrs    r1, #0x08
-    strb    r1, [r0, #0x01]
-    subs    r3, #0x04
-    bpl     .L_gsn_loop
-    movs    r0, #18
-    pop     {r4, r5, pc}
-
-.L_fnv1a:
-    movs    r3, #0x04
-.L_fnv1a_loop:
-    uxtb    r1, r2
-    eors    r4, r1
-    ldr     r1, .L_fnv1a_prime       //FNV1A prime
-    muls    r4, r1
-    lsrs    r2, #0x08
-    subs    r3, #0x01
-    bne     .L_fnv1a_loop
-    bx      lr
-
-    .align 2
-.L_fnv1a_prime:     .long   16777619
-.L_fnv1a_offset:    .long   2166136261
-.L_uid_base:        .long   UID_BASE
-
-    .size _get_serial_desc, . - _get_serial_desc
-
-    .thumb_func
-    .type   _connect, %function
-_connect:
-    subs    r1, r0, #1
-    sbcs    r0, r1
-    lsls    r0, #15
-    ldr     r1, =#USB_REGBASE
-    strh    r0, [r1, #USB_BCDR]      //USB->BCDR
-    bx      lr
-    .size   _connect, . - _connect
-
-
-    .thumb_func
-    .type   _setaddr, %function
-_setaddr:
-    ldr     r1, =USB_REGBASE
-    adds    r0, #0x80
-    strh    r0, [r1, #USB_DADDR]     //USB->DADDR
-    bx      lr
-    .size   _setaddr, . - _setaddr
-
-    .thumb_func
-    .type   _reset, %function
-_reset:
-    ldr     r2, =#USB_REGBASE
-    movs    r0, #0x01           //FRES
-    ldrh    r1, [r2, #USB_CNTR] //USB->CNTR
-    orrs    r1, r0
-    strh    r1, [r2, #USB_CNTR] // set FRES
-    bics    r1, r0
-    strh    r1, [r2, #USB_CNTR] // clr FRES
-    bx      lr
-    .size   _reset, . - _reset
-
-    .thumb_func
-    .type   _get_frame, %function
-_get_frame:
-    ldr     r0, =#USB_REGBASE
-    ldrh    r0, [r0, #USB_FNR]     //FNR
-    lsls    r0, #21
-    lsrs    r0, #21
-    bx      lr
-    .size   _get_frame, . - _get_frame
-
-    .thumb_func
-    .type   _enable, %function
-_enable:
-    ldr     r1, =#USB_REGBASE     //USB->CNTR
-    ldr     r2, =#RCC_BASE        //RCC
-    movs    r3, #0x01
-    lsls    r3, #23             //USBEN or USBRST
-    tst     r0, r0
-    beq     .L_disable
-.L_enable:
-    ldr     r0, [r2, #RCC_APB1ENR]
-    orrs    r0, r3
-    str     r0, [r2, #RCC_APB1ENR]     //RCC->APB1ENR |= USBEN
-    ldr     r0, [r2, #RCC_APB1RSTR]
-    orrs    r0, r3
-    str     r0, [r2, #RCC_APB1RSTR]     //RCC->APB1RSTR |= USBRST
-    bics    r0, r3
-    str     r0, [r2, #RCC_APB1RSTR]     //RCC->APB1RSTR &= ~USBRST
-    movs    r0, #0xBE
-    lsls    r0, #0x08           // CTRM | ERRM | WKUPM | SUSPM | RESETM | SOFM
-    strh    r0, [r1]            //set USB->CNTR
-    bx      lr
-.L_disable:
-    ldr     r0, [r2, #RCC_APB1ENR]
-    tst     r0, r3
-    beq     .L_enable_end       // usb is disabled
-    movs    r0, #0x00
-    strh    r0, [r1, #USB_BCDR]     //USB->BCDR disable USB I/O
-    ldr     r0, [r2, #RCC_APB1RSTR]
-    orrs    r0, r3
-    str     r0, [r2, #RCC_APB1RSTR]     //RCC->APB1RSTR |= USBRST
-    ldr     r0, [r2, #RCC_APB1ENR]
-    bics    r0, r3
-    str     r0, [r2, #RCC_APB1ENR]     //RCC->APB1ENR &= ~USBEN
-.L_enable_end:
-    bx      lr
-    .size   _enable, . - _enable
-
-    .thumb_func
-    .type   _ep_setstall, %function
-
-/*void ep_settall(uint8_t ep, bool stall)
- * in  R0 <- endpoint number
- * in  R1 <- 0 if unstall, !0 if stall
- */
-_ep_setstall:
-    lsls    r2, r0, #28
-    lsrs    r2, #26
-    ldr     r3, =#USB_EPBASE
-    adds    r3, r2          // epr -> r3
-    movs    r2, 0x30        // TX_STAT_MASK -> r2
-    cmp     r0, #80
-    blo     .L_eps_rx
-.L_eps_tx:
-    ldr     r0, =#TX_STALL   //stall TX
-    tst     r1, r1
-    bne     .L_eps_reg_set
-.L_eps_tx_unstall:
-    ldrh    r1, [r3]        // *epr -> r1
-    lsls    r1, #21
-    lsrs    r1, #29         // EPTTYPE | EPKIND mask only
-    ldr     r0, =#DTX_USTALL //unstall dblbulk or iso TX (VALID and clr DTOG_TX & SWBUF_TX)
-    cmp     r1, #0x01       // if doublebuffered bulk endpoint
-    beq     .L_eps_reg_set
-    cmp     r1, #0x04       // if isochronous endpoint
-    ldr     r0, =#TX_USTALL  // unstall other TX (NAKED + clr DTOG_TX)
-    b       .L_eps_reg_set
-.L_eps_rx:
-    lsls    r2, #8          // RX_STAT_MASK -> R2
-    ldr     r0,=#RX_STALL    //stall RX
-    tst     r1, r1
-    bne     .L_eps_reg_set
-.L_eps_rx_unstall:
-    ldrh    r1, [r3]        // *epr -> r1
-    lsls    r1, #21
-    lsrs    r1, #29         // EPTTYPE | EPKIND mask only
-    ldr     r0, =#DRX_USTALL //unstall dblbulk or iso (VALID. clr DTOG_RX set SWBUF_RX)
-    cmp     r1, #0x01       // if dblbulk
-    beq     .L_eps_reg_set
-    cmp     r1, #0x04       // if iso
-    beq     .L_eps_reg_set
-    ldr     r0, =#RX_USTALL  // unstall other RX (VALID + clr
-/* R0 - mask and toggle bits
- * R2 - mask for STAT bits
- * R3 - endpoint register pointer
- */
-.L_eps_reg_set:
-    ldrh    r1, [r3]        // *epr -> r1
-    ands    r2, r1          // check if endpoint disabled
-    beq     .L_eps_exit     // do nothing
-    eors    r1, r0
-    lsrs    r0, #16
-    ands    r1, r0
-    strh    r1, [r3]
-.L_eps_exit:
-    bx      lr
-    .size   _ep_setstall, . - _ep_setstall
-
-
-    .thumb_func
-    .type   _ep_isstalled, %function
-/* bool ep_isstalled(uint8t ep) */
-_ep_isstalled:
-    ldr     r1, =#USB_EPBASE
-    lsls    r2, r0, #28
-    lsrs    r2, #26
-    ldr     r1, [r1, r2]
-    lsls    r1, #17
-    cmp     r0, #0x80
-    bhs     .L_eis_check
-    lsls    r1, #8
-.L_eis_check:
-    lsrs    r1, r1, #28
-    subs    r1, #0x01
-    subs    r0, r1, #0x01
-    sbcs    r1, r1
-    rsbs    r0, r1, #0
-    bx      lr
-    .size  _ep_isstalled, . - _ep_isstalled
-
-
-    .thumb_func
-    .type       _ep_read, %function
-/* uint16_t _ep_read(uint8_t ep, void *buf, uint16_t blen)
- * in  R0 <- endpoint
- * in  R1 <- *buffer
- * in  R2 <- length of the buffer
- * out length of the recieved data -> R0
- */
-_ep_read:
-    push    {r4, r5, lr}
-    ldr     r3, =#USB_EPBASE
-    ldr     r4, =#USB_PMABASE
-    lsls    r0, #28
-    lsrs    r0, #26
-    adds    r3, r0          // *EPR -> R3
-    lsls    r0, #1
-    adds    r4, r0          // *EPT -> R4
-    ldrh    r0, [r3]        // reading epr
-    lsls    r5, r0, #21
-    lsrs    r5, #29
-    cmp     r5, #0x04
-    beq     .L_epr_iso
-    cmp     r5, #0x01
-    bne     .L_epr_sngl
-.L_epr_dblbulk:
-    negs    r0, r0
-    lsrs    r0, #7          // ~SW_RX in CF
-    b       .L_epr_load_table
-.L_epr_iso:
-    lsrs    r0, #15         // DTOG_RX passsed to CF
-.L_epr_load_table:
-    ldrh    r0, [r4, #0]    // R0 rxaddr0
-    ldrh    r5, [r4, #2]    // R5 rxcnt0
-    bcs     .L_epr_prepare
-.L_epr_sngl:
-    ldrh    r0, [r4, #4]    // R0 rxaddr1 or rxaddr
-    ldrh    r5, [r4, #6]    // R5 rxcnt1 or rxcnt
-.L_epr_prepare:
-    ldr     r4, =#USB_PMABASE
-    adds    r0, r4          // R0 now has a physical address
-    lsls    r5, #22
-    lsrs    r5, #22         // R5 bytes count
-    cmp     r2, r5
-    blo     .L_epr_read
-    mov     r2, r5          // if buffer is larger
-.L_epr_read:
-    cmp     r2, #1
-    blo     .L_epr_read_end
-    ldrh    r4, [r0]
-    strb    r4, [r1]
-    beq     .L_epr_read_end
-    lsrs    r4, #8
-    strb    r4, [r1, #1]
-    adds    r1, #2
-    adds    r0, #2
-    subs    r2, #2
-    bne     .L_epr_read
-.L_epr_read_end:
-    ldrh    r0, [r3]
-    lsls    r1, r0, #21
-    lsrs    r1, #29
-    cmp     r1, #0x04
-    beq     .L_epr_exit     // ep is iso. no needs to set it to valid
-    cmp     r1, #0x01
-    beq     .L_epr_exit     // ep is dblbulk. no needs to set it to valid
-    ldr     r2, =#TGL_SET(EP_RX_STAT , EP_RX_VAL)
-    eors    r0, r2
-    lsrs    r2, #16
-    ands    r0, r2
-    strh    r0, [r3]        // set ep to VALID state
-.L_epr_exit:
-    mov     r0, r5
-    pop     {r4, r5, pc}
-    .size   _ep_read, . - _ep_read
-
-
-
-    .thumb_func
-    .type   _ep_write, %function
-/* uint16_t ep_write(uint8_t ep, void *buf, uint16_t blen)
- *
-
- */
-_ep_write:
-    push    {r2, r4, r5, lr}
-    ldr     r3, =#USB_EPBASE
-    ldr     r4, =#USB_PMABASE
-    lsls    r0, #28
-    lsrs    r0, #26
-    adds    r3, r0          // *EPR -> R3
-    lsls    r0, #1
-    adds    r4, r0          // *EPT -> R4
-    ldrh    r0, [r3]        // reading epr
-    lsls    r0, #21
-    lsrs    r0, #29
-    subs    r0, #0x04
-    beq     .L_epw_iso
-    adds    r0, #0x03
-    bne     .L_epw_sngl
-.L_epw_dblbulk:
-    ldrh    r0, [r3]
-    lsrs    r0, #15          // SW_TX in CF
-    bcc     .L_epw_sngl
-    b       .L_epw_settx1
-.L_epw_iso:
-    ldrh    r0, [r3]
-    lsrs    r0, #7          // DTOG_TX passsed to CF
-    bcs     .L_epw_sngl
-.L_epw_settx1:
-    adds    r4, #0x04
-.L_epw_sngl:
-    ldrh    r0, [r4, #0]    // R0 txaddr
-.L_epw_prepare:
-    strh    r2, [r4, #2]    // set txcount
-    ldr     r4, =#USB_PMABASE
-    adds    r0, r4
-.L_epw_write:
-    cmp     r2, #0x01
-    blo     .L_epw_writeend
-    ldrb    r4, [r1]
-    beq     .L_epw_halfw
-    ldrb    r5, [r1, #1]
-    lsls    r5, #8
-    orrs    r4, r5
-    strh    r4, [r0]
-    adds    r1, #2
-    adds    r0, #2
-    subs    r2, #2
-    b       .L_epw_write
-.L_epw_halfw:
-    strh    r4, [r0]
-.L_epw_writeend:
-    ldrh    r0, [r3]
-    lsls    r1, r0, #21
-    lsrs    r1, #29
-    cmp     r1, #0x04
-    beq     .L_epw_exit        //nothing to do with ISO ep
-    ldr     r2, =#TGL_SET(EP_TX_STAT, EP_TX_VAL)
-    cmp     r1, #0x01
-    bne     .L_epw_setstate
-// ep is dblbulk. needs to switch SW_TX
-    ldr     r2, =#TGL_SET(EP_TX_SWBUF, EP_TX_SWBUF)
-    bics    r0, r2              //clearing SW_BUF for setting in to 1 by XOR
- .L_epw_setstate:
-    eors    r0, r2
-    lsrs    r2, #16
-    ands    r0, r2
-    strh    r0, [r3]
-.L_epw_exit:
-    pop     {r0, r4, r5, pc}
-    .size   _ep_write, .- _ep_write
-
-
-
-/* internal function */
-/* requester size passed in R2 */
-/* result returns in R0 CF=1 if OK*/
-
-_get_next_pma:
-    push    {r1, r3, r4, lr}
-    movs    r1, #16
-    movs    r3, #1
-    lsls    r3, #10         //R3 MAX_PMA_SIZE
-    ldr     r0, =#USB_PMABASE
-.L_gnp_chkaddr:
-    ldrh    r4, [r0, #0]    //addr
-    tst     r4, r4
-    beq     .L_gnp_nxtaddr
-    cmp     r3, r4
-    blo     .L_gnp_nxtaddr
-    mov     r3, r4
-.L_gnp_nxtaddr:
-    adds    r0, #4
-    subs    r1, #1
-    bne     .L_gnp_chkaddr
-    subs    r0, r3, r2
-    blo     .L_gnp_exit
-    cmp     r0, #0x40       //check for the pma table overlap
-.L_gnp_exit:
-    pop     {r1, r3, r4, pc}
-
-
-
-    .size   _get_next_pma, . - _get_next_pma
-
-    .thumb_func
-    .type   _ep_config, %function
-/* bool ep_config(uint8_t ep, uint8_t eptype, uint16_t epsize)
- * R0 <- ep
- * R1 <- eptype
- * R2 <- epsize
- * result -> R0
- */
-_ep_config:
-    push    {r4, r5, lr}
-    movs    r3, 0x01
-    ands    r3, r2
-    adds    r2, r3      //R2 -> halfword aligned epsize
-    movs    r3, #0x00   //BULK
-    cmp     r1, #0x02   // is eptype bulk ?
-    beq     .L_epc_settype
-    movs    r3, #0x01   //DBLBULK
-    cmp     r1, #0x06
-    beq     .L_epc_settype
-    movs    r3, #0x02   //CONTROL
-    cmp     r1, #0x00
-    beq     .L_epc_settype
-    movs    r3, #0x04   //ISO
-    cmp     r1, #0x01
-    beq     .L_epc_settype
-    movs    r3, #0x06   //INTERRUPT
-.L_epc_settype:
-    lsls    r3, #8
-    lsls    r4, r0, #28
-    lsrs    r4, #28
-    orrs    r3, r4
-    lsls    r4, #2
-    ldr     r5, =#USB_EPBASE
-    strh    r3, [r5, r4]    //setup EPTYPE EPKIND EPADDR
-    cmp     r1, #0x00       // is a control ep ?
-    beq     .L_epc_setuptx
-    cmp     r0, #0x80
-    blo     .L_epc_setuprx
-.L_epc_setuptx:
-    ldr     r5, =#USB_PMABASE
-    lsls    r4, #1
-    adds    r5, r4
-    bl      _get_next_pma
-    bcc     .L_epc_fail
-    strh    r0, [r5, #TXADDR]    //store txaddr or txaddr0
-    movs    r0, #0x00
-    strh    r0, [r5, #TXCOUNT]    //store txcnt
-    cmp     r1, #0x06       // is DBLBULK
-    beq     .L_epc_txdbl
-    ldr     r3, =#TX_USTALL  //set state NAKED , clr DTOG_TX
-    cmp     r1, #0x01       // is ISO
-    bne     .L_epc_txsetstate   //
-.L_epc_txdbl:
-    ldr     r3, =#DTX_USTALL //set state VALID clr DTOG_TX & SWBUF_TX
-    bl      _get_next_pma
-    bcc     .L_epc_fail
-    strh    r0, [r5, #TXADDR1]    //store txaddr1
-    movs    r0, #0x00
-    strh    r0, [r5, #TXCOUNT1]    //store txcnt
-.L_epc_txsetstate:
-    ldr     r5, =#USB_EPBASE
-    lsrs    r4, #1
-    ldrh    r0, [r5, r4]
-    eors    r0, r3
-    lsrs    r3, #16
-    ands    r0, r3
-    strh    r0, [r5, r4]
-    cmp     r1, #0x00       //is a control ep ?
-    bne     .L_epc_exit
-.L_epc_setuprx:
-    mov     r3, r2
-    cmp     r2, #62
-    bls     .L_epc_rxbb
-    movs    r3, #0x1F
-    ands    r3, r2
-    bne     .L_epc_rxaa
-    subs    r2, #0x20
-.L_epc_rxaa:
-    bics    r2, r3
-    lsrs    r3, r2, #4
-    adds    r3, #0x40
-    adds    r2, #0x20
-.L_epc_rxbb:
-    lsls    r3, #9
-    ldr     r5, =#USB_PMABASE
-    lsls    r4, #1
-    adds    r5, r4
-    cmp     r1, 0x06    //if dblbulk
-    beq     .L_epc_rxdbl
-    cmp     r1, 0x01    // iso
-    bne     .L_epc_rxsngl
-.L_epc_rxdbl:
-    bl      _get_next_pma
-    bcc     .L_epc_fail
-    strh    r0, [r5, #RXADDR0]    //store rxaddr0
-    strh    r3, [r5, #RXCOUNT0]    //store rxcnt0
-    bl      _get_next_pma
-    bcc     .L_epc_fail
-    strh    r0, [r5, #RXADDR1]    //store rxaddr1
-    strh    r3, [r5, #RXCOUNT1]    //store rxcnt1
-    ldr     r3, =#DRX_USTALL
-    b       .L_epc_rxsetstate
-.L_epc_rxsngl:
-    bl      _get_next_pma
-    bcc     .L_epc_fail
-    strh    r0, [r5, #RXADDR]    //store rxaddr1 or rxaddr
-    strh    r3, [r5, #RXCOUNT]    //store rxcnt1 or rxcnt
-    ldr     r3, =#RX_USTALL
-.L_epc_rxsetstate:
-    ldr     r5, =#USB_EPBASE
-    lsrs    r4, #1
-    ldrh    r0, [r5, r4]
-    eors    r0, r3
-    lsrs    r3, #16
-    ands    r0, r3
-    strh    r0, [r5, r4]
-.L_epc_exit:
-    movs    r0, #0x01
-    pop     {r4, r5, pc}
-.L_epc_fail:
-    movs    r0, #0x00
-    pop     {r4, r5, pc}
-
-    .size   _ep_config, . - _ep_config
-
-    .thumb_func
-    .type   _ep_deconfig, %function
-
-
-/* void ep_deconfig( uint8_t ep)
- * R0 <- ep
- */
-_ep_deconfig:
-    lsls    r1, r0, #28
-    lsrs    r1, #26
-    ldr     r2, =#USB_EPBASE
-    ldr     r3, =#USB_PMABASE
-    adds    r2, r1
-    lsls    r1, #1
-    adds    r3, r1
-/* clearing endpoint register */
-    ldr     r1, =#EP_NOTOG
-    ldrh    r0, [r2]
-    bics    r0, r1
-    strh    r0, [r2]
-/* clearing PMA data */
-    movs    r0, #0x00
-    strh    r0, [r3, #TXADDR]
-    strh    r0, [r3, #TXCOUNT]
-    strh    r0, [r3, #RXADDR]
-    strh    r0, [r3, #RXCOUNT]
-    bx      lr
-
-    .size   _ep_deconfig, . - _ep_config
-
-
-
-
-#define ISTRSHIFT   8
-#define ISTRBIT(bit) ((1 << bit) >> ISTRSHIFT)
-
-
-    .thumb_func
-    .type     _evt_poll, %function
-/*void evt_poll(usbd_device *dev, usbd_evt_callback callback)*/
-_evt_poll:
-    push    {r0, r1, r4, r5}
-    ldr     r3, =#USB_REGBASE
-    ldrh    r0, [r3, #4]        //USB->ISTR -> R2
-/* ep_index -> R2 */
-    movs    r2, 0x07
-    ands    r2, r0
-/* checking USB->ISTR for events */
-    lsls    r0, #17             //CTRM -> CF
-    bcs     .L_ep_ctrm
-    lsls    r0, #2              //ERRM -> CF
-    bcs     .L_ep_errm
-    lsls    r0, #1              //WKUPM -> CF
-    bcs     .L_ep_wkupm
-    lsls    r0, #1              //SUSPM -> CF
-    bcs     .L_ep_suspm
-    lsls    r0, #1              //RESETM -> CF
-    bcs     .L_ep_resetm
-    lsls    r0, #1              //SOFM -> CF
-    bcs     .L_ep_sofm
-    lsls    r0, #1
-    bcs     .L_ep_esofm
-    /* exit with no callback */
-    pop     {r0, r1, r4 , r5}
-    bx      lr
-
-.L_ep_ctrm:
-    movs    r3, #0x00
-    ldr     r0,=#USB_EPBASE
-    lsrs    r0, #2
-    adds    r0, r2
-    lsls    r0, #2              // R0 ep register address
-    ldrh    r4, [r0]            //R4 *USB->EPx
-    lsrs    r5, r4, #8         // CTR_TX -> CF
-    bcc     .L_ep_ctr_rx
-/* CTR_TX event */
-    movs    r1, #usbd_evt_eptx
-    movs    r5, #0x80
-    adds    r2, #0x80           // set endpoint tx
-    b       .L_ep_clr_ctr
-.L_ep_ctr_rx:
-/* CTR_RX  RX or SETUP */
-    movs    r1, #usbd_evt_epsetup
-    lsls    r5, r4, #21             //SETUP -> CF
-    bcs     .L_ep_ctr_evt
-    movs    r1, #usbd_evt_eprx
-    lsrs    r5, #29                 //EP_TYPE | EP_KIND -> R5 LSB
-    cmp     r5, #0x01               //if dblbuf bulk
-    bne     .L_ep_ctr_evt
-/* if ep is dblbulk RX */
-    movs    r3, #EP_RX_SWBUF
-.L_ep_ctr_evt:
-/* clear CTR_RX */
-    movs    r5, #0x80
-    lsls    r5, #0x08
-.L_ep_clr_ctr:
-    bics    r4, r5
-    ldr     r5, =#EP_NOTOG
-    ands    r4, r5
-    orrs    r4, r3
-    strh    r4, [r0]            // clr CTR flag
-    b       .L_ep_callback
-.L_ep_errm:
-    movs    r1, #usbd_evt_error
-    movs    r4, #ISTRBIT(13)
-    b      .L_ep_clristr
-
-.L_ep_sofm:
-    movs    r1, #usbd_evt_sof
-    movs    r4, #ISTRBIT(9)
-    b       .L_ep_clristr
-
-.L_ep_esofm:
-    movs    r1, #usbd_evt_esof
-    movs    r4, #ISTRBIT(8)
-    b       .L_ep_clristr
-
-.L_ep_wkupm:
-    ldrh    r1, [r3, #0]            //R1 USB->CNTR
-    movs    r5, #0x08
-    bics    r1, r5                  //clr FSUSP
-    strh    r1, [r3, #0]            //USB->CNTR R2
-    movs    r1, #usbd_evt_wkup
-    movs    r4, #ISTRBIT(12)
-    b       .L_ep_clristr
-
-.L_ep_suspm:
-    ldrh    r1, [r3, #USB_CNTR]     //R1 USB->CNTR
-    movs    r5, #0x08
-    orrs    r1, r5                  //set FSUSP
-    strh    r1, [r3, #USB_CNTR]     //USB->CNTR R2
-    movs    r1, #usbd_evt_susp
-    movs    r4, #ISTRBIT(11)
-    b       .L_ep_clristr
-
-/* do reset routine */
-.L_ep_resetm:
-    movs    r1, #7
-    ldr     r2, =#USB_EPBASE
-    ldr     r0, =#USB_PMABASE
-    ldr     r5, =#EP_NOTOG
-.L_ep_reset_loop:
-    ldrh    r4, [r2]
-    bics    r4, r5
-    strh    r4, [r2]
-    movs    r4, #0
-    strh    r4, [r0, #TXADDR]
-    strh    r4, [r0, #TXCOUNT]
-    strh    r4, [r0, #RXADDR]
-    strh    r4, [r0, #RXCOUNT]
-    adds    r2, #4
-    adds    r0, #8
-    subs    r1, #1
-    bpl     .L_ep_reset_loop
-    movs    r2, #0x00
-    strh    r2, [r3, #USB_BTABLE]     // 0 -> USB->BTABLE
-    movs    r1, #usbd_evt_reset
-    movs    r4, #ISTRBIT(10)
-.L_ep_clristr:
-    lsls    r4, #ISTRSHIFT
-    ldrh    r0, [r3, #4]
-    bics    r0, r4
-    strh    r0, [r3, #4]
-.L_ep_callback:
-    pop     {r0, r3, r4, r5 }
-    bx      r3
-
-    .size   _evt_poll, . - _evt_poll
-
-
-
-
-    .pool
-
-   .end
-
-#endif
+/* This file is the part of the LUS32 project
+ *
+ * Copyright ©2016 Dmitry Filimonchuk <dmitrystu[at]gmail[dot]com>
+ *
+ * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ * 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.
+ */
+
+#if !defined (__ASSEMBLER__)
+    #define __ASSEMBLER__
+#endif
+
+#include "../usb.h"
+#include "memmap.inc"
+#if defined(USE_STMV0A_DRIVER)
+
+#define EP_SETUP    0x0800
+#define EP_TYPE     0x0600
+#define EP_KIND     0x0100
+#define EP_ADDR     0x000F
+
+#define EP_RX_CTR   0x8000
+#define EP_RX_DTOG  0x4000
+#define EP_RX_STAT  0x3000
+#define EP_RX_SWBUF 0x0040
+
+#define EP_RX_DIS   0x0000
+#define EP_RX_STAL  0x1000
+#define EP_RX_NAK   0x2000
+#define EP_RX_VAL   0x3000
+
+#define EP_TX_CTR   0x0080
+#define EP_TX_DTOG  0x0040
+#define EP_TX_STAT  0x0030
+#define EP_TX_SWBUF 0x4000
+
+#define EP_TX_DIS   0x0000
+#define EP_TX_STAL  0x0010
+#define EP_TX_NAK   0x0020
+#define EP_TX_VAL   0x0030
+
+#define RXADDR0     0x00
+#define RXCOUNT0    0x02
+#define RXADDR1     0x04
+#define RXCOUNT1    0x08
+
+#define TXADDR0     0x00
+#define TXCOUNT0    0x02
+#define TXADDR1     0x04
+#define TXCOUNT1    0x08
+
+#define TXADDR      0x00
+#define TXCOUNT     0x02
+#define RXADDR      0x04
+#define RXCOUNT     0x08
+
+
+#define EP_NOTOG    (EP_RX_CTR | EP_TX_CTR | EP_SETUP | EP_TYPE | EP_KIND | EP_ADDR)
+
+#define TGL_SET(mask, bits)  ((EP_NOTOG | (mask))<<16 | (bits))
+
+#define TX_STALL    TGL_SET(EP_TX_STAT,                            EP_TX_STAL)
+#define RX_STALL    TGL_SET(EP_RX_STAT,                            EP_RX_STAL)
+#define TX_USTALL   TGL_SET(EP_TX_STAT | EP_TX_DTOG,               EP_TX_NAK)
+#define RX_USTALL   TGL_SET(EP_RX_STAT | EP_RX_DTOG,               EP_RX_VAL)
+#define DTX_USTALL  TGL_SET(EP_TX_STAT | EP_TX_DTOG | EP_TX_SWBUF, EP_TX_VAL)
+#define DRX_USTALL  TGL_SET(EP_RX_STAT | EP_RX_DTOG | EP_RX_SWBUF, EP_RX_VAL | EP_RX_SWBUF)
+
+
+    .syntax unified
+    .cpu cortex-m0plus
+    .text
+    .thumb
+
+
+    .globl  usb_stmv0a
+    .align  2
+usb_stmv0a:
+    .long   _enable
+    .long   _reset
+    .long   _connect
+    .long   _setaddr
+    .long   _ep_config
+    .long   _ep_deconfig
+    .long   _ep_read
+    .long   _ep_write
+    .long   _ep_setstall
+    .long   _ep_isstalled
+    .long   _evt_poll
+    .long   _get_frame
+    .long   _get_serial_desc
+    .size   usb_stmv0a, . - usb_stmv0a
+
+
+    .thumb_func
+    .type _get_serial_desc, %function
+
+/*  uint16_t get_serial_desc (void *buffer)
+ *  R0 <- buffer for the string descriptor
+ *  descrpitor size -> R0
+ */
+_get_serial_desc:
+    push    {r4, r5, lr}
+    movs    r1,18               //descriptor size 18 bytes
+    strb    r1,[r0]
+    movs    r1, #0x03           //DTYPE_STRING
+    strb    r1,[r0, #0x01]
+    ldr     r5, .L_uid_base     //UID3 this is the serial number
+    ldr     r4, .L_fnv1a_offset //FNV1A offset
+    ldr     r2, [r5, 0x00]      //UID0
+    bl      .L_fnv1a
+    ldr     r2, [r5, 0x04]      //UID1
+    bl      .L_fnv1a
+    ldr     r2, [r5, 0x14]      //UID2
+    bl      .L_fnv1a
+    movs    r3, #28
+.L_gsn_loop:
+    movs    r1, r4
+    lsrs    r1, r3
+    lsls    r1, #28
+    lsrs    r1, #28
+    adds    r1, #0x30           //'0'
+    cmp     r1, #0x3A
+    blo     .L_gsn_store
+    adds    r1, #0x07           //'A' - '0'
+.L_gsn_store:
+    adds    r0, #0x02
+    strb    r1, [r0]
+    lsrs    r1, #0x08
+    strb    r1, [r0, #0x01]
+    subs    r3, #0x04
+    bpl     .L_gsn_loop
+    movs    r0, #18
+    pop     {r4, r5, pc}
+
+.L_fnv1a:
+    movs    r3, #0x04
+.L_fnv1a_loop:
+    uxtb    r1, r2
+    eors    r4, r1
+    ldr     r1, .L_fnv1a_prime       //FNV1A prime
+    muls    r4, r1
+    lsrs    r2, #0x08
+    subs    r3, #0x01
+    bne     .L_fnv1a_loop
+    bx      lr
+
+    .align 2
+.L_fnv1a_prime:     .long   16777619
+.L_fnv1a_offset:    .long   2166136261
+.L_uid_base:        .long   UID_BASE
+
+    .size _get_serial_desc, . - _get_serial_desc
+
+    .thumb_func
+    .type   _connect, %function
+_connect:
+    subs    r1, r0, #1
+    sbcs    r0, r1
+    lsls    r0, #15
+    ldr     r1, =#USB_REGBASE
+    strh    r0, [r1, #USB_BCDR]      //USB->BCDR
+    bx      lr
+    .size   _connect, . - _connect
+
+
+    .thumb_func
+    .type   _setaddr, %function
+_setaddr:
+    ldr     r1, =USB_REGBASE
+    adds    r0, #0x80
+    strh    r0, [r1, #USB_DADDR]     //USB->DADDR
+    bx      lr
+    .size   _setaddr, . - _setaddr
+
+    .thumb_func
+    .type   _reset, %function
+_reset:
+    ldr     r2, =#USB_REGBASE
+    movs    r0, #0x01           //FRES
+    ldrh    r1, [r2, #USB_CNTR] //USB->CNTR
+    orrs    r1, r0
+    strh    r1, [r2, #USB_CNTR] // set FRES
+    bics    r1, r0
+    strh    r1, [r2, #USB_CNTR] // clr FRES
+    bx      lr
+    .size   _reset, . - _reset
+
+    .thumb_func
+    .type   _get_frame, %function
+_get_frame:
+    ldr     r0, =#USB_REGBASE
+    ldrh    r0, [r0, #USB_FNR]     //FNR
+    lsls    r0, #21
+    lsrs    r0, #21
+    bx      lr
+    .size   _get_frame, . - _get_frame
+
+    .thumb_func
+    .type   _enable, %function
+_enable:
+    ldr     r1, =#USB_REGBASE     //USB->CNTR
+    ldr     r2, =#RCC_BASE        //RCC
+    movs    r3, #0x01
+    lsls    r3, #23             //USBEN or USBRST
+    tst     r0, r0
+    beq     .L_disable
+.L_enable:
+    ldr     r0, [r2, #RCC_APB1ENR]
+    orrs    r0, r3
+    str     r0, [r2, #RCC_APB1ENR]     //RCC->APB1ENR |= USBEN
+    ldr     r0, [r2, #RCC_APB1RSTR]
+    orrs    r0, r3
+    str     r0, [r2, #RCC_APB1RSTR]     //RCC->APB1RSTR |= USBRST
+    bics    r0, r3
+    str     r0, [r2, #RCC_APB1RSTR]     //RCC->APB1RSTR &= ~USBRST
+    movs    r0, #0xBE
+    lsls    r0, #0x08           // CTRM | ERRM | WKUPM | SUSPM | RESETM | SOFM
+    strh    r0, [r1]            //set USB->CNTR
+    bx      lr
+.L_disable:
+    ldr     r0, [r2, #RCC_APB1ENR]
+    tst     r0, r3
+    beq     .L_enable_end       // usb is disabled
+    movs    r0, #0x00
+    strh    r0, [r1, #USB_BCDR]     //USB->BCDR disable USB I/O
+    ldr     r0, [r2, #RCC_APB1RSTR]
+    orrs    r0, r3
+    str     r0, [r2, #RCC_APB1RSTR]     //RCC->APB1RSTR |= USBRST
+    ldr     r0, [r2, #RCC_APB1ENR]
+    bics    r0, r3
+    str     r0, [r2, #RCC_APB1ENR]     //RCC->APB1ENR &= ~USBEN
+.L_enable_end:
+    bx      lr
+    .size   _enable, . - _enable
+
+    .thumb_func
+    .type   _ep_setstall, %function
+
+/*void ep_settall(uint8_t ep, bool stall)
+ * in  R0 <- endpoint number
+ * in  R1 <- 0 if unstall, !0 if stall
+ */
+_ep_setstall:
+    lsls    r2, r0, #28
+    lsrs    r2, #26
+    ldr     r3, =#USB_EPBASE
+    adds    r3, r2          // epr -> r3
+    movs    r2, 0x30        // TX_STAT_MASK -> r2
+    cmp     r0, #80
+    blo     .L_eps_rx
+.L_eps_tx:
+    ldr     r0, =#TX_STALL   //stall TX
+    tst     r1, r1
+    bne     .L_eps_reg_set
+.L_eps_tx_unstall:
+    ldrh    r1, [r3]        // *epr -> r1
+    lsls    r1, #21
+    lsrs    r1, #29         // EPTTYPE | EPKIND mask only
+    ldr     r0, =#DTX_USTALL //unstall dblbulk or iso TX (VALID and clr DTOG_TX & SWBUF_TX)
+    cmp     r1, #0x01       // if doublebuffered bulk endpoint
+    beq     .L_eps_reg_set
+    cmp     r1, #0x04       // if isochronous endpoint
+    ldr     r0, =#TX_USTALL  // unstall other TX (NAKED + clr DTOG_TX)
+    b       .L_eps_reg_set
+.L_eps_rx:
+    lsls    r2, #8          // RX_STAT_MASK -> R2
+    ldr     r0,=#RX_STALL    //stall RX
+    tst     r1, r1
+    bne     .L_eps_reg_set
+.L_eps_rx_unstall:
+    ldrh    r1, [r3]        // *epr -> r1
+    lsls    r1, #21
+    lsrs    r1, #29         // EPTTYPE | EPKIND mask only
+    ldr     r0, =#DRX_USTALL //unstall dblbulk or iso (VALID. clr DTOG_RX set SWBUF_RX)
+    cmp     r1, #0x01       // if dblbulk
+    beq     .L_eps_reg_set
+    cmp     r1, #0x04       // if iso
+    beq     .L_eps_reg_set
+    ldr     r0, =#RX_USTALL  // unstall other RX (VALID + clr
+/* R0 - mask and toggle bits
+ * R2 - mask for STAT bits
+ * R3 - endpoint register pointer
+ */
+.L_eps_reg_set:
+    ldrh    r1, [r3]        // *epr -> r1
+    ands    r2, r1          // check if endpoint disabled
+    beq     .L_eps_exit     // do nothing
+    eors    r1, r0
+    lsrs    r0, #16
+    ands    r1, r0
+    strh    r1, [r3]
+.L_eps_exit:
+    bx      lr
+    .size   _ep_setstall, . - _ep_setstall
+
+
+    .thumb_func
+    .type   _ep_isstalled, %function
+/* bool ep_isstalled(uint8t ep) */
+_ep_isstalled:
+    ldr     r1, =#USB_EPBASE
+    lsls    r2, r0, #28
+    lsrs    r2, #26
+    ldr     r1, [r1, r2]
+    lsls    r1, #17
+    cmp     r0, #0x80
+    bhs     .L_eis_check
+    lsls    r1, #8
+.L_eis_check:
+    lsrs    r1, r1, #28
+    subs    r1, #0x01
+    subs    r0, r1, #0x01
+    sbcs    r1, r1
+    rsbs    r0, r1, #0
+    bx      lr
+    .size  _ep_isstalled, . - _ep_isstalled
+
+
+    .thumb_func
+    .type       _ep_read, %function
+/* uint16_t _ep_read(uint8_t ep, void *buf, uint16_t blen)
+ * in  R0 <- endpoint
+ * in  R1 <- *buffer
+ * in  R2 <- length of the buffer
+ * out length of the recieved data -> R0
+ */
+_ep_read:
+    push    {r4, r5, lr}
+    ldr     r3, =#USB_EPBASE
+    ldr     r4, =#USB_PMABASE
+    lsls    r0, #28
+    lsrs    r0, #26
+    adds    r3, r0          // *EPR -> R3
+    lsls    r0, #1
+    adds    r4, r0          // *EPT -> R4
+    ldrh    r0, [r3]        // reading epr
+    lsls    r5, r0, #21
+    lsrs    r5, #29
+    cmp     r5, #0x04
+    beq     .L_epr_iso
+    cmp     r5, #0x01
+    bne     .L_epr_sngl
+.L_epr_dblbulk:
+    negs    r0, r0
+    lsrs    r0, #7          // ~SW_RX in CF
+    b       .L_epr_load_table
+.L_epr_iso:
+    lsrs    r0, #15         // DTOG_RX passsed to CF
+.L_epr_load_table:
+    ldrh    r0, [r4, #0]    // R0 rxaddr0
+    ldrh    r5, [r4, #2]    // R5 rxcnt0
+    bcs     .L_epr_prepare
+.L_epr_sngl:
+    ldrh    r0, [r4, #4]    // R0 rxaddr1 or rxaddr
+    ldrh    r5, [r4, #6]    // R5 rxcnt1 or rxcnt
+.L_epr_prepare:
+    ldr     r4, =#USB_PMABASE
+    adds    r0, r4          // R0 now has a physical address
+    lsls    r5, #22
+    lsrs    r5, #22         // R5 bytes count
+    cmp     r2, r5
+    blo     .L_epr_read
+    mov     r2, r5          // if buffer is larger
+.L_epr_read:
+    cmp     r2, #1
+    blo     .L_epr_read_end
+    ldrh    r4, [r0]
+    strb    r4, [r1]
+    beq     .L_epr_read_end
+    lsrs    r4, #8
+    strb    r4, [r1, #1]
+    adds    r1, #2
+    adds    r0, #2
+    subs    r2, #2
+    bne     .L_epr_read
+.L_epr_read_end:
+    ldrh    r0, [r3]
+    lsls    r1, r0, #21
+    lsrs    r1, #29
+    cmp     r1, #0x04
+    beq     .L_epr_exit     // ep is iso. no needs to set it to valid
+    cmp     r1, #0x01
+    beq     .L_epr_exit     // ep is dblbulk. no needs to set it to valid
+    ldr     r2, =#TGL_SET(EP_RX_STAT , EP_RX_VAL)
+    eors    r0, r2
+    lsrs    r2, #16
+    ands    r0, r2
+    strh    r0, [r3]        // set ep to VALID state
+.L_epr_exit:
+    mov     r0, r5
+    pop     {r4, r5, pc}
+    .size   _ep_read, . - _ep_read
+
+
+
+    .thumb_func
+    .type   _ep_write, %function
+/* uint16_t ep_write(uint8_t ep, void *buf, uint16_t blen)
+ *
+
+ */
+_ep_write:
+    push    {r2, r4, r5, lr}
+    ldr     r3, =#USB_EPBASE
+    ldr     r4, =#USB_PMABASE
+    lsls    r0, #28
+    lsrs    r0, #26
+    adds    r3, r0          // *EPR -> R3
+    lsls    r0, #1
+    adds    r4, r0          // *EPT -> R4
+    ldrh    r0, [r3]        // reading epr
+    lsls    r0, #21
+    lsrs    r0, #29
+    subs    r0, #0x04
+    beq     .L_epw_iso
+    adds    r0, #0x03
+    bne     .L_epw_sngl
+.L_epw_dblbulk:
+    ldrh    r0, [r3]
+    lsrs    r0, #15          // SW_TX in CF
+    bcc     .L_epw_sngl
+    b       .L_epw_settx1
+.L_epw_iso:
+    ldrh    r0, [r3]
+    lsrs    r0, #7          // DTOG_TX passsed to CF
+    bcs     .L_epw_sngl
+.L_epw_settx1:
+    adds    r4, #0x04
+.L_epw_sngl:
+    ldrh    r0, [r4, #0]    // R0 txaddr
+.L_epw_prepare:
+    strh    r2, [r4, #2]    // set txcount
+    ldr     r4, =#USB_PMABASE
+    adds    r0, r4
+.L_epw_write:
+    cmp     r2, #0x01
+    blo     .L_epw_writeend
+    ldrb    r4, [r1]
+    beq     .L_epw_halfw
+    ldrb    r5, [r1, #1]
+    lsls    r5, #8
+    orrs    r4, r5
+    strh    r4, [r0]
+    adds    r1, #2
+    adds    r0, #2
+    subs    r2, #2
+    b       .L_epw_write
+.L_epw_halfw:
+    strh    r4, [r0]
+.L_epw_writeend:
+    ldrh    r0, [r3]
+    lsls    r1, r0, #21
+    lsrs    r1, #29
+    cmp     r1, #0x04
+    beq     .L_epw_exit        //nothing to do with ISO ep
+    ldr     r2, =#TGL_SET(EP_TX_STAT, EP_TX_VAL)
+    cmp     r1, #0x01
+    bne     .L_epw_setstate
+// ep is dblbulk. needs to switch SW_TX
+    ldr     r2, =#TGL_SET(EP_TX_SWBUF, EP_TX_SWBUF)
+    bics    r0, r2              //clearing SW_BUF for setting in to 1 by XOR
+ .L_epw_setstate:
+    eors    r0, r2
+    lsrs    r2, #16
+    ands    r0, r2
+    strh    r0, [r3]
+.L_epw_exit:
+    pop     {r0, r4, r5, pc}
+    .size   _ep_write, .- _ep_write
+
+
+
+/* internal function */
+/* requester size passed in R2 */
+/* result returns in R0 CF=1 if OK*/
+
+_get_next_pma:
+    push    {r1, r3, r4, lr}
+    movs    r1, #16
+    movs    r3, #1
+    lsls    r3, #10         //R3 MAX_PMA_SIZE
+    ldr     r0, =#USB_PMABASE
+.L_gnp_chkaddr:
+    ldrh    r4, [r0, #0]    //addr
+    tst     r4, r4
+    beq     .L_gnp_nxtaddr
+    cmp     r3, r4
+    blo     .L_gnp_nxtaddr
+    mov     r3, r4
+.L_gnp_nxtaddr:
+    adds    r0, #4
+    subs    r1, #1
+    bne     .L_gnp_chkaddr
+    subs    r0, r3, r2
+    blo     .L_gnp_exit
+    cmp     r0, #0x40       //check for the pma table overlap
+.L_gnp_exit:
+    pop     {r1, r3, r4, pc}
+
+
+
+    .size   _get_next_pma, . - _get_next_pma
+
+    .thumb_func
+    .type   _ep_config, %function
+/* bool ep_config(uint8_t ep, uint8_t eptype, uint16_t epsize)
+ * R0 <- ep
+ * R1 <- eptype
+ * R2 <- epsize
+ * result -> R0
+ */
+_ep_config:
+    push    {r4, r5, lr}
+    movs    r3, 0x01
+    ands    r3, r2
+    adds    r2, r3      //R2 -> halfword aligned epsize
+    movs    r3, #0x00   //BULK
+    cmp     r1, #0x02   // is eptype bulk ?
+    beq     .L_epc_settype
+    movs    r3, #0x01   //DBLBULK
+    cmp     r1, #0x06
+    beq     .L_epc_settype
+    movs    r3, #0x02   //CONTROL
+    cmp     r1, #0x00
+    beq     .L_epc_settype
+    movs    r3, #0x04   //ISO
+    cmp     r1, #0x01
+    beq     .L_epc_settype
+    movs    r3, #0x06   //INTERRUPT
+.L_epc_settype:
+    lsls    r3, #8
+    lsls    r4, r0, #28
+    lsrs    r4, #28
+    orrs    r3, r4
+    lsls    r4, #2
+    ldr     r5, =#USB_EPBASE
+    strh    r3, [r5, r4]    //setup EPTYPE EPKIND EPADDR
+    cmp     r1, #0x00       // is a control ep ?
+    beq     .L_epc_setuptx
+    cmp     r0, #0x80
+    blo     .L_epc_setuprx
+.L_epc_setuptx:
+    ldr     r5, =#USB_PMABASE
+    lsls    r4, #1
+    adds    r5, r4
+    bl      _get_next_pma
+    bcc     .L_epc_fail
+    strh    r0, [r5, #TXADDR]    //store txaddr or txaddr0
+    movs    r0, #0x00
+    strh    r0, [r5, #TXCOUNT]    //store txcnt
+    cmp     r1, #0x06       // is DBLBULK
+    beq     .L_epc_txdbl
+    ldr     r3, =#TX_USTALL  //set state NAKED , clr DTOG_TX
+    cmp     r1, #0x01       // is ISO
+    bne     .L_epc_txsetstate   //
+.L_epc_txdbl:
+    ldr     r3, =#DTX_USTALL //set state VALID clr DTOG_TX & SWBUF_TX
+    bl      _get_next_pma
+    bcc     .L_epc_fail
+    strh    r0, [r5, #TXADDR1]    //store txaddr1
+    movs    r0, #0x00
+    strh    r0, [r5, #TXCOUNT1]    //store txcnt
+.L_epc_txsetstate:
+    ldr     r5, =#USB_EPBASE
+    lsrs    r4, #1
+    ldrh    r0, [r5, r4]
+    eors    r0, r3
+    lsrs    r3, #16
+    ands    r0, r3
+    strh    r0, [r5, r4]
+    cmp     r1, #0x00       //is a control ep ?
+    bne     .L_epc_exit
+.L_epc_setuprx:
+    mov     r3, r2
+    cmp     r2, #62
+    bls     .L_epc_rxbb
+    movs    r3, #0x1F
+    ands    r3, r2
+    bne     .L_epc_rxaa
+    subs    r2, #0x20
+.L_epc_rxaa:
+    bics    r2, r3
+    lsrs    r3, r2, #4
+    adds    r3, #0x40
+    adds    r2, #0x20
+.L_epc_rxbb:
+    lsls    r3, #9
+    ldr     r5, =#USB_PMABASE
+    lsls    r4, #1
+    adds    r5, r4
+    cmp     r1, 0x06    //if dblbulk
+    beq     .L_epc_rxdbl
+    cmp     r1, 0x01    // iso
+    bne     .L_epc_rxsngl
+.L_epc_rxdbl:
+    bl      _get_next_pma
+    bcc     .L_epc_fail
+    strh    r0, [r5, #RXADDR0]    //store rxaddr0
+    strh    r3, [r5, #RXCOUNT0]    //store rxcnt0
+    bl      _get_next_pma
+    bcc     .L_epc_fail
+    strh    r0, [r5, #RXADDR1]    //store rxaddr1
+    strh    r3, [r5, #RXCOUNT1]    //store rxcnt1
+    ldr     r3, =#DRX_USTALL
+    b       .L_epc_rxsetstate
+.L_epc_rxsngl:
+    bl      _get_next_pma
+    bcc     .L_epc_fail
+    strh    r0, [r5, #RXADDR]    //store rxaddr1 or rxaddr
+    strh    r3, [r5, #RXCOUNT]    //store rxcnt1 or rxcnt
+    ldr     r3, =#RX_USTALL
+.L_epc_rxsetstate:
+    ldr     r5, =#USB_EPBASE
+    lsrs    r4, #1
+    ldrh    r0, [r5, r4]
+    eors    r0, r3
+    lsrs    r3, #16
+    ands    r0, r3
+    strh    r0, [r5, r4]
+.L_epc_exit:
+    movs    r0, #0x01
+    pop     {r4, r5, pc}
+.L_epc_fail:
+    movs    r0, #0x00
+    pop     {r4, r5, pc}
+
+    .size   _ep_config, . - _ep_config
+
+    .thumb_func
+    .type   _ep_deconfig, %function
+
+
+/* void ep_deconfig( uint8_t ep)
+ * R0 <- ep
+ */
+_ep_deconfig:
+    lsls    r1, r0, #28
+    lsrs    r1, #26
+    ldr     r2, =#USB_EPBASE
+    ldr     r3, =#USB_PMABASE
+    adds    r2, r1
+    lsls    r1, #1
+    adds    r3, r1
+/* clearing endpoint register */
+    ldr     r1, =#EP_NOTOG
+    ldrh    r0, [r2]
+    bics    r0, r1
+    strh    r0, [r2]
+/* clearing PMA data */
+    movs    r0, #0x00
+    strh    r0, [r3, #TXADDR]
+    strh    r0, [r3, #TXCOUNT]
+    strh    r0, [r3, #RXADDR]
+    strh    r0, [r3, #RXCOUNT]
+    bx      lr
+
+    .size   _ep_deconfig, . - _ep_config
+
+
+
+
+#define ISTRSHIFT   8
+#define ISTRBIT(bit) ((1 << bit) >> ISTRSHIFT)
+
+
+    .thumb_func
+    .type     _evt_poll, %function
+/*void evt_poll(usbd_device *dev, usbd_evt_callback callback)*/
+_evt_poll:
+    push    {r0, r1, r4, r5}
+    ldr     r3, =#USB_REGBASE
+    ldrh    r0, [r3, #4]        //USB->ISTR -> R2
+/* ep_index -> R2 */
+    movs    r2, 0x07
+    ands    r2, r0
+/* checking USB->ISTR for events */
+    lsls    r0, #17             //CTRM -> CF
+    bcs     .L_ep_ctrm
+    lsls    r0, #2              //ERRM -> CF
+    bcs     .L_ep_errm
+    lsls    r0, #1              //WKUPM -> CF
+    bcs     .L_ep_wkupm
+    lsls    r0, #1              //SUSPM -> CF
+    bcs     .L_ep_suspm
+    lsls    r0, #1              //RESETM -> CF
+    bcs     .L_ep_resetm
+    lsls    r0, #1              //SOFM -> CF
+    bcs     .L_ep_sofm
+    lsls    r0, #1
+    bcs     .L_ep_esofm
+    /* exit with no callback */
+    pop     {r0, r1, r4 , r5}
+    bx      lr
+
+.L_ep_ctrm:
+    movs    r3, #0x00
+    ldr     r0,=#USB_EPBASE
+    lsrs    r0, #2
+    adds    r0, r2
+    lsls    r0, #2              // R0 ep register address
+    ldrh    r4, [r0]            //R4 *USB->EPx
+    lsrs    r5, r4, #8         // CTR_TX -> CF
+    bcc     .L_ep_ctr_rx
+/* CTR_TX event */
+    movs    r1, #usbd_evt_eptx
+    movs    r5, #0x80
+    adds    r2, #0x80           // set endpoint tx
+    b       .L_ep_clr_ctr
+.L_ep_ctr_rx:
+/* CTR_RX  RX or SETUP */
+    movs    r1, #usbd_evt_epsetup
+    lsls    r5, r4, #21             //SETUP -> CF
+    bcs     .L_ep_ctr_evt
+    movs    r1, #usbd_evt_eprx
+    lsrs    r5, #29                 //EP_TYPE | EP_KIND -> R5 LSB
+    cmp     r5, #0x01               //if dblbuf bulk
+    bne     .L_ep_ctr_evt
+/* if ep is dblbulk RX */
+    movs    r3, #EP_RX_SWBUF
+.L_ep_ctr_evt:
+/* clear CTR_RX */
+    movs    r5, #0x80
+    lsls    r5, #0x08
+.L_ep_clr_ctr:
+    bics    r4, r5
+    ldr     r5, =#EP_NOTOG
+    ands    r4, r5
+    orrs    r4, r3
+    strh    r4, [r0]            // clr CTR flag
+    b       .L_ep_callback
+.L_ep_errm:
+    movs    r1, #usbd_evt_error
+    movs    r4, #ISTRBIT(13)
+    b      .L_ep_clristr
+
+.L_ep_sofm:
+    movs    r1, #usbd_evt_sof
+    movs    r4, #ISTRBIT(9)
+    b       .L_ep_clristr
+
+.L_ep_esofm:
+    movs    r1, #usbd_evt_esof
+    movs    r4, #ISTRBIT(8)
+    b       .L_ep_clristr
+
+.L_ep_wkupm:
+    ldrh    r1, [r3, #0]            //R1 USB->CNTR
+    movs    r5, #0x08
+    bics    r1, r5                  //clr FSUSP
+    strh    r1, [r3, #0]            //USB->CNTR R2
+    movs    r1, #usbd_evt_wkup
+    movs    r4, #ISTRBIT(12)
+    b       .L_ep_clristr
+
+.L_ep_suspm:
+    ldrh    r1, [r3, #USB_CNTR]     //R1 USB->CNTR
+    movs    r5, #0x08
+    orrs    r1, r5                  //set FSUSP
+    strh    r1, [r3, #USB_CNTR]     //USB->CNTR R2
+    movs    r1, #usbd_evt_susp
+    movs    r4, #ISTRBIT(11)
+    b       .L_ep_clristr
+
+/* do reset routine */
+.L_ep_resetm:
+    movs    r1, #7
+    ldr     r2, =#USB_EPBASE
+    ldr     r0, =#USB_PMABASE
+    ldr     r5, =#EP_NOTOG
+.L_ep_reset_loop:
+    ldrh    r4, [r2]
+    bics    r4, r5
+    strh    r4, [r2]
+    movs    r4, #0
+    strh    r4, [r0, #TXADDR]
+    strh    r4, [r0, #TXCOUNT]
+    strh    r4, [r0, #RXADDR]
+    strh    r4, [r0, #RXCOUNT]
+    adds    r2, #4
+    adds    r0, #8
+    subs    r1, #1
+    bpl     .L_ep_reset_loop
+    movs    r2, #0x00
+    strh    r2, [r3, #USB_BTABLE]     // 0 -> USB->BTABLE
+    movs    r1, #usbd_evt_reset
+    movs    r4, #ISTRBIT(10)
+.L_ep_clristr:
+    lsls    r4, #ISTRSHIFT
+    ldrh    r0, [r3, #4]
+    bics    r0, r4
+    strh    r0, [r3, #4]
+.L_ep_callback:
+    pop     {r0, r3, r4, r5 }
+    bx      r3
+
+    .size   _evt_poll, . - _evt_poll
+
+
+
+
+    .pool
+
+   .end
+
+#endif

+ 456 - 456
src/usb_32v1.c

@@ -1,475 +1,475 @@
-#include <stdint.h>
-#include <stdbool.h>
-#include "stm32.h"
-#include "../usb.h"
-
-#if defined(USE_STMV1_DRIVER)
-
-#ifndef USB_PMASIZE
-    #warning PMA memory size is not defined. Use 512 bytes by default
-    #define USB_PMASIZE 0x200
-#endif
-
-#define USB_EP_SWBUF_TX     USB_EP_DTOG_RX
-#define USB_EP_SWBUF_RX     USB_EP_DTOG_TX
-
-
-#define EP_TOGGLE_SET(epr, bits, mask) *(epr) = (*(epr) ^ (bits)) & (USB_EPREG_MASK | (mask))
-
-#define EP_TX_STALL(epr)    EP_TOGGLE_SET((epr), USB_EP_TX_STALL,                   USB_EPTX_STAT)
-#define EP_RX_STALL(epr)    EP_TOGGLE_SET((epr), USB_EP_RX_STALL,                   USB_EPRX_STAT)
-#define EP_TX_UNSTALL(epr)  EP_TOGGLE_SET((epr), USB_EP_TX_NAK,                     USB_EPTX_STAT | USB_EP_DTOG_TX)
-#define EP_RX_UNSTALL(epr)  EP_TOGGLE_SET((epr), USB_EP_RX_VALID,                   USB_EPRX_STAT | USB_EP_DTOG_RX)
-#define EP_DTX_UNSTALL(epr) EP_TOGGLE_SET((epr), USB_EP_TX_VALID,                   USB_EPTX_STAT | USB_EP_DTOG_TX | USB_EP_SWBUF_TX)
-#define EP_DRX_UNSTALL(epr) EP_TOGGLE_SET((epr), USB_EP_RX_VALID | USB_EP_SWBUF_RX, USB_EPRX_STAT | USB_EP_DTOG_RX | USB_EP_SWBUF_RX)
-#define EP_TX_VALID(epr)    EP_TOGGLE_SET((epr), USB_EP_TX_VALID,                   USB_EPTX_STAT)
-#define EP_RX_VALID(epr)    EP_TOGGLE_SET((epr), USB_EP_RX_VALID,                   USB_EPRX_STAT)
-
-
-
-typedef union pma_table {
-    struct {
+#include <stdint.h>
+#include <stdbool.h>
+#include "stm32.h"
+#include "../usb.h"
+
+#if defined(USE_STMV1_DRIVER)
+
+#ifndef USB_PMASIZE
+    #warning PMA memory size is not defined. Use 512 bytes by default
+    #define USB_PMASIZE 0x200
+#endif
+
+#define USB_EP_SWBUF_TX     USB_EP_DTOG_RX
+#define USB_EP_SWBUF_RX     USB_EP_DTOG_TX
+
+
+#define EP_TOGGLE_SET(epr, bits, mask) *(epr) = (*(epr) ^ (bits)) & (USB_EPREG_MASK | (mask))
+
+#define EP_TX_STALL(epr)    EP_TOGGLE_SET((epr), USB_EP_TX_STALL,                   USB_EPTX_STAT)
+#define EP_RX_STALL(epr)    EP_TOGGLE_SET((epr), USB_EP_RX_STALL,                   USB_EPRX_STAT)
+#define EP_TX_UNSTALL(epr)  EP_TOGGLE_SET((epr), USB_EP_TX_NAK,                     USB_EPTX_STAT | USB_EP_DTOG_TX)
+#define EP_RX_UNSTALL(epr)  EP_TOGGLE_SET((epr), USB_EP_RX_VALID,                   USB_EPRX_STAT | USB_EP_DTOG_RX)
+#define EP_DTX_UNSTALL(epr) EP_TOGGLE_SET((epr), USB_EP_TX_VALID,                   USB_EPTX_STAT | USB_EP_DTOG_TX | USB_EP_SWBUF_TX)
+#define EP_DRX_UNSTALL(epr) EP_TOGGLE_SET((epr), USB_EP_RX_VALID | USB_EP_SWBUF_RX, USB_EPRX_STAT | USB_EP_DTOG_RX | USB_EP_SWBUF_RX)
+#define EP_TX_VALID(epr)    EP_TOGGLE_SET((epr), USB_EP_TX_VALID,                   USB_EPTX_STAT)
+#define EP_RX_VALID(epr)    EP_TOGGLE_SET((epr), USB_EP_RX_VALID,                   USB_EPRX_STAT)
+
+
+
+typedef union pma_table {
+    struct {
     uint16_t    txadr;
-    uint16_t    :16;
+    uint16_t    :16;
     uint16_t    txcnt;
-    uint16_t    :16;
+    uint16_t    :16;
     uint16_t    rxadr;
-    uint16_t    :16;
+    uint16_t    :16;
     uint16_t    rxcnt;
-    uint16_t    :16;
-    };
-    struct {
+    uint16_t    :16;
+    };
+    struct {
     uint16_t    txadr0;
-    uint16_t    :16;
+    uint16_t    :16;
     uint16_t    txcnt0;
-    uint16_t    :16;
+    uint16_t    :16;
     uint16_t    txadr1;
-    uint16_t    :16;
+    uint16_t    :16;
     uint16_t    txcnt1;
-    uint16_t    :16;
-    };
-    struct {
-    uint16_t    rxadr0;
     uint16_t    :16;
-    uint16_t    rxcnt0;
+    };
+    struct {
+    uint16_t    rxadr0;
+    uint16_t    :16;
+    uint16_t    rxcnt0;
     uint16_t    :16;
-    uint16_t    rxadr1;
+    uint16_t    rxadr1;
     uint16_t    :16;
     uint16_t    rxcnt1;
-    uint16_t    :16;
-    };
-} pma_table;
-
-
-/** \brief Helper function. Returns pointer to the buffer descriptor table.
- */
-inline static pma_table *EPT(uint8_t ep) {
-    return (pma_table*)((ep & 0x07) * 16 + USB_PMAADDR);
-
-}
-
-/** \brief Helper function. Returns pointer to the endpoint control register.
- */
-inline static volatile uint16_t *EPR(uint8_t ep) {
-    return (uint16_t*)((ep & 0x07) * 4 + USB_BASE);
-}
-
-
-/** \brief Helper function. Returns next available PMA buffer.
- *
- * \param sz uint16_t Requested buffer size.
- * \return uint16_t Buffer address for PMA table.
- * \note PMA buffers grown from top to bottom like stack.
- */
-static uint16_t get_next_pma(uint16_t sz) {
-    unsigned _result = USB_PMASIZE;
-    for (int i = 0; i < 8; i++) {
-        pma_table *tbl = EPT(i);
-        if ((tbl->rxadr) && (tbl->rxadr < _result)) _result = tbl->rxadr;
-        if ((tbl->txadr) && (tbl->txadr < _result)) _result = tbl->txadr;
-    }
-    if ( _result < (4 * sizeof(pma_table) + sz)) {
-        return 0;
-    } else {
-        return _result - sz;
-    }
-}
-
-void ep_setstall(uint8_t ep, bool stall) {
-    volatile uint16_t *reg = EPR(ep);
-    /* ISOCHRONOUS endpoint can't be stalled or unstalled */
-    if (USB_EP_ISOCHRONOUS == (*reg & USB_EP_T_FIELD)) return;
-    /* If it's an IN endpoint */
-    if (ep & 0x80) {
-        /* DISABLED endpoint can't be stalled or unstalled */
-        if (USB_EP_TX_DIS == (*reg & USB_EPTX_STAT)) return;
-        if (stall) {
-            EP_TX_STALL(reg);
-        } else {
-            /* if it's a doublebuffered endpoint */
-            if ((USB_EP_KIND | USB_EP_BULK) == (*reg & (USB_EP_T_FIELD | USB_EP_KIND))) {
-                /* set endpoint to VALID and clear DTOG_TX & SWBUF_TX */
-                EP_DTX_UNSTALL(reg);
-            } else {
-                /* set endpoint to NAKED and clear DTOG_TX */
-                EP_TX_UNSTALL(reg);
-            }
-        }
-    } else {
-        if (USB_EP_RX_DIS == (*reg & USB_EPRX_STAT)) return;
-        if (stall) {
-            EP_RX_STALL(reg);
-        } else {
-            /* if it's a doublebuffered endpoint */
-            if ((USB_EP_KIND | USB_EP_BULK) == (*reg & (USB_EP_T_FIELD | USB_EP_KIND))) {
-                /* set endpoint to VALID, clear DTOG_RX, set SWBUF_RX */
-                EP_DRX_UNSTALL(reg);
-            } else {
-                /* set endpoint to VALID and clear DTOG_RX */
-                EP_RX_UNSTALL(reg);
-            }
-        }
-    }
-}
-
-bool ep_isstalled(uint8_t ep) {
-    if (ep & 0x80) {
-        return (USB_EP_TX_STALL == (USB_EPTX_STAT & *EPR(ep)));
-    } else {
-        return (USB_EP_RX_STALL == (USB_EPRX_STAT & *EPR(ep)));
-    }
-}
-
-void enable(bool enable) {
-    if (enable) {
+    uint16_t    :16;
+    };
+} pma_table;
+
+
+/** \brief Helper function. Returns pointer to the buffer descriptor table.
+ */
+inline static pma_table *EPT(uint8_t ep) {
+    return (pma_table*)((ep & 0x07) * 16 + USB_PMAADDR);
+
+}
+
+/** \brief Helper function. Returns pointer to the endpoint control register.
+ */
+inline static volatile uint16_t *EPR(uint8_t ep) {
+    return (uint16_t*)((ep & 0x07) * 4 + USB_BASE);
+}
+
+
+/** \brief Helper function. Returns next available PMA buffer.
+ *
+ * \param sz uint16_t Requested buffer size.
+ * \return uint16_t Buffer address for PMA table.
+ * \note PMA buffers grown from top to bottom like stack.
+ */
+static uint16_t get_next_pma(uint16_t sz) {
+    unsigned _result = USB_PMASIZE;
+    for (int i = 0; i < 8; i++) {
+        pma_table *tbl = EPT(i);
+        if ((tbl->rxadr) && (tbl->rxadr < _result)) _result = tbl->rxadr;
+        if ((tbl->txadr) && (tbl->txadr < _result)) _result = tbl->txadr;
+    }
+    if ( _result < (4 * sizeof(pma_table) + sz)) {
+        return 0;
+    } else {
+        return _result - sz;
+    }
+}
+
+void ep_setstall(uint8_t ep, bool stall) {
+    volatile uint16_t *reg = EPR(ep);
+    /* ISOCHRONOUS endpoint can't be stalled or unstalled */
+    if (USB_EP_ISOCHRONOUS == (*reg & USB_EP_T_FIELD)) return;
+    /* If it's an IN endpoint */
+    if (ep & 0x80) {
+        /* DISABLED endpoint can't be stalled or unstalled */
+        if (USB_EP_TX_DIS == (*reg & USB_EPTX_STAT)) return;
+        if (stall) {
+            EP_TX_STALL(reg);
+        } else {
+            /* if it's a doublebuffered endpoint */
+            if ((USB_EP_KIND | USB_EP_BULK) == (*reg & (USB_EP_T_FIELD | USB_EP_KIND))) {
+                /* set endpoint to VALID and clear DTOG_TX & SWBUF_TX */
+                EP_DTX_UNSTALL(reg);
+            } else {
+                /* set endpoint to NAKED and clear DTOG_TX */
+                EP_TX_UNSTALL(reg);
+            }
+        }
+    } else {
+        if (USB_EP_RX_DIS == (*reg & USB_EPRX_STAT)) return;
+        if (stall) {
+            EP_RX_STALL(reg);
+        } else {
+            /* if it's a doublebuffered endpoint */
+            if ((USB_EP_KIND | USB_EP_BULK) == (*reg & (USB_EP_T_FIELD | USB_EP_KIND))) {
+                /* set endpoint to VALID, clear DTOG_RX, set SWBUF_RX */
+                EP_DRX_UNSTALL(reg);
+            } else {
+                /* set endpoint to VALID and clear DTOG_RX */
+                EP_RX_UNSTALL(reg);
+            }
+        }
+    }
+}
+
+bool ep_isstalled(uint8_t ep) {
+    if (ep & 0x80) {
+        return (USB_EP_TX_STALL == (USB_EPTX_STAT & *EPR(ep)));
+    } else {
+        return (USB_EP_RX_STALL == (USB_EPRX_STAT & *EPR(ep)));
+    }
+}
+
+void enable(bool enable) {
+    if (enable) {
         RCC->APB1ENR  |= RCC_APB1ENR_USBEN;
-        RCC->APB2ENR  |= RCC_APB2ENR_SYSCFGEN;
-        RCC->APB1RSTR |= RCC_APB1RSTR_USBRST;
-        RCC->APB1RSTR &= ~RCC_APB1RSTR_USBRST;
-        USB->CNTR = USB_CNTR_CTRM | USB_CNTR_RESETM | USB_CNTR_SOFM | USB_CNTR_ESOFM | USB_CNTR_ERRM | USB_CNTR_SUSPM | USB_CNTR_WKUPM ;
-    } else if (RCC->APB1ENR & RCC_APB1ENR_USBEN) {
-        SYSCFG->PMC &= ~SYSCFG_PMC_USB_PU;
-        RCC->APB1RSTR |= RCC_APB1RSTR_USBRST;
-        RCC->APB1ENR &= ~RCC_APB1ENR_USBEN;
-    }
-}
-
-void reset (void) {
-    USB->CNTR |= USB_CNTR_FRES;
-    USB->CNTR &= ~USB_CNTR_FRES;
-}
-
-void connect(bool connect) {
+        RCC->APB2ENR  |= RCC_APB2ENR_SYSCFGEN;
+        RCC->APB1RSTR |= RCC_APB1RSTR_USBRST;
+        RCC->APB1RSTR &= ~RCC_APB1RSTR_USBRST;
+        USB->CNTR = USB_CNTR_CTRM | USB_CNTR_RESETM | USB_CNTR_SOFM | USB_CNTR_ESOFM | USB_CNTR_ERRM | USB_CNTR_SUSPM | USB_CNTR_WKUPM ;
+    } else if (RCC->APB1ENR & RCC_APB1ENR_USBEN) {
+        SYSCFG->PMC &= ~SYSCFG_PMC_USB_PU;
+        RCC->APB1RSTR |= RCC_APB1RSTR_USBRST;
+        RCC->APB1ENR &= ~RCC_APB1ENR_USBEN;
+    }
+}
+
+void reset (void) {
+    USB->CNTR |= USB_CNTR_FRES;
+    USB->CNTR &= ~USB_CNTR_FRES;
+}
+
+void connect(bool connect) {
     if (connect) {
         SYSCFG->PMC |= SYSCFG_PMC_USB_PU;
     } else {
         SYSCFG->PMC &= ~SYSCFG_PMC_USB_PU;
     }
-}
-
-void setaddr (uint8_t addr) {
-    USB->DADDR = USB_DADDR_EF | addr;
-}
-
-
-bool ep_config(uint8_t ep, uint8_t eptype, uint16_t epsize) {
-    volatile uint16_t *reg = EPR(ep);
-    pma_table *tbl = EPT(ep);
-    /* epsize should be 16-bit aligned */
-    if (epsize & 0x01) epsize++;
-
-    switch (eptype) {
-    case USB_EPTYPE_CONTROL:
-        *reg = USB_EP_CONTROL | (ep & 0x07);
-        break;
-    case USB_EPTYPE_ISOCHRONUS:
-        *reg = USB_EP_ISOCHRONOUS | (ep & 0x07);
-        break;
-    case USB_EPTYPE_BULK:
-        *reg = USB_EP_BULK | (ep & 0x07);
-        break;
-    case USB_EPTYPE_BULK | USB_EPTYPE_DBLBUF:
-        *reg = USB_EP_BULK | USB_EP_KIND | (ep & 0x07);
-        break;
-    default:
-        *reg = USB_EP_INTERRUPT | (ep & 0x07);
-        break;
-    }
-    /* if it TX or CONTROL endpoint */
-    if ((ep & 0x80) || (eptype == USB_EPTYPE_CONTROL)) {
-        uint16_t _pma;
-        _pma = get_next_pma(epsize);
-        if (_pma == 0) return false;
-        if ((eptype == USB_EPTYPE_ISOCHRONUS) ||
-            (eptype == (USB_EPTYPE_BULK | USB_EPTYPE_DBLBUF))) {
-            tbl->txadr0 = _pma;
-            _pma = get_next_pma(epsize);
-            if (_pma == 0) return false;
-            tbl->txadr1 = _pma;
-            tbl->txcnt0 = 0;
-            tbl->txcnt1 = 0;
-            EP_DTX_UNSTALL(reg);
-        } else {
-            tbl->txadr = _pma;
-            tbl->txcnt = 0;
-            EP_TX_UNSTALL(reg);
-        }
-    }
-    if (!(ep & 0x80)) {
-        uint16_t _rxcnt;
-        uint16_t _pma;
-        if (epsize > 62) {
-            if (epsize & 0x1F) {
-                epsize &= 0x1F;
-            } else {
-                epsize -= 0x20;
-            }
-            _rxcnt = 0x8000 | (epsize << 5);
-            epsize += 0x20;
-        } else {
-            _rxcnt = epsize << 9;
-        }
-        _pma = get_next_pma(epsize);
-        if (_pma == 0) return false;
-        if ((eptype == USB_EPTYPE_ISOCHRONUS) ||
-            (eptype == (USB_EPTYPE_BULK | USB_EPTYPE_DBLBUF))) {
-            tbl->rxadr0 = _pma;
-            _pma = get_next_pma(epsize);
-            if (_pma == 0) return false;
-            tbl->rxadr1 = _pma;
-            tbl->rxcnt0 = _rxcnt;
-            tbl->rxcnt1 = _rxcnt;
-            EP_DRX_UNSTALL(reg);
-        } else {
-            tbl->rxadr = _pma;
-            tbl->rxcnt = _rxcnt;
-            EP_RX_UNSTALL(reg);
-        }
-    }
-    return true;
-}
-
-static void ep_deconfig(uint8_t ep) {
-    pma_table *ept = EPT(ep);
-    *EPR(ep) &= ~USB_EPREG_MASK;
-    ept->rxadr = 0;
-    ept->rxcnt = 0;
-    ept->txadr = 0;
-    ept->txcnt = 0;
-}
-
-
-
-static void pma_write(const uint16_t txadr, const uint8_t *buf, uint16_t blen) {
-    uint16_t *pma = (void*)(USB_PMAADDR + 2 * txadr);
-    while (blen > 1) {
+}
+
+void setaddr (uint8_t addr) {
+    USB->DADDR = USB_DADDR_EF | addr;
+}
+
+
+bool ep_config(uint8_t ep, uint8_t eptype, uint16_t epsize) {
+    volatile uint16_t *reg = EPR(ep);
+    pma_table *tbl = EPT(ep);
+    /* epsize should be 16-bit aligned */
+    if (epsize & 0x01) epsize++;
+
+    switch (eptype) {
+    case USB_EPTYPE_CONTROL:
+        *reg = USB_EP_CONTROL | (ep & 0x07);
+        break;
+    case USB_EPTYPE_ISOCHRONUS:
+        *reg = USB_EP_ISOCHRONOUS | (ep & 0x07);
+        break;
+    case USB_EPTYPE_BULK:
+        *reg = USB_EP_BULK | (ep & 0x07);
+        break;
+    case USB_EPTYPE_BULK | USB_EPTYPE_DBLBUF:
+        *reg = USB_EP_BULK | USB_EP_KIND | (ep & 0x07);
+        break;
+    default:
+        *reg = USB_EP_INTERRUPT | (ep & 0x07);
+        break;
+    }
+    /* if it TX or CONTROL endpoint */
+    if ((ep & 0x80) || (eptype == USB_EPTYPE_CONTROL)) {
+        uint16_t _pma;
+        _pma = get_next_pma(epsize);
+        if (_pma == 0) return false;
+        if ((eptype == USB_EPTYPE_ISOCHRONUS) ||
+            (eptype == (USB_EPTYPE_BULK | USB_EPTYPE_DBLBUF))) {
+            tbl->txadr0 = _pma;
+            _pma = get_next_pma(epsize);
+            if (_pma == 0) return false;
+            tbl->txadr1 = _pma;
+            tbl->txcnt0 = 0;
+            tbl->txcnt1 = 0;
+            EP_DTX_UNSTALL(reg);
+        } else {
+            tbl->txadr = _pma;
+            tbl->txcnt = 0;
+            EP_TX_UNSTALL(reg);
+        }
+    }
+    if (!(ep & 0x80)) {
+        uint16_t _rxcnt;
+        uint16_t _pma;
+        if (epsize > 62) {
+            if (epsize & 0x1F) {
+                epsize &= 0x1F;
+            } else {
+                epsize -= 0x20;
+            }
+            _rxcnt = 0x8000 | (epsize << 5);
+            epsize += 0x20;
+        } else {
+            _rxcnt = epsize << 9;
+        }
+        _pma = get_next_pma(epsize);
+        if (_pma == 0) return false;
+        if ((eptype == USB_EPTYPE_ISOCHRONUS) ||
+            (eptype == (USB_EPTYPE_BULK | USB_EPTYPE_DBLBUF))) {
+            tbl->rxadr0 = _pma;
+            _pma = get_next_pma(epsize);
+            if (_pma == 0) return false;
+            tbl->rxadr1 = _pma;
+            tbl->rxcnt0 = _rxcnt;
+            tbl->rxcnt1 = _rxcnt;
+            EP_DRX_UNSTALL(reg);
+        } else {
+            tbl->rxadr = _pma;
+            tbl->rxcnt = _rxcnt;
+            EP_RX_UNSTALL(reg);
+        }
+    }
+    return true;
+}
+
+static void ep_deconfig(uint8_t ep) {
+    pma_table *ept = EPT(ep);
+    *EPR(ep) &= ~USB_EPREG_MASK;
+    ept->rxadr = 0;
+    ept->rxcnt = 0;
+    ept->txadr = 0;
+    ept->txcnt = 0;
+}
+
+
+
+static void pma_write(const uint16_t txadr, const uint8_t *buf, uint16_t blen) {
+    uint16_t *pma = (void*)(USB_PMAADDR + 2 * txadr);
+    while (blen > 1) {
         *pma = buf[1] << 8 | buf[0];
-        pma += 2;
-        buf += 2;
-        blen -= 2;
-    }
-    if (blen) *pma = *buf;
-}
-
-static void pma_read (const uint16_t rxadr, uint8_t *buf, uint16_t blen, uint16_t rxlen) {
-    uint16_t *pma = (void*)(USB_PMAADDR + 2 * rxadr);
-    if (blen > rxlen) blen = rxlen;
-    while (blen) {
-        uint16_t _t = *pma;
-        *buf++ = _t & 0xFF;
-        if (--blen) {
-            *buf++ = _t >> 8;
-            pma += 2;
-            blen--;
-        } else break;
-    }
-}
-
-uint16_t ep_read(uint8_t ep, void *buf, uint16_t blen) {
-    pma_table *tbl = EPT(ep);
-    volatile uint16_t *reg = EPR(ep);
-    uint16_t rxlen, rxbuf;
-
-    switch (*reg & (USB_EP_T_FIELD | USB_EP_KIND)) {
-    case (USB_EP_BULK | USB_EP_KIND):
-        if (*reg & USB_EP_SWBUF_RX) {
-            rxbuf = tbl->rxadr1;
-            rxlen = tbl->rxcnt1 & 0x03FF;
-        } else {
-            rxbuf = tbl->rxadr0;
-            rxlen = tbl->rxcnt0 & 0x03FF;
-        }
-        pma_read(rxbuf, buf, blen, rxlen);
-        break;
-    case USB_EP_ISOCHRONOUS:
-        if (*reg & USB_EP_DTOG_RX) {
-            rxbuf = tbl->rxadr0;
-            rxlen = tbl->rxcnt0 & 0x03FF;
-        } else {
-            rxbuf = tbl->rxadr1;
-            rxlen = tbl->rxcnt1 & 0x03FF;
-        }
-        pma_read(rxbuf, buf, blen, rxlen);
-        break;
-    default:
-        rxbuf = tbl->rxadr;
-        rxlen = tbl->rxcnt & 0x03FF;
-        pma_read(rxbuf, buf, blen, rxlen);
-        /* setting endpoint to VALID state */
-        EP_RX_VALID(reg);
-        break;
-    }
-    return rxlen;
-}
-
-
-
-uint16_t ep_write(uint8_t ep, void *buf, uint16_t blen) {
-    pma_table *tbl = EPT(ep);
-    volatile uint16_t *reg = EPR(ep);
-    uint16_t txbuf;
-    switch (*reg & (USB_EP_T_FIELD | USB_EP_KIND)) {
-    case (USB_EP_BULK | USB_EP_KIND):
-        if (*reg & USB_EP_SWBUF_TX) {
-            tbl->txcnt1 = blen;
-            txbuf = tbl->txadr1;
-        } else {
-            tbl->txcnt0 = blen;
-            txbuf = tbl->txadr0;
-        }
-        break;
-    case USB_EP_ISOCHRONOUS:
-        if (*reg & USB_EP_DTOG_TX) {
-            tbl->txcnt0 = blen;
-            txbuf = tbl->txadr0;
-        } else {
-            tbl->txcnt1 = blen;
-            txbuf = tbl->txadr1;
-        }
-        break;
-    default:
-        tbl->txcnt = blen;
-        txbuf = tbl->txadr;
-        break;
-    }
-    pma_write(txbuf, buf, blen);
-
-    switch (*reg & (USB_EP_T_FIELD | USB_EP_KIND)) {
-    case (USB_EP_BULK | USB_EP_KIND):
-        /* switching buffer if doublebuffered bulk endpoint */
-        *reg = (*reg & USB_EPREG_MASK) | USB_EP_SWBUF_TX;
-        break;
-    case USB_EP_ISOCHRONOUS:
-        break;
-    default:
-        /* set TX valid to start transfer */
-        EP_TX_VALID(reg);
-    }
-    return blen;
-
-}
-
-uint16_t get_frame (void) {
-    return USB->FNR & USB_FNR_FN;
-}
-
-
-
-void evt_poll(usbd_device *dev, usbd_evt_callback callback) {
-    uint8_t _ev, _ep;
-    uint16_t _istr = USB->ISTR;
-    _ep = _istr & USB_ISTR_EP_ID;
-
-    if (_istr & USB_ISTR_CTR) {
-        volatile uint16_t *reg = EPR(_ep);
-        if (*reg & USB_EP_CTR_TX) {
-            *reg &= (USB_EPREG_MASK ^ USB_EP_CTR_TX);
-            _ep |= 0x80;
-            _ev = usbd_evt_eptx;
-        } else {
-            /* clearing CTR */
-            if ((*reg & (USB_EP_T_FIELD | USB_EP_KIND)) == (USB_EP_BULK | USB_EP_KIND)) {
-                /* switching RX buffer and if doublebuffered bulk endpoint */
-                *reg = (*reg & (USB_EPREG_MASK ^ USB_EP_CTR_RX)) | USB_EP_SWBUF_RX;
-            } else {
-                *reg &= (USB_EPREG_MASK ^ USB_EP_CTR_RX);
-            }
-            _ev = (*reg & USB_EP_SETUP) ? usbd_evt_epsetup : usbd_evt_eprx;
-        }
-    } else if (_istr & USB_ISTR_RESET) {
-        USB->ISTR &= ~USB_ISTR_RESET;
-        USB->BTABLE = 0;
-        for (int i = 0; i < 8; i++) {
-            ep_deconfig(i);
-        }
-        _ev = usbd_evt_reset;
-    } else if (_istr & USB_ISTR_SOF) {
-        _ev = usbd_evt_sof;
-        USB->ISTR &= ~USB_ISTR_SOF;
-    } else if (_istr & USB_ISTR_WKUP) {
-        _ev = usbd_evt_wkup;
-        USB->CNTR &= ~USB_CNTR_FSUSP;
-        USB->ISTR &= ~USB_ISTR_WKUP;
-    } else if (_istr & USB_ISTR_SUSP) {
-        _ev = usbd_evt_susp;
-        USB->CNTR |= USB_CNTR_FSUSP;
-        USB->ISTR &= ~USB_ISTR_SUSP;
-    } else if (_istr & USB_ISTR_ESOF) {
-        USB->ISTR &= ~USB_ISTR_ESOF;
-        _ev = usbd_evt_esof;
-    } else if (_istr & USB_ISTR_ERR) {
-        USB->ISTR &= ~USB_ISTR_ERR;
-        _ev = usbd_evt_error;
-    } else {
-        return;
-    }
-    callback(dev, _ev, _ep);
-}
-
-static uint32_t fnv1a32_turn (uint32_t fnv, uint32_t data ) {
-    for (int i = 0; i < 4 ; i++) {
-        fnv ^= (data & 0xFF);
-        fnv *= 16777619;
-        data >>= 8;
-    }
-    return fnv;
-}
-
-static uint16_t get_serialno_desc(void *buffer) {
-    struct  usb_string_descriptor *dsc = buffer;
-    uint16_t *str = dsc->wString;
-    uint32_t fnv = 2166136261;
-    fnv = fnv1a32_turn(fnv, *(uint32_t*)(UID_BASE + 0x00));
-    fnv = fnv1a32_turn(fnv, *(uint32_t*)(UID_BASE + 0x04));
-    fnv = fnv1a32_turn(fnv, *(uint32_t*)(UID_BASE + 0x14));
-    for (int i = 28; i >= 0; i -= 4 ) {
-        uint16_t c = (fnv >> i) & 0x0F;
-        c += (c < 10) ? '0' : ('A' - 10);
-        *str++ = c;
-    }
-    dsc->bDescriptorType = USB_DTYPE_STRING;
-    dsc->bLength = 18;
-    return 18;
-}
-
-
-
-
-
-const struct usbd_driver usb_stmv1 = {
-    enable,
-    reset,
-    connect,
-    setaddr,
-    ep_config,
-    ep_deconfig,
-    ep_read,
-    ep_write,
-    ep_setstall,
-    ep_isstalled,
-    evt_poll,
-    get_frame,
-    get_serialno_desc,
-};
-
-#endif //USE_STM32V1_DRIVER
+        pma += 2;
+        buf += 2;
+        blen -= 2;
+    }
+    if (blen) *pma = *buf;
+}
+
+static void pma_read (const uint16_t rxadr, uint8_t *buf, uint16_t blen, uint16_t rxlen) {
+    uint16_t *pma = (void*)(USB_PMAADDR + 2 * rxadr);
+    if (blen > rxlen) blen = rxlen;
+    while (blen) {
+        uint16_t _t = *pma;
+        *buf++ = _t & 0xFF;
+        if (--blen) {
+            *buf++ = _t >> 8;
+            pma += 2;
+            blen--;
+        } else break;
+    }
+}
+
+uint16_t ep_read(uint8_t ep, void *buf, uint16_t blen) {
+    pma_table *tbl = EPT(ep);
+    volatile uint16_t *reg = EPR(ep);
+    uint16_t rxlen, rxbuf;
+
+    switch (*reg & (USB_EP_T_FIELD | USB_EP_KIND)) {
+    case (USB_EP_BULK | USB_EP_KIND):
+        if (*reg & USB_EP_SWBUF_RX) {
+            rxbuf = tbl->rxadr1;
+            rxlen = tbl->rxcnt1 & 0x03FF;
+        } else {
+            rxbuf = tbl->rxadr0;
+            rxlen = tbl->rxcnt0 & 0x03FF;
+        }
+        pma_read(rxbuf, buf, blen, rxlen);
+        break;
+    case USB_EP_ISOCHRONOUS:
+        if (*reg & USB_EP_DTOG_RX) {
+            rxbuf = tbl->rxadr0;
+            rxlen = tbl->rxcnt0 & 0x03FF;
+        } else {
+            rxbuf = tbl->rxadr1;
+            rxlen = tbl->rxcnt1 & 0x03FF;
+        }
+        pma_read(rxbuf, buf, blen, rxlen);
+        break;
+    default:
+        rxbuf = tbl->rxadr;
+        rxlen = tbl->rxcnt & 0x03FF;
+        pma_read(rxbuf, buf, blen, rxlen);
+        /* setting endpoint to VALID state */
+        EP_RX_VALID(reg);
+        break;
+    }
+    return rxlen;
+}
+
+
+
+uint16_t ep_write(uint8_t ep, void *buf, uint16_t blen) {
+    pma_table *tbl = EPT(ep);
+    volatile uint16_t *reg = EPR(ep);
+    uint16_t txbuf;
+    switch (*reg & (USB_EP_T_FIELD | USB_EP_KIND)) {
+    case (USB_EP_BULK | USB_EP_KIND):
+        if (*reg & USB_EP_SWBUF_TX) {
+            tbl->txcnt1 = blen;
+            txbuf = tbl->txadr1;
+        } else {
+            tbl->txcnt0 = blen;
+            txbuf = tbl->txadr0;
+        }
+        break;
+    case USB_EP_ISOCHRONOUS:
+        if (*reg & USB_EP_DTOG_TX) {
+            tbl->txcnt0 = blen;
+            txbuf = tbl->txadr0;
+        } else {
+            tbl->txcnt1 = blen;
+            txbuf = tbl->txadr1;
+        }
+        break;
+    default:
+        tbl->txcnt = blen;
+        txbuf = tbl->txadr;
+        break;
+    }
+    pma_write(txbuf, buf, blen);
+
+    switch (*reg & (USB_EP_T_FIELD | USB_EP_KIND)) {
+    case (USB_EP_BULK | USB_EP_KIND):
+        /* switching buffer if doublebuffered bulk endpoint */
+        *reg = (*reg & USB_EPREG_MASK) | USB_EP_SWBUF_TX;
+        break;
+    case USB_EP_ISOCHRONOUS:
+        break;
+    default:
+        /* set TX valid to start transfer */
+        EP_TX_VALID(reg);
+    }
+    return blen;
+
+}
+
+uint16_t get_frame (void) {
+    return USB->FNR & USB_FNR_FN;
+}
+
+
+
+void evt_poll(usbd_device *dev, usbd_evt_callback callback) {
+    uint8_t _ev, _ep;
+    uint16_t _istr = USB->ISTR;
+    _ep = _istr & USB_ISTR_EP_ID;
+
+    if (_istr & USB_ISTR_CTR) {
+        volatile uint16_t *reg = EPR(_ep);
+        if (*reg & USB_EP_CTR_TX) {
+            *reg &= (USB_EPREG_MASK ^ USB_EP_CTR_TX);
+            _ep |= 0x80;
+            _ev = usbd_evt_eptx;
+        } else {
+            /* clearing CTR */
+            if ((*reg & (USB_EP_T_FIELD | USB_EP_KIND)) == (USB_EP_BULK | USB_EP_KIND)) {
+                /* switching RX buffer and if doublebuffered bulk endpoint */
+                *reg = (*reg & (USB_EPREG_MASK ^ USB_EP_CTR_RX)) | USB_EP_SWBUF_RX;
+            } else {
+                *reg &= (USB_EPREG_MASK ^ USB_EP_CTR_RX);
+            }
+            _ev = (*reg & USB_EP_SETUP) ? usbd_evt_epsetup : usbd_evt_eprx;
+        }
+    } else if (_istr & USB_ISTR_RESET) {
+        USB->ISTR &= ~USB_ISTR_RESET;
+        USB->BTABLE = 0;
+        for (int i = 0; i < 8; i++) {
+            ep_deconfig(i);
+        }
+        _ev = usbd_evt_reset;
+    } else if (_istr & USB_ISTR_SOF) {
+        _ev = usbd_evt_sof;
+        USB->ISTR &= ~USB_ISTR_SOF;
+    } else if (_istr & USB_ISTR_WKUP) {
+        _ev = usbd_evt_wkup;
+        USB->CNTR &= ~USB_CNTR_FSUSP;
+        USB->ISTR &= ~USB_ISTR_WKUP;
+    } else if (_istr & USB_ISTR_SUSP) {
+        _ev = usbd_evt_susp;
+        USB->CNTR |= USB_CNTR_FSUSP;
+        USB->ISTR &= ~USB_ISTR_SUSP;
+    } else if (_istr & USB_ISTR_ESOF) {
+        USB->ISTR &= ~USB_ISTR_ESOF;
+        _ev = usbd_evt_esof;
+    } else if (_istr & USB_ISTR_ERR) {
+        USB->ISTR &= ~USB_ISTR_ERR;
+        _ev = usbd_evt_error;
+    } else {
+        return;
+    }
+    callback(dev, _ev, _ep);
+}
+
+static uint32_t fnv1a32_turn (uint32_t fnv, uint32_t data ) {
+    for (int i = 0; i < 4 ; i++) {
+        fnv ^= (data & 0xFF);
+        fnv *= 16777619;
+        data >>= 8;
+    }
+    return fnv;
+}
+
+static uint16_t get_serialno_desc(void *buffer) {
+    struct  usb_string_descriptor *dsc = buffer;
+    uint16_t *str = dsc->wString;
+    uint32_t fnv = 2166136261;
+    fnv = fnv1a32_turn(fnv, *(uint32_t*)(UID_BASE + 0x00));
+    fnv = fnv1a32_turn(fnv, *(uint32_t*)(UID_BASE + 0x04));
+    fnv = fnv1a32_turn(fnv, *(uint32_t*)(UID_BASE + 0x14));
+    for (int i = 28; i >= 0; i -= 4 ) {
+        uint16_t c = (fnv >> i) & 0x0F;
+        c += (c < 10) ? '0' : ('A' - 10);
+        *str++ = c;
+    }
+    dsc->bDescriptorType = USB_DTYPE_STRING;
+    dsc->bLength = 18;
+    return 18;
+}
+
+
+
+
+
+const struct usbd_driver usb_stmv1 = {
+    enable,
+    reset,
+    connect,
+    setaddr,
+    ep_config,
+    ep_deconfig,
+    ep_read,
+    ep_write,
+    ep_setstall,
+    ep_isstalled,
+    evt_poll,
+    get_frame,
+    get_serialno_desc,
+};
+
+#endif //USE_STM32V1_DRIVER

+ 825 - 825
src/usb_32v1A.S

@@ -1,825 +1,825 @@
-/* This file is the part of the LUS32 project
- *
- * Copyright ©2016 Dmitry Filimonchuk <dmitrystu[at]gmail[dot]com>
- *
- * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
- * 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.
- */
-
-#if !defined (__ASSEMBLER__)
-    #define __ASSEMBLER__
-#endif
-
-#include "../usb.h"
-#include "memmap.inc"
-#if defined(USE_STMV1A_DRIVER)
-
-
-#define EP_SETUP    0x0800
-#define EP_TYPE     0x0600
-#define EP_KIND     0x0100
-#define EP_ADDR     0x000F
-
-#define EP_RX_CTR   0x8000
-#define EP_RX_DTOG  0x4000
-#define EP_RX_STAT  0x3000
-#define EP_RX_SWBUF 0x0040
-
-#define EP_RX_DIS   0x0000
-#define EP_RX_STAL  0x1000
-#define EP_RX_NAK   0x2000
-#define EP_RX_VAL   0x3000
-
-#define EP_TX_CTR   0x0080
-#define EP_TX_DTOG  0x0040
-#define EP_TX_STAT  0x0030
-#define EP_TX_SWBUF 0x4000
-
-#define EP_TX_DIS   0x0000
-#define EP_TX_STAL  0x0010
-#define EP_TX_NAK   0x0020
-#define EP_TX_VAL   0x0030
-
-#define RXADDR0     0x00
-#define RXCOUNT0    0x04
-#define RXADDR1     0x08
-#define RXCOUNT1    0x0C
-
-#define TXADDR0     0x00
-#define TXCOUNT0    0x04
-#define TXADDR1     0x08
-#define TXCOUNT1    0x0C
-
-#define TXADDR      0x00
-#define TXCOUNT     0x04
-#define RXADDR      0x08
-#define RXCOUNT     0x0C
-
-
-
-#define EP_NOTOG    (EP_RX_CTR | EP_TX_CTR | EP_SETUP | EP_TYPE | EP_KIND | EP_ADDR)
-
-#define TGL_SET(mask, bits)  ((EP_NOTOG | (mask))<<16 | (bits))
-
-#define TX_STALL    TGL_SET(EP_TX_STAT,                            EP_TX_STAL)
-#define RX_STALL    TGL_SET(EP_RX_STAT,                            EP_RX_STAL)
-#define TX_USTALL   TGL_SET(EP_TX_STAT | EP_TX_DTOG,               EP_TX_NAK)
-#define RX_USTALL   TGL_SET(EP_RX_STAT | EP_RX_DTOG,               EP_RX_VAL)
-#define DTX_USTALL  TGL_SET(EP_TX_STAT | EP_TX_DTOG | EP_TX_SWBUF, EP_TX_VAL)
-#define DRX_USTALL  TGL_SET(EP_RX_STAT | EP_RX_DTOG | EP_RX_SWBUF, EP_RX_VAL | EP_RX_SWBUF)
-
-
-    .syntax unified
-    .cpu cortex-m3
-    .text
-    .thumb
-
-
-    .globl  usb_stmv1a
-    .align  2
-usb_stmv1a:
-    .long   _enable
-    .long   _reset
-    .long   _connect
-    .long   _setaddr
-    .long   _ep_config
-    .long   _ep_deconfig
-    .long   _ep_read
-    .long   _ep_write
-    .long   _ep_setstall
-    .long   _ep_isstalled
-    .long   _evt_poll
-    .long   _get_frame
-    .long   _get_serial_desc
-    .size   usb_stmv1a, . - usb_stmv1a
-
-
-    .thumb_func
-    .type _get_serial_desc, %function
-
-/*  uint16_t get_serial_desc (void *buffer)
- *  R0 <- buffer for the string descriptor
- *  descrpitor size -> R0
- */
-_get_serial_desc:
-    push    {r4, r5, lr}
-    movs    r1, #18             //descriptor size 18 bytes
-    strb    r1, [r0]
-    movs    r1, #0x03           //DTYPE_STRING
-    strb    r1, [r0, #0x01]
-    ldr     r5, .L_uid_base     //UID3 this is the serial number
-    ldr     r4, .L_fnv1a_offset //FNV1A offset
-    ldr     r2, [r5, 0x00]      //UID0
-    bl      .L_fnv1a
-    ldr     r2, [r5, 0x04]      //UID1
-    bl      .L_fnv1a
-    ldr     r2, [r5, 0x14]      //UID2
-    bl      .L_fnv1a
-    movs    r3, #28
-.L_gsn_loop:
-    lsrs    r1, r4, r3
-    and     r1, #0x0F
-    cmp     r1, #0x09
-    ite     gt
-    addgt   r1, #55
-    addle   r1, #48
-.L_gsn_store:
-    adds    r0, #0x02
-    strb    r1, [r0]
-    lsrs    r1, #0x08
-    strb    r1, [r0, #0x01]
-    subs    r3, #0x04
-    bpl     .L_gsn_loop
-    movs    r0, #18
-    pop     {r4, r5, pc}
-
-.L_fnv1a:
-    movs    r3, #0x04
-.L_fnv1a_loop:
-    uxtb    r1, r2
-    eors    r4, r1
-    ldr     r1, .L_fnv1a_prime       //FNV1A prime
-    muls    r4, r1
-    lsrs    r2, #0x08
-    subs    r3, #0x01
-    bne     .L_fnv1a_loop
-    bx      lr
-
-    .align 2
-.L_uid_base:        .long   UID_BASE
-.L_fnv1a_offset:    .long   2166136261
-.L_fnv1a_prime:     .long   16777619
-
-    .size _get_serial_desc, . - _get_serial_desc
-
-    .thumb_func
-    .type   _connect, %function
-_connect:
-    ldr     r1, =#SYSCFG_BASE
-    movs    r3, #0x01
-    ldr     r2, [r1, #SYSCFG_PMC]
-    bics    r2, r3
-    cbz     r0, .L_conn_store
-    orrs    r2, r3
-.L_conn_store:
-    str     r2, [r1, #SYSCFG_PMC]
-    bx      lr
-    .size   _connect, . - _connect
-
-
-    .thumb_func
-    .type   _setaddr, %function
-_setaddr:
-    ldr     r1, =USB_REGBASE
-    adds    r0, #0x80
-    strh    r0, [r1, #USB_DADDR]     //USB->DADDR
-    bx      lr
-    .size   _setaddr, . - _setaddr
-
-    .thumb_func
-    .type   _reset, %function
-_reset:
-    ldr     r2, =#USB_REGBASE
-    movs    r0, #0x01           //FRES
-    ldrh    r1, [r2, #USB_CNTR]
-    orrs    r1, r0
-    strh    r1, [r2, #USB_CNTR]  // set FRES
-    bics    r1, r0
-    strh    r1, [r2, #USB_CNTR]  // clr FRES
-    bx      lr
-    .size   _reset, . - _reset
-
-    .thumb_func
-    .type   _get_frame, %function
-_get_frame:
-    ldr     r0, =#USB_REGBASE
-    ldrh    r0, [r0, #USB_FNR]     //FNR
-    lsls    r0, #21
-    lsrs    r0, #21
-    bx      lr
-    .size   _get_frame, . - _get_frame
-
-    .thumb_func
-    .type   _enable, %function
-_enable:
-
-    ldr     r2, =#RCC_BASE        //RCC
-    movs    r3, #0x01
-    lsls    r3, #23             //USBEN or USBRST
-    cbz     r0, .L_disable
-.L_enable:
-/* enabling and resetting USB peripheral */
-    ldr     r1, =#USB_REGBASE
-    ldr     r0, [r2, #RCC_APB1ENR]
-    orrs    r0, r3
-    str     r0, [r2, #RCC_APB1ENR]     //RCC->APB1ENR |= USBEN
-    ldr     r0, [r2, #RCC_APB1RSTR]
-    orrs    r0, r3
-    str     r0, [r2, #RCC_APB1RSTR]     //RCC->APB1RSTR |= USBRST
-    bics    r0, r3
-    str     r0, [r2, #RCC_APB1RSTR]     //RCC->APB1RSTR &= ~USBRST
-/* enabling SYSCFG peripheral */
-    movs    r3, #0x01                   //SYSCFGEN
-    ldr     r0, [r2, #RCC_APB2ENR]
-    orrs    r0, r3
-    str     r0, [r2, #RCC_APB2ENR]
-/* setting up USB CNTR */
-    movs    r0, #0xBE
-    lsls    r0, #0x08                   // CTRM | ERRM | WKUPM | SUSPM | RESETM | SOFM
-    strh    r0, [r1, #USB_CNTR]         //set USB->CNTR
-    bx      lr
-.L_disable:
-    ldr     r0, [r2, #RCC_APB1ENR]
-    tst     r0, r3
-    beq     .L_enable_end               // usb is already disabled
-/* disabling USB peripheral */
-    bics    r0, r3
-    str     r0, [r2, #RCC_APB1ENR]
-/* disabling USB_PU in SYSCFG_PMC */
-    movs    r3, #0x01
-    ldr     r1, =#SYSCFG_BASE
-    ldr     r0, [r1, #SYSCFG_PMC]
-    bics    r0, r3
-    str     r0, [r1, #SYSCFG_PMC]
-    bx      lr
-.L_enable_end:
-    bx      lr
-    .size   _enable, . - _enable
-
-    .thumb_func
-    .type   _ep_setstall, %function
-
-/*void ep_settall(uint8_t ep, bool stall)
- * in  R0 <- endpoint number
- * in  R1 <- 0 if unstall, !0 if stall
- */
-_ep_setstall:
-    lsls    r2, r0, #28
-    lsrs    r2, #26
-    ldr     r3, =#USB_EPBASE
-    adds    r3, r2          // epr -> r3
-    movs    r2, 0x30        // TX_STAT_MASK -> r2
-    cmp     r0, #80
-    blo     .L_eps_rx
-.L_eps_tx:
-    ldr     r0, =#TX_STALL   //stall TX
-    tst     r1, r1
-    bne     .L_eps_reg_set
-.L_eps_tx_unstall:
-    ldrh    r1, [r3]        // *epr -> r1
-    lsls    r1, #21
-    lsrs    r1, #29         // EPTTYPE | EPKIND mask only
-    ldr     r0, =#DTX_USTALL //unstall dblbulk or iso TX (VALID and clr DTOG_TX & SWBUF_TX)
-    cmp     r1, #0x01       // if doublebuffered bulk endpoint
-    beq     .L_eps_reg_set
-    cmp     r1, #0x04       // if isochronous endpoint
-    ldr     r0, =#TX_USTALL  // unstall other TX (NAKED + clr DTOG_TX)
-    b       .L_eps_reg_set
-.L_eps_rx:
-    lsls    r2, #8          // RX_STAT_MASK -> R2
-    ldr     r0,=#RX_STALL    //stall RX
-    tst     r1, r1
-    bne     .L_eps_reg_set
-.L_eps_rx_unstall:
-    ldrh    r1, [r3]        // *epr -> r1
-    lsls    r1, #21
-    lsrs    r1, #29         // EPTTYPE | EPKIND mask only
-    ldr     r0, =#DRX_USTALL //unstall dblbulk or iso (VALID. clr DTOG_RX set SWBUF_RX)
-    cmp     r1, #0x01       // if dblbulk
-    beq     .L_eps_reg_set
-    cmp     r1, #0x04       // if iso
-    beq     .L_eps_reg_set
-    ldr     r0, =#RX_USTALL  // unstall other RX (VALID + clr
-/* R0 - mask and toggle bits
- * R2 - mask for STAT bits
- * R3 - endpoint register pointer
- */
-.L_eps_reg_set:
-    ldrh    r1, [r3]        // *epr -> r1
-    ands    r2, r1          // check if endpoint disabled
-    beq     .L_eps_exit     // do nothing
-    eors    r1, r0
-    lsrs    r0, #16
-    ands    r1, r0
-    strh    r1, [r3]
-.L_eps_exit:
-    bx      lr
-    .size   _ep_setstall, . - _ep_setstall
-
-
-    .thumb_func
-    .type   _ep_isstalled, %function
-/* bool ep_isstalled(uint8t ep) */
-_ep_isstalled:
-    ldr     r1, =#USB_EPBASE
-    lsls    r2, r0, #28
-    lsrs    r2, #26
-    ldr     r1, [r1, r2]
-    lsls    r1, #17
-    cmp     r0, #0x80
-    bhs     .L_eis_check
-    lsls    r1, #8
-.L_eis_check:
-    lsrs    r1, r1, #28
-    subs    r1, #0x01
-    subs    r0, r1, #0x01
-    sbcs    r1, r1
-    rsbs    r0, r1, #0
-    bx      lr
-    .size  _ep_isstalled, . - _ep_isstalled
-
-
-    .thumb_func
-    .type       _ep_read, %function
-/* uint16_t _ep_read(uint8_t ep, void *buf, uint16_t blen)
- * in  R0 <- endpoint
- * in  R1 <- *buffer
- * in  R2 <- length of the buffer
- * out length of the recieved data -> R0
- */
-_ep_read:
-    push    {r4, r5, lr}
-    ldr     r3, =#USB_EPBASE
-    ldr     r4, =#USB_PMABASE
-    lsls    r0, #28
-    lsrs    r0, #26
-    adds    r3, r0          // *EPR -> R3
-    lsls    r0, #2
-    adds    r4, r0          // *EPT -> R4
-    ldrh    r0, [r3]        // reading epr
-    lsls    r5, r0, #21
-    lsrs    r5, #29
-    cmp     r5, #0x04
-    beq     .L_epr_iso
-    cmp     r5, #0x01
-    bne     .L_epr_sngl
-.L_epr_dblbulk:
-    negs    r0, r0
-    lsrs    r0, #7          // ~SW_RX in CF
-    b       .L_epr_load_table
-.L_epr_iso:
-    lsrs    r0, #15         // DTOG_RX passsed to CF
-.L_epr_load_table:
-    ldrh    r0, [r4, #RXADDR0]    // R0 rxaddr0
-    ldrh    r5, [r4, #RXCOUNT0]    // R5 rxcnt0
-    bcs     .L_epr_prepare
-.L_epr_sngl:
-    ldrh    r0, [r4, #RXADDR]    // R0 rxaddr1 or rxaddr
-    ldrh    r5, [r4, #RXCOUNT]   // R5 rxcnt1 or rxcnt
-.L_epr_prepare:
-    ldr     r4, =#USB_PMABASE
-    lsls    r0, #0x01
-    adds    r0, r4          // R0 now has a physical address
-    lsls    r5, #22
-    lsrs    r5, #22         // R5 bytes count
-    cmp     r2, r5
-    blo     .L_epr_read
-    mov     r2, r5          // if buffer is larger
-.L_epr_read:
-    cmp     r2, #1
-    blo     .L_epr_read_end
-    ldrh    r4, [r0]
-    strb    r4, [r1]
-    beq     .L_epr_read_end
-    lsrs    r4, #8
-    strb    r4, [r1, #1]
-    adds    r1, #2
-    adds    r0, #4
-    subs    r2, #2
-    bne     .L_epr_read
-.L_epr_read_end:
-    ldrh    r0, [r3]
-    lsls    r1, r0, #21
-    lsrs    r1, #29
-    cmp     r1, #0x04
-    beq     .L_epr_exit     // ep is iso. no needs to set it to valid
-    cmp     r1, #0x01
-    beq     .L_epr_exit     // ep is dblbulk. no needs to set it to valid
-    ldr     r2, =#TGL_SET(EP_RX_STAT , EP_RX_VAL)
-    eors    r0, r2
-    lsrs    r2, #16
-    ands    r0, r2
-    strh    r0, [r3]        // set ep to VALID state
-.L_epr_exit:
-    mov     r0, r5
-    pop     {r4, r5, pc}
-    .size   _ep_read, . - _ep_read
-
-
-
-    .thumb_func
-    .type   _ep_write, %function
-/* uint16_t ep_write(uint8_t ep, void *buf, uint16_t blen)
- *
-
- */
-_ep_write:
-    push    {r2, r4, r5, lr}
-    ldr     r3, =#USB_EPBASE
-    ldr     r4, =#USB_PMABASE
-    lsls    r0, #28
-    lsrs    r0, #26
-    adds    r3, r0          // *EPR -> R3
-    lsls    r0, #2
-    adds    r4, r0          // *EPT -> R4
-    ldrh    r0, [r3]        // reading epr
-    lsls    r0, #21
-    lsrs    r0, #29
-    subs    r0, #0x04
-    beq     .L_epw_iso
-    adds    r0, #0x03
-    bne     .L_epw_sngl
-.L_epw_dblbulk:
-    ldrh    r0, [r3]
-    lsrs    r0, #15          // SW_TX in CF
-    bcc     .L_epw_sngl
-    b       .L_epw_settx1
-.L_epw_iso:
-    ldrh    r0, [r3]
-    lsrs    r0, #7          // DTOG_TX passsed to CF
-    bcs     .L_epw_sngl
-.L_epw_settx1:
-    adds    r4, #0x08
-.L_epw_sngl:
-    ldrh    r0, [r4, #TXADDR]    // R0 txaddr
-    lsls    r0, #0x01
-//.L_epw_prepare:
-    strh    r2, [r4, #TXCOUNT]   // set txcount
-    ldr     r4, =#USB_PMABASE
-    adds    r0, r4
-.L_epw_write:
-    cmp     r2, #0x01
-    blo     .L_epw_writeend
-    ldrb    r4, [r1]
-    beq     .L_epw_halfw
-    ldrb    r5, [r1, #1]
-    lsls    r5, #8
-    orrs    r4, r5
-    strh    r4, [r0]
-    adds    r1, #2
-    adds    r0, #4
-    subs    r2, #2
-    b       .L_epw_write
-.L_epw_halfw:
-    strh    r4, [r0]
-.L_epw_writeend:
-    ldrh    r0, [r3]
-    lsls    r1, r0, #21
-    lsrs    r1, #29
-    cmp     r1, #0x04
-    beq     .L_epw_exit        //nothing to do with ISO ep
-    ldr     r2, =#TGL_SET(EP_TX_STAT, EP_TX_VAL)
-    cmp     r1, #0x01
-    bne     .L_epw_setstate
-// ep is dblbulk. needs to switch SW_TX
-    ldr     r2, =#TGL_SET(EP_TX_SWBUF, EP_TX_SWBUF)
-    bics    r0, r2              //clearing SW_BUF for setting in to 1 by XOR
- .L_epw_setstate:
-    eors    r0, r2
-    lsrs    r2, #16
-    ands    r0, r2
-    strh    r0, [r3]
-.L_epw_exit:
-    pop     {r0, r4, r5, pc}
-    .size   _ep_write, .- _ep_write
-
-
-
-/* internal function */
-/* requester size passed in R2 */
-/* result returns in R0 CF=1 if OK*/
-
-_get_next_pma:
-    push    {r1, r3, r4, lr}
-    movs    r1, #16
-    movs    r3, #1
-    lsls    r3, #9         //R3 MAX_PMA_SIZE 512b
-    ldr     r0, =#USB_PMABASE
-.L_gnp_chkaddr:
-    ldrh    r4, [r0, #0]    //txaddr
-    tst     r4, r4
-    beq     .L_gnp_nxtaddr
-    cmp     r3, r4
-    blo     .L_gnp_nxtaddr
-    mov     r3, r4
-.L_gnp_nxtaddr:
-    adds    r0, #8
-    subs    r1, #1
-    bne     .L_gnp_chkaddr
-    subs    r0, r3, r2
-    blo     .L_gnp_exit
-    cmp     r0, #0x40       //check for the pma table overlap
-.L_gnp_exit:
-    pop     {r1, r3, r4, pc}
-
-
-
-    .size   _get_next_pma, . - _get_next_pma
-
-    .thumb_func
-    .type   _ep_config, %function
-/* bool ep_config(uint8_t ep, uint8_t eptype, uint16_t epsize)
- * R0 <- ep
- * R1 <- eptype
- * R2 <- epsize
- * result -> R0
- */
-_ep_config:
-    push    {r4, r5, lr}
-    movs    r3, 0x01
-    ands    r3, r2
-    adds    r2, r3      //R2 -> halfword aligned epsize
-    movs    r3, #0x00   //BULK
-    cmp     r1, #0x02   // is eptype bulk ?
-    beq     .L_epc_settype
-    movs    r3, #0x01   //DBLBULK
-    cmp     r1, #0x06
-    beq     .L_epc_settype
-    movs    r3, #0x02   //CONTROL
-    cmp     r1, #0x00
-    beq     .L_epc_settype
-    movs    r3, #0x04   //ISO
-    cmp     r1, #0x01
-    beq     .L_epc_settype
-    movs    r3, #0x06   //INTERRUPT
-.L_epc_settype:
-    lsls    r3, #8
-    lsls    r4, r0, #28
-    lsrs    r4, #28
-    orrs    r3, r4
-    lsls    r4, #2
-    ldr     r5, =#USB_EPBASE
-    strh    r3, [r5, r4]    //setup EPTYPE EPKIND EPADDR
-    cmp     r1, #0x00       // is a control ep ?
-    beq     .L_epc_setuptx
-    cmp     r0, #0x80
-    blo     .L_epc_setuprx
-.L_epc_setuptx:
-    ldr     r5, =#USB_PMABASE
-    lsls    r4, #2
-    adds    r5, r4
-    bl      _get_next_pma
-    bcc     .L_epc_fail
-    strh    r0, [r5, #TXADDR]    //store txaddr or txaddr0
-    movs    r0, #0x00
-    strh    r0, [r5, #TXCOUNT]    //store txcnt
-    cmp     r1, #0x06       // is DBLBULK
-    beq     .L_epc_txdbl
-    ldr     r3, =#TX_USTALL  //set state NAKED , clr DTOG_TX
-    cmp     r1, #0x01       // is ISO
-    bne     .L_epc_txsetstate   //
-.L_epc_txdbl:
-    ldr     r3, =#DTX_USTALL //set state VALID clr DTOG_TX & SWBUF_TX
-    bl      _get_next_pma
-    bcc     .L_epc_fail
-    strh    r0, [r5, #TXADDR1]    //store txaddr1
-    movs    r0, #0x00
-    strh    r0, [r5, #TXCOUNT1]    //store txcnt
-.L_epc_txsetstate:
-    ldr     r5, =#USB_EPBASE
-    lsrs    r4, #1
-    ldrh    r0, [r5, r4]
-    eors    r0, r3
-    lsrs    r3, #16
-    ands    r0, r3
-    strh    r0, [r5, r4]
-    cmp     r1, #0x00       //is a control ep ?
-    bne     .L_epc_exit
-.L_epc_setuprx:
-    mov     r3, r2
-    cmp     r2, #62
-    bls     .L_epc_rxbb
-    movs    r3, #0x1F
-    ands    r3, r2
-    bne     .L_epc_rxaa
-    subs    r2, #0x20
-.L_epc_rxaa:
-    bics    r2, r3
-    lsrs    r3, r2, #4
-    adds    r3, #0x40
-    adds    r2, #0x20
-.L_epc_rxbb:
-    lsls    r3, #9
-    ldr     r5, =#USB_PMABASE
-    lsls    r4, #2
-    adds    r5, r4
-    cmp     r1, 0x06    //if dblbulk
-    beq     .L_epc_rxdbl
-    cmp     r1, 0x01    // iso
-    bne     .L_epc_rxsngl
-.L_epc_rxdbl:
-    bl      _get_next_pma
-    bcc     .L_epc_fail
-    strh    r0, [r5, #RXADDR0]    //store rxaddr0
-    strh    r3, [r5, #RXCOUNT0]    //store rxcnt0
-    bl      _get_next_pma
-    bcc     .L_epc_fail
-    strh    r0, [r5, #RXADDR1]    //store rxaddr1
-    strh    r3, [r5, #RXCOUNT1]    //store rxcnt1
-    ldr     r3, =#DRX_USTALL
-    b       .L_epc_rxsetstate
-.L_epc_rxsngl:
-    bl      _get_next_pma
-    bcc     .L_epc_fail
-    strh    r0, [r5, #RXADDR]    //store rxaddr1 or rxaddr
-    strh    r3, [r5, #RXCOUNT]    //store rxcnt1 or rxcnt
-    ldr     r3, =#RX_USTALL
-.L_epc_rxsetstate:
-    ldr     r5, =#USB_EPBASE
-    lsrs    r4, #1
-    ldrh    r0, [r5, r4]
-    eors    r0, r3
-    lsrs    r3, #16
-    ands    r0, r3
-    strh    r0, [r5, r4]
-.L_epc_exit:
-    movs    r0, #0x01
-    pop     {r4, r5, pc}
-.L_epc_fail:
-    movs    r0, #0x00
-    pop     {r4, r5, pc}
-
-    .size   _ep_config, . - _ep_config
-
-    .thumb_func
-    .type   _ep_deconfig, %function
-
-
-/* void ep_deconfig( uint8_t ep)
- * R0 <- ep
- */
-_ep_deconfig:
-    lsls    r1, r0, #28
-    lsrs    r1, #26
-    ldr     r2, =#USB_EPBASE
-    ldr     r3, =#USB_PMABASE
-    adds    r2, r1
-    lsls    r1, #1
-    adds    r3, r1
-/* clearing endpoint register */
-    ldr     r1, =#EP_NOTOG
-    ldrh    r0, [r2]
-    bics    r0, r1
-    strh    r0, [r2]
-/* clearing PMA data */
-    movs    r0, #0x00
-    strh    r0, [r3, #TXADDR]
-    strh    r0, [r3, #TXCOUNT]
-    strh    r0, [r3, #RXADDR]
-    strh    r0, [r3, #RXCOUNT]
-    bx      lr
-
-    .size   _ep_deconfig, . - _ep_config
-
-
-
-
-#define ISTRSHIFT   8
-#define ISTRBIT(bit) ((1 << bit) >> ISTRSHIFT)
-
-
-    .thumb_func
-    .type     _evt_poll, %function
-/*void evt_poll(usbd_device *dev, usbd_evt_callback callback)*/
-_evt_poll:
-    push    {r0, r1, r4, r5}
-    ldr     r3, =#USB_REGBASE
-    ldrh    r0, [r3, #4]        //USB->ISTR -> R2
-/* ep_index -> R2 */
-    movs    r2, 0x07
-    ands    r2, r0
-/* checking USB->ISTR for events */
-    lsls    r0, #17             //CTRM -> CF
-    bcs     .L_ep_ctrm
-    lsls    r0, #2              //ERRM -> CF
-    bcs     .L_ep_errm
-    lsls    r0, #1              //WKUPM -> CF
-    bcs     .L_ep_wkupm
-    lsls    r0, #1              //SUSPM -> CF
-    bcs     .L_ep_suspm
-    lsls    r0, #1              //RESETM -> CF
-    bcs     .L_ep_resetm
-    lsls    r0, #1              //SOFM -> CF
-    bcs     .L_ep_sofm
-    lsls    r0, #1
-    bcs     .L_ep_esofm
-    /* exit with no callback */
-    pop     {r0, r1, r4 , r5}
-    bx      lr
-
-.L_ep_ctrm:
-    movs    r3, #0x00
-    ldr     r0,=#USB_EPBASE
-    lsrs    r0, #2
-    adds    r0, r2
-    lsls    r0, #2              // R0 ep register address
-    ldrh    r4, [r0]            //R4 *USB->EPx
-    lsrs    r5, r4, #8         // CTR_TX -> CF
-    bcc     .L_ep_ctr_rx
-/* CTR_TX event */
-    movs    r1, #usbd_evt_eptx
-    movs    r5, #0x80
-    adds    r2, #0x80           // set endpoint tx
-    b       .L_ep_clr_ctr
-.L_ep_ctr_rx:
-/* CTR_RX  RX or SETUP */
-    movs    r1, #usbd_evt_epsetup
-    lsls    r5, r4, #21             //SETUP -> CF
-    bcs     .L_ep_ctr_evt
-    movs    r1, #usbd_evt_eprx
-    lsrs    r5, #29                 //EP_TYPE | EP_KIND -> R5 LSB
-    cmp     r5, #0x01               //if dblbuf bulk
-    bne     .L_ep_ctr_evt
-/* if ep is dblbulk RX */
-    movs    r3, #EP_RX_SWBUF
-.L_ep_ctr_evt:
-/* clear CTR_RX */
-    movs    r5, #0x80
-    lsls    r5, #0x08
-.L_ep_clr_ctr:
-    bics    r4, r5
-    ldr     r5, =#EP_NOTOG
-    ands    r4, r5
-    orrs    r4, r3
-    strh    r4, [r0]            // clr CTR flag
-    b       .L_ep_callback
-
-.L_ep_errm:
-    movs    r1, #usbd_evt_error
-    movs    r4, #ISTRBIT(13)
-    b      .L_ep_clristr
-
-.L_ep_sofm:
-    movs    r1, #usbd_evt_sof
-    movs    r4, #ISTRBIT(9)
-    b       .L_ep_clristr
-
-.L_ep_esofm:
-    movs    r1, #usbd_evt_esof
-    movs    r4, #ISTRBIT(8)
-    b       .L_ep_clristr
-
-.L_ep_wkupm:
-    ldrh    r1, [r3, #0]            //R1 USB->CNTR
-    movs    r5, #0x08
-    bics    r1, r5                  //clr FSUSP
-    strh    r1, [r3, #0]            //USB->CNTR R2
-    movs    r1, #usbd_evt_wkup
-    movs    r4, #ISTRBIT(12)
-    b       .L_ep_clristr
-
-.L_ep_suspm:
-    ldrh    r1, [r3, #0]            //R1 USB->CNTR
-    movs    r5, #0x08
-    orrs    r1, r5                  //set FSUSP
-    strh    r1, [r3, #0]            //USB->CNTR R2
-    movs    r1, #usbd_evt_susp
-    movs    r4, #ISTRBIT(11)
-    b       .L_ep_clristr
-
-/* do reset routine */
-.L_ep_resetm:
-    movs    r1, #7
-    ldr     r2, =#USB_EPBASE
-    ldr     r0, =#USB_PMABASE
-    ldr     r5, =#EP_NOTOG
-.L_ep_reset_loop:
-    ldrh    r4, [r2]
-    bics    r4, r5
-    strh    r4, [r2]
-    movs    r4, #0
-    strh    r4, [r0, #TXADDR]
-    strh    r4, [r0, #TXCOUNT]
-    strh    r4, [r0, #RXADDR]
-    strh    r4, [r0, #RXCOUNT]
-    adds    r2, #0x04
-    adds    r0, #0x10
-    subs    r1, #1
-    bpl     .L_ep_reset_loop
-    movs    r2, #0x00
-    strh    r2, [r3, #0x10]     // 0 -> USB->BTABLE
-    movs    r1, #usbd_evt_reset
-    movs    r4, #ISTRBIT(10)
-.L_ep_clristr:
-    lsls    r4, #ISTRSHIFT
-    ldrh    r0, [r3, #4]
-    bics    r0, r4
-    strh    r0, [r3, #4]
-.L_ep_callback:
-    pop     {r0, r3, r4, r5 }
-    bx      r3
-
-    .size   _evt_poll, . - _evt_poll
-
-    .pool
-
-   .end
-
-#endif
+/* This file is the part of the LUS32 project
+ *
+ * Copyright ©2016 Dmitry Filimonchuk <dmitrystu[at]gmail[dot]com>
+ *
+ * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ * 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.
+ */
+
+#if !defined (__ASSEMBLER__)
+    #define __ASSEMBLER__
+#endif
+
+#include "../usb.h"
+#include "memmap.inc"
+#if defined(USE_STMV1A_DRIVER)
+
+
+#define EP_SETUP    0x0800
+#define EP_TYPE     0x0600
+#define EP_KIND     0x0100
+#define EP_ADDR     0x000F
+
+#define EP_RX_CTR   0x8000
+#define EP_RX_DTOG  0x4000
+#define EP_RX_STAT  0x3000
+#define EP_RX_SWBUF 0x0040
+
+#define EP_RX_DIS   0x0000
+#define EP_RX_STAL  0x1000
+#define EP_RX_NAK   0x2000
+#define EP_RX_VAL   0x3000
+
+#define EP_TX_CTR   0x0080
+#define EP_TX_DTOG  0x0040
+#define EP_TX_STAT  0x0030
+#define EP_TX_SWBUF 0x4000
+
+#define EP_TX_DIS   0x0000
+#define EP_TX_STAL  0x0010
+#define EP_TX_NAK   0x0020
+#define EP_TX_VAL   0x0030
+
+#define RXADDR0     0x00
+#define RXCOUNT0    0x04
+#define RXADDR1     0x08
+#define RXCOUNT1    0x0C
+
+#define TXADDR0     0x00
+#define TXCOUNT0    0x04
+#define TXADDR1     0x08
+#define TXCOUNT1    0x0C
+
+#define TXADDR      0x00
+#define TXCOUNT     0x04
+#define RXADDR      0x08
+#define RXCOUNT     0x0C
+
+
+
+#define EP_NOTOG    (EP_RX_CTR | EP_TX_CTR | EP_SETUP | EP_TYPE | EP_KIND | EP_ADDR)
+
+#define TGL_SET(mask, bits)  ((EP_NOTOG | (mask))<<16 | (bits))
+
+#define TX_STALL    TGL_SET(EP_TX_STAT,                            EP_TX_STAL)
+#define RX_STALL    TGL_SET(EP_RX_STAT,                            EP_RX_STAL)
+#define TX_USTALL   TGL_SET(EP_TX_STAT | EP_TX_DTOG,               EP_TX_NAK)
+#define RX_USTALL   TGL_SET(EP_RX_STAT | EP_RX_DTOG,               EP_RX_VAL)
+#define DTX_USTALL  TGL_SET(EP_TX_STAT | EP_TX_DTOG | EP_TX_SWBUF, EP_TX_VAL)
+#define DRX_USTALL  TGL_SET(EP_RX_STAT | EP_RX_DTOG | EP_RX_SWBUF, EP_RX_VAL | EP_RX_SWBUF)
+
+
+    .syntax unified
+    .cpu cortex-m3
+    .text
+    .thumb
+
+
+    .globl  usb_stmv1a
+    .align  2
+usb_stmv1a:
+    .long   _enable
+    .long   _reset
+    .long   _connect
+    .long   _setaddr
+    .long   _ep_config
+    .long   _ep_deconfig
+    .long   _ep_read
+    .long   _ep_write
+    .long   _ep_setstall
+    .long   _ep_isstalled
+    .long   _evt_poll
+    .long   _get_frame
+    .long   _get_serial_desc
+    .size   usb_stmv1a, . - usb_stmv1a
+
+
+    .thumb_func
+    .type _get_serial_desc, %function
+
+/*  uint16_t get_serial_desc (void *buffer)
+ *  R0 <- buffer for the string descriptor
+ *  descrpitor size -> R0
+ */
+_get_serial_desc:
+    push    {r4, r5, lr}
+    movs    r1, #18             //descriptor size 18 bytes
+    strb    r1, [r0]
+    movs    r1, #0x03           //DTYPE_STRING
+    strb    r1, [r0, #0x01]
+    ldr     r5, .L_uid_base     //UID3 this is the serial number
+    ldr     r4, .L_fnv1a_offset //FNV1A offset
+    ldr     r2, [r5, 0x00]      //UID0
+    bl      .L_fnv1a
+    ldr     r2, [r5, 0x04]      //UID1
+    bl      .L_fnv1a
+    ldr     r2, [r5, 0x14]      //UID2
+    bl      .L_fnv1a
+    movs    r3, #28
+.L_gsn_loop:
+    lsrs    r1, r4, r3
+    and     r1, #0x0F
+    cmp     r1, #0x09
+    ite     gt
+    addgt   r1, #55
+    addle   r1, #48
+.L_gsn_store:
+    adds    r0, #0x02
+    strb    r1, [r0]
+    lsrs    r1, #0x08
+    strb    r1, [r0, #0x01]
+    subs    r3, #0x04
+    bpl     .L_gsn_loop
+    movs    r0, #18
+    pop     {r4, r5, pc}
+
+.L_fnv1a:
+    movs    r3, #0x04
+.L_fnv1a_loop:
+    uxtb    r1, r2
+    eors    r4, r1
+    ldr     r1, .L_fnv1a_prime       //FNV1A prime
+    muls    r4, r1
+    lsrs    r2, #0x08
+    subs    r3, #0x01
+    bne     .L_fnv1a_loop
+    bx      lr
+
+    .align 2
+.L_uid_base:        .long   UID_BASE
+.L_fnv1a_offset:    .long   2166136261
+.L_fnv1a_prime:     .long   16777619
+
+    .size _get_serial_desc, . - _get_serial_desc
+
+    .thumb_func
+    .type   _connect, %function
+_connect:
+    ldr     r1, =#SYSCFG_BASE
+    movs    r3, #0x01
+    ldr     r2, [r1, #SYSCFG_PMC]
+    bics    r2, r3
+    cbz     r0, .L_conn_store
+    orrs    r2, r3
+.L_conn_store:
+    str     r2, [r1, #SYSCFG_PMC]
+    bx      lr
+    .size   _connect, . - _connect
+
+
+    .thumb_func
+    .type   _setaddr, %function
+_setaddr:
+    ldr     r1, =USB_REGBASE
+    adds    r0, #0x80
+    strh    r0, [r1, #USB_DADDR]     //USB->DADDR
+    bx      lr
+    .size   _setaddr, . - _setaddr
+
+    .thumb_func
+    .type   _reset, %function
+_reset:
+    ldr     r2, =#USB_REGBASE
+    movs    r0, #0x01           //FRES
+    ldrh    r1, [r2, #USB_CNTR]
+    orrs    r1, r0
+    strh    r1, [r2, #USB_CNTR]  // set FRES
+    bics    r1, r0
+    strh    r1, [r2, #USB_CNTR]  // clr FRES
+    bx      lr
+    .size   _reset, . - _reset
+
+    .thumb_func
+    .type   _get_frame, %function
+_get_frame:
+    ldr     r0, =#USB_REGBASE
+    ldrh    r0, [r0, #USB_FNR]     //FNR
+    lsls    r0, #21
+    lsrs    r0, #21
+    bx      lr
+    .size   _get_frame, . - _get_frame
+
+    .thumb_func
+    .type   _enable, %function
+_enable:
+
+    ldr     r2, =#RCC_BASE        //RCC
+    movs    r3, #0x01
+    lsls    r3, #23             //USBEN or USBRST
+    cbz     r0, .L_disable
+.L_enable:
+/* enabling and resetting USB peripheral */
+    ldr     r1, =#USB_REGBASE
+    ldr     r0, [r2, #RCC_APB1ENR]
+    orrs    r0, r3
+    str     r0, [r2, #RCC_APB1ENR]     //RCC->APB1ENR |= USBEN
+    ldr     r0, [r2, #RCC_APB1RSTR]
+    orrs    r0, r3
+    str     r0, [r2, #RCC_APB1RSTR]     //RCC->APB1RSTR |= USBRST
+    bics    r0, r3
+    str     r0, [r2, #RCC_APB1RSTR]     //RCC->APB1RSTR &= ~USBRST
+/* enabling SYSCFG peripheral */
+    movs    r3, #0x01                   //SYSCFGEN
+    ldr     r0, [r2, #RCC_APB2ENR]
+    orrs    r0, r3
+    str     r0, [r2, #RCC_APB2ENR]
+/* setting up USB CNTR */
+    movs    r0, #0xBE
+    lsls    r0, #0x08                   // CTRM | ERRM | WKUPM | SUSPM | RESETM | SOFM
+    strh    r0, [r1, #USB_CNTR]         //set USB->CNTR
+    bx      lr
+.L_disable:
+    ldr     r0, [r2, #RCC_APB1ENR]
+    tst     r0, r3
+    beq     .L_enable_end               // usb is already disabled
+/* disabling USB peripheral */
+    bics    r0, r3
+    str     r0, [r2, #RCC_APB1ENR]
+/* disabling USB_PU in SYSCFG_PMC */
+    movs    r3, #0x01
+    ldr     r1, =#SYSCFG_BASE
+    ldr     r0, [r1, #SYSCFG_PMC]
+    bics    r0, r3
+    str     r0, [r1, #SYSCFG_PMC]
+    bx      lr
+.L_enable_end:
+    bx      lr
+    .size   _enable, . - _enable
+
+    .thumb_func
+    .type   _ep_setstall, %function
+
+/*void ep_settall(uint8_t ep, bool stall)
+ * in  R0 <- endpoint number
+ * in  R1 <- 0 if unstall, !0 if stall
+ */
+_ep_setstall:
+    lsls    r2, r0, #28
+    lsrs    r2, #26
+    ldr     r3, =#USB_EPBASE
+    adds    r3, r2          // epr -> r3
+    movs    r2, 0x30        // TX_STAT_MASK -> r2
+    cmp     r0, #80
+    blo     .L_eps_rx
+.L_eps_tx:
+    ldr     r0, =#TX_STALL   //stall TX
+    tst     r1, r1
+    bne     .L_eps_reg_set
+.L_eps_tx_unstall:
+    ldrh    r1, [r3]        // *epr -> r1
+    lsls    r1, #21
+    lsrs    r1, #29         // EPTTYPE | EPKIND mask only
+    ldr     r0, =#DTX_USTALL //unstall dblbulk or iso TX (VALID and clr DTOG_TX & SWBUF_TX)
+    cmp     r1, #0x01       // if doublebuffered bulk endpoint
+    beq     .L_eps_reg_set
+    cmp     r1, #0x04       // if isochronous endpoint
+    ldr     r0, =#TX_USTALL  // unstall other TX (NAKED + clr DTOG_TX)
+    b       .L_eps_reg_set
+.L_eps_rx:
+    lsls    r2, #8          // RX_STAT_MASK -> R2
+    ldr     r0,=#RX_STALL    //stall RX
+    tst     r1, r1
+    bne     .L_eps_reg_set
+.L_eps_rx_unstall:
+    ldrh    r1, [r3]        // *epr -> r1
+    lsls    r1, #21
+    lsrs    r1, #29         // EPTTYPE | EPKIND mask only
+    ldr     r0, =#DRX_USTALL //unstall dblbulk or iso (VALID. clr DTOG_RX set SWBUF_RX)
+    cmp     r1, #0x01       // if dblbulk
+    beq     .L_eps_reg_set
+    cmp     r1, #0x04       // if iso
+    beq     .L_eps_reg_set
+    ldr     r0, =#RX_USTALL  // unstall other RX (VALID + clr
+/* R0 - mask and toggle bits
+ * R2 - mask for STAT bits
+ * R3 - endpoint register pointer
+ */
+.L_eps_reg_set:
+    ldrh    r1, [r3]        // *epr -> r1
+    ands    r2, r1          // check if endpoint disabled
+    beq     .L_eps_exit     // do nothing
+    eors    r1, r0
+    lsrs    r0, #16
+    ands    r1, r0
+    strh    r1, [r3]
+.L_eps_exit:
+    bx      lr
+    .size   _ep_setstall, . - _ep_setstall
+
+
+    .thumb_func
+    .type   _ep_isstalled, %function
+/* bool ep_isstalled(uint8t ep) */
+_ep_isstalled:
+    ldr     r1, =#USB_EPBASE
+    lsls    r2, r0, #28
+    lsrs    r2, #26
+    ldr     r1, [r1, r2]
+    lsls    r1, #17
+    cmp     r0, #0x80
+    bhs     .L_eis_check
+    lsls    r1, #8
+.L_eis_check:
+    lsrs    r1, r1, #28
+    subs    r1, #0x01
+    subs    r0, r1, #0x01
+    sbcs    r1, r1
+    rsbs    r0, r1, #0
+    bx      lr
+    .size  _ep_isstalled, . - _ep_isstalled
+
+
+    .thumb_func
+    .type       _ep_read, %function
+/* uint16_t _ep_read(uint8_t ep, void *buf, uint16_t blen)
+ * in  R0 <- endpoint
+ * in  R1 <- *buffer
+ * in  R2 <- length of the buffer
+ * out length of the recieved data -> R0
+ */
+_ep_read:
+    push    {r4, r5, lr}
+    ldr     r3, =#USB_EPBASE
+    ldr     r4, =#USB_PMABASE
+    lsls    r0, #28
+    lsrs    r0, #26
+    adds    r3, r0          // *EPR -> R3
+    lsls    r0, #2
+    adds    r4, r0          // *EPT -> R4
+    ldrh    r0, [r3]        // reading epr
+    lsls    r5, r0, #21
+    lsrs    r5, #29
+    cmp     r5, #0x04
+    beq     .L_epr_iso
+    cmp     r5, #0x01
+    bne     .L_epr_sngl
+.L_epr_dblbulk:
+    negs    r0, r0
+    lsrs    r0, #7          // ~SW_RX in CF
+    b       .L_epr_load_table
+.L_epr_iso:
+    lsrs    r0, #15         // DTOG_RX passsed to CF
+.L_epr_load_table:
+    ldrh    r0, [r4, #RXADDR0]    // R0 rxaddr0
+    ldrh    r5, [r4, #RXCOUNT0]    // R5 rxcnt0
+    bcs     .L_epr_prepare
+.L_epr_sngl:
+    ldrh    r0, [r4, #RXADDR]    // R0 rxaddr1 or rxaddr
+    ldrh    r5, [r4, #RXCOUNT]   // R5 rxcnt1 or rxcnt
+.L_epr_prepare:
+    ldr     r4, =#USB_PMABASE
+    lsls    r0, #0x01
+    adds    r0, r4          // R0 now has a physical address
+    lsls    r5, #22
+    lsrs    r5, #22         // R5 bytes count
+    cmp     r2, r5
+    blo     .L_epr_read
+    mov     r2, r5          // if buffer is larger
+.L_epr_read:
+    cmp     r2, #1
+    blo     .L_epr_read_end
+    ldrh    r4, [r0]
+    strb    r4, [r1]
+    beq     .L_epr_read_end
+    lsrs    r4, #8
+    strb    r4, [r1, #1]
+    adds    r1, #2
+    adds    r0, #4
+    subs    r2, #2
+    bne     .L_epr_read
+.L_epr_read_end:
+    ldrh    r0, [r3]
+    lsls    r1, r0, #21
+    lsrs    r1, #29
+    cmp     r1, #0x04
+    beq     .L_epr_exit     // ep is iso. no needs to set it to valid
+    cmp     r1, #0x01
+    beq     .L_epr_exit     // ep is dblbulk. no needs to set it to valid
+    ldr     r2, =#TGL_SET(EP_RX_STAT , EP_RX_VAL)
+    eors    r0, r2
+    lsrs    r2, #16
+    ands    r0, r2
+    strh    r0, [r3]        // set ep to VALID state
+.L_epr_exit:
+    mov     r0, r5
+    pop     {r4, r5, pc}
+    .size   _ep_read, . - _ep_read
+
+
+
+    .thumb_func
+    .type   _ep_write, %function
+/* uint16_t ep_write(uint8_t ep, void *buf, uint16_t blen)
+ *
+
+ */
+_ep_write:
+    push    {r2, r4, r5, lr}
+    ldr     r3, =#USB_EPBASE
+    ldr     r4, =#USB_PMABASE
+    lsls    r0, #28
+    lsrs    r0, #26
+    adds    r3, r0          // *EPR -> R3
+    lsls    r0, #2
+    adds    r4, r0          // *EPT -> R4
+    ldrh    r0, [r3]        // reading epr
+    lsls    r0, #21
+    lsrs    r0, #29
+    subs    r0, #0x04
+    beq     .L_epw_iso
+    adds    r0, #0x03
+    bne     .L_epw_sngl
+.L_epw_dblbulk:
+    ldrh    r0, [r3]
+    lsrs    r0, #15          // SW_TX in CF
+    bcc     .L_epw_sngl
+    b       .L_epw_settx1
+.L_epw_iso:
+    ldrh    r0, [r3]
+    lsrs    r0, #7          // DTOG_TX passsed to CF
+    bcs     .L_epw_sngl
+.L_epw_settx1:
+    adds    r4, #0x08
+.L_epw_sngl:
+    ldrh    r0, [r4, #TXADDR]    // R0 txaddr
+    lsls    r0, #0x01
+//.L_epw_prepare:
+    strh    r2, [r4, #TXCOUNT]   // set txcount
+    ldr     r4, =#USB_PMABASE
+    adds    r0, r4
+.L_epw_write:
+    cmp     r2, #0x01
+    blo     .L_epw_writeend
+    ldrb    r4, [r1]
+    beq     .L_epw_halfw
+    ldrb    r5, [r1, #1]
+    lsls    r5, #8
+    orrs    r4, r5
+    strh    r4, [r0]
+    adds    r1, #2
+    adds    r0, #4
+    subs    r2, #2
+    b       .L_epw_write
+.L_epw_halfw:
+    strh    r4, [r0]
+.L_epw_writeend:
+    ldrh    r0, [r3]
+    lsls    r1, r0, #21
+    lsrs    r1, #29
+    cmp     r1, #0x04
+    beq     .L_epw_exit        //nothing to do with ISO ep
+    ldr     r2, =#TGL_SET(EP_TX_STAT, EP_TX_VAL)
+    cmp     r1, #0x01
+    bne     .L_epw_setstate
+// ep is dblbulk. needs to switch SW_TX
+    ldr     r2, =#TGL_SET(EP_TX_SWBUF, EP_TX_SWBUF)
+    bics    r0, r2              //clearing SW_BUF for setting in to 1 by XOR
+ .L_epw_setstate:
+    eors    r0, r2
+    lsrs    r2, #16
+    ands    r0, r2
+    strh    r0, [r3]
+.L_epw_exit:
+    pop     {r0, r4, r5, pc}
+    .size   _ep_write, .- _ep_write
+
+
+
+/* internal function */
+/* requester size passed in R2 */
+/* result returns in R0 CF=1 if OK*/
+
+_get_next_pma:
+    push    {r1, r3, r4, lr}
+    movs    r1, #16
+    movs    r3, #1
+    lsls    r3, #9         //R3 MAX_PMA_SIZE 512b
+    ldr     r0, =#USB_PMABASE
+.L_gnp_chkaddr:
+    ldrh    r4, [r0, #0]    //txaddr
+    tst     r4, r4
+    beq     .L_gnp_nxtaddr
+    cmp     r3, r4
+    blo     .L_gnp_nxtaddr
+    mov     r3, r4
+.L_gnp_nxtaddr:
+    adds    r0, #8
+    subs    r1, #1
+    bne     .L_gnp_chkaddr
+    subs    r0, r3, r2
+    blo     .L_gnp_exit
+    cmp     r0, #0x40       //check for the pma table overlap
+.L_gnp_exit:
+    pop     {r1, r3, r4, pc}
+
+
+
+    .size   _get_next_pma, . - _get_next_pma
+
+    .thumb_func
+    .type   _ep_config, %function
+/* bool ep_config(uint8_t ep, uint8_t eptype, uint16_t epsize)
+ * R0 <- ep
+ * R1 <- eptype
+ * R2 <- epsize
+ * result -> R0
+ */
+_ep_config:
+    push    {r4, r5, lr}
+    movs    r3, 0x01
+    ands    r3, r2
+    adds    r2, r3      //R2 -> halfword aligned epsize
+    movs    r3, #0x00   //BULK
+    cmp     r1, #0x02   // is eptype bulk ?
+    beq     .L_epc_settype
+    movs    r3, #0x01   //DBLBULK
+    cmp     r1, #0x06
+    beq     .L_epc_settype
+    movs    r3, #0x02   //CONTROL
+    cmp     r1, #0x00
+    beq     .L_epc_settype
+    movs    r3, #0x04   //ISO
+    cmp     r1, #0x01
+    beq     .L_epc_settype
+    movs    r3, #0x06   //INTERRUPT
+.L_epc_settype:
+    lsls    r3, #8
+    lsls    r4, r0, #28
+    lsrs    r4, #28
+    orrs    r3, r4
+    lsls    r4, #2
+    ldr     r5, =#USB_EPBASE
+    strh    r3, [r5, r4]    //setup EPTYPE EPKIND EPADDR
+    cmp     r1, #0x00       // is a control ep ?
+    beq     .L_epc_setuptx
+    cmp     r0, #0x80
+    blo     .L_epc_setuprx
+.L_epc_setuptx:
+    ldr     r5, =#USB_PMABASE
+    lsls    r4, #2
+    adds    r5, r4
+    bl      _get_next_pma
+    bcc     .L_epc_fail
+    strh    r0, [r5, #TXADDR]    //store txaddr or txaddr0
+    movs    r0, #0x00
+    strh    r0, [r5, #TXCOUNT]    //store txcnt
+    cmp     r1, #0x06       // is DBLBULK
+    beq     .L_epc_txdbl
+    ldr     r3, =#TX_USTALL  //set state NAKED , clr DTOG_TX
+    cmp     r1, #0x01       // is ISO
+    bne     .L_epc_txsetstate   //
+.L_epc_txdbl:
+    ldr     r3, =#DTX_USTALL //set state VALID clr DTOG_TX & SWBUF_TX
+    bl      _get_next_pma
+    bcc     .L_epc_fail
+    strh    r0, [r5, #TXADDR1]    //store txaddr1
+    movs    r0, #0x00
+    strh    r0, [r5, #TXCOUNT1]    //store txcnt
+.L_epc_txsetstate:
+    ldr     r5, =#USB_EPBASE
+    lsrs    r4, #1
+    ldrh    r0, [r5, r4]
+    eors    r0, r3
+    lsrs    r3, #16
+    ands    r0, r3
+    strh    r0, [r5, r4]
+    cmp     r1, #0x00       //is a control ep ?
+    bne     .L_epc_exit
+.L_epc_setuprx:
+    mov     r3, r2
+    cmp     r2, #62
+    bls     .L_epc_rxbb
+    movs    r3, #0x1F
+    ands    r3, r2
+    bne     .L_epc_rxaa
+    subs    r2, #0x20
+.L_epc_rxaa:
+    bics    r2, r3
+    lsrs    r3, r2, #4
+    adds    r3, #0x40
+    adds    r2, #0x20
+.L_epc_rxbb:
+    lsls    r3, #9
+    ldr     r5, =#USB_PMABASE
+    lsls    r4, #2
+    adds    r5, r4
+    cmp     r1, 0x06    //if dblbulk
+    beq     .L_epc_rxdbl
+    cmp     r1, 0x01    // iso
+    bne     .L_epc_rxsngl
+.L_epc_rxdbl:
+    bl      _get_next_pma
+    bcc     .L_epc_fail
+    strh    r0, [r5, #RXADDR0]    //store rxaddr0
+    strh    r3, [r5, #RXCOUNT0]    //store rxcnt0
+    bl      _get_next_pma
+    bcc     .L_epc_fail
+    strh    r0, [r5, #RXADDR1]    //store rxaddr1
+    strh    r3, [r5, #RXCOUNT1]    //store rxcnt1
+    ldr     r3, =#DRX_USTALL
+    b       .L_epc_rxsetstate
+.L_epc_rxsngl:
+    bl      _get_next_pma
+    bcc     .L_epc_fail
+    strh    r0, [r5, #RXADDR]    //store rxaddr1 or rxaddr
+    strh    r3, [r5, #RXCOUNT]    //store rxcnt1 or rxcnt
+    ldr     r3, =#RX_USTALL
+.L_epc_rxsetstate:
+    ldr     r5, =#USB_EPBASE
+    lsrs    r4, #1
+    ldrh    r0, [r5, r4]
+    eors    r0, r3
+    lsrs    r3, #16
+    ands    r0, r3
+    strh    r0, [r5, r4]
+.L_epc_exit:
+    movs    r0, #0x01
+    pop     {r4, r5, pc}
+.L_epc_fail:
+    movs    r0, #0x00
+    pop     {r4, r5, pc}
+
+    .size   _ep_config, . - _ep_config
+
+    .thumb_func
+    .type   _ep_deconfig, %function
+
+
+/* void ep_deconfig( uint8_t ep)
+ * R0 <- ep
+ */
+_ep_deconfig:
+    lsls    r1, r0, #28
+    lsrs    r1, #26
+    ldr     r2, =#USB_EPBASE
+    ldr     r3, =#USB_PMABASE
+    adds    r2, r1
+    lsls    r1, #1
+    adds    r3, r1
+/* clearing endpoint register */
+    ldr     r1, =#EP_NOTOG
+    ldrh    r0, [r2]
+    bics    r0, r1
+    strh    r0, [r2]
+/* clearing PMA data */
+    movs    r0, #0x00
+    strh    r0, [r3, #TXADDR]
+    strh    r0, [r3, #TXCOUNT]
+    strh    r0, [r3, #RXADDR]
+    strh    r0, [r3, #RXCOUNT]
+    bx      lr
+
+    .size   _ep_deconfig, . - _ep_config
+
+
+
+
+#define ISTRSHIFT   8
+#define ISTRBIT(bit) ((1 << bit) >> ISTRSHIFT)
+
+
+    .thumb_func
+    .type     _evt_poll, %function
+/*void evt_poll(usbd_device *dev, usbd_evt_callback callback)*/
+_evt_poll:
+    push    {r0, r1, r4, r5}
+    ldr     r3, =#USB_REGBASE
+    ldrh    r0, [r3, #4]        //USB->ISTR -> R2
+/* ep_index -> R2 */
+    movs    r2, 0x07
+    ands    r2, r0
+/* checking USB->ISTR for events */
+    lsls    r0, #17             //CTRM -> CF
+    bcs     .L_ep_ctrm
+    lsls    r0, #2              //ERRM -> CF
+    bcs     .L_ep_errm
+    lsls    r0, #1              //WKUPM -> CF
+    bcs     .L_ep_wkupm
+    lsls    r0, #1              //SUSPM -> CF
+    bcs     .L_ep_suspm
+    lsls    r0, #1              //RESETM -> CF
+    bcs     .L_ep_resetm
+    lsls    r0, #1              //SOFM -> CF
+    bcs     .L_ep_sofm
+    lsls    r0, #1
+    bcs     .L_ep_esofm
+    /* exit with no callback */
+    pop     {r0, r1, r4 , r5}
+    bx      lr
+
+.L_ep_ctrm:
+    movs    r3, #0x00
+    ldr     r0,=#USB_EPBASE
+    lsrs    r0, #2
+    adds    r0, r2
+    lsls    r0, #2              // R0 ep register address
+    ldrh    r4, [r0]            //R4 *USB->EPx
+    lsrs    r5, r4, #8         // CTR_TX -> CF
+    bcc     .L_ep_ctr_rx
+/* CTR_TX event */
+    movs    r1, #usbd_evt_eptx
+    movs    r5, #0x80
+    adds    r2, #0x80           // set endpoint tx
+    b       .L_ep_clr_ctr
+.L_ep_ctr_rx:
+/* CTR_RX  RX or SETUP */
+    movs    r1, #usbd_evt_epsetup
+    lsls    r5, r4, #21             //SETUP -> CF
+    bcs     .L_ep_ctr_evt
+    movs    r1, #usbd_evt_eprx
+    lsrs    r5, #29                 //EP_TYPE | EP_KIND -> R5 LSB
+    cmp     r5, #0x01               //if dblbuf bulk
+    bne     .L_ep_ctr_evt
+/* if ep is dblbulk RX */
+    movs    r3, #EP_RX_SWBUF
+.L_ep_ctr_evt:
+/* clear CTR_RX */
+    movs    r5, #0x80
+    lsls    r5, #0x08
+.L_ep_clr_ctr:
+    bics    r4, r5
+    ldr     r5, =#EP_NOTOG
+    ands    r4, r5
+    orrs    r4, r3
+    strh    r4, [r0]            // clr CTR flag
+    b       .L_ep_callback
+
+.L_ep_errm:
+    movs    r1, #usbd_evt_error
+    movs    r4, #ISTRBIT(13)
+    b      .L_ep_clristr
+
+.L_ep_sofm:
+    movs    r1, #usbd_evt_sof
+    movs    r4, #ISTRBIT(9)
+    b       .L_ep_clristr
+
+.L_ep_esofm:
+    movs    r1, #usbd_evt_esof
+    movs    r4, #ISTRBIT(8)
+    b       .L_ep_clristr
+
+.L_ep_wkupm:
+    ldrh    r1, [r3, #0]            //R1 USB->CNTR
+    movs    r5, #0x08
+    bics    r1, r5                  //clr FSUSP
+    strh    r1, [r3, #0]            //USB->CNTR R2
+    movs    r1, #usbd_evt_wkup
+    movs    r4, #ISTRBIT(12)
+    b       .L_ep_clristr
+
+.L_ep_suspm:
+    ldrh    r1, [r3, #0]            //R1 USB->CNTR
+    movs    r5, #0x08
+    orrs    r1, r5                  //set FSUSP
+    strh    r1, [r3, #0]            //USB->CNTR R2
+    movs    r1, #usbd_evt_susp
+    movs    r4, #ISTRBIT(11)
+    b       .L_ep_clristr
+
+/* do reset routine */
+.L_ep_resetm:
+    movs    r1, #7
+    ldr     r2, =#USB_EPBASE
+    ldr     r0, =#USB_PMABASE
+    ldr     r5, =#EP_NOTOG
+.L_ep_reset_loop:
+    ldrh    r4, [r2]
+    bics    r4, r5
+    strh    r4, [r2]
+    movs    r4, #0
+    strh    r4, [r0, #TXADDR]
+    strh    r4, [r0, #TXCOUNT]
+    strh    r4, [r0, #RXADDR]
+    strh    r4, [r0, #RXCOUNT]
+    adds    r2, #0x04
+    adds    r0, #0x10
+    subs    r1, #1
+    bpl     .L_ep_reset_loop
+    movs    r2, #0x00
+    strh    r2, [r3, #0x10]     // 0 -> USB->BTABLE
+    movs    r1, #usbd_evt_reset
+    movs    r4, #ISTRBIT(10)
+.L_ep_clristr:
+    lsls    r4, #ISTRSHIFT
+    ldrh    r0, [r3, #4]
+    bics    r0, r4
+    strh    r0, [r3, #4]
+.L_ep_callback:
+    pop     {r0, r3, r4, r5 }
+    bx      r3
+
+    .size   _evt_poll, . - _evt_poll
+
+    .pool
+
+   .end
+
+#endif

+ 376 - 376
src/usbd_core.c

@@ -1,376 +1,376 @@
-/* This file is the part of the LUS32 project
- *
- * Copyright ©2016 Dmitry Filimonchuk <dmitrystu[at]gmail[dot]com>
- *
- * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
- * 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.
- */
-
-#include <stdint.h>
-#include <stdbool.h>
-#include <string.h>
-#include "../usb.h"
-
-#define _MIN(a, b) ((a) < (b)) ? (a) : (b)
-
-static void usbd_process_ep0 (usbd_device *dev, uint8_t event, uint8_t ep);
-
-/** \brief Resets USB device state
- * \param dev pointer to usb device
- * \return none
- */
-static void usbd_process_reset(usbd_device *dev) {
-    dev->status.device_state = usbd_state_default;
-    dev->status.control_state = usbd_ctl_idle;
-    dev->status.device_cfg = 0;
-    dev->driver->ep_config(0, USB_EPTYPE_CONTROL, dev->status.ep0size);
-    dev->endpoint[0] = usbd_process_ep0;
-    dev->driver->setaddr(0);
-}
-
-/** \brief Callback that sets USB device address
- * \param dev pointer to usb device
- * \param req pointer to usb control request data
- * \return none
- */
-static void usbd_set_address (usbd_device *dev, usbd_ctlreq *req) {
-    dev->driver->setaddr(req->wValue);
-    dev->status.device_state = (req->wValue) ? usbd_state_addressed : usbd_state_default;
-}
-
-/** \brief Callback processing after STATUS-IN or STATUS-OUT stage completed
- * \param dev pointer to the usb device
- * \return none
- */
-static void usbd_process_callback (usbd_device *dev) {
-    if (dev->complete_callback) {
-        dev->complete_callback(dev, dev->status.data_buf);
-        dev->complete_callback = 0;
-    }
-}
-
-static usbd_respond usbd_configure(usbd_device *dev, uint8_t config) {
-    usbd_respond resp = usbd_fail;
-    if (dev->config_callback) {
-        resp = dev->config_callback(dev, config);
-    }
-    if (config == 0 && resp == usbd_ack) {
-        dev->status.device_state = usbd_state_addressed;
-    }
-    return resp;
-}
-
-
-/** \brief Processing standard device control request
- * \param dev pointer to usb device
- * \param req pointer to control request
- * \return TRUE if request is handled
- */
-static usbd_respond usbd_process_devrq (usbd_device *dev, usbd_ctlreq *req) {
-    switch (req->bRequest) {
-    case USB_STD_CLEAR_FEATURE:
-        /* not yet supported */
-        break;
-    case USB_STD_GET_CONFIG:
-        req->data[0] = dev->status.device_cfg;
-        return usbd_ack;
-    case USB_STD_GET_DESCRIPTOR:
-        if (req->wValue == ((USB_DTYPE_STRING << 8) | INTSERIALNO_DESCRIPTOR )) {
-            dev->status.data_count = dev->driver->get_serialno_desc(req->data);
-            return usbd_ack;
-        } else {
-            if (dev->descriptor_callback) {
-                return dev->descriptor_callback(req, &(dev->status.data_ptr), &(dev->status.data_count));
-            }
-        }
-        break;
-    case USB_STD_GET_STATUS:
-        req->data[0] = 0;
-        req->data[1] = 0;
-        return usbd_ack;
-    case USB_STD_SET_ADDRESS:
-        dev->complete_callback = usbd_set_address;
-        return usbd_ack;
-    case USB_STD_SET_CONFIG:
-        return usbd_configure(dev, req->wValue);
-    case USB_STD_SET_DESCRIPTOR:
-        /* should be externally handled */
-        break;
-    case USB_STD_SET_FEATURE:
-        /* not yet supported */
-        break;
-    default:
-        break;
-    }
-    return usbd_fail;
-}
-
-/** \brief Processing standard interface control request
- * \param dev pointer to usb device
- * \param req pointer to control request
- * \return TRUE if request is handled
- */
-static usbd_respond usbd_process_intrq(usbd_device *dev, usbd_ctlreq *req) {
-    (void)dev;
-    switch (req->bRequest) {
-    case USB_STD_GET_STATUS:
-        req->data[0] = 0;
-        req->data[1] = 0;
-        return usbd_ack;
-    default:
-        break;
-    }
-    return usbd_fail;
-}
-
-/** \brief Processing standard endpoint control request
- * \param dev pointer to usb device
- * \param req pointer to control request
- * \return TRUE if request is handled
- */
-static usbd_respond usbd_process_eptrq(usbd_device *dev, usbd_ctlreq *req) {
-    switch (req->bRequest) {
-    case USB_STD_SET_FEATURE:
-        dev->driver->ep_setstall(req->wIndex, 1);
-        return usbd_ack;
-    case USB_STD_CLEAR_FEATURE:
-        dev->driver->ep_setstall(req->wIndex, 0);
-        return usbd_ack;
-    case USB_STD_GET_STATUS:
-        req->data[0] = dev->driver->ep_isstalled(req->wIndex) ? 1 : 0;
-        req->data[1] = 0;
-        return usbd_ack;
-    default:
-        break;
-    }
-    return usbd_fail;
-}
-
-/** \brief Processing control request
- * \param dev pointer to usb device
- * \param req pointer to usb control request
- * \return TRUE if request is handled
- */
-static usbd_respond usbd_process_request(usbd_device *dev, usbd_ctlreq *req) {
-    /* processing control request by callback */
-    if (dev->control_callback) {
-        usbd_respond r = dev->control_callback(dev, req, &(dev->complete_callback));
-        if (r != usbd_fail) return r;
-    }
-    /* continuing standard USB requests */
-    switch (req->bmRequestType & (USB_REQ_TYPE | USB_REQ_RECIPIENT)) {
-    case USB_REQ_STANDARD | USB_REQ_DEVICE:
-        return usbd_process_devrq(dev, req);
-    case USB_REQ_STANDARD | USB_REQ_INTERFACE:
-        return usbd_process_intrq(dev, req);
-    case USB_REQ_STANDARD | USB_REQ_ENDPOINT:
-        return usbd_process_eptrq(dev, req);
-    default:
-        break;
-    }
-    return usbd_fail;
-}
-
-
-/** \brief Control endpoint stall (STALL PID)
- * \param dev pointer to usb device
- * \param ep endpoint number
- */
-static void usbd_stall_pid(usbd_device *dev, uint8_t ep) {
-    dev->driver->ep_setstall(ep & 0x7F, 1);
-    dev->driver->ep_setstall(ep | 0x80, 1);
-    dev->status.control_state = usbd_ctl_idle;
-}
-
-
-/** \brief Control endpoint TX event processing
- * \param dev pointer to usb device
- * \param ep endpoint number
- */
-static void usbd_process_eptx(usbd_device *dev, uint8_t ep) {
-    uint16_t _t;
-    switch (dev->status.control_state) {
-    case usbd_ctl_ztxdata:
-    case usbd_ctl_txdata:
-        _t = _MIN(dev->status.data_count, dev->status.ep0size);
-        dev->driver->ep_write(ep, dev->status.data_ptr, _t);
-        dev->status.data_ptr += _t;
-        dev->status.data_count -= _t;
-        /* if all data is not sent */
-        if (0 != dev->status.data_count) break;
-        /* if last packet has a EP0 size and host awaiting for the more data ZLP should be sent*/
-        /* if ZLP required, control state will be unchanged, therefore next TX event sends ZLP */
-        if ( usbd_ctl_txdata == dev->status.control_state || _t != dev->status.ep0size ) {
-            dev->status.control_state = usbd_ctl_lastdata; /* no ZLP required */
-        }
-        break;
-    case usbd_ctl_lastdata:
-        dev->status.control_state = usbd_ctl_statusout;
-        break;
-    case usbd_ctl_statusin:
-        dev->status.control_state = usbd_ctl_idle;
-        return usbd_process_callback(dev);
-    default:
-        /* unexpected TX completion */
-        /* just skipping it */
-        break;
-    }
-}
-
-/** \brief Control endpoint RX event processing
- * \param dev pointer to usb device
- * \param ep endpoint number
- */
-static void usbd_process_eprx(usbd_device *dev, uint8_t ep) {
-    uint16_t _t;
-    usbd_ctlreq *const req = dev->status.data_buf;
-    switch (dev->status.control_state) {
-    case usbd_ctl_idle:
-        /* read SETUP packet, send STALL_PID if incorrect packet length */
-        if (0x08 !=  dev->driver->ep_read(ep, req, dev->status.data_maxsize)) {
-            return usbd_stall_pid(dev, ep);
-        }
-        dev->status.data_ptr = req->data;
-        dev->status.data_count = req->wLength;
-        /* processing request with no payload data*/
-        if ((req->bmRequestType & USB_REQ_DEVTOHOST) || (0 == req->wLength)) goto do_process_request;
-        /* checking available memory for DATA OUT stage */
-        if (req->wLength > dev->status.data_maxsize) {
-            return usbd_stall_pid(dev, ep);
-        }
-        /* continue DATA OUT stage */
-        dev->status.control_state = usbd_ctl_rxdata;
-        break;
-    case usbd_ctl_rxdata:
-        /*receive DATA OUT packet(s) */
-        _t = dev->driver->ep_read(ep, dev->status.data_ptr, dev->status.data_count);
-        if (dev->status.data_count < _t) {
-        /* if received packet is large than expected */
-        /* Must be error. Let's drop this request */
-            return usbd_stall_pid(dev, ep);
-        } else if (dev->status.data_count != _t) {
-        /* if all data payload was not received yet */
-            dev->status.data_count -= _t;
-            dev->status.data_ptr += _t;
-            break;
-        }
-do_process_request:
-        /* usb request received */
-        /* let's handle it */
-        /* preparing */
-        dev->status.data_ptr = req->data;
-        dev->status.data_count = req->wLength;/*dev->status.data_maxsize;*/
-        switch (usbd_process_request(dev, req)){
-        case usbd_ack:
-            if (req->bmRequestType & USB_REQ_DEVTOHOST) {
-                /* return data from function */
-                if (dev->status.data_count >= req->wLength) {
-                    dev->status.data_count = req->wLength;
-                    dev->status.control_state = usbd_ctl_txdata;
-                } else {
-                    /* DATA IN packet smaller than requested */
-                    /* ZLP maybe wanted */
-                    dev->status.control_state = usbd_ctl_ztxdata;
-                }
-                return usbd_process_eptx(dev, ep | 0x80);
-
-            } else {
-                /* confirming by ZLP in STATUS_IN stage */
-                dev->driver->ep_write(ep | 0x80, 0, 0);
-                dev->status.control_state = usbd_ctl_statusin;
-            }
-            break;
-        case usbd_nak:
-            dev->status.control_state = usbd_ctl_statusin;
-            break;
-        default:
-            return usbd_stall_pid(dev, ep);
-        }
-        break;
-    case usbd_ctl_statusout:
-        /* reading STATUS OUT data to buffer */
-        dev->driver->ep_read(ep, dev->status.data_ptr, dev->status.data_maxsize);
-        dev->status.control_state = usbd_ctl_idle;
-        return usbd_process_callback(dev);
-    default:
-        /* unexpected RX packet */
-        return usbd_stall_pid(dev, ep);
-    }
-}
-
-/** \brief Control endpoint 0 event processing callback
- * \param dev usb device
- * \param event endpoint event
- */
-static void usbd_process_ep0 (usbd_device *dev, uint8_t event, uint8_t ep) {
-    switch (event) {
-    case usbd_evt_epsetup:
-        /* force switch to setup state */
-        dev->status.control_state = usbd_ctl_idle;
-        dev->complete_callback = 0;
-    case usbd_evt_eprx:
-        return usbd_process_eprx(dev, ep);
-    case usbd_evt_eptx:
-        return usbd_process_eptx(dev, ep);
-    default:
-        break;
-    }
-}
-
-
-/** \brief General event processing callback
- * \param dev usb device
- * \param evt usb event
- * \param ep active endpoint
- */
-static void usbd_process_evt(usbd_device *dev, uint8_t evt, uint8_t ep) {
-    switch (evt) {
-    case usbd_evt_reset:
-        usbd_process_reset(dev);
-        break;
-    case usbd_evt_eprx:
-    case usbd_evt_eptx:
-    case usbd_evt_epsetup:
-        if (dev->endpoint[ep & 0x07]) dev->endpoint[ep & 0x07](dev, evt, ep);
-        break;
-    default:
-        break;
-    }
-    if (dev->events[evt]) dev->events[evt](dev, evt, ep);
-}
-
-void usbd_poll(usbd_device *dev) {
-    return dev->driver->poll(dev, usbd_process_evt);
-}
-
-void usbd_control(usbd_device *dev, enum usbd_commands cmd) {
-    switch (cmd) {
-    case usbd_cmd_enable:
-        dev->driver->enable(true);
-        dev->status.device_state = usbd_state_disconnected;
-        break;
-    case usbd_cmd_disable:
-        dev->driver->enable(false);
-        dev->status.device_state = usbd_state_disabled;
-        break;
-    case usbd_cmd_connect:
-        dev->driver->connect(true);
-        break;
-    case usbd_cmd_disconnect:
-        dev->driver->connect(false);
-        dev->status.device_state = usbd_state_disconnected;
-        break;
-    case usbd_cmd_reset:
-        dev->driver->reset();
-        break;
-    default:
-        break;
-    }
-}
+/* This file is the part of the LUS32 project
+ *
+ * Copyright ©2016 Dmitry Filimonchuk <dmitrystu[at]gmail[dot]com>
+ *
+ * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ * 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.
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+#include "../usb.h"
+
+#define _MIN(a, b) ((a) < (b)) ? (a) : (b)
+
+static void usbd_process_ep0 (usbd_device *dev, uint8_t event, uint8_t ep);
+
+/** \brief Resets USB device state
+ * \param dev pointer to usb device
+ * \return none
+ */
+static void usbd_process_reset(usbd_device *dev) {
+    dev->status.device_state = usbd_state_default;
+    dev->status.control_state = usbd_ctl_idle;
+    dev->status.device_cfg = 0;
+    dev->driver->ep_config(0, USB_EPTYPE_CONTROL, dev->status.ep0size);
+    dev->endpoint[0] = usbd_process_ep0;
+    dev->driver->setaddr(0);
+}
+
+/** \brief Callback that sets USB device address
+ * \param dev pointer to usb device
+ * \param req pointer to usb control request data
+ * \return none
+ */
+static void usbd_set_address (usbd_device *dev, usbd_ctlreq *req) {
+    dev->driver->setaddr(req->wValue);
+    dev->status.device_state = (req->wValue) ? usbd_state_addressed : usbd_state_default;
+}
+
+/** \brief Callback processing after STATUS-IN or STATUS-OUT stage completed
+ * \param dev pointer to the usb device
+ * \return none
+ */
+static void usbd_process_callback (usbd_device *dev) {
+    if (dev->complete_callback) {
+        dev->complete_callback(dev, dev->status.data_buf);
+        dev->complete_callback = 0;
+    }
+}
+
+static usbd_respond usbd_configure(usbd_device *dev, uint8_t config) {
+    usbd_respond resp = usbd_fail;
+    if (dev->config_callback) {
+        resp = dev->config_callback(dev, config);
+    }
+    if (config == 0 && resp == usbd_ack) {
+        dev->status.device_state = usbd_state_addressed;
+    }
+    return resp;
+}
+
+
+/** \brief Processing standard device control request
+ * \param dev pointer to usb device
+ * \param req pointer to control request
+ * \return TRUE if request is handled
+ */
+static usbd_respond usbd_process_devrq (usbd_device *dev, usbd_ctlreq *req) {
+    switch (req->bRequest) {
+    case USB_STD_CLEAR_FEATURE:
+        /* not yet supported */
+        break;
+    case USB_STD_GET_CONFIG:
+        req->data[0] = dev->status.device_cfg;
+        return usbd_ack;
+    case USB_STD_GET_DESCRIPTOR:
+        if (req->wValue == ((USB_DTYPE_STRING << 8) | INTSERIALNO_DESCRIPTOR )) {
+            dev->status.data_count = dev->driver->get_serialno_desc(req->data);
+            return usbd_ack;
+        } else {
+            if (dev->descriptor_callback) {
+                return dev->descriptor_callback(req, &(dev->status.data_ptr), &(dev->status.data_count));
+            }
+        }
+        break;
+    case USB_STD_GET_STATUS:
+        req->data[0] = 0;
+        req->data[1] = 0;
+        return usbd_ack;
+    case USB_STD_SET_ADDRESS:
+        dev->complete_callback = usbd_set_address;
+        return usbd_ack;
+    case USB_STD_SET_CONFIG:
+        return usbd_configure(dev, req->wValue);
+    case USB_STD_SET_DESCRIPTOR:
+        /* should be externally handled */
+        break;
+    case USB_STD_SET_FEATURE:
+        /* not yet supported */
+        break;
+    default:
+        break;
+    }
+    return usbd_fail;
+}
+
+/** \brief Processing standard interface control request
+ * \param dev pointer to usb device
+ * \param req pointer to control request
+ * \return TRUE if request is handled
+ */
+static usbd_respond usbd_process_intrq(usbd_device *dev, usbd_ctlreq *req) {
+    (void)dev;
+    switch (req->bRequest) {
+    case USB_STD_GET_STATUS:
+        req->data[0] = 0;
+        req->data[1] = 0;
+        return usbd_ack;
+    default:
+        break;
+    }
+    return usbd_fail;
+}
+
+/** \brief Processing standard endpoint control request
+ * \param dev pointer to usb device
+ * \param req pointer to control request
+ * \return TRUE if request is handled
+ */
+static usbd_respond usbd_process_eptrq(usbd_device *dev, usbd_ctlreq *req) {
+    switch (req->bRequest) {
+    case USB_STD_SET_FEATURE:
+        dev->driver->ep_setstall(req->wIndex, 1);
+        return usbd_ack;
+    case USB_STD_CLEAR_FEATURE:
+        dev->driver->ep_setstall(req->wIndex, 0);
+        return usbd_ack;
+    case USB_STD_GET_STATUS:
+        req->data[0] = dev->driver->ep_isstalled(req->wIndex) ? 1 : 0;
+        req->data[1] = 0;
+        return usbd_ack;
+    default:
+        break;
+    }
+    return usbd_fail;
+}
+
+/** \brief Processing control request
+ * \param dev pointer to usb device
+ * \param req pointer to usb control request
+ * \return TRUE if request is handled
+ */
+static usbd_respond usbd_process_request(usbd_device *dev, usbd_ctlreq *req) {
+    /* processing control request by callback */
+    if (dev->control_callback) {
+        usbd_respond r = dev->control_callback(dev, req, &(dev->complete_callback));
+        if (r != usbd_fail) return r;
+    }
+    /* continuing standard USB requests */
+    switch (req->bmRequestType & (USB_REQ_TYPE | USB_REQ_RECIPIENT)) {
+    case USB_REQ_STANDARD | USB_REQ_DEVICE:
+        return usbd_process_devrq(dev, req);
+    case USB_REQ_STANDARD | USB_REQ_INTERFACE:
+        return usbd_process_intrq(dev, req);
+    case USB_REQ_STANDARD | USB_REQ_ENDPOINT:
+        return usbd_process_eptrq(dev, req);
+    default:
+        break;
+    }
+    return usbd_fail;
+}
+
+
+/** \brief Control endpoint stall (STALL PID)
+ * \param dev pointer to usb device
+ * \param ep endpoint number
+ */
+static void usbd_stall_pid(usbd_device *dev, uint8_t ep) {
+    dev->driver->ep_setstall(ep & 0x7F, 1);
+    dev->driver->ep_setstall(ep | 0x80, 1);
+    dev->status.control_state = usbd_ctl_idle;
+}
+
+
+/** \brief Control endpoint TX event processing
+ * \param dev pointer to usb device
+ * \param ep endpoint number
+ */
+static void usbd_process_eptx(usbd_device *dev, uint8_t ep) {
+    uint16_t _t;
+    switch (dev->status.control_state) {
+    case usbd_ctl_ztxdata:
+    case usbd_ctl_txdata:
+        _t = _MIN(dev->status.data_count, dev->status.ep0size);
+        dev->driver->ep_write(ep, dev->status.data_ptr, _t);
+        dev->status.data_ptr += _t;
+        dev->status.data_count -= _t;
+        /* if all data is not sent */
+        if (0 != dev->status.data_count) break;
+        /* if last packet has a EP0 size and host awaiting for the more data ZLP should be sent*/
+        /* if ZLP required, control state will be unchanged, therefore next TX event sends ZLP */
+        if ( usbd_ctl_txdata == dev->status.control_state || _t != dev->status.ep0size ) {
+            dev->status.control_state = usbd_ctl_lastdata; /* no ZLP required */
+        }
+        break;
+    case usbd_ctl_lastdata:
+        dev->status.control_state = usbd_ctl_statusout;
+        break;
+    case usbd_ctl_statusin:
+        dev->status.control_state = usbd_ctl_idle;
+        return usbd_process_callback(dev);
+    default:
+        /* unexpected TX completion */
+        /* just skipping it */
+        break;
+    }
+}
+
+/** \brief Control endpoint RX event processing
+ * \param dev pointer to usb device
+ * \param ep endpoint number
+ */
+static void usbd_process_eprx(usbd_device *dev, uint8_t ep) {
+    uint16_t _t;
+    usbd_ctlreq *const req = dev->status.data_buf;
+    switch (dev->status.control_state) {
+    case usbd_ctl_idle:
+        /* read SETUP packet, send STALL_PID if incorrect packet length */
+        if (0x08 !=  dev->driver->ep_read(ep, req, dev->status.data_maxsize)) {
+            return usbd_stall_pid(dev, ep);
+        }
+        dev->status.data_ptr = req->data;
+        dev->status.data_count = req->wLength;
+        /* processing request with no payload data*/
+        if ((req->bmRequestType & USB_REQ_DEVTOHOST) || (0 == req->wLength)) goto do_process_request;
+        /* checking available memory for DATA OUT stage */
+        if (req->wLength > dev->status.data_maxsize) {
+            return usbd_stall_pid(dev, ep);
+        }
+        /* continue DATA OUT stage */
+        dev->status.control_state = usbd_ctl_rxdata;
+        break;
+    case usbd_ctl_rxdata:
+        /*receive DATA OUT packet(s) */
+        _t = dev->driver->ep_read(ep, dev->status.data_ptr, dev->status.data_count);
+        if (dev->status.data_count < _t) {
+        /* if received packet is large than expected */
+        /* Must be error. Let's drop this request */
+            return usbd_stall_pid(dev, ep);
+        } else if (dev->status.data_count != _t) {
+        /* if all data payload was not received yet */
+            dev->status.data_count -= _t;
+            dev->status.data_ptr += _t;
+            break;
+        }
+do_process_request:
+        /* usb request received */
+        /* let's handle it */
+        /* preparing */
+        dev->status.data_ptr = req->data;
+        dev->status.data_count = req->wLength;/*dev->status.data_maxsize;*/
+        switch (usbd_process_request(dev, req)){
+        case usbd_ack:
+            if (req->bmRequestType & USB_REQ_DEVTOHOST) {
+                /* return data from function */
+                if (dev->status.data_count >= req->wLength) {
+                    dev->status.data_count = req->wLength;
+                    dev->status.control_state = usbd_ctl_txdata;
+                } else {
+                    /* DATA IN packet smaller than requested */
+                    /* ZLP maybe wanted */
+                    dev->status.control_state = usbd_ctl_ztxdata;
+                }
+                return usbd_process_eptx(dev, ep | 0x80);
+
+            } else {
+                /* confirming by ZLP in STATUS_IN stage */
+                dev->driver->ep_write(ep | 0x80, 0, 0);
+                dev->status.control_state = usbd_ctl_statusin;
+            }
+            break;
+        case usbd_nak:
+            dev->status.control_state = usbd_ctl_statusin;
+            break;
+        default:
+            return usbd_stall_pid(dev, ep);
+        }
+        break;
+    case usbd_ctl_statusout:
+        /* reading STATUS OUT data to buffer */
+        dev->driver->ep_read(ep, dev->status.data_ptr, dev->status.data_maxsize);
+        dev->status.control_state = usbd_ctl_idle;
+        return usbd_process_callback(dev);
+    default:
+        /* unexpected RX packet */
+        return usbd_stall_pid(dev, ep);
+    }
+}
+
+/** \brief Control endpoint 0 event processing callback
+ * \param dev usb device
+ * \param event endpoint event
+ */
+static void usbd_process_ep0 (usbd_device *dev, uint8_t event, uint8_t ep) {
+    switch (event) {
+    case usbd_evt_epsetup:
+        /* force switch to setup state */
+        dev->status.control_state = usbd_ctl_idle;
+        dev->complete_callback = 0;
+    case usbd_evt_eprx:
+        return usbd_process_eprx(dev, ep);
+    case usbd_evt_eptx:
+        return usbd_process_eptx(dev, ep);
+    default:
+        break;
+    }
+}
+
+
+/** \brief General event processing callback
+ * \param dev usb device
+ * \param evt usb event
+ * \param ep active endpoint
+ */
+static void usbd_process_evt(usbd_device *dev, uint8_t evt, uint8_t ep) {
+    switch (evt) {
+    case usbd_evt_reset:
+        usbd_process_reset(dev);
+        break;
+    case usbd_evt_eprx:
+    case usbd_evt_eptx:
+    case usbd_evt_epsetup:
+        if (dev->endpoint[ep & 0x07]) dev->endpoint[ep & 0x07](dev, evt, ep);
+        break;
+    default:
+        break;
+    }
+    if (dev->events[evt]) dev->events[evt](dev, evt, ep);
+}
+
+void usbd_poll(usbd_device *dev) {
+    return dev->driver->poll(dev, usbd_process_evt);
+}
+
+void usbd_control(usbd_device *dev, enum usbd_commands cmd) {
+    switch (cmd) {
+    case usbd_cmd_enable:
+        dev->driver->enable(true);
+        dev->status.device_state = usbd_state_disconnected;
+        break;
+    case usbd_cmd_disable:
+        dev->driver->enable(false);
+        dev->status.device_state = usbd_state_disabled;
+        break;
+    case usbd_cmd_connect:
+        dev->driver->connect(true);
+        break;
+    case usbd_cmd_disconnect:
+        dev->driver->connect(false);
+        dev->status.device_state = usbd_state_disconnected;
+        break;
+    case usbd_cmd_reset:
+        dev->driver->reset();
+        break;
+    default:
+        break;
+    }
+}

+ 13 - 13
usb.h

@@ -1,16 +1,16 @@
-/* This file is the part of the LUS32 project
- *
- * Copyright ©2016 Dmitry Filimonchuk <dmitrystu[at]gmail[dot]com>
- *
- * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
- * 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.
+/* This file is the part of the LUS32 project
+ *
+ * Copyright ©2016 Dmitry Filimonchuk <dmitrystu[at]gmail[dot]com>
+ *
+ * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
+ * 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.
  */