From 821563417565776d2dc3a02b0265e6fcd5218739 Mon Sep 17 00:00:00 2001 From: tmk Date: Mon, 11 Feb 2013 22:57:40 +0900 Subject: [PATCH] Now includes LUFA-120730 in repository --- .../HID_EEPROM_Loader/HID_EEPROM_Loader.c | 61 + .../LUFA/Build/HID_EEPROM_Loader/makefile | 40 + .../LUFA-120730/LUFA/Build/lufa_atprogram.mk | 101 + .../LUFA-120730/LUFA/Build/lufa_avrdude.mk | 84 + .../lufa/LUFA-120730/LUFA/Build/lufa_build.mk | 296 +++ .../lufa/LUFA-120730/LUFA/Build/lufa_core.mk | 152 ++ .../LUFA-120730/LUFA/Build/lufa_cppcheck.mk | 104 + .../lufa/LUFA-120730/LUFA/Build/lufa_dfu.mk | 93 + .../LUFA-120730/LUFA/Build/lufa_doxygen.mk | 81 + .../lufa/LUFA-120730/LUFA/Build/lufa_hid.mk | 88 + .../LUFA-120730/LUFA/Build/lufa_sources.mk | 116 ++ .../LUFA/CodeTemplates/DriverStubs/Buttons.h | 90 + .../CodeTemplates/DriverStubs/Dataflash.h | 220 ++ .../LUFA/CodeTemplates/DriverStubs/Joystick.h | 102 + .../LUFA/CodeTemplates/DriverStubs/LEDs.h | 130 ++ .../LUFA/CodeTemplates/LUFAConfig.h | 167 ++ .../LUFA/CodeTemplates/makefile_template | 36 + .../LUFA/Common/ArchitectureSpecific.h | 177 ++ .../LUFA-120730/LUFA/Common/Architectures.h | 84 + .../lufa/LUFA-120730/LUFA/Common/Attributes.h | 150 ++ .../lufa/LUFA-120730/LUFA/Common/BoardTypes.h | 231 +++ .../lufa/LUFA-120730/LUFA/Common/Common.h | 381 ++++ .../LUFA/Common/CompilerSpecific.h | 97 + .../lufa/LUFA-120730/LUFA/Common/Endianness.h | 489 +++++ protocol/lufa/LUFA-120730/LUFA/Doxygen.conf | 1809 +++++++++++++++++ .../LUFA/DoxygenPages/BuildSystem.txt | 846 ++++++++ .../BuildingLinkableLibraries.txt | 23 + .../LUFA/DoxygenPages/ChangeLog.txt | 1444 +++++++++++++ .../LUFA/DoxygenPages/CompileTimeTokens.txt | 223 ++ .../LUFA/DoxygenPages/CompilingApps.txt | 50 + .../LUFA/DoxygenPages/ConfiguringApps.txt | 104 + .../LUFA/DoxygenPages/DevelopingWithLUFA.txt | 23 + .../LUFA/DoxygenPages/DeviceSupport.txt | 432 ++++ .../LUFA/DoxygenPages/DirectorySummaries.txt | 80 + .../LUFA/DoxygenPages/Donating.txt | 24 + .../LUFA/DoxygenPages/ExportingLibrary.txt | 106 + .../LUFA/DoxygenPages/FutureChanges.txt | 49 + .../LUFA/DoxygenPages/GettingStarted.txt | 25 + .../LUFA-120730/LUFA/DoxygenPages/Groups.txt | 38 + .../AS5_AS6_Import/AS5_AS6_Import_Step1.png | Bin 0 -> 98201 bytes .../AS5_AS6_Import/AS5_AS6_Import_Step2.png | Bin 0 -> 100532 bytes .../AS5_AS6_Import/AS5_AS6_Import_Step3.png | Bin 0 -> 32987 bytes .../AS5_AS6_Import/AS5_AS6_Import_Step4.png | Bin 0 -> 161824 bytes .../AS5_AS6_Import/AS5_AS6_Import_Step5_1.png | Bin 0 -> 43666 bytes .../AS5_AS6_Import/AS5_AS6_Import_Step5_2.png | Bin 0 -> 28918 bytes .../AS5_AS6_Import/AS5_AS6_Import_Step5_3.png | Bin 0 -> 23561 bytes .../LUFA/DoxygenPages/Images/Author.jpg | Bin 0 -> 28410 bytes .../LUFA/DoxygenPages/Images/LUFA.png | Bin 0 -> 10296 bytes .../LUFA/DoxygenPages/Images/LUFA_thumb.png | Bin 0 -> 3729 bytes .../LUFA/DoxygenPages/KnownIssues.txt | 44 + .../LUFA/DoxygenPages/LUFAPoweredProjects.txt | 181 ++ .../LUFA/DoxygenPages/LibraryResources.txt | 34 + .../LUFA/DoxygenPages/LicenseInfo.txt | 22 + .../LUFA/DoxygenPages/MainPage.txt | 52 + .../DoxygenPages/MigrationInformation.txt | 674 ++++++ .../LUFA/DoxygenPages/ProgrammingApps.txt | 30 + .../DoxygenPages/SoftwareBootloaderJump.txt | 71 + .../LUFA/DoxygenPages/Style/Footer.htm | 35 + .../LUFA/DoxygenPages/Style/Style.css | 1123 ++++++++++ .../LUFA/DoxygenPages/VIDAndPIDValues.txt | 424 ++++ .../LUFA/DoxygenPages/WritingBoardDrivers.txt | 27 + .../LUFA/Drivers/Board/AVR8/ADAFRUITU4/LEDs.h | 135 ++ .../Drivers/Board/AVR8/ATAVRUSBRF01/Buttons.h | 103 + .../Drivers/Board/AVR8/ATAVRUSBRF01/LEDs.h | 139 ++ .../LUFA/Drivers/Board/AVR8/BENITO/Buttons.h | 103 + .../LUFA/Drivers/Board/AVR8/BENITO/LEDs.h | 139 ++ .../LUFA/Drivers/Board/AVR8/BIGMULTIO/LEDs.h | 161 ++ .../LUFA/Drivers/Board/AVR8/BLACKCAT/LEDs.h | 139 ++ .../LUFA/Drivers/Board/AVR8/BUI/LEDs.h | 143 ++ .../LUFA/Drivers/Board/AVR8/BUMBLEB/Buttons.h | 105 + .../Drivers/Board/AVR8/BUMBLEB/Joystick.h | 123 ++ .../LUFA/Drivers/Board/AVR8/BUMBLEB/LEDs.h | 149 ++ .../LUFA/Drivers/Board/AVR8/CULV3/Buttons.h | 103 + .../LUFA/Drivers/Board/AVR8/CULV3/LEDs.h | 135 ++ .../LUFA/Drivers/Board/AVR8/DUCE/LEDs.h | 147 ++ .../LUFA/Drivers/Board/AVR8/EVK527/Buttons.h | 103 + .../Drivers/Board/AVR8/EVK527/Dataflash.h | 220 ++ .../LUFA/Drivers/Board/AVR8/EVK527/Joystick.h | 130 ++ .../LUFA/Drivers/Board/AVR8/EVK527/LEDs.h | 143 ++ .../LUFA/Drivers/Board/AVR8/JMDBU2/Buttons.h | 103 + .../LUFA/Drivers/Board/AVR8/JMDBU2/LEDs.h | 135 ++ .../LUFA/Drivers/Board/AVR8/MAXIMUS/LEDs.h | 139 ++ .../Drivers/Board/AVR8/MICROPENDOUS/Buttons.h | 208 ++ .../Drivers/Board/AVR8/MICROPENDOUS/LEDs.h | 177 ++ .../Drivers/Board/AVR8/MICROSIN162/Buttons.h | 103 + .../Drivers/Board/AVR8/MICROSIN162/LEDs.h | 135 ++ .../LUFA/Drivers/Board/AVR8/MINIMUS/Buttons.h | 103 + .../LUFA/Drivers/Board/AVR8/MINIMUS/LEDs.h | 143 ++ .../LUFA/Drivers/Board/AVR8/MULTIO/LEDs.h | 161 ++ .../Drivers/Board/AVR8/OLIMEX162/Buttons.h | 103 + .../LUFA/Drivers/Board/AVR8/OLIMEX162/LEDs.h | 135 ++ .../Drivers/Board/AVR8/OLIMEX32U4/Buttons.h | 103 + .../LUFA/Drivers/Board/AVR8/OLIMEX32U4/LEDs.h | 179 ++ .../Drivers/Board/AVR8/OLIMEXISPMK2/Buttons.h | 103 + .../Drivers/Board/AVR8/OLIMEXISPMK2/LEDs.h | 143 ++ .../Drivers/Board/AVR8/OLIMEXT32U4/Buttons.h | 103 + .../Drivers/Board/AVR8/OLIMEXT32U4/LEDs.h | 169 ++ .../LUFA/Drivers/Board/AVR8/RZUSBSTICK/LEDs.h | 175 ++ .../Drivers/Board/AVR8/SPARKFUN8U2/LEDs.h | 135 ++ .../LUFA/Drivers/Board/AVR8/STK525/Buttons.h | 103 + .../Drivers/Board/AVR8/STK525/Dataflash.h | 220 ++ .../LUFA/Drivers/Board/AVR8/STK525/Joystick.h | 130 ++ .../LUFA/Drivers/Board/AVR8/STK525/LEDs.h | 147 ++ .../LUFA/Drivers/Board/AVR8/STK526/Buttons.h | 103 + .../Drivers/Board/AVR8/STK526/Dataflash.h | 220 ++ .../LUFA/Drivers/Board/AVR8/STK526/Joystick.h | 123 ++ .../LUFA/Drivers/Board/AVR8/STK526/LEDs.h | 147 ++ .../LUFA/Drivers/Board/AVR8/TEENSY/LEDs.h | 176 ++ .../LUFA/Drivers/Board/AVR8/TUL/Buttons.h | 103 + .../LUFA/Drivers/Board/AVR8/TUL/LEDs.h | 135 ++ .../LUFA/Drivers/Board/AVR8/UDIP/Buttons.h | 103 + .../LUFA/Drivers/Board/AVR8/UDIP/LEDs.h | 163 ++ .../LUFA/Drivers/Board/AVR8/UNO/LEDs.h | 139 ++ .../LUFA/Drivers/Board/AVR8/USB2AX/Buttons.h | 113 + .../LUFA/Drivers/Board/AVR8/USB2AX/LEDs.h | 196 ++ .../LUFA/Drivers/Board/AVR8/USBFOO/Buttons.h | 103 + .../LUFA/Drivers/Board/AVR8/USBFOO/LEDs.h | 135 ++ .../LUFA/Drivers/Board/AVR8/USBKEY/Buttons.h | 103 + .../Drivers/Board/AVR8/USBKEY/Dataflash.h | 229 +++ .../LUFA/Drivers/Board/AVR8/USBKEY/Joystick.h | 130 ++ .../LUFA/Drivers/Board/AVR8/USBKEY/LEDs.h | 147 ++ .../Drivers/Board/AVR8/USBTINYMKII/Buttons.h | 103 + .../Drivers/Board/AVR8/USBTINYMKII/LEDs.h | 143 ++ .../Drivers/Board/AVR8/XPLAIN/Dataflash.h | 243 +++ .../LUFA/Drivers/Board/AVR8/XPLAIN/LEDs.h | 142 ++ .../LUFA-120730/LUFA/Drivers/Board/Buttons.h | 178 ++ .../LUFA/Drivers/Board/Dataflash.h | 252 +++ .../LUFA-120730/LUFA/Drivers/Board/Joystick.h | 144 ++ .../LUFA-120730/LUFA/Drivers/Board/LEDs.h | 274 +++ .../LUFA/Drivers/Board/Temperature.c | 66 + .../LUFA/Drivers/Board/Temperature.h | 147 ++ .../LUFA/Drivers/Board/UC3/EVK1100/Buttons.h | 117 ++ .../LUFA/Drivers/Board/UC3/EVK1100/Joystick.h | 122 ++ .../LUFA/Drivers/Board/UC3/EVK1100/LEDs.h | 173 ++ .../LUFA/Drivers/Board/UC3/EVK1101/Buttons.h | 113 + .../LUFA/Drivers/Board/UC3/EVK1101/Joystick.h | 131 ++ .../LUFA/Drivers/Board/UC3/EVK1101/LEDs.h | 156 ++ .../LUFA/Drivers/Board/UC3/EVK1104/Buttons.h | 109 + .../LUFA/Drivers/Board/UC3/EVK1104/LEDs.h | 174 ++ .../Board/XMEGA/A3BU_XPLAINED/Buttons.h | 119 ++ .../Board/XMEGA/A3BU_XPLAINED/Dataflash.h | 222 ++ .../Drivers/Board/XMEGA/A3BU_XPLAINED/LEDs.h | 144 ++ .../Drivers/Board/XMEGA/B1_XPLAINED/Buttons.h | 119 ++ .../Board/XMEGA/B1_XPLAINED/Dataflash.h | 224 ++ .../Drivers/Board/XMEGA/B1_XPLAINED/LEDs.h | 182 ++ .../LUFA/Drivers/Misc/AT45DB321C.h | 100 + .../LUFA/Drivers/Misc/AT45DB642D.h | 116 ++ .../LUFA/Drivers/Misc/RingBuffer.h | 303 +++ .../LUFA/Drivers/Misc/TerminalCodes.h | 231 +++ .../LUFA-120730/LUFA/Drivers/Peripheral/ADC.h | 75 + .../LUFA/Drivers/Peripheral/AVR8/ADC_AVR8.h | 456 +++++ .../LUFA/Drivers/Peripheral/AVR8/SPI_AVR8.h | 256 +++ .../Drivers/Peripheral/AVR8/SerialSPI_AVR8.h | 200 ++ .../Drivers/Peripheral/AVR8/Serial_AVR8.c | 119 ++ .../Drivers/Peripheral/AVR8/Serial_AVR8.h | 239 +++ .../LUFA/Drivers/Peripheral/AVR8/TWI_AVR8.c | 207 ++ .../LUFA/Drivers/Peripheral/AVR8/TWI_AVR8.h | 304 +++ .../LUFA-120730/LUFA/Drivers/Peripheral/SPI.h | 76 + .../LUFA/Drivers/Peripheral/Serial.h | 76 + .../LUFA/Drivers/Peripheral/SerialSPI.h | 76 + .../LUFA-120730/LUFA/Drivers/Peripheral/TWI.h | 74 + .../LUFA/Drivers/Peripheral/XMEGA/SPI_XMEGA.h | 248 +++ .../Peripheral/XMEGA/SerialSPI_XMEGA.h | 203 ++ .../Drivers/Peripheral/XMEGA/Serial_XMEGA.c | 122 ++ .../Drivers/Peripheral/XMEGA/Serial_XMEGA.h | 252 +++ .../Drivers/USB/Class/AndroidAccessoryClass.h | 76 + .../LUFA/Drivers/USB/Class/AudioClass.h | 80 + .../LUFA/Drivers/USB/Class/CDCClass.h | 80 + .../Common/AndroidAccessoryClassCommon.h | 128 ++ .../USB/Class/Common/AudioClassCommon.h | 774 +++++++ .../Drivers/USB/Class/Common/CDCClassCommon.h | 386 ++++ .../Drivers/USB/Class/Common/HIDClassCommon.h | 655 ++++++ .../LUFA/Drivers/USB/Class/Common/HIDParser.c | 363 ++++ .../LUFA/Drivers/USB/Class/Common/HIDParser.h | 364 ++++ .../Drivers/USB/Class/Common/HIDReportData.h | 126 ++ .../USB/Class/Common/MIDIClassCommon.h | 320 +++ .../USB/Class/Common/MassStorageClassCommon.h | 365 ++++ .../USB/Class/Common/PrinterClassCommon.h | 119 ++ .../USB/Class/Common/RNDISClassCommon.h | 414 ++++ .../USB/Class/Common/StillImageClassCommon.h | 161 ++ .../USB/Class/Device/AudioClassDevice.c | 198 ++ .../USB/Class/Device/AudioClassDevice.h | 396 ++++ .../Drivers/USB/Class/Device/CDCClassDevice.c | 339 +++ .../Drivers/USB/Class/Device/CDCClassDevice.h | 352 ++++ .../Drivers/USB/Class/Device/HIDClassDevice.c | 200 ++ .../Drivers/USB/Class/Device/HIDClassDevice.h | 210 ++ .../USB/Class/Device/MIDIClassDevice.c | 125 ++ .../USB/Class/Device/MIDIClassDevice.h | 175 ++ .../USB/Class/Device/MassStorageClassDevice.c | 215 ++ .../USB/Class/Device/MassStorageClassDevice.h | 161 ++ .../USB/Class/Device/RNDISClassDevice.c | 502 +++++ .../USB/Class/Device/RNDISClassDevice.h | 203 ++ .../LUFA/Drivers/USB/Class/HIDClass.h | 81 + .../Class/Host/AndroidAccessoryClassHost.c | 422 ++++ .../Class/Host/AndroidAccessoryClassHost.h | 314 +++ .../Drivers/USB/Class/Host/AudioClassHost.c | 223 ++ .../Drivers/USB/Class/Host/AudioClassHost.h | 411 ++++ .../Drivers/USB/Class/Host/CDCClassHost.c | 478 +++++ .../Drivers/USB/Class/Host/CDCClassHost.h | 351 ++++ .../Drivers/USB/Class/Host/HIDClassHost.c | 396 ++++ .../Drivers/USB/Class/Host/HIDClassHost.h | 313 +++ .../Drivers/USB/Class/Host/MIDIClassHost.c | 231 +++ .../Drivers/USB/Class/Host/MIDIClassHost.h | 190 ++ .../USB/Class/Host/MassStorageClassHost.c | 579 ++++++ .../USB/Class/Host/MassStorageClassHost.h | 335 +++ .../Drivers/USB/Class/Host/PrinterClassHost.c | 400 ++++ .../Drivers/USB/Class/Host/PrinterClassHost.h | 285 +++ .../Drivers/USB/Class/Host/RNDISClassHost.c | 476 +++++ .../Drivers/USB/Class/Host/RNDISClassHost.h | 270 +++ .../USB/Class/Host/StillImageClassHost.c | 436 ++++ .../USB/Class/Host/StillImageClassHost.h | 317 +++ .../LUFA/Drivers/USB/Class/MIDIClass.h | 83 + .../LUFA/Drivers/USB/Class/MassStorageClass.h | 80 + .../LUFA/Drivers/USB/Class/PrinterClass.h | 77 + .../LUFA/Drivers/USB/Class/RNDISClass.h | 80 + .../LUFA/Drivers/USB/Class/StillImageClass.h | 75 + .../LUFA/Drivers/USB/Core/AVR8/Device_AVR8.c | 57 + .../LUFA/Drivers/USB/Core/AVR8/Device_AVR8.h | 264 +++ .../USB/Core/AVR8/EndpointStream_AVR8.c | 275 +++ .../USB/Core/AVR8/EndpointStream_AVR8.h | 648 ++++++ .../Drivers/USB/Core/AVR8/Endpoint_AVR8.c | 201 ++ .../Drivers/USB/Core/AVR8/Endpoint_AVR8.h | 819 ++++++++ .../LUFA/Drivers/USB/Core/AVR8/Host_AVR8.c | 294 +++ .../LUFA/Drivers/USB/Core/AVR8/Host_AVR8.h | 372 ++++ .../LUFA/Drivers/USB/Core/AVR8/OTG_AVR8.h | 159 ++ .../Drivers/USB/Core/AVR8/PipeStream_AVR8.c | 221 ++ .../Drivers/USB/Core/AVR8/PipeStream_AVR8.h | 442 ++++ .../LUFA/Drivers/USB/Core/AVR8/Pipe_AVR8.c | 210 ++ .../LUFA/Drivers/USB/Core/AVR8/Pipe_AVR8.h | 921 +++++++++ .../Template/Template_Endpoint_Control_R.c | 85 + .../Template/Template_Endpoint_Control_W.c | 94 + .../Core/AVR8/Template/Template_Endpoint_RW.c | 90 + .../USB/Core/AVR8/Template/Template_Pipe_RW.c | 89 + .../USB/Core/AVR8/USBController_AVR8.c | 265 +++ .../USB/Core/AVR8/USBController_AVR8.h | 436 ++++ .../Drivers/USB/Core/AVR8/USBInterrupt_AVR8.c | 279 +++ .../Drivers/USB/Core/AVR8/USBInterrupt_AVR8.h | 369 ++++ .../LUFA/Drivers/USB/Core/ConfigDescriptors.c | 146 ++ .../LUFA/Drivers/USB/Core/ConfigDescriptors.h | 286 +++ .../LUFA/Drivers/USB/Core/Device.h | 159 ++ .../LUFA/Drivers/USB/Core/DeviceStandardReq.c | 378 ++++ .../LUFA/Drivers/USB/Core/DeviceStandardReq.h | 158 ++ .../LUFA/Drivers/USB/Core/Endpoint.h | 130 ++ .../LUFA/Drivers/USB/Core/EndpointStream.h | 124 ++ .../LUFA/Drivers/USB/Core/Events.c | 40 + .../LUFA/Drivers/USB/Core/Events.h | 366 ++++ .../LUFA-120730/LUFA/Drivers/USB/Core/Host.h | 139 ++ .../LUFA/Drivers/USB/Core/HostStandardReq.c | 322 +++ .../LUFA/Drivers/USB/Core/HostStandardReq.h | 292 +++ .../LUFA-120730/LUFA/Drivers/USB/Core/OTG.h | 80 + .../LUFA-120730/LUFA/Drivers/USB/Core/Pipe.h | 144 ++ .../LUFA/Drivers/USB/Core/PipeStream.h | 100 + .../LUFA/Drivers/USB/Core/StdDescriptors.h | 739 +++++++ .../LUFA/Drivers/USB/Core/StdRequestType.h | 258 +++ .../LUFA/Drivers/USB/Core/UC3/Device_UC3.c | 51 + .../LUFA/Drivers/USB/Core/UC3/Device_UC3.h | 260 +++ .../Drivers/USB/Core/UC3/EndpointStream_UC3.c | 235 +++ .../Drivers/USB/Core/UC3/EndpointStream_UC3.h | 434 ++++ .../LUFA/Drivers/USB/Core/UC3/Endpoint_UC3.c | 196 ++ .../LUFA/Drivers/USB/Core/UC3/Endpoint_UC3.h | 795 ++++++++ .../LUFA/Drivers/USB/Core/UC3/Host_UC3.c | 294 +++ .../LUFA/Drivers/USB/Core/UC3/Host_UC3.h | 363 ++++ .../Drivers/USB/Core/UC3/PipeStream_UC3.c | 166 ++ .../Drivers/USB/Core/UC3/PipeStream_UC3.h | 352 ++++ .../LUFA/Drivers/USB/Core/UC3/Pipe_UC3.c | 209 ++ .../LUFA/Drivers/USB/Core/UC3/Pipe_UC3.h | 924 +++++++++ .../Template/Template_Endpoint_Control_R.c | 85 + .../Template/Template_Endpoint_Control_W.c | 94 + .../Core/UC3/Template/Template_Endpoint_RW.c | 90 + .../USB/Core/UC3/Template/Template_Pipe_RW.c | 89 + .../Drivers/USB/Core/UC3/USBController_UC3.c | 222 ++ .../Drivers/USB/Core/UC3/USBController_UC3.h | 365 ++++ .../Drivers/USB/Core/UC3/USBInterrupt_UC3.c | 228 +++ .../Drivers/USB/Core/UC3/USBInterrupt_UC3.h | 370 ++++ .../LUFA/Drivers/USB/Core/USBController.h | 151 ++ .../LUFA/Drivers/USB/Core/USBInterrupt.h | 73 + .../LUFA/Drivers/USB/Core/USBMode.h | 286 +++ .../LUFA/Drivers/USB/Core/USBTask.c | 91 + .../LUFA/Drivers/USB/Core/USBTask.h | 204 ++ .../Drivers/USB/Core/XMEGA/Device_XMEGA.c | 49 + .../Drivers/USB/Core/XMEGA/Device_XMEGA.h | 258 +++ .../USB/Core/XMEGA/EndpointStream_XMEGA.c | 275 +++ .../USB/Core/XMEGA/EndpointStream_XMEGA.h | 648 ++++++ .../Drivers/USB/Core/XMEGA/Endpoint_XMEGA.c | 168 ++ .../Drivers/USB/Core/XMEGA/Endpoint_XMEGA.h | 777 +++++++ .../LUFA/Drivers/USB/Core/XMEGA/Host_XMEGA.c | 41 + .../Drivers/USB/Core/XMEGA/PipeStream_XMEGA.c | 41 + .../LUFA/Drivers/USB/Core/XMEGA/Pipe_XMEGA.c | 37 + .../Template/Template_Endpoint_Control_R.c | 87 + .../Template/Template_Endpoint_Control_W.c | 96 + .../XMEGA/Template/Template_Endpoint_RW.c | 90 + .../USB/Core/XMEGA/USBController_XMEGA.c | 189 ++ .../USB/Core/XMEGA/USBController_XMEGA.h | 313 +++ .../USB/Core/XMEGA/USBInterrupt_XMEGA.c | 106 + .../USB/Core/XMEGA/USBInterrupt_XMEGA.h | 166 ++ .../lufa/LUFA-120730/LUFA/Drivers/USB/USB.h | 418 ++++ protocol/lufa/LUFA-120730/LUFA/License.txt | 24 + .../lufa/LUFA-120730/LUFA/Platform/Platform.h | 80 + .../LUFA/Platform/UC3/ClockManagement.h | 338 +++ .../LUFA-120730/LUFA/Platform/UC3/Exception.S | 128 ++ .../LUFA/Platform/UC3/InterruptManagement.c | 68 + .../LUFA/Platform/UC3/InterruptManagement.h | 163 ++ .../LUFA/Platform/XMEGA/ClockManagement.h | 397 ++++ protocol/lufa/LUFA-120730/LUFA/Version.h | 52 + protocol/lufa/LUFA-120730/LUFA/makefile | 50 + protocol/lufa/LUFA-120730/README.txt | 56 + 306 files changed, 64019 insertions(+) create mode 100644 protocol/lufa/LUFA-120730/LUFA/Build/HID_EEPROM_Loader/HID_EEPROM_Loader.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Build/HID_EEPROM_Loader/makefile create mode 100644 protocol/lufa/LUFA-120730/LUFA/Build/lufa_atprogram.mk create mode 100644 protocol/lufa/LUFA-120730/LUFA/Build/lufa_avrdude.mk create mode 100644 protocol/lufa/LUFA-120730/LUFA/Build/lufa_build.mk create mode 100644 protocol/lufa/LUFA-120730/LUFA/Build/lufa_core.mk create mode 100644 protocol/lufa/LUFA-120730/LUFA/Build/lufa_cppcheck.mk create mode 100644 protocol/lufa/LUFA-120730/LUFA/Build/lufa_dfu.mk create mode 100644 protocol/lufa/LUFA-120730/LUFA/Build/lufa_doxygen.mk create mode 100644 protocol/lufa/LUFA-120730/LUFA/Build/lufa_hid.mk create mode 100644 protocol/lufa/LUFA-120730/LUFA/Build/lufa_sources.mk create mode 100644 protocol/lufa/LUFA-120730/LUFA/CodeTemplates/DriverStubs/Buttons.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/CodeTemplates/DriverStubs/Dataflash.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/CodeTemplates/DriverStubs/Joystick.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/CodeTemplates/DriverStubs/LEDs.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/CodeTemplates/LUFAConfig.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/CodeTemplates/makefile_template create mode 100644 protocol/lufa/LUFA-120730/LUFA/Common/ArchitectureSpecific.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Common/Architectures.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Common/Attributes.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Common/BoardTypes.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Common/Common.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Common/CompilerSpecific.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Common/Endianness.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Doxygen.conf create mode 100644 protocol/lufa/LUFA-120730/LUFA/DoxygenPages/BuildSystem.txt create mode 100644 protocol/lufa/LUFA-120730/LUFA/DoxygenPages/BuildingLinkableLibraries.txt create mode 100644 protocol/lufa/LUFA-120730/LUFA/DoxygenPages/ChangeLog.txt create mode 100644 protocol/lufa/LUFA-120730/LUFA/DoxygenPages/CompileTimeTokens.txt create mode 100644 protocol/lufa/LUFA-120730/LUFA/DoxygenPages/CompilingApps.txt create mode 100644 protocol/lufa/LUFA-120730/LUFA/DoxygenPages/ConfiguringApps.txt create mode 100644 protocol/lufa/LUFA-120730/LUFA/DoxygenPages/DevelopingWithLUFA.txt create mode 100644 protocol/lufa/LUFA-120730/LUFA/DoxygenPages/DeviceSupport.txt create mode 100644 protocol/lufa/LUFA-120730/LUFA/DoxygenPages/DirectorySummaries.txt create mode 100644 protocol/lufa/LUFA-120730/LUFA/DoxygenPages/Donating.txt create mode 100644 protocol/lufa/LUFA-120730/LUFA/DoxygenPages/ExportingLibrary.txt create mode 100644 protocol/lufa/LUFA-120730/LUFA/DoxygenPages/FutureChanges.txt create mode 100644 protocol/lufa/LUFA-120730/LUFA/DoxygenPages/GettingStarted.txt create mode 100644 protocol/lufa/LUFA-120730/LUFA/DoxygenPages/Groups.txt create mode 100644 protocol/lufa/LUFA-120730/LUFA/DoxygenPages/Images/AS5_AS6_Import/AS5_AS6_Import_Step1.png create mode 100644 protocol/lufa/LUFA-120730/LUFA/DoxygenPages/Images/AS5_AS6_Import/AS5_AS6_Import_Step2.png create mode 100644 protocol/lufa/LUFA-120730/LUFA/DoxygenPages/Images/AS5_AS6_Import/AS5_AS6_Import_Step3.png create mode 100644 protocol/lufa/LUFA-120730/LUFA/DoxygenPages/Images/AS5_AS6_Import/AS5_AS6_Import_Step4.png create mode 100644 protocol/lufa/LUFA-120730/LUFA/DoxygenPages/Images/AS5_AS6_Import/AS5_AS6_Import_Step5_1.png create mode 100644 protocol/lufa/LUFA-120730/LUFA/DoxygenPages/Images/AS5_AS6_Import/AS5_AS6_Import_Step5_2.png create mode 100644 protocol/lufa/LUFA-120730/LUFA/DoxygenPages/Images/AS5_AS6_Import/AS5_AS6_Import_Step5_3.png create mode 100644 protocol/lufa/LUFA-120730/LUFA/DoxygenPages/Images/Author.jpg create mode 100644 protocol/lufa/LUFA-120730/LUFA/DoxygenPages/Images/LUFA.png create mode 100644 protocol/lufa/LUFA-120730/LUFA/DoxygenPages/Images/LUFA_thumb.png create mode 100644 protocol/lufa/LUFA-120730/LUFA/DoxygenPages/KnownIssues.txt create mode 100644 protocol/lufa/LUFA-120730/LUFA/DoxygenPages/LUFAPoweredProjects.txt create mode 100644 protocol/lufa/LUFA-120730/LUFA/DoxygenPages/LibraryResources.txt create mode 100644 protocol/lufa/LUFA-120730/LUFA/DoxygenPages/LicenseInfo.txt create mode 100644 protocol/lufa/LUFA-120730/LUFA/DoxygenPages/MainPage.txt create mode 100644 protocol/lufa/LUFA-120730/LUFA/DoxygenPages/MigrationInformation.txt create mode 100644 protocol/lufa/LUFA-120730/LUFA/DoxygenPages/ProgrammingApps.txt create mode 100644 protocol/lufa/LUFA-120730/LUFA/DoxygenPages/SoftwareBootloaderJump.txt create mode 100644 protocol/lufa/LUFA-120730/LUFA/DoxygenPages/Style/Footer.htm create mode 100644 protocol/lufa/LUFA-120730/LUFA/DoxygenPages/Style/Style.css create mode 100644 protocol/lufa/LUFA-120730/LUFA/DoxygenPages/VIDAndPIDValues.txt create mode 100644 protocol/lufa/LUFA-120730/LUFA/DoxygenPages/WritingBoardDrivers.txt create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/ADAFRUITU4/LEDs.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/ATAVRUSBRF01/Buttons.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/ATAVRUSBRF01/LEDs.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/BENITO/Buttons.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/BENITO/LEDs.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/BIGMULTIO/LEDs.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/BLACKCAT/LEDs.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/BUI/LEDs.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/BUMBLEB/Buttons.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/BUMBLEB/Joystick.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/BUMBLEB/LEDs.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/CULV3/Buttons.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/CULV3/LEDs.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/DUCE/LEDs.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/EVK527/Buttons.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/EVK527/Dataflash.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/EVK527/Joystick.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/EVK527/LEDs.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/JMDBU2/Buttons.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/JMDBU2/LEDs.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/MAXIMUS/LEDs.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/MICROPENDOUS/Buttons.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/MICROPENDOUS/LEDs.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/MICROSIN162/Buttons.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/MICROSIN162/LEDs.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/MINIMUS/Buttons.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/MINIMUS/LEDs.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/MULTIO/LEDs.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/OLIMEX162/Buttons.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/OLIMEX162/LEDs.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/OLIMEX32U4/Buttons.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/OLIMEX32U4/LEDs.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/OLIMEXISPMK2/Buttons.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/OLIMEXISPMK2/LEDs.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/OLIMEXT32U4/Buttons.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/OLIMEXT32U4/LEDs.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/RZUSBSTICK/LEDs.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/SPARKFUN8U2/LEDs.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/STK525/Buttons.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/STK525/Dataflash.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/STK525/Joystick.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/STK525/LEDs.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/STK526/Buttons.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/STK526/Dataflash.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/STK526/Joystick.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/STK526/LEDs.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/TEENSY/LEDs.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/TUL/Buttons.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/TUL/LEDs.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/UDIP/Buttons.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/UDIP/LEDs.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/UNO/LEDs.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/USB2AX/Buttons.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/USB2AX/LEDs.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/USBFOO/Buttons.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/USBFOO/LEDs.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/USBKEY/Buttons.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/USBKEY/Dataflash.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/USBKEY/Joystick.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/USBKEY/LEDs.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/USBTINYMKII/Buttons.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/USBTINYMKII/LEDs.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/XPLAIN/Dataflash.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/XPLAIN/LEDs.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/Buttons.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/Dataflash.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/Joystick.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/LEDs.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/Temperature.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/Temperature.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/UC3/EVK1100/Buttons.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/UC3/EVK1100/Joystick.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/UC3/EVK1100/LEDs.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/UC3/EVK1101/Buttons.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/UC3/EVK1101/Joystick.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/UC3/EVK1101/LEDs.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/UC3/EVK1104/Buttons.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/UC3/EVK1104/LEDs.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/XMEGA/A3BU_XPLAINED/Buttons.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/XMEGA/A3BU_XPLAINED/Dataflash.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/XMEGA/A3BU_XPLAINED/LEDs.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/XMEGA/B1_XPLAINED/Buttons.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/XMEGA/B1_XPLAINED/Dataflash.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Board/XMEGA/B1_XPLAINED/LEDs.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Misc/AT45DB321C.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Misc/AT45DB642D.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Misc/RingBuffer.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Misc/TerminalCodes.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/ADC.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/AVR8/ADC_AVR8.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/AVR8/SPI_AVR8.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/AVR8/SerialSPI_AVR8.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/AVR8/Serial_AVR8.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/AVR8/Serial_AVR8.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/AVR8/TWI_AVR8.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/AVR8/TWI_AVR8.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/SPI.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/Serial.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/SerialSPI.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/TWI.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/XMEGA/SPI_XMEGA.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/XMEGA/SerialSPI_XMEGA.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/XMEGA/Serial_XMEGA.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/XMEGA/Serial_XMEGA.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/AndroidAccessoryClass.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/AudioClass.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/CDCClass.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Common/AndroidAccessoryClassCommon.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Common/AudioClassCommon.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Common/CDCClassCommon.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Common/HIDClassCommon.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Common/HIDParser.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Common/HIDParser.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Common/HIDReportData.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Common/MIDIClassCommon.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Common/MassStorageClassCommon.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Common/PrinterClassCommon.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Common/RNDISClassCommon.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Common/StillImageClassCommon.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Device/AudioClassDevice.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Device/AudioClassDevice.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Device/CDCClassDevice.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Device/CDCClassDevice.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Device/HIDClassDevice.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Device/HIDClassDevice.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Device/MIDIClassDevice.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Device/MIDIClassDevice.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Device/MassStorageClassDevice.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Device/MassStorageClassDevice.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Device/RNDISClassDevice.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Device/RNDISClassDevice.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/HIDClass.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/AndroidAccessoryClassHost.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/AndroidAccessoryClassHost.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/AudioClassHost.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/AudioClassHost.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/CDCClassHost.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/CDCClassHost.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/HIDClassHost.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/HIDClassHost.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/MIDIClassHost.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/MIDIClassHost.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/MassStorageClassHost.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/MassStorageClassHost.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/PrinterClassHost.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/PrinterClassHost.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/RNDISClassHost.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/RNDISClassHost.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/StillImageClassHost.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/StillImageClassHost.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/MIDIClass.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/MassStorageClass.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/PrinterClass.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/RNDISClass.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/StillImageClass.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/Device_AVR8.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/Device_AVR8.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/EndpointStream_AVR8.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/EndpointStream_AVR8.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/Endpoint_AVR8.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/Endpoint_AVR8.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/Host_AVR8.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/Host_AVR8.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/OTG_AVR8.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/PipeStream_AVR8.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/PipeStream_AVR8.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/Pipe_AVR8.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/Pipe_AVR8.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/Template/Template_Endpoint_Control_R.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/Template/Template_Endpoint_Control_W.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/Template/Template_Endpoint_RW.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/Template/Template_Pipe_RW.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/USBController_AVR8.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/USBController_AVR8.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/USBInterrupt_AVR8.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/USBInterrupt_AVR8.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/ConfigDescriptors.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/ConfigDescriptors.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/Device.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/DeviceStandardReq.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/DeviceStandardReq.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/Endpoint.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/EndpointStream.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/Events.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/Events.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/Host.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/HostStandardReq.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/HostStandardReq.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/OTG.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/Pipe.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/PipeStream.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/StdDescriptors.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/StdRequestType.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/Device_UC3.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/Device_UC3.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/EndpointStream_UC3.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/EndpointStream_UC3.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/Endpoint_UC3.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/Endpoint_UC3.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/Host_UC3.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/Host_UC3.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/PipeStream_UC3.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/PipeStream_UC3.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/Pipe_UC3.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/Pipe_UC3.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/Template/Template_Endpoint_Control_R.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/Template/Template_Endpoint_Control_W.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/Template/Template_Endpoint_RW.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/Template/Template_Pipe_RW.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/USBController_UC3.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/USBController_UC3.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/USBInterrupt_UC3.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/USBInterrupt_UC3.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/USBController.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/USBInterrupt.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/USBMode.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/USBTask.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/USBTask.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/Device_XMEGA.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/Device_XMEGA.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/EndpointStream_XMEGA.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/EndpointStream_XMEGA.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/Host_XMEGA.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/PipeStream_XMEGA.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/Pipe_XMEGA.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/Template/Template_Endpoint_Control_R.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/Template/Template_Endpoint_Control_W.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/Template/Template_Endpoint_RW.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/USBController_XMEGA.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/USBController_XMEGA.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/USBInterrupt_XMEGA.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/USBInterrupt_XMEGA.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Drivers/USB/USB.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/License.txt create mode 100644 protocol/lufa/LUFA-120730/LUFA/Platform/Platform.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Platform/UC3/ClockManagement.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Platform/UC3/Exception.S create mode 100644 protocol/lufa/LUFA-120730/LUFA/Platform/UC3/InterruptManagement.c create mode 100644 protocol/lufa/LUFA-120730/LUFA/Platform/UC3/InterruptManagement.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Platform/XMEGA/ClockManagement.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/Version.h create mode 100644 protocol/lufa/LUFA-120730/LUFA/makefile create mode 100644 protocol/lufa/LUFA-120730/README.txt diff --git a/protocol/lufa/LUFA-120730/LUFA/Build/HID_EEPROM_Loader/HID_EEPROM_Loader.c b/protocol/lufa/LUFA-120730/LUFA/Build/HID_EEPROM_Loader/HID_EEPROM_Loader.c new file mode 100644 index 00000000..600469fa --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Build/HID_EEPROM_Loader/HID_EEPROM_Loader.c @@ -0,0 +1,61 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * + * Special application to extract an EEPROM image stored in FLASH memory, and + * copy it to the device EEPROM. This application is designed to be used with + * the HID build system module of LUFA to program the EEPROM of a target device + * that uses the HID bootloader protocol, which does not have native EEPROM + * programming support. + */ + +#include +#include +#include + +/* References to the binary EEPROM data linked in the AVR's FLASH memory space */ +extern const char _binary_InputEEData_bin_start[]; +extern const char _binary_InputEEData_bin_end[]; +extern const char _binary_InputEEData_bin_size[]; + +/* Friendly names for the embedded binary data stored in FLASH memory space */ +#define InputEEData _binary_InputEEData_bin_start +#define InputEEData_size ((int)_binary_InputEEData_bin_size) + +int main(void) +{ + /* Copy out the embedded EEPROM data from FLASH to EEPROM memory space */ + for (uint16_t i = 0; i < InputEEData_size; i++) + eeprom_update_byte((uint8_t*)i, pgm_read_byte(&InputEEData[i])); + + /* Infinite loop once complete */ + for (;;); +} diff --git a/protocol/lufa/LUFA-120730/LUFA/Build/HID_EEPROM_Loader/makefile b/protocol/lufa/LUFA-120730/LUFA/Build/HID_EEPROM_Loader/makefile new file mode 100644 index 00000000..f6dcbea6 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Build/HID_EEPROM_Loader/makefile @@ -0,0 +1,40 @@ +# +# LUFA Library +# Copyright (C) Dean Camera, 2012. +# +# dean [at] fourwalledcubicle [dot] com +# www.lufa-lib.org +# +# -------------------------------------- +# LUFA Project Makefile. +# -------------------------------------- + +MCU = at90usb1287 +ARCH = AVR8 +F_CPU = 1000000 +F_USB = $(F_CPU) +OPTIMIZATION = s +TARGET = HID_EEPROM_Loader +SRC = $(TARGET).c +LUFA_PATH = ../../../LUFA +CC_FLAGS = +LD_FLAGS = +OBJECT_FILES = InputEEData.o + +# Default target +all: + +# Determine the AVR sub-architecture of the build main application object file +FIND_AVR_SUBARCH = avr$(shell avr-objdump -f $(TARGET).o | grep architecture | cut -d':' -f3 | cut -d',' -f1) + +# Create a linkable object file with the input binary EEPROM data stored in the FLASH section +InputEEData.o: InputEEData.bin $(TARGET).o $(MAKEFILE_LIST) + @echo $(MSG_OBJCPY_CMD) Converting \"$<\" to a object file \"$@\" + avr-objcopy -I binary -O elf32-avr -B $(call FIND_AVR_SUBARCH) --rename-section .data=.progmem.data,contents,alloc,readonly,data $< $@ + +# Include LUFA build script makefiles +include $(LUFA_PATH)/Build/lufa_core.mk +include $(LUFA_PATH)/Build/lufa_build.mk +include $(LUFA_PATH)/Build/lufa_cppcheck.mk +include $(LUFA_PATH)/Build/lufa_doxygen.mk +include $(LUFA_PATH)/Build/lufa_hid.mk diff --git a/protocol/lufa/LUFA-120730/LUFA/Build/lufa_atprogram.mk b/protocol/lufa/LUFA-120730/LUFA/Build/lufa_atprogram.mk new file mode 100644 index 00000000..4e15e399 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Build/lufa_atprogram.mk @@ -0,0 +1,101 @@ +# +# LUFA Library +# Copyright (C) Dean Camera, 2012. +# +# dean [at] fourwalledcubicle [dot] com +# www.lufa-lib.org +# + +LUFA_BUILD_MODULES += ATPROGRAM +LUFA_BUILD_TARGETS += atprogram atprogram-ee +LUFA_BUILD_MANDATORY_VARS += MCU TARGET +LUFA_BUILD_OPTIONAL_VARS += ATPROGRAM_PROGRAMMER ATPROGRAM_INTERFACE ATPROGRAM_PORT +LUFA_BUILD_PROVIDED_VARS += +LUFA_BUILD_PROVIDED_MACROS += + +# ----------------------------------------------------------------------------- +# LUFA ATPROGRAM Programmer Buildsystem Makefile Module. +# ----------------------------------------------------------------------------- +# DESCRIPTION: +# Provides a set of targets to re-program a device using the Atmel atprogram +# utility in AVR Studio 5.x and Atmel Studio 6.0 onwards. +# ----------------------------------------------------------------------------- +# TARGETS: +# +# atprogram - Program target FLASH with application using +# atprogram +# atprogram-ee - Program target EEPROM with application data +# using atprogram +# +# MANDATORY PARAMETERS: +# +# MCU - Microcontroller device model name +# TARGET - Application name +# +# OPTIONAL PARAMETERS: +# +# ATPROGRAM_PROGRAMMER - Name of programming hardware to use +# ATPROGRAM_INTERFACE - Name of programming interface to use +# ATPROGRAM_PORT - Name of communication port to use +# +# PROVIDED VARIABLES: +# +# (None) +# +# PROVIDED MACROS: +# +# (None) +# +# ----------------------------------------------------------------------------- + +SHELL = /bin/sh + +ERROR_IF_UNSET ?= $(if $(filter undefined, $(origin $(strip $(1)))), $(error Makefile $(strip $(1)) value not set)) +ERROR_IF_EMPTY ?= $(if $(strip $($(strip $(1)))), , $(error Makefile $(strip $(1)) option cannot be blank)) +ERROR_IF_NONBOOL ?= $(if $(filter Y N, $($(strip $(1)))), , $(error Makefile $(strip $(1)) option must be Y or N)) + +# Default values of optionally user-supplied variables +ATPROGRAM_PROGRAMMER ?= jtagice3 +ATPROGRAM_INTERFACE ?= jtag +ATPROGRAM_PORT ?= + +# Sanity check user supplied values +$(foreach MANDATORY_VAR, $(LUFA_BUILD_MANDATORY_VARS), $(call ERROR_IF_UNSET, $(MANDATORY_VAR))) +$(call ERROR_IF_EMPTY, MCU) +$(call ERROR_IF_EMPTY, TARGET) +$(call ERROR_IF_EMPTY, ATPROGRAM_PROGRAMMER) +$(call ERROR_IF_EMPTY, ATPROGRAM_INTERFACE) + +# Output Messages +MSG_ATPROGRAM_CMD := ' [ATPRGRM] :' + +# Construct base atprogram command flags +BASE_ATPROGRAM_FLAGS := --tool $(ATPROGRAM_PROGRAMMER) --interface $(ATPROGRAM_INTERFACE) --device $(MCU) +ifneq ($(ATPROGRAM_PORT),) + BASE_ATPROGRAM_FLAGS += --port $(ATPROGRAM_PORT) +endif + +# Construct the flags to use for the various memory spaces +ifeq ($(ARCH), AVR8) + ATPROGRAM_FLASH_FLAGS := --chiperase --flash + ATPROGRAM_EEPROM_FLAGS := --eeprom +else ifeq ($(ARCH), XMEGA) + ATPROGRAM_FLASH_FLAGS := --erase --flash + ATPROGRAM_EEPROM_FLAGS := --eeprom +else ifeq ($(ARCH), UC3) + ATPROGRAM_FLASH_FLAGS := --erase + ATPROGRAM_EEPROM_FLAGS := --eeprom +else + $(error Unsupported architecture "$(ARCH)") +endif + +atprogram: $(TARGET).elf $(MAKEFILE_LIST) + @echo $(MSG_ATPROGRAM_CMD) Programming device \"$(MCU)\" FLASH using \"$(ATPROGRAM_PROGRAMMER)\" + atprogram $(BASE_ATPROGRAM_FLAGS) program $(ATPROGRAM_FLASH_FLAGS) --file $< + +atprogram-ee: $(TARGET).elf $(MAKEFILE_LIST) + @echo $(MSG_ATPROGRAM_CMD) Programming device \"$(MCU)\" EEPROM using \"$(ATPROGRAM_PROGRAMMER)\" + atprogram $(BASE_ATPROGRAM_FLAGS) program $(ATPROGRAM_EEPROM_FLAGS) --file $< + +# Phony build targets for this module +.PHONY: atprogram atprogram-ee diff --git a/protocol/lufa/LUFA-120730/LUFA/Build/lufa_avrdude.mk b/protocol/lufa/LUFA-120730/LUFA/Build/lufa_avrdude.mk new file mode 100644 index 00000000..83936252 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Build/lufa_avrdude.mk @@ -0,0 +1,84 @@ +# +# LUFA Library +# Copyright (C) Dean Camera, 2012. +# +# dean [at] fourwalledcubicle [dot] com +# www.lufa-lib.org +# + +LUFA_BUILD_MODULES += AVRDUDE +LUFA_BUILD_TARGETS += avrdude avrdude-ee +LUFA_BUILD_MANDATORY_VARS += MCU TARGET +LUFA_BUILD_OPTIONAL_VARS += AVRDUDE_PROGRAMMER AVRDUDE_PORT AVRDUDE_FLAGS +LUFA_BUILD_PROVIDED_VARS += +LUFA_BUILD_PROVIDED_MACROS += + +# ----------------------------------------------------------------------------- +# LUFA AVRDUDE Programmer Buildsystem Makefile Module. +# ----------------------------------------------------------------------------- +# DESCRIPTION: +# Provides a set of targets to re-program a device using the open source +# avr-dude utility. +# ----------------------------------------------------------------------------- +# TARGETS: +# +# avrdude - Program target FLASH with application using +# avrdude +# avrdude-ee - Program target EEPROM with application data +# using avrdude +# +# MANDATORY PARAMETERS: +# +# MCU - Microcontroller device model name +# TARGET - Application name +# +# OPTIONAL PARAMETERS: +# +# AVRDUDE_PROGRAMMER - Name of programming hardware to use +# AVRDUDE_PORT - Name of communication port to use +# AVRDUDE_FLAGS - Flags to pass to avr-dude +# +# PROVIDED VARIABLES: +# +# (None) +# +# PROVIDED MACROS: +# +# (None) +# +# ----------------------------------------------------------------------------- + +SHELL = /bin/sh + +ERROR_IF_UNSET ?= $(if $(filter undefined, $(origin $(strip $(1)))), $(error Makefile $(strip $(1)) value not set)) +ERROR_IF_EMPTY ?= $(if $(strip $($(strip $(1)))), , $(error Makefile $(strip $(1)) option cannot be blank)) +ERROR_IF_NONBOOL ?= $(if $(filter Y N, $($(strip $(1)))), , $(error Makefile $(strip $(1)) option must be Y or N)) + +# Default values of optionally user-supplied variables +AVRDUDE_PROGRAMMER ?= jtagicemkii +AVRDUDE_PORT ?= usb +AVRDUDE_FLAGS ?= + +# Sanity check user supplied values +$(foreach MANDATORY_VAR, $(LUFA_BUILD_MANDATORY_VARS), $(call ERROR_IF_UNSET, $(MANDATORY_VAR))) +$(call ERROR_IF_EMPTY, MCU) +$(call ERROR_IF_EMPTY, TARGET) +$(call ERROR_IF_EMPTY, AVRDUDE_PROGRAMMER) +$(call ERROR_IF_EMPTY, AVRDUDE_PORT) + +# Output Messages +MSG_AVRDUDE_CMD := ' [AVRDUDE] :' + +# Construct base avrdude command flags +BASE_AVRDUDE_FLAGS := -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) + +avrdude: $(TARGET).hex $(MAKEFILE_LIST) + @echo $(MSG_AVRDUDE_CMD) Programming device \"$(MCU)\" FLASH with settings \"$(AVRDUDE_FLASH_FLAGS)\" using \"$(AVRDUDE_PROGRAMMER)\" on port \"$(AVRDUDE_PORT)\" + avrdude $(BASE_AVRDUDE_FLAGS) -U flash:w:$< $(AVRDUDE_FLAGS) + +avrdude-ee: $(TARGET).eep $(MAKEFILE_LIST) + @echo $(MSG_AVRDUDE_CMD) Programming device \"$(MCU)\" EEPROM with settings \"$(AVRDUDE_EEP_FLAGS)\" using \"$(AVRDUDE_PROGRAMMER)\" on port \"$(AVRDUDE_PORT)\" + avrdude $(BASE_AVRDUDE_FLAGS) -U eeprom:w:$< $(AVRDUDE_FLAGS) + +# Phony build targets for this module +.PHONY: avrdude avrdude-ee diff --git a/protocol/lufa/LUFA-120730/LUFA/Build/lufa_build.mk b/protocol/lufa/LUFA-120730/LUFA/Build/lufa_build.mk new file mode 100644 index 00000000..87886062 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Build/lufa_build.mk @@ -0,0 +1,296 @@ +# +# LUFA Library +# Copyright (C) Dean Camera, 2012. +# +# dean [at] fourwalledcubicle [dot] com +# www.lufa-lib.org +# + +LUFA_BUILD_MODULES += BUILD +LUFA_BUILD_TARGETS += size check-source symbol-sizes all lib elf hex lss clean mostlyclean +LUFA_BUILD_MANDATORY_VARS += TARGET ARCH MCU SRC F_USB LUFA_PATH +LUFA_BUILD_OPTIONAL_VARS += BOARD OPTIMIZATION C_STANDARD CPP_STANDARD F_CPU C_FLAGS CPP_FLAGS ASM_FLAGS CC_FLAGS LD_FLAGS OBJDIR OBJECT_FILES DEBUG_TYPE DEBUG_LEVEL +LUFA_BUILD_PROVIDED_VARS += +LUFA_BUILD_PROVIDED_MACROS += + +# ----------------------------------------------------------------------------- +# LUFA GCC Compiler Buildsystem Makefile Module. +# ----------------------------------------------------------------------------- +# DESCRIPTION: +# Provides a set of targets to build a C, C++ and/or Assembly application +# via the AVR-GCC compiler. +# ----------------------------------------------------------------------------- +# TARGETS: +# +# size - List built application size +# symbol-sizes - Print application symbols from the binary ELF +# file as a list sorted by size in bytes +# check-source - Print a list of SRC source files that cannot +# be found +# all - Build application and list size +# lib - Build and archive source files into a library +# elf - Build application ELF debug object file +# hex - Build application HEX object files +# lss - Build application LSS assembly listing file +# clean - Remove all project intermediatary and binary +# output files +# mostlyclean - Remove intermediatary output files, but +# preserve binaries +# +# MANDATORY PARAMETERS: +# +# TARGET - Application name +# ARCH - Device architecture name +# MCU - Microcontroller device model name +# SRC - List of input source files (*.c, *.cpp, *.S) +# F_USB - Speed of the input clock of the USB controller +# in Hz +# LUFA_PATH - Path to the LUFA library core +# +# OPTIONAL PARAMETERS: +# +# BOARD - LUFA board hardware +# OPTIMIZATION - Optimization level +# C_STANDARD - C Language Standard to use +# CPP_STANDARD - C++ Language Standard to use +# F_CPU - Speed of the CPU, in Hz +# C_FLAGS - Flags to pass to the C compiler only +# CPP_FLAGS - Flags to pass to the C++ compiler only +# ASM_FLAGS - Flags to pass to the assembler only +# CC_FLAGS - Common flags to pass to the C/C++ compiler and +# assembler +# LD_FLAGS - Flags to pass to the linker +# OBJDIR - Directory for the output object and dependency +# files; if equal to ".", the output files will +# be generated in the same folder as the sources +# OBJECT_FILES - Extra object files to link in to the binaries +# DEBUG_FORMAT - Format of the debugging information to +# generate in the compiled object files +# DEBUG_LEVEL - Level the debugging information to generate in +# the compiled object files +# +# PROVIDED VARIABLES: +# +# (None) +# +# PROVIDED MACROS: +# +# (None) +# +# ----------------------------------------------------------------------------- + +SHELL = /bin/sh + +ERROR_IF_UNSET ?= $(if $(filter undefined, $(origin $(strip $(1)))), $(error Makefile $(strip $(1)) value not set)) +ERROR_IF_EMPTY ?= $(if $(strip $($(strip $(1)))), , $(error Makefile $(strip $(1)) option cannot be blank)) +ERROR_IF_NONBOOL ?= $(if $(filter Y N, $($(strip $(1)))), , $(error Makefile $(strip $(1)) option must be Y or N)) + +# Default values of optionally user-supplied variables +BOARD ?= NONE +OPTIMIZATION ?= s +F_CPU ?= +C_STANDARD ?= gnu99 +CPP_STANDARD ?= gnu++98 +C_FLAGS ?= +CPP_FLAGS ?= +ASM_FLAGS ?= +CC_FLAGS ?= +OBJDIR ?= . +OBJECT_FILES ?= +DEBUG_FORMAT ?= dwarf-2 +DEBUG_LEVEL ?= 3 + +# Sanity check user supplied values +$(foreach MANDATORY_VAR, $(LUFA_BUILD_MANDATORY_VARS), $(call ERROR_IF_UNSET, $(MANDATORY_VAR))) +$(call ERROR_IF_EMPTY, MCU) +$(call ERROR_IF_EMPTY, TARGET) +$(call ERROR_IF_EMPTY, ARCH) +$(call ERROR_IF_EMPTY, F_USB) +$(call ERROR_IF_EMPTY, LUFA_PATH) +$(call ERROR_IF_EMPTY, BOARD) +$(call ERROR_IF_EMPTY, OPTIMIZATION) +$(call ERROR_IF_EMPTY, C_STANDARD) +$(call ERROR_IF_EMPTY, CPP_STANDARD) +$(call ERROR_IF_EMPTY, OBJDIR) +$(call ERROR_IF_EMPTY, DEBUG_FORMAT) +$(call ERROR_IF_EMPTY, DEBUG_LEVEL) + +# Determine the utility prefix to use for the selected architecture +ifeq ($(ARCH), AVR8) + CROSS := avr +else ifeq ($(ARCH), XMEGA) + CROSS := avr + $(warning The XMEGA device support is currently EXPERIMENTAL (incomplete and/or non-functional), and is included for preview purposes only.) +else ifeq ($(ARCH), UC3) + CROSS := avr32 + $(warning The UC3 device support is currently EXPERIMENTAL (incomplete and/or non-functional), and is included for preview purposes only.) +else + $(error Unsupported architecture "$(ARCH)") +endif + +# Output Messages +MSG_COMPILE_CMD := ' [GCC] :' +MSG_ASSEMBLE_CMD := ' [GAS] :' +MSG_NM_CMD := ' [NM] :' +MSG_REMOVE_CMD := ' [RM] :' +MSG_LINK_CMD := ' [LNK] :' +MSG_ARCHIVE_CMD := ' [AR] :' +MSG_SIZE_CMD := ' [SIZE] :' +MSG_OBJCPY_CMD := ' [OBJCPY] :' +MSG_OBJDMP_CMD := ' [OBJDMP] :' + +# Convert input source file list to differentiate them by type +C_SOURCE := $(filter %.c, $(SRC)) +CPP_SOURCE := $(filter %.cpp, $(SRC)) +ASM_SOURCE := $(filter %.S, $(SRC)) + +# Create a list of unknown source file types, if any are found throw an error +UNKNOWN_SOURCE := $(filter-out $(C_SOURCE) $(CPP_SOURCE) $(ASM_SOURCE), $(SRC)) +ifneq ($(UNKNOWN_SOURCE),) + $(error Unknown input source file formats: $(UNKNOWN_SOURCE)) +endif + +# Convert input source filenames into a list of required output object files +OBJECT_FILES += $(addsuffix .o, $(basename $(SRC))) +ifneq ($(OBJDIR),.) + $(shell mkdir $(OBJDIR) 2> /dev/null) + VPATH += $(dir $(SRC)) + OBJECT_FILES := $(addprefix $(patsubst %/,%,$(OBJDIR))/, $(notdir $(OBJECT_FILES))) + + # Check if any object file (without path) appears more than once in the object file list + ifneq ($(words $(sort $(OBJECT_FILES))), $(words $(OBJECT_FILES))) + $(error Cannot build with OBJDIR parameter set - one or more object file name is not unique) + endif +endif + +# Create a list of dependency files from the list of object files +DEPENDENCY_FILES := $(OBJECT_FILES:%.o=%.d) + +# Create a list of common flags to pass to the compiler/linker/assembler +BASE_CC_FLAGS := -pipe -g$(DEBUG_FORMAT) -g$(DEBUG_LEVEL) +ifeq ($(ARCH), AVR8) + BASE_CC_FLAGS += -mmcu=$(MCU) -fshort-enums -fno-inline-small-functions -fpack-struct +else ifeq ($(ARCH), XMEGA) + BASE_CC_FLAGS += -mmcu=$(MCU) -fshort-enums -fno-inline-small-functions -fpack-struct +else ifeq ($(ARCH), UC3) + BASE_CC_FLAGS += -mpart=$(MCU:at32%=%) -masm-addr-pseudos +endif +BASE_CC_FLAGS += -Wall -fno-strict-aliasing -funsigned-char -funsigned-bitfields -ffunction-sections +BASE_CC_FLAGS += -I. -I$(patsubst %/,%,$(LUFA_PATH))/.. +BASE_CC_FLAGS += -DARCH=ARCH_$(ARCH) -DBOARD=BOARD_$(BOARD) -DF_USB=$(F_USB)UL +ifneq ($(F_CPU),) + BASE_CC_FLAGS += -DF_CPU=$(F_CPU)UL +endif + +# Additional language specific compiler flags +BASE_C_FLAGS := -x c -O$(OPTIMIZATION) -std=$(C_STANDARD) -Wstrict-prototypes +BASE_CPP_FLAGS := -x c++ -O$(OPTIMIZATION) -std=$(CPP_STANDARD) +BASE_ASM_FLAGS := -x assembler-with-cpp + +# Create a list of flags to pass to the linker +BASE_LD_FLAGS := -lm -Wl,-Map=$(TARGET).map,--cref -Wl,--gc-sections -Wl,--relax +ifeq ($(ARCH), AVR8) + BASE_LD_FLAGS += -mmcu=$(MCU) +else ifeq ($(ARCH), XMEGA) + BASE_LD_FLAGS += -mmcu=$(MCU) +else ifeq ($(ARCH), UC3) + BASE_LD_FLAGS += -mpart=$(MCU:at32%=%) --rodata-writable --direct-data +endif + +# Determine flags to pass to the size utility based on its reported features (only invoke if size target required) +size: SIZE_MCU_FLAG := $(shell $(CROSS)-size --help | grep -- --mcu > /dev/null && echo --mcu=$(MCU) ) +size: SIZE_FORMAT_FLAG := $(shell $(CROSS)-size --help | grep -- --format=.*avr > /dev/null && echo --format=avr ) + + +build_begin: + @echo "" + @echo Begin compilation of project \"$(TARGET)\"... + @echo "" + +build_end: + @echo Finished building project \"$(TARGET)\". + @echo "" + +gcc-version: + @$(CROSS)-gcc --version + +check-source: + @for f in $(SRC); do \ + if [ ! -f $$f ]; then \ + echo "Error: Source file not found: $$f"; \ + exit 1; \ + fi; \ + done + +size: $(TARGET).elf + @echo $(MSG_SIZE_CMD) Determining size of \"$<\" + @echo "" + $(CROSS)-size $(SIZE_MCU_FLAG) $(SIZE_FORMAT_FLAG) $< ; 2>/dev/null; + +symbol-sizes: $(TARGET).elf + @echo $(MSG_NM_CMD) Extracting \"$<\" symbols with decimal byte sizes + $(CROSS)-nm --size-sort --demangle --radix=d $< + +mostlyclean: + @echo $(MSG_REMOVE_CMD) Removing object files of \"$(TARGET)\" + rm -f $(OBJECT_FILES) + @echo $(MSG_REMOVE_CMD) Removing dependency files of \"$(TARGET)\" + rm -f $(DEPENDENCY_FILES) + +clean: mostlyclean + @echo $(MSG_REMOVE_CMD) Removing output files of \"$(TARGET)\" + rm -f $(TARGET).elf $(TARGET).hex $(TARGET).eep $(TARGET).map $(TARGET).lss $(TARGET).sym $(TARGET).a + +all: build_begin check-source gcc-version elf hex lss sym size build_end + +lib: lib$(TARGET).a +elf: $(TARGET).elf +hex: $(TARGET).hex $(TARGET).eep +lss: $(TARGET).lss +sym: $(TARGET).sym + +$(OBJDIR)/%.o: %.c $(MAKEFILE_LIST) + @echo $(MSG_COMPILE_CMD) Compiling C file \"$(notdir $<)\" + $(CROSS)-gcc -c $(BASE_CC_FLAGS) $(BASE_C_FLAGS) $(CC_FLAGS) $(C_FLAGS) -MMD -MP -MF $(@:%.o=%.d) $< -o $@ + +$(OBJDIR)/%.o: %.cpp $(MAKEFILE_LIST) + @echo $(MSG_COMPILE_CMD) Compiling C++ file \"$(notdir $<)\" + $(CROSS)-gcc -c $(BASE_CC_FLAGS) $(BASE_CPP_FLAGS) $(CC_FLAGS) $(CPP_FLAGS) -MMD -MP -MF $(@:%.o=%.d) $< -o $@ + +$(OBJDIR)/%.o: %.S $(MAKEFILE_LIST) + @echo $(MSG_ASSEMBLE_CMD) Assembling \"$(notdir $<)\" + $(CROSS)-gcc -c $(BASE_CC_FLAGS) $(BASE_ASM_FLAGS) $(CC_FLAGS) $(ASM_FLAGS) -MMD -MP -MF $(@:%.o=%.d) $< -o $@ + +.PRECIOUS : $(OBJECT_FILES) +.SECONDARY : %.a +%.a: $(OBJECT_FILES) + @echo $(MSG_ARCHIVE_CMD) Archiving object files into \"$@\" + $(CROSS)-ar rcs $@ $(OBJECT_FILES) + +.PRECIOUS : $(OBJECT_FILES) +.SECONDARY : %.elf +%.elf: $(OBJECT_FILES) + @echo $(MSG_LINK_CMD) Linking object files into \"$@\" + $(CROSS)-gcc $(BASE_LD_FLAGS) $(LD_FLAGS) $^ -o $@ + +%.hex: %.elf + @echo $(MSG_OBJCPY_CMD) Extracting HEX file data from \"$<\" + $(CROSS)-objcopy -O ihex -R .eeprom -R .fuse -R .lock -R .signature $< $@ + +%.eep: %.elf + @echo $(MSG_OBJCPY_CMD) Extracting EEP file data from \"$<\" + $(CROSS)-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 --no-change-warnings -O ihex $< $@ || exit 0 + +%.lss: %.elf + @echo $(MSG_OBJDMP_CMD) Extracting LSS file data from \"$<\" + $(CROSS)-objdump -h -S -z $< > $@ + +%.sym: %.elf + @echo $(MSG_NM_CMD) Extracting SYM file data from \"$<\" + $(CROSS)-nm -n $< > $@ + +# Include build dependency files +-include $(DEPENDENCY_FILES) + +# Phony build targets for this module +.PHONY: build_begin build_end gcc-version check-source size symbol-sizes lib elf hex lss clean mostlyclean diff --git a/protocol/lufa/LUFA-120730/LUFA/Build/lufa_core.mk b/protocol/lufa/LUFA-120730/LUFA/Build/lufa_core.mk new file mode 100644 index 00000000..bde1e11c --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Build/lufa_core.mk @@ -0,0 +1,152 @@ +# +# LUFA Library +# Copyright (C) Dean Camera, 2012. +# +# dean [at] fourwalledcubicle [dot] com +# www.lufa-lib.org +# + +LUFA_BUILD_MODULES += CORE +LUFA_BUILD_TARGETS += help list_targets list_modules list_mandatory list_optional list_provided list_macros +LUFA_BUILD_MANDATORY_VARS += +LUFA_BUILD_OPTIONAL_VARS += +LUFA_BUILD_PROVIDED_VARS += +LUFA_BUILD_PROVIDED_MACROS += + +# ----------------------------------------------------------------------------- +# LUFA Core Build System Makefile Module. +# ----------------------------------------------------------------------------- +# DESCRIPTION: +# Provides a set of core build targets for the LUFA build system +# ----------------------------------------------------------------------------- +# TARGETS: +# +# help - Build system help +# list_targets - List all build targets +# list_modules - List all build modules +# list_mandatory - List all mandatory make variables required by +# the included build modules of the application +# list_optional - List all optional make variables required by +# the included build modules of the application +# list_provided - List all provided make variables from the +# included build modules of the application +# list_macros - List all provided make macros from the +# included build modules of the application +# +# MANDATORY PARAMETERS: +# +# (None) +# +# OPTIONAL PARAMETERS: +# +# (None) +# +# PROVIDED VARIABLES: +# +# (None) +# +# PROVIDED MACROS: +# +# (None) +# +# ----------------------------------------------------------------------------- + +SHELL = /bin/sh + +# Build sorted and filtered lists of the included build module data +SORTED_LUFA_BUILD_MODULES = $(sort $(LUFA_BUILD_MODULES)) +SORTED_LUFA_BUILD_TARGETS = $(sort $(LUFA_BUILD_TARGETS)) +SORTED_LUFA_MANDATORY_VARS = $(sort $(LUFA_BUILD_MANDATORY_VARS)) +SORTED_LUFA_OPTIONAL_VARS = $(filter-out $(SORTED_LUFA_MANDATORY_VARS), $(sort $(LUFA_BUILD_OPTIONAL_VARS))) +SORTED_LUFA_PROVIDED_VARS = $(sort $(LUFA_BUILD_PROVIDED_VARS)) +SORTED_LUFA_PROVIDED_MACROS = $(sort $(LUFA_BUILD_PROVIDED_MACROS)) + +# Create printable versions of the sorted build module data (use "(None)" when no data is available) +PRINTABLE_LUFA_BUILD_MODULES = $(if $(strip $(SORTED_LUFA_BUILD_MODULES)), $(SORTED_LUFA_BUILD_MODULES), (None)) +PRINTABLE_LUFA_BUILD_TARGETS = $(if $(strip $(SORTED_LUFA_BUILD_TARGETS)), $(SORTED_LUFA_BUILD_TARGETS), (None)) +PRINTABLE_LUFA_MANDATORY_VARS = $(if $(strip $(SORTED_LUFA_MANDATORY_VARS)), $(SORTED_LUFA_MANDATORY_VARS), (None)) +PRINTABLE_LUFA_OPTIONAL_VARS = $(if $(strip $(SORTED_LUFA_OPTIONAL_VARS)), $(SORTED_LUFA_OPTIONAL_VARS), (None)) +PRINTABLE_LUFA_PROVIDED_VARS = $(if $(strip $(SORTED_LUFA_PROVIDED_VARS)), $(SORTED_LUFA_PROVIDED_VARS), (None)) +PRINTABLE_LUFA_PROVIDED_MACROS = $(if $(strip $(SORTED_LUFA_PROVIDED_MACROS)), $(SORTED_LUFA_PROVIDED_MACROS), (None)) + +help: + @echo "===================================================================" + @echo " LUFA Build System 2.0 " + @echo " (C) Dean Camera, 2012 { dean @ fourwalledcubicle . com } " + @echo "===================================================================" + @echo "DESCRIPTION: " + @echo " This build system is a set of makefile modules for (GNU) Make, to " + @echo " provide a simple system for building LUFA powered applications. " + @echo " Each makefile module can be included from within a user makefile, " + @echo " to expose the build rules documented in the comments at the top of" + @echo " each build module. " + @echo " " + @echo "USAGE: " + @echo " To execute a rule, define all variables indicated in the desired " + @echo " module as a required parameter before including the build module " + @echo " in your project makefile. Parameters marked as optional will " + @echo " assume a default value in the modules if not user-assigned. " + @echo " " + @echo " By default the target output shows both a friendly summary, as " + @echo " well as the actual invoked command. To suppress the output of the " + @echo " invoked commands and show only the friendly command output, run " + @echo " make with the \"-s\" switch added before the target(s). " + @echo "===================================================================" + @echo " " + @echo " Currently used build system modules in this application: " + @echo " " + @printf " %b" "$(PRINTABLE_LUFA_BUILD_MODULES:%= - %\n)" + @echo " " + @echo " " + @echo " Currently available build targets in this application: " + @echo " " + @printf " %b" "$(PRINTABLE_LUFA_BUILD_TARGETS:%= - %\n)" + @echo " " + @echo " " + @echo " Mandatory variables required by the selected build Modules: " + @echo " " + @printf " %b" "$(PRINTABLE_LUFA_MANDATORY_VARS:%= - %\n)" + @echo " " + @echo " " + @echo " Optional variables required by the selected build Modules: " + @echo " " + @printf " %b" "$(PRINTABLE_LUFA_OPTIONAL_VARS:%= - %\n)" + @echo " " + @echo " " + @echo " Variables provided by the selected build Modules: " + @echo " " + @printf " %b" "$(PRINTABLE_LUFA_PROVIDED_VARS:%= - %\n)" + @echo " " + @echo " " + @echo " Macros provided by the selected build Modules: " + @echo " " + @printf " %b" "$(PRINTABLE_LUFA_PROVIDED_MACROS:%= - %\n)" + @echo " " + @echo "===================================================================" + @echo " The LUFA BuildSystem 2.0 - Powered By Unicorns (tm) " + @echo "===================================================================" + +list_modules: + @echo Currently Used Build System Modules: $(PRINTABLE_LUFA_BUILD_MODULES) + +list_targets: + @echo Currently Available Build Targets: $(PRINTABLE_LUFA_BUILD_TARGETS) + +list_mandatory: + @echo Mandatory Variables for Included Modules: $(PRINTABLE_LUFA_MANDATORY_VARS) + +list_optional: + @echo Optional Variables for Included Modules: $(PRINTABLE_LUFA_OPTIONAL_VARS) + +list_provided: + @echo Variables Provided by the Included Modules: $(PRINTABLE_LUFA_PROVIDED_VARS) + +list_macros: + @echo Macros Provided by the Included Modules: $(PRINTABLE_LUFA_PROVIDED_MACROS) + +# Disable default in-built make rules (those that are needed are explicitly +# defined, and doing so has performance benefits when recursively building) +.SUFFIXES: + +# Phony build targets for this module +.PHONY: help list_modules list_targets list_mandatory list_optional list_provided list_macros diff --git a/protocol/lufa/LUFA-120730/LUFA/Build/lufa_cppcheck.mk b/protocol/lufa/LUFA-120730/LUFA/Build/lufa_cppcheck.mk new file mode 100644 index 00000000..1e3604c7 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Build/lufa_cppcheck.mk @@ -0,0 +1,104 @@ +# +# LUFA Library +# Copyright (C) Dean Camera, 2012. +# +# dean [at] fourwalledcubicle [dot] com +# www.lufa-lib.org +# + +LUFA_BUILD_MODULES += CPPCHECK +LUFA_BUILD_TARGETS += cppcheck cppcheck-config +LUFA_BUILD_MANDATORY_VARS += SRC +LUFA_BUILD_OPTIONAL_VARS += CPPCHECK_INCLUDES CPPCHECK_EXCLUDES CPPCHECK_MSG_TEMPLATE CPPCHECK_ENABLE \ + CPPCHECK_SUPPRESS CPPCHECK_FAIL_ON_WARNING CPPCHECK_QUIET CPPCHECK_FLAGS +LUFA_BUILD_PROVIDED_VARS += +LUFA_BUILD_PROVIDED_MACROS += + +# ----------------------------------------------------------------------------- +# LUFA CPPCheck Buildsystem Makefile Module. +# ----------------------------------------------------------------------------- +# DESCRIPTION: +# Provides a set of targets to scan a project with the free "cppcheck" static +# analysis tool, to check for code errors at runtime (see http://cppcheck.sourceforge.net). +# ----------------------------------------------------------------------------- +# TARGETS: +# +# cppcheck - Scan the project with CPPCheck +# cppcheck-config - Use CPPCheck to look for missing include files +# +# MANDATORY PARAMETERS: +# +# SRC - List of source files to statically analyze +# +# OPTIONAL PARAMETERS: +# +# CPPCHECK_INCLUDES - Extra include paths to search for missing +# header files +# CPPCHECK_EXCLUDES - Source file paths to exclude checking (can be +# a path fragment if desired) +# CPPCHECK_MSG_TEMPLATE - Template for cppcheck error and warning output +# CPPCHECK_ENABLE - General cppcheck category checks to enable +# CPPCHECK_SUPPRESS - Specific cppcheck warnings to disable by ID +# CPPCHECK_FAIL_ON_WARNING - Set to Y to fail the build on cppcheck +# warnings, N to continue even if warnings occur +# CPPCHECK_QUIET - Enable cppcheck verbose or quiet output mode +# CPPCHECK_FLAGS - Additional flags to pass to cppcheck +# +# PROVIDED VARIABLES: +# +# (None) +# +# PROVIDED MACROS: +# +# (None) +# +# ----------------------------------------------------------------------------- + +SHELL = /bin/sh + +ERROR_IF_UNSET ?= $(if $(filter undefined, $(origin $(strip $(1)))), $(error Makefile $(strip $(1)) value not set)) +ERROR_IF_EMPTY ?= $(if $(strip $($(strip $(1)))), , $(error Makefile $(strip $(1)) option cannot be blank)) +ERROR_IF_NONBOOL ?= $(if $(filter Y N, $($(strip $(1)))), , $(error Makefile $(strip $(1)) option must be Y or N)) + +# Default values of optionally user-supplied variables +CPPCHECK_INCLUDES ?= +CPPCHECK_EXCLUDES ?= +CPPCHECK_MSG_TEMPLATE ?= {file}:{line}: {severity} ({id}): {message} +CPPCHECK_ENABLE ?= all +CPPCHECK_SUPPRESS ?= variableScope missingInclude +CPPCHECK_FAIL_ON_WARNING ?= Y +CPPCHECK_QUIET ?= Y +CPPCHECK_FLAGS ?= + +# Sanity check user supplied values +$(foreach MANDATORY_VAR, $(LUFA_BUILD_MANDATORY_VARS), $(call ERROR_IF_UNSET, $(MANDATORY_VAR))) +$(call ERROR_IF_EMPTY, SRC) +$(call ERROR_IF_EMPTY, CPPCHECK_MSG_TEMPLATE) +$(call ERROR_IF_EMPTY, CPPCHECK_ENABLE) +$(call ERROR_IF_NONBOOL, CPPCHECK_FAIL_ON_WARNING) +$(call ERROR_IF_NONBOOL, CPPCHECK_QUIET) + +# Build a default argument list for cppcheck +BASE_CPPCHECK_FLAGS := --template="$(CPPCHECK_MSG_TEMPLATE)" $(CPPCHECK_INCLUDES:%=-I%) $(CPPCHECK_EXCLUDES:%=-i%) --inline-suppr --force --std=c99 + +# Sanity check parameters and construct additional command line arguments to cppcheck +ifeq ($(CPPCHECK_FAIL_ON_WARNING), Y) + BASE_CPPCHECK_FLAGS += --error-exitcode=1 +endif +ifeq ($(CPPCHECK_QUIET), Y) + BASE_CPPCHECK_FLAGS += --quiet +endif + +# Output Messages +MSG_CPPCHECK_CMD := ' [CPPCHECK]:' + +cppcheck-config: + @echo $(MSG_CPPCHECK_CMD) Checking cppcheck configuration check on source files + cppcheck $(BASE_CPPCHECK_FLAGS) --check-config $(CPPCHECK_FLAGS) $(SRC) + +cppcheck: + @echo $(MSG_CPPCHECK_CMD) Performing static analysis on source files + cppcheck $(BASE_CPPCHECK_FLAGS) --enable=$(CPPCHECK_ENABLE) $(CPPCHECK_SUPPRESS:%=--suppress=%) $(CPPCHECK_FLAGS) $(SRC) + +# Phony build targets for this module +.PHONY: cppcheck-config cppcheck diff --git a/protocol/lufa/LUFA-120730/LUFA/Build/lufa_dfu.mk b/protocol/lufa/LUFA-120730/LUFA/Build/lufa_dfu.mk new file mode 100644 index 00000000..6bfe9794 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Build/lufa_dfu.mk @@ -0,0 +1,93 @@ +# +# LUFA Library +# Copyright (C) Dean Camera, 2012. +# +# dean [at] fourwalledcubicle [dot] com +# www.lufa-lib.org +# + +LUFA_BUILD_MODULES += DFU +LUFA_BUILD_TARGETS += flip flip-ee dfu dfu-ee +LUFA_BUILD_MANDATORY_VARS += MCU TARGET +LUFA_BUILD_OPTIONAL_VARS += +LUFA_BUILD_PROVIDED_VARS += +LUFA_BUILD_PROVIDED_MACROS += + +# ----------------------------------------------------------------------------- +# LUFA DFU Bootloader Buildsystem Makefile Module. +# ----------------------------------------------------------------------------- +# DESCRIPTION: +# Provides a set of targets to re-program a device currently running a DFU +# class bootloader with a project's FLASH and EEPROM files. +# ----------------------------------------------------------------------------- +# TARGETS: +# +# flip - Program FLASH into target via Atmel FLIP +# flip-ee - Program EEPROM into target via Atmel FLIP +# dfu - Program FLASH into target via dfu-programmer +# dfu-ee - Program EEPROM into target via dfu-programmer +# +# MANDATORY PARAMETERS: +# +# MCU - Microcontroller device model name +# TARGET - Application name +# +# OPTIONAL PARAMETERS: +# +# (None) +# +# PROVIDED VARIABLES: +# +# (None) +# +# PROVIDED MACROS: +# +# (None) +# +# ----------------------------------------------------------------------------- + +SHELL = /bin/sh + +ERROR_IF_UNSET ?= $(if $(filter undefined, $(origin $(strip $(1)))), $(error Makefile $(strip $(1)) value not set)) +ERROR_IF_EMPTY ?= $(if $(strip $($(strip $(1)))), , $(error Makefile $(strip $(1)) option cannot be blank)) +ERROR_IF_NONBOOL ?= $(if $(filter Y N, $($(strip $(1)))), , $(error Makefile $(strip $(1)) option must be Y or N)) + +# Sanity-check values of mandatory user-supplied variables +$(foreach MANDATORY_VAR, $(LUFA_BUILD_MANDATORY_VARS), $(call ERROR_IF_UNSET, $(MANDATORY_VAR))) +$(call ERROR_IF_EMPTY, MCU) +$(call ERROR_IF_EMPTY, TARGET) + +# Output Messages +MSG_COPY_CMD := ' [CP] :' +MSG_REMOVE_CMD := ' [RM] :' +MSG_DFU_CMD := ' [DFU] :' + +flip: $(TARGET).hex $(MAKEFILE_LIST) + @echo $(MSG_DFU_CMD) Programming FLASH with batchisp using \"$<\" + batchisp -hardware usb -device $(MCU) -operation erase f + batchisp -hardware usb -device $(MCU) -operation loadbuffer $< program + batchisp -hardware usb -device $(MCU) -operation start reset 0 + +flip-ee: $(TARGET).eep $(MAKEFILE_LIST) + @echo $(MSG_DFU_CMD) Copying EEP file to temporary file \"$<.hex\" + cp $< $<.hex + @echo $(MSG_DFU_CMD) Programming EEPROM with batchisp using \"$<.hex\" + batchisp -hardware usb -device $(MCU) -operation memory EEPROM erase + batchisp -hardware usb -device $(MCU) -operation memory EEPROM loadbuffer $<.hex program + batchisp -hardware usb -device $(MCU) -operation start reset 0 + @echo $(MSG_DFU_CMD) Removing temporary file \"$<.hex\" + rm $<.hex + +dfu: $(TARGET).hex $(MAKEFILE_LIST) + @echo $(MSG_DFU_CMD) Programming FLASH with dfu-programmer using \"$<\" + dfu-programmer $(MCU) erase + dfu-programmer $(MCU) flash $< + dfu-programmer $(MCU) reset + +dfu-ee: $(TARGET).eep $(MAKEFILE_LIST) + @echo $(MSG_DFU_CMD) Programming EEPROM with dfu-programmer using \"$<\" + dfu-programmer $(MCU) eeprom-flash $< + dfu-programmer $(MCU) reset + +# Phony build targets for this module +.PHONY: flip flip-ee dfu dfu-ee diff --git a/protocol/lufa/LUFA-120730/LUFA/Build/lufa_doxygen.mk b/protocol/lufa/LUFA-120730/LUFA/Build/lufa_doxygen.mk new file mode 100644 index 00000000..87427fd2 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Build/lufa_doxygen.mk @@ -0,0 +1,81 @@ +# +# LUFA Library +# Copyright (C) Dean Camera, 2012. +# +# dean [at] fourwalledcubicle [dot] com +# www.lufa-lib.org +# + +LUFA_BUILD_MODULES += DOXYGEN +LUFA_BUILD_TARGETS += doxygen +LUFA_BUILD_MANDATORY_VARS += LUFA_PATH +LUFA_BUILD_OPTIONAL_VARS += DOXYGEN_CONF DOXYGEN_FAIL_ON_WARNING DOXYGEN_OVERRIDE_PARAMS +LUFA_BUILD_PROVIDED_VARS += +LUFA_BUILD_PROVIDED_MACROS += + +# ----------------------------------------------------------------------------- +# LUFA Doxygen Buildsystem Makefile Module. +# ----------------------------------------------------------------------------- +# DESCRIPTION: +# Provides a set of targets to automatically build Doxygen documentation for +# a project (see www.doxygen.org). +# ----------------------------------------------------------------------------- +# TARGETS: +# +# doxygen - Build Doxygen Documentation +# +# MANDATORY PARAMETERS: +# +# LUFA_PATH - Path to the LUFA library core +# +# OPTIONAL PARAMETERS: +# +# DOXYGEN_CONF - Doxygen configuration filename +# DOXYGEN_FAIL_ON_WARNING - Set to Y to fail the build on Doxygen warnings, +# N to continue even if warnings occur +# DOXYGEN_OVERRIDE_PARAMS - Parameters to override in the doxygen +# configuration file +# PROVIDED VARIABLES: +# +# (None) +# +# PROVIDED MACROS: +# +# (None) +# +# ----------------------------------------------------------------------------- + +SHELL = /bin/sh + +ERROR_IF_UNSET ?= $(if $(filter undefined, $(origin $(strip $(1)))), $(error Makefile $(strip $(1)) value not set)) +ERROR_IF_EMPTY ?= $(if $(strip $($(strip $(1)))), , $(error Makefile $(strip $(1)) option cannot be blank)) +ERROR_IF_NONBOOL ?= $(if $(filter Y N, $($(strip $(1)))), , $(error Makefile $(strip $(1)) option must be Y or N)) + +# Default values of optionally user-supplied variables +DOXYGEN_CONF ?= Doxygen.conf +DOXYGEN_FAIL_ON_WARNING ?= Y +DOXYGEN_OVERRIDE_PARAMS ?= QUIET=YES HTML_STYLESHEET=$(patsubst %/,%,$(LUFA_PATH))/DoxygenPages/Style/Style.css + +# Sanity check user supplied values +$(foreach MANDATORY_VAR, $(LUFA_BUILD_MANDATORY_VARS), $(call ERROR_IF_UNSET, $(MANDATORY_VAR))) +$(call ERROR_IF_EMPTY, DOXYGEN_CONF) +$(call ERROR_IF_EMPTY, LUFA_PATH) +$(call ERROR_IF_NONBOOL, DOXYGEN_FAIL_ON_WARNING) + +# Output Messages +MSG_DOXYGEN_CMD := ' [DOXYGEN] :' + +# Determine Doxygen invocation command +BASE_DOXYGEN_CMD := ( cat $(DOXYGEN_CONF) $(DOXYGEN_OVERRIDE_PARAMS:%=; echo "%") ) | doxygen - +ifeq ($(DOXYGEN_FAIL_ON_WARNING), Y) + DOXYGEN_CMD := if ( $(BASE_DOXYGEN_CMD) 2>&1 | grep -v "warning: ignoring unsupported tag" ;); then exit 1; fi; +else + DOXYGEN_CMD := $(BASE_DOXYGEN_CMD) +endif + +doxygen: + @echo $(MSG_DOXYGEN_CMD) Configuration file \"$(DOXYGEN_CONF)\" with parameters \"$(DOXYGEN_OVERRIDE_PARAMS)\" + $(DOXYGEN_CMD) + +# Phony build targets for this module +.PHONY: doxygen diff --git a/protocol/lufa/LUFA-120730/LUFA/Build/lufa_hid.mk b/protocol/lufa/LUFA-120730/LUFA/Build/lufa_hid.mk new file mode 100644 index 00000000..b8f6f268 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Build/lufa_hid.mk @@ -0,0 +1,88 @@ +# +# LUFA Library +# Copyright (C) Dean Camera, 2012. +# +# dean [at] fourwalledcubicle [dot] com +# www.lufa-lib.org +# + +LUFA_BUILD_MODULES += HID +LUFA_BUILD_TARGETS += hid hid-ee teensy teensy-ee +LUFA_BUILD_MANDATORY_VARS += MCU TARGET +LUFA_BUILD_OPTIONAL_VARS += +LUFA_BUILD_PROVIDED_VARS += +LUFA_BUILD_PROVIDED_MACROS += + +# ----------------------------------------------------------------------------- +# LUFA HID Bootloader Buildsystem Makefile Module. +# ----------------------------------------------------------------------------- +# DESCRIPTION: +# Provides a set of targets to re-program a device currently running a HID +# class bootloader with a project's FLASH files. +# ----------------------------------------------------------------------------- +# TARGETS: +# +# hid - Program FLASH into target via +# hid_bootloader_cli +# hid-ee - Program EEPROM into target via a temporary +# AVR application and hid_bootloader_cli +# teensy - Program FLASH into target via +# teensy_loader_cli +# teensy-ee - Program EEPROM into target via a temporary +# AVR application and teensy_loader_cli +# +# MANDATORY PARAMETERS: +# +# MCU - Microcontroller device model name +# TARGET - Application name +# +# OPTIONAL PARAMETERS: +# +# (None) +# +# PROVIDED VARIABLES: +# +# (None) +# +# PROVIDED MACROS: +# +# (None) +# +# ----------------------------------------------------------------------------- + +ERROR_IF_UNSET ?= $(if $(filter undefined, $(origin $(strip $(1)))), $(error Makefile $(strip $(1)) value not set)) +ERROR_IF_EMPTY ?= $(if $(strip $($(strip $(1)))), , $(error Makefile $(strip $(1)) option cannot be blank)) +ERROR_IF_NONBOOL ?= $(if $(filter Y N, $($(strip $(1)))), , $(error Makefile $(strip $(1)) option must be Y or N)) + +# Sanity-check values of mandatory user-supplied variables +$(foreach MANDATORY_VAR, $(LUFA_BUILD_MANDATORY_VARS), $(call ERROR_IF_UNSET, $(MANDATORY_VAR))) +$(call ERROR_IF_EMPTY, MCU) +$(call ERROR_IF_EMPTY, TARGET) + +# Output Messages +MSG_HID_BOOTLOADER_CMD := ' [HID] :' +MSG_OBJCPY_CMD := ' [OBJCPY] :' +MSG_MAKE_CMD := ' [MAKE] :' + +hid: $(TARGET).hex $(MAKEFILE_LIST) + @echo $(MSG_HID_BOOTLOADER_CMD) Programming FLASH with hid_bootloader_cli using \"$<\" + hid_bootloader_cli -mmcu=$(MCU) -v $< + +hid-ee: $(TARGET).eep $(MAKEFILE_LIST) + @echo $(MSG_OBJCPY_CMD) Converting \"$<\" to a binary file \"InputEEData.bin\" + avr-objcopy -I ihex -O binary $< $(patsubst %/,%,$(LUFA_PATH))/Build/HID_EEPROM_Loader/InputEEData.bin + @echo $(MSG_MAKE_CMD) Making EEPROM loader application for \"$<\" + make -C $(patsubst %/,%,$(LUFA_PATH))/Build/HID_EEPROM_Loader/ MCU=$(MCU) clean hid + +teensy: $(TARGET).hex $(MAKEFILE_LIST) + @echo $(MSG_HID_BOOTLOADER_CMD) Programming FLASH with teensy_loader_cli using \"$<\" + teensy_loader_cli -mmcu=$(MCU) -v $< + +teensy-ee: $(TARGET).hex $(MAKEFILE_LIST) + @echo $(MSG_OBJCPY_CMD) Converting \"$<\" to a binary file \"InputEEData.bin\" + avr-objcopy -I ihex -O binary $< $(patsubst %/,%,$(LUFA_PATH))/Build/HID_EEPROM_Loader/InputEEData.bin + @echo $(MSG_MAKE_CMD) Making EEPROM loader application for \"$<\" + make -s -C $(patsubst %/,%,$(LUFA_PATH))/Build/HID_EEPROM_Loader/ MCU=$(MCU) clean hid-teensy + +# Phony build targets for this module +.PHONY: hid hid-ee teensy teensy-ee diff --git a/protocol/lufa/LUFA-120730/LUFA/Build/lufa_sources.mk b/protocol/lufa/LUFA-120730/LUFA/Build/lufa_sources.mk new file mode 100644 index 00000000..663c9302 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Build/lufa_sources.mk @@ -0,0 +1,116 @@ +# +# LUFA Library +# Copyright (C) Dean Camera, 2012. +# +# dean [at] fourwalledcubicle [dot] com +# www.lufa-lib.org +# + +LUFA_BUILD_MODULES += SOURCES +LUFA_BUILD_TARGETS += +LUFA_BUILD_MANDATORY_VARS += LUFA_PATH ARCH +LUFA_BUILD_OPTIONAL_VARS += +LUFA_BUILD_PROVIDED_VARS += LUFA_SRC_USB LUFA_SRC_USBCLASS LUFA_SRC_TEMPERATURE LUFA_SRC_SERIAL LUFA_SRC_TWI LUFA_SRC_PLATFORM +LUFA_BUILD_PROVIDED_MACROS += + +# ----------------------------------------------------------------------------- +# LUFA Sources Buildsystem Makefile Module. +# ----------------------------------------------------------------------------- +# DESCRIPTION: +# Provides a set of makefile variables for the various LUFA module sources. +# Once included, the sources required to use a given LUFA module will become +# available using the makefile variable names listed in the LUFA project +# documentation. +# ----------------------------------------------------------------------------- +# TARGETS: +# +# (None) +# +# MANDATORY PARAMETERS: +# +# LUFA_PATH - Path to the LUFA library core +# ARCH - Device architecture name +# +# OPTIONAL PARAMETERS: +# +# (None) +# +# PROVIDED VARIABLES: +# +# LUFA_SRC_USB - List of LUFA USB driver source files +# LUFA_SRC_USBCLASS - List of LUFA USB Class driver source files +# LUFA_SRC_TEMPERATURE - List of LUFA temperature sensor driver source +# files +# LUFA_SRC_SERIAL - List of LUFA Serial U(S)ART driver source files +# LUFA_SRC_TWI - List of LUFA TWI driver source files +# LUFA_SRC_PLATFORM - List of LUFA architecture specific platform +# management source files +# +# PROVIDED MACROS: +# +# (None) +# +# ----------------------------------------------------------------------------- + +SHELL = /bin/sh + +ERROR_IF_UNSET ?= $(if $(filter undefined, $(origin $(strip $(1)))), $(error Makefile $(strip $(1)) value not set)) +ERROR_IF_EMPTY ?= $(if $(strip $($(strip $(1)))), , $(error Makefile $(strip $(1)) option cannot be blank)) +ERROR_IF_NONBOOL ?= $(if $(filter Y N, $($(strip $(1)))), , $(error Makefile $(strip $(1)) option must be Y or N)) + +# Sanity check user supplied values +$(foreach MANDATORY_VAR, $(LUFA_BUILD_MANDATORY_VARS), $(call ERROR_IF_UNSET, $(MANDATORY_VAR))) +$(call ERROR_IF_EMPTY, LUFA_PATH) +$(call ERROR_IF_EMPTY, ARCH) + +# Allow LUFA_ROOT_PATH to be overridden elsewhere to support legacy LUFA makefiles +LUFA_ROOT_PATH ?= $(patsubst %/,%,$(LUFA_PATH)) + +# Construct LUFA module source variables +LUFA_SRC_USB := $(LUFA_ROOT_PATH)/Drivers/USB/Core/$(ARCH)/Device_$(ARCH).c \ + $(LUFA_ROOT_PATH)/Drivers/USB/Core/$(ARCH)/Endpoint_$(ARCH).c \ + $(LUFA_ROOT_PATH)/Drivers/USB/Core/$(ARCH)/Host_$(ARCH).c \ + $(LUFA_ROOT_PATH)/Drivers/USB/Core/$(ARCH)/Pipe_$(ARCH).c \ + $(LUFA_ROOT_PATH)/Drivers/USB/Core/$(ARCH)/USBController_$(ARCH).c \ + $(LUFA_ROOT_PATH)/Drivers/USB/Core/$(ARCH)/USBInterrupt_$(ARCH).c \ + $(LUFA_ROOT_PATH)/Drivers/USB/Core/$(ARCH)/EndpointStream_$(ARCH).c \ + $(LUFA_ROOT_PATH)/Drivers/USB/Core/$(ARCH)/PipeStream_$(ARCH).c \ + $(LUFA_ROOT_PATH)/Drivers/USB/Core/ConfigDescriptors.c \ + $(LUFA_ROOT_PATH)/Drivers/USB/Core/DeviceStandardReq.c \ + $(LUFA_ROOT_PATH)/Drivers/USB/Core/Events.c \ + $(LUFA_ROOT_PATH)/Drivers/USB/Core/HostStandardReq.c \ + $(LUFA_ROOT_PATH)/Drivers/USB/Core/USBTask.c \ + $(LUFA_ROOT_PATH)/Drivers/USB/Class/Common/HIDParser.c +LUFA_SRC_USBCLASS := $(LUFA_ROOT_PATH)/Drivers/USB/Class/Device/AudioClassDevice.c \ + $(LUFA_ROOT_PATH)/Drivers/USB/Class/Device/CDCClassDevice.c \ + $(LUFA_ROOT_PATH)/Drivers/USB/Class/Device/HIDClassDevice.c \ + $(LUFA_ROOT_PATH)/Drivers/USB/Class/Device/MassStorageClassDevice.c \ + $(LUFA_ROOT_PATH)/Drivers/USB/Class/Device/MIDIClassDevice.c \ + $(LUFA_ROOT_PATH)/Drivers/USB/Class/Device/RNDISClassDevice.c \ + $(LUFA_ROOT_PATH)/Drivers/USB/Class/Host/AndroidAccessoryClassHost.c \ + $(LUFA_ROOT_PATH)/Drivers/USB/Class/Host/AudioClassHost.c \ + $(LUFA_ROOT_PATH)/Drivers/USB/Class/Host/CDCClassHost.c \ + $(LUFA_ROOT_PATH)/Drivers/USB/Class/Host/HIDClassHost.c \ + $(LUFA_ROOT_PATH)/Drivers/USB/Class/Host/MassStorageClassHost.c \ + $(LUFA_ROOT_PATH)/Drivers/USB/Class/Host/MIDIClassHost.c \ + $(LUFA_ROOT_PATH)/Drivers/USB/Class/Host/PrinterClassHost.c \ + $(LUFA_ROOT_PATH)/Drivers/USB/Class/Host/RNDISClassHost.c \ + $(LUFA_ROOT_PATH)/Drivers/USB/Class/Host/StillImageClassHost.c +LUFA_SRC_TEMPERATURE := $(LUFA_ROOT_PATH)/Drivers/Board/Temperature.c +LUFA_SRC_SERIAL := $(LUFA_ROOT_PATH)/Drivers/Peripheral/$(ARCH)/Serial_$(ARCH).c +LUFA_SRC_TWI := $(LUFA_ROOT_PATH)/Drivers/Peripheral/$(ARCH)/TWI_$(ARCH).c + +ifeq ($(ARCH), UC3) + LUFA_SRC_PLATFORM := $(LUFA_ROOT_PATH)/Platform/UC3/Exception.S \ + $(LUFA_ROOT_PATH)/Platform/UC3/InterruptManagement.c +else + LUFA_SRC_PLATFORM := +endif + +# Build a list of all available module sources +LUFA_SRC_ALL_FILES := $(LUFA_SRC_USB) \ + $(LUFA_SRC_USBCLASS) \ + $(LUFA_SRC_TEMPERATURE) \ + $(LUFA_SRC_SERIAL) \ + $(LUFA_SRC_TWI) \ + $(LUFA_SRC_PLATFORM) diff --git a/protocol/lufa/LUFA-120730/LUFA/CodeTemplates/DriverStubs/Buttons.h b/protocol/lufa/LUFA-120730/LUFA/CodeTemplates/DriverStubs/Buttons.h new file mode 100644 index 00000000..ca4c7a5e --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/CodeTemplates/DriverStubs/Buttons.h @@ -0,0 +1,90 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief LUFA Custom Board Button Hardware Driver (Template) + * + * This is a stub driver header file, for implementing custom board + * layout hardware with compatible LUFA board specific drivers. If + * the library is configured to use the BOARD_USER board mode, this + * driver file should be completed and copied into the "/Board/" folder + * inside the application's folder. + * + * This stub is for the board-specific component of the LUFA Buttons driver, + * for the control of physical board-mounted GPIO pushbuttons. + */ + +#ifndef __BUTTONS_USER_H__ +#define __BUTTONS_USER_H__ + + /* Includes: */ + // TODO: Add any required includes here + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_BUTTONS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/Buttons.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Button mask for the first button on the board. */ + #define BUTTONS_BUTTON1 // TODO: Add mask for first board button here + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void Buttons_Init(void) + { + // TODO: Initialize the appropriate port pins as an inputs here, with pull-ups + } + + static inline void Buttons_Disable(void) + { + // TODO: Clear the appropriate port pins as high impedance inputs here + } + + static inline uint8_t Buttons_GetStatus(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t Buttons_GetStatus(void) + { + // TODO: Return current button status here, debounced if required + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + diff --git a/protocol/lufa/LUFA-120730/LUFA/CodeTemplates/DriverStubs/Dataflash.h b/protocol/lufa/LUFA-120730/LUFA/CodeTemplates/DriverStubs/Dataflash.h new file mode 100644 index 00000000..d397f77e --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/CodeTemplates/DriverStubs/Dataflash.h @@ -0,0 +1,220 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief LUFA Custom Board Dataflash Hardware Driver (Template) + * + * This is a stub driver header file, for implementing custom board + * layout hardware with compatible LUFA board specific drivers. If + * the library is configured to use the BOARD_USER board mode, this + * driver file should be completed and copied into the "/Board/" folder + * inside the application's folder. + * + * This stub is for the board-specific component of the LUFA Dataflash + * driver. +*/ + +#ifndef __DATAFLASH_USER_H__ +#define __DATAFLASH_USER_H__ + + /* Includes: */ + // TODO: Add any required includes here + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_DATAFLASH_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/Dataflash.h instead. + #endif + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Macros: */ + #define DATAFLASH_CHIPCS_MASK // TODO: Replace this with a mask of all the /CS pins of all Dataflashes + #define DATAFLASH_CHIPCS_DDR // TODO: Replace with the DDR register name for the board's Dataflash ICs + #define DATAFLASH_CHIPCS_PORT // TODO: Replace with the PORT register name for the board's Dataflash ICs + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Constant indicating the total number of dataflash ICs mounted on the selected board. */ + #define DATAFLASH_TOTALCHIPS 1 // TODO: Replace with the number of Dataflashes on the board, max 2 + + /** Mask for no dataflash chip selected. */ + #define DATAFLASH_NO_CHIP DATAFLASH_CHIPCS_MASK + + /** Mask for the first dataflash chip selected. */ + #define DATAFLASH_CHIP1 // TODO: Replace with mask to hold /CS of first Dataflash low, and all others high + + /** Mask for the second dataflash chip selected. */ + #define DATAFLASH_CHIP2 // TODO: Replace with mask to hold /CS of second Dataflash low, and all others high + + /** Internal main memory page size for the board's dataflash ICs. */ + #define DATAFLASH_PAGE_SIZE // TODO: Replace with the page size for the Dataflash ICs + + /** Total number of pages inside each of the board's dataflash ICs. */ + #define DATAFLASH_PAGES // TODO: Replace with the total number of pages inside one of the Dataflash ICs + + /* Inline Functions: */ + /** Initializes the dataflash driver so that commands and data may be sent to an attached dataflash IC. + * The microcontroller's SPI driver MUST be initialized before any of the dataflash commands are used. + */ + static inline void Dataflash_Init(void) + { + DATAFLASH_CHIPCS_DDR |= DATAFLASH_CHIPCS_MASK; + DATAFLASH_CHIPCS_PORT |= DATAFLASH_CHIPCS_MASK; + } + + /** Sends a byte to the currently selected dataflash IC, and returns a byte from the dataflash. + * + * \param[in] Byte Byte of data to send to the dataflash + * + * \return Last response byte from the dataflash + */ + static inline uint8_t Dataflash_TransferByte(const uint8_t Byte) ATTR_ALWAYS_INLINE; + static inline uint8_t Dataflash_TransferByte(const uint8_t Byte) + { + // TODO + } + + /** Sends a byte to the currently selected dataflash IC, and ignores the next byte from the dataflash. + * + * \param[in] Byte Byte of data to send to the dataflash + */ + static inline void Dataflash_SendByte(const uint8_t Byte) ATTR_ALWAYS_INLINE; + static inline void Dataflash_SendByte(const uint8_t Byte) + { + // TODO + } + + /** Sends a dummy byte to the currently selected dataflash IC, and returns the next byte from the dataflash. + * + * \return Last response byte from the dataflash + */ + static inline uint8_t Dataflash_ReceiveByte(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT; + static inline uint8_t Dataflash_ReceiveByte(void) + { + // TODO + } + + /** Determines the currently selected dataflash chip. + * + * \return Mask of the currently selected Dataflash chip, either \ref DATAFLASH_NO_CHIP if no chip is selected + * or a DATAFLASH_CHIPn mask (where n is the chip number). + */ + static inline uint8_t Dataflash_GetSelectedChip(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT; + static inline uint8_t Dataflash_GetSelectedChip(void) + { + return (DATAFLASH_CHIPCS_PORT & DATAFLASH_CHIPCS_MASK); + } + + /** Selects the given dataflash chip. + * + * \param[in] ChipMask Mask of the Dataflash IC to select, in the form of DATAFLASH_CHIPn mask (where n is + * the chip number). + */ + static inline void Dataflash_SelectChip(const uint8_t ChipMask) ATTR_ALWAYS_INLINE; + static inline void Dataflash_SelectChip(const uint8_t ChipMask) + { + DATAFLASH_CHIPCS_PORT = ((DATAFLASH_CHIPCS_PORT & ~DATAFLASH_CHIPCS_MASK) | ChipMask); + } + + /** Deselects the current dataflash chip, so that no dataflash is selected. */ + static inline void Dataflash_DeselectChip(void) ATTR_ALWAYS_INLINE; + static inline void Dataflash_DeselectChip(void) + { + Dataflash_SelectChip(DATAFLASH_NO_CHIP); + } + + /** Selects a dataflash IC from the given page number, which should range from 0 to + * ((DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS) - 1). For boards containing only one + * dataflash IC, this will select DATAFLASH_CHIP1. If the given page number is outside + * the total number of pages contained in the boards dataflash ICs, all dataflash ICs + * are deselected. + * + * \param[in] PageAddress Address of the page to manipulate, ranging from + * 0 to ((DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS) - 1). + */ + static inline void Dataflash_SelectChipFromPage(const uint16_t PageAddress) + { + Dataflash_DeselectChip(); + + if (PageAddress >= (DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS)) + return; + + #if (DATAFLASH_TOTALCHIPS == 2) + if (PageAddress & 0x01) + Dataflash_SelectChip(DATAFLASH_CHIP2); + else + Dataflash_SelectChip(DATAFLASH_CHIP1); + #else + Dataflash_SelectChip(DATAFLASH_CHIP1); + #endif + } + + /** Toggles the select line of the currently selected dataflash IC, so that it is ready to receive + * a new command. + */ + static inline void Dataflash_ToggleSelectedChipCS(void) + { + uint8_t SelectedChipMask = Dataflash_GetSelectedChip(); + + Dataflash_DeselectChip(); + Dataflash_SelectChip(SelectedChipMask); + } + + /** Spin-loops while the currently selected dataflash is busy executing a command, such as a main + * memory page program or main memory to buffer transfer. + */ + static inline void Dataflash_WaitWhileBusy(void) + { + Dataflash_ToggleSelectedChipCS(); + Dataflash_SendByte(DF_CMD_GETSTATUS); + while (!(Dataflash_ReceiveByte() & DF_STATUS_READY)); + Dataflash_ToggleSelectedChipCS(); + } + + /** Sends a set of page and buffer address bytes to the currently selected dataflash IC, for use with + * dataflash commands which require a complete 24-bit address. + * + * \param[in] PageAddress Page address within the selected dataflash IC + * \param[in] BufferByte Address within the dataflash's buffer + */ + static inline void Dataflash_SendAddressBytes(uint16_t PageAddress, const uint16_t BufferByte) + { + #if (DATAFLASH_TOTALCHIPS == 2) + PageAddress >>= 1; + #endif + + Dataflash_SendByte(PageAddress >> 5); + Dataflash_SendByte((PageAddress << 3) | (BufferByte >> 8)); + Dataflash_SendByte(BufferByte); + } + +#endif + diff --git a/protocol/lufa/LUFA-120730/LUFA/CodeTemplates/DriverStubs/Joystick.h b/protocol/lufa/LUFA-120730/LUFA/CodeTemplates/DriverStubs/Joystick.h new file mode 100644 index 00000000..31c79d9e --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/CodeTemplates/DriverStubs/Joystick.h @@ -0,0 +1,102 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief LUFA Custom Board Joystick Hardware Driver (Template) + * + * This is a stub driver header file, for implementing custom board + * layout hardware with compatible LUFA board specific drivers. If + * the library is configured to use the BOARD_USER board mode, this + * driver file should be completed and copied into the "/Board/" folder + * inside the application's folder. + * + * This stub is for the board-specific component of the LUFA Joystick + * driver, for a digital four-way (plus button) joystick. +*/ + +#ifndef __JOYSTICK_USER_H__ +#define __JOYSTICK_USER_H__ + + /* Includes: */ + // TODO: Add any required includes here + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_JOYSTICK_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/Joystick.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Mask for the joystick being pushed in the left direction. */ + #define JOY_LEFT // TODO: Add mask to indicate joystick left position here + + /** Mask for the joystick being pushed in the right direction. */ + #define JOY_RIGHT // TODO: Add mask to indicate joystick right position here + + /** Mask for the joystick being pushed in the upward direction. */ + #define JOY_UP // TODO: Add mask to indicate joystick up position here + + /** Mask for the joystick being pushed in the downward direction. */ + #define JOY_DOWN // TODO: Add mask to indicate joystick down position here + + /** Mask for the joystick being pushed inward. */ + #define JOY_PRESS // TODO: Add mask to indicate joystick pressed position here + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void Joystick_Init(void) + { + // TODO: Initialize joystick port pins as inputs with pull-ups + } + + static inline void Joystick_Disable(void) + { + // TODO: Clear the joystick pins as high impedance inputs here + } + + static inline uint8_t Joystick_GetStatus(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t Joystick_GetStatus(void) + { + // TODO: Return current joystick position data which can be obtained by masking against the JOY_* macros + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + diff --git a/protocol/lufa/LUFA-120730/LUFA/CodeTemplates/DriverStubs/LEDs.h b/protocol/lufa/LUFA-120730/LUFA/CodeTemplates/DriverStubs/LEDs.h new file mode 100644 index 00000000..d4853463 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/CodeTemplates/DriverStubs/LEDs.h @@ -0,0 +1,130 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief LUFA Custom Board LED Hardware Driver (Template) + * + * This is a stub driver header file, for implementing custom board + * layout hardware with compatible LUFA board specific drivers. If + * the library is configured to use the BOARD_USER board mode, this + * driver file should be completed and copied into the "/Board/" folder + * inside the application's folder. + * + * This stub is for the board-specific component of the LUFA LEDs driver, + * for the LEDs (up to four) mounted on most development boards. +*/ + +#ifndef __LEDS_USER_H__ +#define __LEDS_USER_H__ + + /* Includes: */ + // TODO: Add any required includes here + +/* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_LEDS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/LEDS.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** LED mask for the first LED on the board. */ + #define LEDS_LED1 // TODO: Add mask for first board LED here + + /** LED mask for the second LED on the board. */ + #define LEDS_LED2 // TODO: Add mask for second board LED here + + /** LED mask for the third LED on the board. */ + #define LEDS_LED3 // TODO: Add mask for third board LED here + + /** LED mask for the fourth LED on the board. */ + #define LEDS_LED4 // TODO: Add mask for fourth board LED here + + /** LED mask for all the LEDs on the board. */ + #define LEDS_ALL_LEDS (LEDS_LED1 | LEDS_LED2 | LEDS_LED3 | LEDS_LED4) + + /** LED mask for none of the board LEDs. */ + #define LEDS_NO_LEDS 0 + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void LEDs_Init(void) + { + // TODO: Add code to initialize LED port pins as outputs here + } + + static inline void LEDs_Disable(void) + { + // TODO: Clear the LED port pins as high impedance inputs here + } + + static inline void LEDs_TurnOnLEDs(const uint8_t LEDMask) + { + // TODO: Add code to turn on LEDs given in the LEDMask mask here, leave others as-is + } + + static inline void LEDs_TurnOffLEDs(const uint8_t LEDMask) + { + // TODO: Add code to turn off LEDs given in the LEDMask mask here, leave others as-is + } + + static inline void LEDs_SetAllLEDs(const uint8_t LEDMask) + { + // TODO: Add code to turn on only LEDs given in the LEDMask mask here, all others off + } + + static inline void LEDs_ChangeLEDs(const uint8_t LEDMask, const uint8_t ActiveMask) + { + // TODO: Add code to set the Leds in the given LEDMask to the status given in ActiveMask here + } + + static inline void LEDs_ToggleLEDs(const uint8_t LEDMask) + { + // TODO: Add code to toggle the Leds in the given LEDMask, ignoring all others + } + + static inline uint8_t LEDs_GetLEDs(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t LEDs_GetLEDs(void) + { + // TODO: Add code to return the current LEDs status' here which can be masked against LED_LED* macros + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + diff --git a/protocol/lufa/LUFA-120730/LUFA/CodeTemplates/LUFAConfig.h b/protocol/lufa/LUFA-120730/LUFA/CodeTemplates/LUFAConfig.h new file mode 100644 index 00000000..6c98d03a --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/CodeTemplates/LUFAConfig.h @@ -0,0 +1,167 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief LUFA Library Configuration Header File (Template) + * + * This is a header file which can be used to configure LUFA's + * compile time options, as an alternative to the compile time + * constants supplied through a makefile. To use this configuration + * header, copy this into your project's root directory and supply + * the \c USE_LUFA_CONFIG_HEADER token to the compiler so that it is + * defined in all compiled source files. + * + * For information on what each token does, refer to the LUFA + * manual section "Summary of Compile Tokens". + */ + +#ifndef __LUFA_CONFIG_H__ +#define __LUFA_CONFIG_H__ + + #if (ARCH == ARCH_AVR8) + + /* Non-USB Related Configuration Tokens: */ +// #define DISABLE_TERMINAL_CODES + + /* USB Class Driver Related Tokens: */ +// #define HID_HOST_BOOT_PROTOCOL_ONLY +// #define HID_STATETABLE_STACK_DEPTH {Insert Value Here} +// #define HID_USAGE_STACK_DEPTH {Insert Value Here} +// #define HID_MAX_COLLECTIONS {Insert Value Here} +// #define HID_MAX_REPORTITEMS {Insert Value Here} +// #define HID_MAX_REPORT_IDS {Insert Value Here} +// #define NO_CLASS_DRIVER_AUTOFLUSH + + /* General USB Driver Related Tokens: */ +// #define ORDERED_EP_CONFIG +// #define USE_STATIC_OPTIONS {Insert Value Here} +// #define USB_DEVICE_ONLY +// #define USB_HOST_ONLY +// #define USB_STREAM_TIMEOUT_MS {Insert Value Here} +// #define NO_LIMITED_CONTROLLER_CONNECT +// #define NO_SOF_EVENTS + + /* USB Device Mode Driver Related Tokens: */ +// #define USE_RAM_DESCRIPTORS +// #define USE_FLASH_DESCRIPTORS +// #define USE_EEPROM_DESCRIPTORS +// #define NO_INTERNAL_SERIAL +// #define FIXED_CONTROL_ENDPOINT_SIZE {Insert Value Here} +// #define DEVICE_STATE_AS_GPIOR {Insert Value Here} +// #define FIXED_NUM_CONFIGURATIONS {Insert Value Here} +// #define CONTROL_ONLY_DEVICE +// #define INTERRUPT_CONTROL_ENDPOINT +// #define NO_DEVICE_REMOTE_WAKEUP +// #define NO_DEVICE_SELF_POWER + + /* USB Host Mode Driver Related Tokens: */ +// #define HOST_STATE_AS_GPIOR {Insert Value Here} +// #define USB_HOST_TIMEOUT_MS {Insert Value Here} +// #define HOST_DEVICE_SETTLE_DELAY_MS {Insert Value Here} +// #define NO_AUTO_VBUS_MANAGEMENT +// #define INVERTED_VBUS_ENABLE_LINE + + #elif (ARCH == ARCH_XMEGA) + + /* Non-USB Related Configuration Tokens: */ +// #define DISABLE_TERMINAL_CODES + + /* USB Class Driver Related Tokens: */ +// #define HID_HOST_BOOT_PROTOCOL_ONLY +// #define HID_STATETABLE_STACK_DEPTH {Insert Value Here} +// #define HID_USAGE_STACK_DEPTH {Insert Value Here} +// #define HID_MAX_COLLECTIONS {Insert Value Here} +// #define HID_MAX_REPORTITEMS {Insert Value Here} +// #define HID_MAX_REPORT_IDS {Insert Value Here} +// #define NO_CLASS_DRIVER_AUTOFLUSH + + /* General USB Driver Related Tokens: */ +// #define USE_STATIC_OPTIONS {Insert Value Here} +// #define USB_STREAM_TIMEOUT_MS {Insert Value Here} +// #define NO_LIMITED_CONTROLLER_CONNECT +// #define NO_SOF_EVENTS + + /* USB Device Mode Driver Related Tokens: */ +// #define USE_RAM_DESCRIPTORS +// #define USE_FLASH_DESCRIPTORS +// #define USE_EEPROM_DESCRIPTORS +// #define NO_INTERNAL_SERIAL +// #define FIXED_CONTROL_ENDPOINT_SIZE {Insert Value Here} +// #define DEVICE_STATE_AS_GPIOR {Insert Value Here} +// #define FIXED_NUM_CONFIGURATIONS {Insert Value Here} +// #define CONTROL_ONLY_DEVICE +// #define MAX_ENDPOINT_INDEX {Insert Value Here} +// #define NO_DEVICE_REMOTE_WAKEUP +// #define NO_DEVICE_SELF_POWER + + #elif (ARCH == ARCH_UC3) + + /* Non-USB Related Configuration Tokens: */ +// #define DISABLE_TERMINAL_CODES + + /* USB Class Driver Related Tokens: */ +// #define HID_HOST_BOOT_PROTOCOL_ONLY +// #define HID_STATETABLE_STACK_DEPTH {Insert Value Here} +// #define HID_USAGE_STACK_DEPTH {Insert Value Here} +// #define HID_MAX_COLLECTIONS {Insert Value Here} +// #define HID_MAX_REPORTITEMS {Insert Value Here} +// #define HID_MAX_REPORT_IDS {Insert Value Here} +// #define NO_CLASS_DRIVER_AUTOFLUSH + + /* General USB Driver Related Tokens: */ +// #define ORDERED_EP_CONFIG +// #define USE_STATIC_OPTIONS {Insert Value Here} +// #define USB_DEVICE_ONLY +// #define USB_HOST_ONLY +// #define USB_STREAM_TIMEOUT_MS {Insert Value Here} +// #define NO_SOF_EVENTS + + /* USB Device Mode Driver Related Tokens: */ +// #define NO_INTERNAL_SERIAL +// #define FIXED_CONTROL_ENDPOINT_SIZE {Insert Value Here} +// #define FIXED_NUM_CONFIGURATIONS {Insert Value Here} +// #define CONTROL_ONLY_DEVICE +// #define INTERRUPT_CONTROL_ENDPOINT +// #define NO_DEVICE_REMOTE_WAKEUP +// #define NO_DEVICE_SELF_POWER + + /* USB Host Mode Driver Related Tokens: */ +// #define USB_HOST_TIMEOUT_MS {Insert Value Here} +// #define HOST_DEVICE_SETTLE_DELAY_MS {Insert Value Here} +// #define NO_AUTO_VBUS_MANAGEMENT +// #define INVERTED_VBUS_ENABLE_LINE + + #else + + #error Unsupported architecture for this LUFA configuration file. + + #endif +#endif + diff --git a/protocol/lufa/LUFA-120730/LUFA/CodeTemplates/makefile_template b/protocol/lufa/LUFA-120730/LUFA/CodeTemplates/makefile_template new file mode 100644 index 00000000..ae6cfd3e --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/CodeTemplates/makefile_template @@ -0,0 +1,36 @@ +# +# LUFA Library +# Copyright (C) Dean Camera, 2012. +# +# dean [at] fourwalledcubicle [dot] com +# www.lufa-lib.org +# +# -------------------------------------- +# LUFA Project Makefile. +# -------------------------------------- + +MCU = at90usb1287 +ARCH = AVR8 +BOARD = USBKEY +F_CPU = 8000000 +F_USB = $(F_CPU) +OPTIMIZATION = s +TARGET = Target +SRC = $(TARGET).c $(LUFA_SRC_USB) $(LUFA_SRC_USBCLASS) $(LUFA_SRC_PLATFORM) +LUFA_PATH = ../../LUFA +CC_FLAGS = -DUSE_LUFA_CONFIG_HEADER -IConfig +LD_FLAGS = + +# Default target +all: + +# Include LUFA build script makefiles +include $(LUFA_PATH)/Build/lufa_core.mk +include $(LUFA_PATH)/Build/lufa_sources.mk +include $(LUFA_PATH)/Build/lufa_build.mk +include $(LUFA_PATH)/Build/lufa_cppcheck.mk +include $(LUFA_PATH)/Build/lufa_doxygen.mk +include $(LUFA_PATH)/Build/lufa_dfu.mk +include $(LUFA_PATH)/Build/lufa_hid.mk +include $(LUFA_PATH)/Build/lufa_avrdude.mk +include $(LUFA_PATH)/Build/lufa_atprogram.mk diff --git a/protocol/lufa/LUFA-120730/LUFA/Common/ArchitectureSpecific.h b/protocol/lufa/LUFA-120730/LUFA/Common/ArchitectureSpecific.h new file mode 100644 index 00000000..1e09edf2 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Common/ArchitectureSpecific.h @@ -0,0 +1,177 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Architecture specific definitions relating to specific processor architectures. + * + * \copydetails Group_ArchitectureSpecific + * + * \note Do not include this file directly, rather include the Common.h header file instead to gain this file's + * functionality. + */ + +/** \ingroup Group_Common + * \defgroup Group_ArchitectureSpecific Architecture Specific Definitions + * \brief Architecture specific definitions relating to specific processor architectures. + * + * Architecture specific macros, functions and other definitions, which relate to specific architectures. This + * definitions may or may not be available in some form on other architectures, and thus should be protected by + * preprocessor checks in portable code to prevent compile errors. + * + * @{ + */ + +#ifndef __LUFA_ARCHSPEC_H__ +#define __LUFA_ARCHSPEC_H__ + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_COMMON_H) + #error Do not include this file directly. Include LUFA/Common/Common.h instead to gain this functionality. + #endif + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + #if (ARCH == ARCH_AVR8) || (ARCH == ARCH_XMEGA) || defined(__DOXYGEN__) + #if (ARCH == ARCH_AVR8) || defined(__DOXYGEN__) + /** Re-enables the AVR's JTAG bus in software, until a system reset. This will re-enable JTAG debugging + * interface after is has been disabled in software via \ref JTAG_DISABLE(). + * + * \note This macro is not available for all architectures. + */ + #define JTAG_ENABLE() MACROS{ \ + __asm__ __volatile__ ( \ + "in __tmp_reg__,__SREG__" "\n\t" \ + "cli" "\n\t" \ + "out %1, %0" "\n\t" \ + "out __SREG__, __tmp_reg__" "\n\t" \ + "out %1, %0" "\n\t" \ + : \ + : "r" (MCUCR & ~(1 << JTD)), \ + "M" (_SFR_IO_ADDR(MCUCR)) \ + : "r0"); \ + }MACROE + + /** Disables the AVR's JTAG bus in software, until a system reset. This will override the current JTAG + * status as set by the JTAGEN fuse, disabling JTAG debugging and reverting the JTAG pins back to GPIO + * mode. + * + * \note This macro is not available for all architectures. + */ + #define JTAG_DISABLE() MACROS{ \ + __asm__ __volatile__ ( \ + "in __tmp_reg__,__SREG__" "\n\t" \ + "cli" "\n\t" \ + "out %1, %0" "\n\t" \ + "out __SREG__, __tmp_reg__" "\n\t" \ + "out %1, %0" "\n\t" \ + : \ + : "r" (MCUCR | (1 << JTD)), \ + "M" (_SFR_IO_ADDR(MCUCR)) \ + : "r0"); \ + }MACROE + #endif + + /** Defines a volatile \c NOP statement which cannot be optimized out by the compiler, and thus can always + * be set as a breakpoint in the resulting code. Useful for debugging purposes, where the optimizer + * removes/reorders code to the point where break points cannot reliably be set. + * + * \note This macro is not available for all architectures. + */ + #define JTAG_DEBUG_POINT() __asm__ __volatile__ ("nop" ::) + + /** Defines an explicit JTAG break point in the resulting binary via the assembly \c BREAK statement. When + * a JTAG is used, this causes the program execution to halt when reached until manually resumed. + * + * \note This macro is not available for all architectures. + */ + #define JTAG_DEBUG_BREAK() __asm__ __volatile__ ("break" ::) + + /** Macro for testing condition "x" and breaking via \ref JTAG_DEBUG_BREAK() if the condition is false. + * + * \note This macro is not available for all architectures. + * + * \param[in] Condition Condition that will be evaluated. + */ + #define JTAG_ASSERT(Condition) MACROS{ if (!(Condition)) { JTAG_DEBUG_BREAK(); } }MACROE + + /** Macro for testing condition \c "x" and writing debug data to the stdout stream if \c false. The stdout stream + * must be pre-initialized before this macro is run and linked to an output device, such as the microcontroller's + * USART peripheral. + * + * The output takes the form "{FILENAME}: Function {FUNCTION NAME}, Line {LINE NUMBER}: Assertion {Condition} failed." + * + * \note This macro is not available for all architectures. + * + * \param[in] Condition Condition that will be evaluated, + */ + #define STDOUT_ASSERT(Condition) MACROS{ if (!(x)) { \ + printf_P(PSTR("%s: Function \"%s\", Line %d: " \ + "Assertion \"%s\" failed.\r\n"), \ + __FILE__, __func__, __LINE__, #Condition); } }MACROE + + #if !defined(pgm_read_ptr) || defined(__DOXYGEN__) + /** Reads a pointer out of PROGMEM space on the AVR8 architecture. This is currently a wrapper for the + * avr-libc \c pgm_read_ptr() macro with a \c void* cast, so that its value can be assigned directly + * to a pointer variable or used in pointer arithmetic without further casting in C. In a future + * avr-libc distribution this will be part of the standard API and will be implemented in a more formal + * manner. + * + * \note This macro is not available for all architectures. + * + * \param[in] Address Address of the pointer to read. + * + * \return Pointer retrieved from PROGMEM space. + */ + #define pgm_read_ptr(Address) (void*)pgm_read_word(Address) + #endif + #elif (ARCH == ARCH_UC3) + #define JTAG_DEBUG_POINT() __asm__ __volatile__ ("nop" ::) + #define JTAG_DEBUG_BREAK() __asm__ __volatile__ ("breakpoint" ::) + #define JTAG_ASSERT(Condition) MACROS{ if (!(Condition)) { JTAG_DEBUG_BREAK(); } }MACROE + #define STDOUT_ASSERT(Condition) MACROS{ if (!(x)) { \ + printf("%s: Function \"%s\", Line %d: " \ + "Assertion \"%s\" failed.\r\n"), \ + __FILE__, __func__, __LINE__, #Condition); } }MACROE + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Common/Architectures.h b/protocol/lufa/LUFA-120730/LUFA/Common/Architectures.h new file mode 100644 index 00000000..8941f7c0 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Common/Architectures.h @@ -0,0 +1,84 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Supported library architecture defines. + * + * \copydetails Group_Architectures + * + * \note Do not include this file directly, rather include the Common.h header file instead to gain this file's + * functionality. + */ + +/** \ingroup Group_Common + * \defgroup Group_Architectures Hardware Architectures + * \brief Supported library architecture defines. + * + * Architecture macros for selecting the desired target microcontroller architecture. One of these values should be + * defined as the value of \c ARCH in the user project makefile via the \c -D compiler switch to GCC, to select the + * target architecture. + * + * The selected architecture should remain consistent with the makefile \c ARCH value, which is used to select the + * underlying driver source files for each architecture. + * + * @{ + */ + +#ifndef __LUFA_ARCHITECTURES_H__ +#define __LUFA_ARCHITECTURES_H__ + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_COMMON_H) + #error Do not include this file directly. Include LUFA/Common/Common.h instead to gain this functionality. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Selects the Atmel 8-bit AVR (AT90USB* and ATMEGA*U* chips) architecture. */ + #define ARCH_AVR8 0 + + /** Selects the Atmel 32-bit UC3 AVR (AT32UC3* chips) architecture. */ + #define ARCH_UC3 1 + + /** Selects the Atmel XMEGA AVR (ATXMEGA*U chips) architecture. */ + #define ARCH_XMEGA 2 + + #if !defined(__DOXYGEN__) + #define ARCH_ ARCH_AVR8 + + #if !defined(ARCH) + #define ARCH ARCH_AVR8 + #endif + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Common/Attributes.h b/protocol/lufa/LUFA-120730/LUFA/Common/Attributes.h new file mode 100644 index 00000000..fce75d0e --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Common/Attributes.h @@ -0,0 +1,150 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Special function/variable attribute macros. + * + * \copydetails Group_FuncVarAttributes + * + * \note Do not include this file directly, rather include the Common.h header file instead to gain this file's + * functionality. + */ + +/** \ingroup Group_Common + * \defgroup Group_FuncVarAttributes Function/Variable Attributes + * \brief Special function/variable attribute macros. + * + * This module contains macros for applying specific attributes to functions and variables to control various + * optimizer and code generation features of the compiler. Attributes may be placed in the function prototype + * or variable declaration in any order, and multiple attributes can be specified for a single item via a space + * separated list. + * + * On incompatible versions of GCC or on other compilers, these macros evaluate to nothing unless they are + * critical to the code's function and thus must throw a compile error when used. + * + * @{ + */ + +#ifndef __LUFA_ATTR_H__ +#define __LUFA_ATTR_H__ + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_COMMON_H) + #error Do not include this file directly. Include LUFA/Common/Common.h instead to gain this functionality. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + #if (__GNUC__ >= 3) || defined(__DOXYGEN__) + /** Indicates to the compiler that the function can not ever return, so that any stack restoring or + * return code may be omitted by the compiler in the resulting binary. + */ + #define ATTR_NO_RETURN __attribute__ ((noreturn)) + + /** Indicates that the function returns a value which should not be ignored by the user code. When + * applied, any ignored return value from calling the function will produce a compiler warning. + */ + #define ATTR_WARN_UNUSED_RESULT __attribute__ ((warn_unused_result)) + + /** Indicates that the specified parameters of the function are pointers which should never be \c NULL. + * When applied as a 1-based comma separated list the compiler will emit a warning if the specified + * parameters are known at compiler time to be \c NULL at the point of calling the function. + */ + #define ATTR_NON_NULL_PTR_ARG(...) __attribute__ ((nonnull (__VA_ARGS__))) + + /** Removes any preamble or postamble from the function. When used, the function will not have any + * register or stack saving code. This should be used with caution, and when used the programmer + * is responsible for maintaining stack and register integrity. + */ + #define ATTR_NAKED __attribute__ ((naked)) + + /** Prevents the compiler from considering a specified function for in-lining. When applied, the given + * function will not be in-lined under any circumstances. + */ + #define ATTR_NO_INLINE __attribute__ ((noinline)) + + /** Forces the compiler to inline the specified function. When applied, the given function will be + * in-lined under all circumstances. + */ + #define ATTR_ALWAYS_INLINE __attribute__ ((always_inline)) + + /** Indicates that the specified function is pure, in that it has no side-effects other than global + * or parameter variable access. + */ + #define ATTR_PURE __attribute__ ((pure)) + + /** Indicates that the specified function is constant, in that it has no side effects other than + * parameter access. + */ + #define ATTR_CONST __attribute__ ((const)) + + /** Marks a given function as deprecated, which produces a warning if the function is called. */ + #define ATTR_DEPRECATED __attribute__ ((deprecated)) + + /** Marks a function as a weak reference, which can be overridden by other functions with an + * identical name (in which case the weak reference is discarded at link time). + */ + #define ATTR_WEAK __attribute__ ((weak)) + #endif + + /** Forces the compiler to not automatically zero the given global variable on startup, so that the + * current RAM contents is retained. Under most conditions this value will be random due to the + * behavior of volatile memory once power is removed, but may be used in some specific circumstances, + * like the passing of values back after a system watchdog reset. + */ + #define ATTR_NO_INIT __attribute__ ((section (".noinit"))) + + /** Places the function in one of the initialization sections, which execute before the main function + * of the application. Refer to the avr-libc manual for more information on the initialization sections. + * + * \param[in] SectionIndex Initialization section number where the function should be placed. + */ + #define ATTR_INIT_SECTION(SectionIndex) __attribute__ ((used, naked, section (".init" #SectionIndex ))) + + /** Marks a function as an alias for another function. + * + * \param[in] Func Name of the function which the given function name should alias. + */ + #define ATTR_ALIAS(Func) __attribute__ ((alias( #Func ))) + + /** Marks a variable or struct element for packing into the smallest space available, omitting any + * alignment bytes usually added between fields to optimize field accesses. + */ + #define ATTR_PACKED __attribute__ ((packed)) + + /** Indicates the minimum alignment in bytes for a variable or struct element. + * + * \param[in] Bytes Minimum number of bytes the item should be aligned to. + */ + #define ATTR_ALIGNED(Bytes) __attribute__ ((aligned(Bytes))) +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Common/BoardTypes.h b/protocol/lufa/LUFA-120730/LUFA/Common/BoardTypes.h new file mode 100644 index 00000000..4c152dab --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Common/BoardTypes.h @@ -0,0 +1,231 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Supported pre-made board hardware defines. + * + * \copydetails Group_BoardTypes + * + * \note Do not include this file directly, rather include the Common.h header file instead to gain this file's + * functionality. + */ + +/** \ingroup Group_Common + * \defgroup Group_BoardTypes Board Types + * \brief Supported pre-made board hardware defines. + * + * Board macros for indicating the chosen physical board hardware to the library. These macros should be used when + * defining the \c BOARD token to the chosen hardware via the \c -D switch in the project makefile. If a custom + * board is used, the \ref BOARD_NONE or \ref BOARD_USER values should be selected. + * + * @{ + */ + +#ifndef __LUFA_BOARDTYPES_H__ +#define __LUFA_BOARDTYPES_H__ + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_COMMON_H) + #error Do not include this file directly. Include LUFA/Common/Common.h instead to gain this functionality. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Selects the user-defined board drivers, which should be placed in the user project's folder + * under a directory named \c /Board/. Each board driver should be named identically to the LUFA + * master board driver (i.e., driver in the \c LUFA/Drivers/Board directory) so that the library + * can correctly identify it. + */ + #define BOARD_USER 0 + + /** Disables board drivers when operation will not be adversely affected (e.g. LEDs) - use of board drivers + * such as the Joystick driver, where the removal would adversely affect the code's operation is still disallowed. */ + #define BOARD_NONE 1 + + /** Selects the USBKEY specific board drivers, including Temperature, Button, Dataflash, Joystick and LED drivers. */ + #define BOARD_USBKEY 2 + + /** Selects the STK525 specific board drivers, including Temperature, Button, Dataflash, Joystick and LED drivers. */ + #define BOARD_STK525 3 + + /** Selects the STK526 specific board drivers, including Temperature, Button, Dataflash, Joystick and LED drivers. */ + #define BOARD_STK526 4 + + /** Selects the RZUSBSTICK specific board drivers, including the driver for the boards LEDs. */ + #define BOARD_RZUSBSTICK 5 + + /** Selects the ATAVRUSBRF01 specific board drivers, including the driver for the board LEDs. */ + #define BOARD_ATAVRUSBRF01 6 + + /** Selects the BUMBLEB specific board drivers, using the officially recommended peripheral layout. */ + #define BOARD_BUMBLEB 7 + + /** Selects the XPLAIN (Revision 2 or newer) specific board drivers, including LED and Dataflash drivers. */ + #define BOARD_XPLAIN 8 + + /** Selects the XPLAIN (Revision 1) specific board drivers, including LED and Dataflash drivers. */ + #define BOARD_XPLAIN_REV1 9 + + /** Selects the EVK527 specific board drivers, including Temperature, Button, Dataflash, Joystick and LED drivers. */ + #define BOARD_EVK527 10 + + /** Selects the Teensy version 1.x specific board drivers, including the driver for the board LEDs. */ + #define BOARD_TEENSY 11 + + /** Selects the USBTINY MKII specific board drivers, including the Button and LEDs drivers. */ + #define BOARD_USBTINYMKII 12 + + /** Selects the Benito specific board drivers, including the Button and LEDs drivers. */ + #define BOARD_BENITO 13 + + /** Selects the JM-DB-U2 specific board drivers, including the Button and LEDs drivers. */ + #define BOARD_JMDBU2 14 + + /** Selects the Olimex AVR-USB-162 specific board drivers, including the Button and LEDs drivers. */ + #define BOARD_OLIMEX162 15 + + /** Selects the UDIP specific board drivers, including the Button and LEDs drivers. */ + #define BOARD_UDIP 16 + + /** Selects the BUI specific board drivers, including the driver for the board LEDs. */ + #define BOARD_BUI 17 + + /** Selects the Arduino Uno specific board drivers, including the driver for the board LEDs. */ + #define BOARD_UNO 18 + + /** Selects the Busware CUL V3 specific board drivers, including the Button and LEDs drivers. */ + #define BOARD_CULV3 19 + + /** Selects the Blackcat USB JTAG specific board drivers, including the driver for the board LEDs. */ + #define BOARD_BLACKCAT 20 + + /** Selects the Maximus specific board drivers, including the driver for the board LEDs. */ + #define BOARD_MAXIMUS 21 + + /** Selects the Minimus specific board drivers, including the Button and LEDs drivers. */ + #define BOARD_MINIMUS 22 + + /** Selects the Adafruit U4 specific board drivers, including the Button driver. */ + #define BOARD_ADAFRUITU4 23 + + /** Selects the Microsin AVR-USB162 specific board drivers, including the Button and LEDs drivers. */ + #define BOARD_MICROSIN162 24 + + /** Selects the Kernel Concepts USBFOO specific board drivers, including the Button and LEDs drivers. */ + #define BOARD_USBFOO 25 + + /** Selects the Sparkfun ATMEGA8U2 specific board drivers, including the driver for the board LEDs. */ + #define BOARD_SPARKFUN8U2 26 + + /** Selects the Atmel EVK1101 specific board drivers, including the Button, Joystick and LED drivers. */ + #define BOARD_EVK1101 27 + + /** Selects the Busware TUL specific board drivers, including the Button and LED drivers. */ + #define BOARD_TUL 28 + + /** Selects the Atmel EVK1100 specific board drivers, including the Button, Joystick and LED drivers. */ + #define BOARD_EVK1100 29 + + /** Selects the Atmel EVK1104 specific board drivers, including the Button and LED drivers. */ + #define BOARD_EVK1104 30 + + /** Selects the Atmel XMEGA A3BU Xplained specific board drivers, including Dataflash, Button and LED drivers. */ + #define BOARD_A3BU_XPLAINED 31 + + /** Selects the Teensy version 2.x specific board drivers, including the driver for the board LEDs. */ + #define BOARD_TEENSY2 32 + + /** Selects the USB2AX version 1 and 2 specific board drivers, including the Button and LEDs drivers. */ + #define BOARD_USB2AX 33 + + /** Selects the USB2AX version 3 specific board drivers, including the Button and LEDs drivers. */ + #define BOARD_USB2AX_V3 34 + + /** Selects the Micropendous 32U2 specific board drivers, including the Button and LED drivers. */ + #define BOARD_MICROPENDOUS_32U2 35 + + /** Selects the Micropendous A specific board drivers, including the driver for the board Button. */ + #define BOARD_MICROPENDOUS_A 36 + + /** Selects the Micropendous 1 specific board drivers, including the driver for the board Button. */ + #define BOARD_MICROPENDOUS_1 37 + + /** Selects the Micropendous 2 specific board drivers, including the driver for the board Button. */ + #define BOARD_MICROPENDOUS_2 38 + + /** Selects the Micropendous 3 specific board drivers, including the driver for the board Button. */ + #define BOARD_MICROPENDOUS_3 39 + + /** Selects the Micropendous 4 specific board drivers, including the driver for the board Button. */ + #define BOARD_MICROPENDOUS_4 40 + + /** Selects the Micropendous DIP specific board drivers, including the driver for the board Button. */ + #define BOARD_MICROPENDOUS_DIP 41 + + /** Selects the Micropendous (Arduino-like) revision 1 specific board drivers, including the Button and LED drivers. */ + #define BOARD_MICROPENDOUS_REV1 42 + + /** Selects the Micropendous (Arduino-like) revision 2 specific board drivers, including the Button and LED drivers. */ + #define BOARD_MICROPENDOUS_REV2 43 + + /** Selects the XMEGA B1 Xplained specific board drivers, including the Button and LED drivers. */ + #define BOARD_B1_XPLAINED 44 + + /** Selects the Bitwizard Multio specific board drivers, including the driver for the board LEDs. */ + #define BOARD_MULTIO 45 + + /** Selects the Bitwizard Big-Multio specific board drivers, including the driver for the board LEDs. */ + #define BOARD_BIGMULTIO 46 + + /** Selects the DorkbotPDX Duce specific board drivers, including the driver for the board LEDs. */ + #define BOARD_DUCE 47 + + /** Selects the Olimex AVR-USB-32U4 specific board drivers, including the Button and LED drivers. */ + #define BOARD_OLIMEX32U4 48 + + /** Selects the Olimex AVR-USB-T32U4 specific board drivers, including the Button and LED drivers. */ + #define BOARD_OLIMEXT32U4 49 + + /** Selects the Olimex AVR-ISP-MK2 specific board drivers, including the Button and LED drivers. */ + #define BOARD_OLIMEXISPMK2 50 + + + #if !defined(__DOXYGEN__) + #define BOARD_ BOARD_NONE + + #if !defined(BOARD) + #define BOARD BOARD_NONE + #endif + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Common/Common.h b/protocol/lufa/LUFA-120730/LUFA/Common/Common.h new file mode 100644 index 00000000..cf1f49b9 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Common/Common.h @@ -0,0 +1,381 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \dir + * \brief Common library header files. + * + * This folder contains header files which are common to all parts of the LUFA library. They may be used freely in + * user applications. + */ + +/** \file + * \brief Common library convenience headers, macros and functions. + * + * \copydetails Group_Common + */ + +/** \defgroup Group_Common Common Utility Headers - LUFA/Drivers/Common/Common.h + * \brief Common library convenience headers, macros and functions. + * + * Common utility headers containing macros, functions, enums and types which are common to all + * aspects of the library. + * + * @{ + */ + +/** \defgroup Group_GlobalInt Global Interrupt Macros + * \brief Convenience macros for the management of interrupts globally within the device. + * + * Macros and functions to create and control global interrupts within the device. + */ + +#ifndef __LUFA_COMMON_H__ +#define __LUFA_COMMON_H__ + + /* Macros: */ + #define __INCLUDE_FROM_COMMON_H + + /* Includes: */ + #include + #include + #include + #include + + #include "Architectures.h" + #include "BoardTypes.h" + #include "ArchitectureSpecific.h" + #include "CompilerSpecific.h" + #include "Attributes.h" + + #if defined(USE_LUFA_CONFIG_HEADER) + #include "LUFAConfig.h" + #endif + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Architecture specific utility includes: */ + #if defined(__DOXYGEN__) + /** Type define for an unsigned integer the same width as the selected architecture's machine register. + * This is distinct from the non-specific standard int data type, whose width is machine dependant but + * which may not reflect the actual machine register width on some targets (e.g. AVR8). + */ + typedef MACHINE_REG_t uint_reg_t; + #elif (ARCH == ARCH_AVR8) + #include + #include + #include + #include + #include + #include + #include + + typedef uint8_t uint_reg_t; + + #define ARCH_HAS_EEPROM_ADDRESS_SPACE + #define ARCH_HAS_FLASH_ADDRESS_SPACE + #define ARCH_HAS_MULTI_ADDRESS_SPACE + #define ARCH_LITTLE_ENDIAN + + #include "Endianness.h" + #elif (ARCH == ARCH_UC3) + #include + #include + + // === TODO: Find abstracted way to handle these === + #define PROGMEM + #define pgm_read_byte(x) *x + #define memcmp_P(...) memcmp(__VA_ARGS__) + #define memcpy_P(...) memcpy(__VA_ARGS__) + // ================================================= + + typedef uint32_t uint_reg_t; + + #define ARCH_BIG_ENDIAN + + #include "Endianness.h" + #elif (ARCH == ARCH_XMEGA) + #include + #include + #include + #include + #include + #include + + typedef uint8_t uint_reg_t; + + #define ARCH_HAS_EEPROM_ADDRESS_SPACE + #define ARCH_HAS_FLASH_ADDRESS_SPACE + #define ARCH_HAS_MULTI_ADDRESS_SPACE + #define ARCH_LITTLE_ENDIAN + + #include "Endianness.h" + #else + #error Unknown device architecture specified. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Macro for encasing other multi-statement macros. This should be used along with an opening brace + * before the start of any multi-statement macro, so that the macros contents as a whole are treated + * as a discrete block and not as a list of separate statements which may cause problems when used as + * a block (such as inline \c if statements). + */ + #define MACROS do + + /** Macro for encasing other multi-statement macros. This should be used along with a preceding closing + * brace at the end of any multi-statement macro, so that the macros contents as a whole are treated + * as a discrete block and not as a list of separate statements which may cause problems when used as + * a block (such as inline \c if statements). + */ + #define MACROE while (0) + + /** Convenience macro to determine the larger of two values. + * + * \attention This macro should only be used with operands that do not have side effects from being evaluated + * multiple times. + * + * \param[in] x First value to compare + * \param[in] y First value to compare + * + * \return The larger of the two input parameters + */ + #if !defined(MAX) || defined(__DOXYGEN__) + #define MAX(x, y) (((x) > (y)) ? (x) : (y)) + #endif + + /** Convenience macro to determine the smaller of two values. + * + * \attention This macro should only be used with operands that do not have side effects from being evaluated + * multiple times. + * + * \param[in] x First value to compare + * \param[in] y First value to compare + * + * \return The smaller of the two input parameters + */ + #if !defined(MIN) || defined(__DOXYGEN__) + #define MIN(x, y) (((x) < (y)) ? (x) : (y)) + #endif + + #if !defined(STRINGIFY) || defined(__DOXYGEN__) + /** Converts the given input into a string, via the C Preprocessor. This macro puts literal quotation + * marks around the input, converting the source into a string literal. + * + * \param[in] x Input to convert into a string literal. + * + * \return String version of the input. + */ + #define STRINGIFY(x) #x + + /** Converts the given input into a string after macro expansion, via the C Preprocessor. This macro puts + * literal quotation marks around the expanded input, converting the source into a string literal. + * + * \param[in] x Input to expand and convert into a string literal. + * + * \return String version of the expanded input. + */ + #define STRINGIFY_EXPANDED(x) STRINGIFY(x) + #endif + + #if !defined(ISR) || defined(__DOXYGEN__) + /** Macro for the definition of interrupt service routines, so that the compiler can insert the required + * prologue and epilogue code to properly manage the interrupt routine without affecting the main thread's + * state with unintentional side-effects. + * + * Interrupt handlers written using this macro may still need to be registered with the microcontroller's + * Interrupt Controller (if present) before they will properly handle incoming interrupt events. + * + * \note This macro is only supplied on some architectures, where the standard library does not include a valid + * definition. If an existing definition exists, the alternative definition here will be ignored. + * + * \ingroup Group_GlobalInt + * + * \param[in] Name Unique name of the interrupt service routine. + */ + #define ISR(Name, ...) void Name (void) __attribute__((__interrupt__)) __VA_ARGS__; void Name (void) + #endif + + /* Inline Functions: */ + /** Function to reverse the individual bits in a byte - i.e. bit 7 is moved to bit 0, bit 6 to bit 1, + * etc. + * + * \param[in] Byte Byte of data whose bits are to be reversed. + * + * \return Input data with the individual bits reversed (mirrored). + */ + static inline uint8_t BitReverse(uint8_t Byte) ATTR_WARN_UNUSED_RESULT ATTR_CONST; + static inline uint8_t BitReverse(uint8_t Byte) + { + Byte = (((Byte & 0xF0) >> 4) | ((Byte & 0x0F) << 4)); + Byte = (((Byte & 0xCC) >> 2) | ((Byte & 0x33) << 2)); + Byte = (((Byte & 0xAA) >> 1) | ((Byte & 0x55) << 1)); + + return Byte; + } + + /** Function to perform a blocking delay for a specified number of milliseconds. The actual delay will be + * at a minimum the specified number of milliseconds, however due to loop overhead and internal calculations + * may be slightly higher. + * + * \param[in] Milliseconds Number of milliseconds to delay + */ + static inline void Delay_MS(uint16_t Milliseconds) ATTR_ALWAYS_INLINE; + static inline void Delay_MS(uint16_t Milliseconds) + { + #if (ARCH == ARCH_AVR8) + if (GCC_IS_COMPILE_CONST(Milliseconds)) + { + _delay_ms(Milliseconds); + } + else + { + while (Milliseconds--) + _delay_ms(1); + } + #elif (ARCH == ARCH_UC3) + while (Milliseconds--) + { + __builtin_mtsr(AVR32_COUNT, 0); + while ((uint32_t)__builtin_mfsr(AVR32_COUNT) < (F_CPU / 1000)); + } + #elif (ARCH == ARCH_XMEGA) + if (GCC_IS_COMPILE_CONST(Milliseconds)) + { + _delay_ms(Milliseconds); + } + else + { + while (Milliseconds--) + _delay_ms(1); + } + #endif + } + + /** Retrieves a mask which contains the current state of the global interrupts for the device. This + * value can be stored before altering the global interrupt enable state, before restoring the + * flag(s) back to their previous values after a critical section using \ref SetGlobalInterruptMask(). + * + * \ingroup Group_GlobalInt + * + * \return Mask containing the current Global Interrupt Enable Mask bit(s). + */ + static inline uint_reg_t GetGlobalInterruptMask(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT; + static inline uint_reg_t GetGlobalInterruptMask(void) + { + GCC_MEMORY_BARRIER(); + + #if (ARCH == ARCH_AVR8) + return SREG; + #elif (ARCH == ARCH_UC3) + return __builtin_mfsr(AVR32_SR); + #elif (ARCH == ARCH_XMEGA) + return SREG; + #endif + } + + /** Sets the global interrupt enable state of the microcontroller to the mask passed into the function. + * This can be combined with \ref GetGlobalInterruptMask() to save and restore the Global Interrupt Enable + * Mask bit(s) of the device after a critical section has completed. + * + * \ingroup Group_GlobalInt + * + * \param[in] GlobalIntState Global Interrupt Enable Mask value to use + */ + static inline void SetGlobalInterruptMask(const uint_reg_t GlobalIntState) ATTR_ALWAYS_INLINE; + static inline void SetGlobalInterruptMask(const uint_reg_t GlobalIntState) + { + GCC_MEMORY_BARRIER(); + + #if (ARCH == ARCH_AVR8) + SREG = GlobalIntState; + #elif (ARCH == ARCH_UC3) + if (GlobalIntState & AVR32_SR_GM) + __builtin_ssrf(AVR32_SR_GM_OFFSET); + else + __builtin_csrf(AVR32_SR_GM_OFFSET); + #elif (ARCH == ARCH_XMEGA) + SREG = GlobalIntState; + #endif + + GCC_MEMORY_BARRIER(); + } + + /** Enables global interrupt handling for the device, allowing interrupts to be handled. + * + * \ingroup Group_GlobalInt + */ + static inline void GlobalInterruptEnable(void) ATTR_ALWAYS_INLINE; + static inline void GlobalInterruptEnable(void) + { + GCC_MEMORY_BARRIER(); + + #if (ARCH == ARCH_AVR8) + sei(); + #elif (ARCH == ARCH_UC3) + __builtin_csrf(AVR32_SR_GM_OFFSET); + #elif (ARCH == ARCH_XMEGA) + sei(); + #endif + + GCC_MEMORY_BARRIER(); + } + + /** Disabled global interrupt handling for the device, preventing interrupts from being handled. + * + * \ingroup Group_GlobalInt + */ + static inline void GlobalInterruptDisable(void) ATTR_ALWAYS_INLINE; + static inline void GlobalInterruptDisable(void) + { + GCC_MEMORY_BARRIER(); + + #if (ARCH == ARCH_AVR8) + cli(); + #elif (ARCH == ARCH_UC3) + __builtin_ssrf(AVR32_SR_GM_OFFSET); + #elif (ARCH == ARCH_XMEGA) + cli(); + #endif + + GCC_MEMORY_BARRIER(); + } + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Common/CompilerSpecific.h b/protocol/lufa/LUFA-120730/LUFA/Common/CompilerSpecific.h new file mode 100644 index 00000000..22afe940 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Common/CompilerSpecific.h @@ -0,0 +1,97 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Compiler specific definitions for code optimization and correctness. + * + * \copydetails Group_CompilerSpecific + * + * \note Do not include this file directly, rather include the Common.h header file instead to gain this file's + * functionality. + */ + +/** \ingroup Group_Common + * \defgroup Group_CompilerSpecific Compiler Specific Definitions + * \brief Compiler specific definitions for code optimization and correctness. + * + * Compiler specific definitions to expose certain compiler features which may increase the level of code optimization + * for a specific compiler, or correct certain issues that may be present such as memory barriers for use in conjunction + * with atomic variable access. + * + * Where possible, on alternative compilers, these macros will either have no effect, or default to returning a sane value + * so that they can be used in existing code without the need for extra compiler checks in the user application code. + * + * @{ + */ + +#ifndef __LUFA_COMPILERSPEC_H__ +#define __LUFA_COMPILERSPEC_H__ + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_COMMON_H) + #error Do not include this file directly. Include LUFA/Common/Common.h instead to gain this functionality. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + #if defined(__GNUC__) || defined(__DOXYGEN__) + /** Forces GCC to use pointer indirection (via the device's pointer register pairs) when accessing the given + * struct pointer. In some cases GCC will emit non-optimal assembly code when accessing a structure through + * a pointer, resulting in a larger binary. When this macro is used on a (non \c const) structure pointer before + * use, it will force GCC to use pointer indirection on the elements rather than direct store and load + * instructions. + * + * \param[in, out] StructPtr Pointer to a structure which is to be forced into indirect access mode. + */ + #define GCC_FORCE_POINTER_ACCESS(StructPtr) __asm__ __volatile__("" : "=b" (StructPtr) : "0" (StructPtr)) + + /** Forces GCC to create a memory barrier, ensuring that memory accesses are not reordered past the barrier point. + * This can be used before ordering-critical operations, to ensure that the compiler does not re-order the resulting + * assembly output in an unexpected manner on sections of code that are ordering-specific. + */ + #define GCC_MEMORY_BARRIER() __asm__ __volatile__("" ::: "memory"); + + /** Determines if the specified value can be determined at compile-time to be a constant value when compiling under GCC. + * + * \param[in] x Value to check compile-time constantness of. + * + * \return Boolean true if the given value is known to be a compile time constant, false otherwise. + */ + #define GCC_IS_COMPILE_CONST(x) __builtin_constant_p(x) + #else + #define GCC_FORCE_POINTER_ACCESS(StructPtr) + #define GCC_MEMORY_BARRIER() + #define GCC_IS_COMPILE_CONST(x) 0 + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Common/Endianness.h b/protocol/lufa/LUFA-120730/LUFA/Common/Endianness.h new file mode 100644 index 00000000..d0812e4e --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Common/Endianness.h @@ -0,0 +1,489 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Endianness and Byte Ordering macros and functions. + * + * \copydetails Group_Endianness + */ + +/** \ingroup Group_Endianness + * \defgroup Group_ByteSwapping Byte Reordering + * \brief Macros and functions for forced byte reordering. + */ + +/** \ingroup Group_Endianness + * \defgroup Group_EndianConversion Endianness Conversion + * \brief Macros and functions for automatic endianness conversion. + */ + +/** \ingroup Group_Common + * \defgroup Group_Endianness Endianness and Byte Ordering + * \brief Convenience macros and functions relating to byte (re-)ordering + * + * Common library convenience macros and functions relating to byte (re-)ordering. + * + * @{ + */ + +#ifndef __LUFA_ENDIANNESS_H__ +#define __LUFA_ENDIANNESS_H__ + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_COMMON_H) + #error Do not include this file directly. Include LUFA/Common/Common.h instead to gain this functionality. + #endif + + #if !(defined(ARCH_BIG_ENDIAN) || defined(ARCH_LITTLE_ENDIAN)) + #error ARCH_BIG_ENDIAN or ARCH_LITTLE_ENDIAN not set for the specified architecture. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Swaps the byte ordering of a 16-bit value at compile-time. Do not use this macro for swapping byte orderings + * of dynamic values computed at runtime, use \ref SwapEndian_16() instead. The result of this macro can be used + * inside struct or other variable initializers outside of a function, something that is not possible with the + * inline function variant. + * + * \ingroup Group_ByteSwapping + * + * \param[in] x 16-bit value whose byte ordering is to be swapped. + * + * \return Input value with the byte ordering reversed. + */ + #define SWAPENDIAN_16(x) (uint16_t)((((x) & 0xFF00) >> 8) | (((x) & 0x00FF) << 8)) + + /** Swaps the byte ordering of a 32-bit value at compile-time. Do not use this macro for swapping byte orderings + * of dynamic values computed at runtime- use \ref SwapEndian_32() instead. The result of this macro can be used + * inside struct or other variable initializers outside of a function, something that is not possible with the + * inline function variant. + * + * \ingroup Group_ByteSwapping + * + * \param[in] x 32-bit value whose byte ordering is to be swapped. + * + * \return Input value with the byte ordering reversed. + */ + #define SWAPENDIAN_32(x) (uint32_t)((((x) & 0xFF000000UL) >> 24UL) | (((x) & 0x00FF0000UL) >> 8UL) | \ + (((x) & 0x0000FF00UL) << 8UL) | (((x) & 0x000000FFUL) << 24UL)) + + #if defined(ARCH_BIG_ENDIAN) && !defined(le16_to_cpu) + #define le16_to_cpu(x) SwapEndian_16(x) + #define le32_to_cpu(x) SwapEndian_32(x) + #define be16_to_cpu(x) (x) + #define be32_to_cpu(x) (x) + #define cpu_to_le16(x) SwapEndian_16(x) + #define cpu_to_le32(x) SwapEndian_32(x) + #define cpu_to_be16(x) (x) + #define cpu_to_be32(x) (x) + #define LE16_TO_CPU(x) SWAPENDIAN_16(x) + #define LE32_TO_CPU(x) SWAPENDIAN_32(x) + #define BE16_TO_CPU(x) (x) + #define BE32_TO_CPU(x) (x) + #define CPU_TO_LE16(x) SWAPENDIAN_16(x) + #define CPU_TO_LE32(x) SWAPENDIAN_32(x) + #define CPU_TO_BE16(x) (x) + #define CPU_TO_BE32(x) (x) + #elif !defined(le16_to_cpu) + /** \name Run-time endianness conversion */ + //@{ + + /** Performs a conversion between a Little Endian encoded 16-bit piece of data and the + * Endianness of the currently selected CPU architecture. + * + * On little endian architectures, this macro does nothing. + * + * \note This macro is designed for run-time conversion of data - for compile-time endianness + * conversion, use \ref LE16_TO_CPU instead. + * + * \ingroup Group_EndianConversion + * + * \param[in] x Data to perform the endianness conversion on. + * + * \return Endian corrected version of the input value. + */ + #define le16_to_cpu(x) (x) + + /** Performs a conversion between a Little Endian encoded 32-bit piece of data and the + * Endianness of the currently selected CPU architecture. + * + * On little endian architectures, this macro does nothing. + * + * \note This macro is designed for run-time conversion of data - for compile-time endianness + * conversion, use \ref LE32_TO_CPU instead. + * + * \ingroup Group_EndianConversion + * + * \param[in] x Data to perform the endianness conversion on. + * + * \return Endian corrected version of the input value. + */ + #define le32_to_cpu(x) (x) + + /** Performs a conversion between a Big Endian encoded 16-bit piece of data and the + * Endianness of the currently selected CPU architecture. + * + * On big endian architectures, this macro does nothing. + * + * \note This macro is designed for run-time conversion of data - for compile-time endianness + * conversion, use \ref BE16_TO_CPU instead. + * + * \ingroup Group_EndianConversion + * + * \param[in] x Data to perform the endianness conversion on. + * + * \return Endian corrected version of the input value. + */ + #define be16_to_cpu(x) SwapEndian_16(x) + + /** Performs a conversion between a Big Endian encoded 32-bit piece of data and the + * Endianness of the currently selected CPU architecture. + * + * On big endian architectures, this macro does nothing. + * + * \note This macro is designed for run-time conversion of data - for compile-time endianness + * conversion, use \ref BE32_TO_CPU instead. + * + * \ingroup Group_EndianConversion + * + * \param[in] x Data to perform the endianness conversion on. + * + * \return Endian corrected version of the input value. + */ + #define be32_to_cpu(x) SwapEndian_32(x) + + /** Performs a conversion on a natively encoded 16-bit piece of data to ensure that it + * is in Little Endian format regardless of the currently selected CPU architecture. + * + * On little endian architectures, this macro does nothing. + * + * \note This macro is designed for run-time conversion of data - for compile-time endianness + * conversion, use \ref CPU_TO_LE16 instead. + * + * \ingroup Group_EndianConversion + * + * \param[in] x Data to perform the endianness conversion on. + * + * \return Endian corrected version of the input value. + */ + #define cpu_to_le16(x) (x) + + /** Performs a conversion on a natively encoded 32-bit piece of data to ensure that it + * is in Little Endian format regardless of the currently selected CPU architecture. + * + * On little endian architectures, this macro does nothing. + * + * \note This macro is designed for run-time conversion of data - for compile-time endianness + * conversion, use \ref CPU_TO_LE32 instead. + * + * \ingroup Group_EndianConversion + * + * \param[in] x Data to perform the endianness conversion on. + * + * \return Endian corrected version of the input value. + */ + #define cpu_to_le32(x) (x) + + /** Performs a conversion on a natively encoded 16-bit piece of data to ensure that it + * is in Big Endian format regardless of the currently selected CPU architecture. + * + * On big endian architectures, this macro does nothing. + * + * \note This macro is designed for run-time conversion of data - for compile-time endianness + * conversion, use \ref CPU_TO_BE16 instead. + * + * \ingroup Group_EndianConversion + * + * \param[in] x Data to perform the endianness conversion on. + * + * \return Endian corrected version of the input value. + */ + #define cpu_to_be16(x) SwapEndian_16(x) + + /** Performs a conversion on a natively encoded 32-bit piece of data to ensure that it + * is in Big Endian format regardless of the currently selected CPU architecture. + * + * On big endian architectures, this macro does nothing. + * + * \note This macro is designed for run-time conversion of data - for compile-time endianness + * conversion, use \ref CPU_TO_BE32 instead. + * + * \ingroup Group_EndianConversion + * + * \param[in] x Data to perform the endianness conversion on. + * + * \return Endian corrected version of the input value. + */ + #define cpu_to_be32(x) SwapEndian_32(x) + + //@} + + /** \name Compile-time endianness conversion */ + //@{ + + /** Performs a conversion between a Little Endian encoded 16-bit piece of data and the + * Endianness of the currently selected CPU architecture. + * + * On little endian architectures, this macro does nothing. + * + * \note This macro is designed for compile-time conversion of data - for run time endianness + * conversion, use \ref le16_to_cpu instead. + * + * \ingroup Group_EndianConversion + * + * \param[in] x Data to perform the endianness conversion on. + * + * \return Endian corrected version of the input value. + */ + #define LE16_TO_CPU(x) (x) + + /** Performs a conversion between a Little Endian encoded 32-bit piece of data and the + * Endianness of the currently selected CPU architecture. + * + * On little endian architectures, this macro does nothing. + * + * \note This macro is designed for compile-time conversion of data - for run time endianness + * conversion, use \ref le32_to_cpu instead. + * + * \ingroup Group_EndianConversion + * + * \param[in] x Data to perform the endianness conversion on. + * + * \return Endian corrected version of the input value. + */ + #define LE32_TO_CPU(x) (x) + + /** Performs a conversion between a Big Endian encoded 16-bit piece of data and the + * Endianness of the currently selected CPU architecture. + * + * On big endian architectures, this macro does nothing. + * + * \note This macro is designed for compile-time conversion of data - for run-time endianness + * conversion, use \ref be16_to_cpu instead. + * + * \ingroup Group_EndianConversion + * + * \param[in] x Data to perform the endianness conversion on. + * + * \return Endian corrected version of the input value. + */ + #define BE16_TO_CPU(x) SWAPENDIAN_16(x) + + /** Performs a conversion between a Big Endian encoded 32-bit piece of data and the + * Endianness of the currently selected CPU architecture. + * + * On big endian architectures, this macro does nothing. + * + * \note This macro is designed for compile-time conversion of data - for run-time endianness + * conversion, use \ref be32_to_cpu instead. + * + * \ingroup Group_EndianConversion + * + * \param[in] x Data to perform the endianness conversion on. + * + * \return Endian corrected version of the input value. + */ + #define BE32_TO_CPU(x) SWAPENDIAN_32(x) + + /** Performs a conversion on a natively encoded 16-bit piece of data to ensure that it + * is in Little Endian format regardless of the currently selected CPU architecture. + * + * On little endian architectures, this macro does nothing. + * + * \note This macro is designed for compile-time conversion of data - for run-time endianness + * conversion, use \ref cpu_to_le16 instead. + * + * \ingroup Group_EndianConversion + * + * \param[in] x Data to perform the endianness conversion on. + * + * \return Endian corrected version of the input value. + */ + #define CPU_TO_LE16(x) (x) + + /** Performs a conversion on a natively encoded 32-bit piece of data to ensure that it + * is in Little Endian format regardless of the currently selected CPU architecture. + * + * On little endian architectures, this macro does nothing. + * + * \note This macro is designed for compile-time conversion of data - for run-time endianness + * conversion, use \ref cpu_to_le32 instead. + * + * \ingroup Group_EndianConversion + * + * \param[in] x Data to perform the endianness conversion on. + * + * \return Endian corrected version of the input value. + */ + #define CPU_TO_LE32(x) (x) + + /** Performs a conversion on a natively encoded 16-bit piece of data to ensure that it + * is in Big Endian format regardless of the currently selected CPU architecture. + * + * On big endian architectures, this macro does nothing. + * + * \note This macro is designed for compile-time conversion of data - for run-time endianness + * conversion, use \ref cpu_to_be16 instead. + * + * \ingroup Group_EndianConversion + * + * \param[in] x Data to perform the endianness conversion on. + * + * \return Endian corrected version of the input value. + */ + #define CPU_TO_BE16(x) SWAPENDIAN_16(x) + + /** Performs a conversion on a natively encoded 32-bit piece of data to ensure that it + * is in Big Endian format regardless of the currently selected CPU architecture. + * + * On big endian architectures, this macro does nothing. + * + * \note This macro is designed for compile-time conversion of data - for run-time endianness + * conversion, use \ref cpu_to_be32 instead. + * + * \ingroup Group_EndianConversion + * + * \param[in] x Data to perform the endianness conversion on. + * + * \return Endian corrected version of the input value. + */ + #define CPU_TO_BE32(x) SWAPENDIAN_32(x) + + //! @} + #endif + + /* Inline Functions: */ + /** Function to reverse the byte ordering of the individual bytes in a 16 bit value. + * + * \ingroup Group_ByteSwapping + * + * \param[in] Word Word of data whose bytes are to be swapped. + * + * \return Input data with the individual bytes reversed. + */ + static inline uint16_t SwapEndian_16(const uint16_t Word) ATTR_WARN_UNUSED_RESULT ATTR_CONST; + static inline uint16_t SwapEndian_16(const uint16_t Word) + { + if (GCC_IS_COMPILE_CONST(Word)) + return SWAPENDIAN_16(Word); + + uint8_t Temp; + + union + { + uint16_t Word; + uint8_t Bytes[2]; + } Data; + + Data.Word = Word; + + Temp = Data.Bytes[0]; + Data.Bytes[0] = Data.Bytes[1]; + Data.Bytes[1] = Temp; + + return Data.Word; + } + + /** Function to reverse the byte ordering of the individual bytes in a 32 bit value. + * + * \ingroup Group_ByteSwapping + * + * \param[in] DWord Double word of data whose bytes are to be swapped. + * + * \return Input data with the individual bytes reversed. + */ + static inline uint32_t SwapEndian_32(const uint32_t DWord) ATTR_WARN_UNUSED_RESULT ATTR_CONST; + static inline uint32_t SwapEndian_32(const uint32_t DWord) + { + if (GCC_IS_COMPILE_CONST(DWord)) + return SWAPENDIAN_32(DWord); + + uint8_t Temp; + + union + { + uint32_t DWord; + uint8_t Bytes[4]; + } Data; + + Data.DWord = DWord; + + Temp = Data.Bytes[0]; + Data.Bytes[0] = Data.Bytes[3]; + Data.Bytes[3] = Temp; + + Temp = Data.Bytes[1]; + Data.Bytes[1] = Data.Bytes[2]; + Data.Bytes[2] = Temp; + + return Data.DWord; + } + + /** Function to reverse the byte ordering of the individual bytes in a n byte value. + * + * \ingroup Group_ByteSwapping + * + * \param[in,out] Data Pointer to a number containing an even number of bytes to be reversed. + * \param[in] Length Length of the data in bytes. + * + * \return Input data with the individual bytes reversed. + */ + static inline void SwapEndian_n(void* const Data, + uint8_t Length) ATTR_NON_NULL_PTR_ARG(1); + static inline void SwapEndian_n(void* const Data, + uint8_t Length) + { + uint8_t* CurrDataPos = (uint8_t*)Data; + + while (Length > 1) + { + uint8_t Temp = *CurrDataPos; + *CurrDataPos = *(CurrDataPos + Length - 1); + *(CurrDataPos + Length - 1) = Temp; + + CurrDataPos++; + Length -= 2; + } + } + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Doxygen.conf b/protocol/lufa/LUFA-120730/LUFA/Doxygen.conf new file mode 100644 index 00000000..89b2a332 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Doxygen.conf @@ -0,0 +1,1809 @@ +# Doxyfile 1.8.1.2 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" "). + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or sequence of words) that should +# identify the project. Note that if you do not use Doxywizard you need +# to put quotes around the project name if it contains spaces. + +PROJECT_NAME = "LUFA Library" + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = 000000 + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer +# a quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = + +# With the PROJECT_LOGO tag one can specify an logo or icon that is +# included in the documentation. The maximum height of the logo should not +# exceed 55 pixels and the maximum width should not exceed 200 pixels. +# Doxygen will copy the logo to the output directory. + +PROJECT_LOGO = ./DoxygenPages/Images/LUFA_thumb.png + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = ./Documentation/ + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, +# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, +# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = NO + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful if your file system +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# This tag can be used to specify a number of word-keyword mappings (TCL only). +# A mapping has the form "name=value". For example adding +# "class=itcl::class" will allow you to use the command class in the +# itcl::class meaning. + +TCL_SUBST = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = YES + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given extension. +# Doxygen has a built-in mapping, but you can override or extend it using this +# tag. The format is ext=language, where ext is a file extension, and language +# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, +# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make +# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C +# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions +# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all +# comments according to the Markdown format, which allows for more readable +# documentation. See http://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by doxygen, so you +# can mix doxygen, HTML, and XML commands with Markdown formatting. +# Disable only in case of backward compatibilities issues. + +MARKDOWN_SUPPORT = NO + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also makes the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate getter +# and setter methods for a property. Setting this option to YES (the default) +# will make doxygen replace the get and set methods by a property in the +# documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the +# methods anyway, you should set this option to NO. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and +# unions are shown inside the group in which they are included (e.g. using +# @ingroup) instead of on a separate page (for HTML and Man pages) or +# section (for LaTeX and RTF). + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and +# unions with only public data fields will be shown inline in the documentation +# of the scope in which they are defined (i.e. file, namespace, or group +# documentation), provided this scope is documented. If set to NO (the default), +# structs, classes, and unions are shown on a separate page (for HTML and Man +# pages) or section (for LaTeX and RTF). + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = YES + +# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to +# determine which symbols to keep in memory and which to flush to disk. +# When the cache is full, less often used symbols will be written to disk. +# For small to medium size projects (<1000 input files) the default value is +# probably good enough. For larger projects a too small cache size can cause +# doxygen to be busy swapping symbols to and from disk most of the time +# causing a significant performance penalty. +# If the system has enough physical memory increasing the cache will improve the +# performance by keeping more symbols in memory. Note that the value works on +# a logarithmic scale so increasing the size by one will roughly double the +# memory usage. The cache size is given by this formula: +# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols. + +SYMBOL_CACHE_SIZE = 0 + +# Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be +# set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given +# their name and scope. Since this can be an expensive process and often the +# same symbol appear multiple times in the code, doxygen keeps a cache of +# pre-resolved symbols. If the cache is too small doxygen will become slower. +# If the cache is too large, memory is wasted. The cache size is given by this +# formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols. + +LOOKUP_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = YES + +# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal scope will be included in the documentation. + +EXTRACT_PACKAGE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespaces are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = NO + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen +# will list include files with double quotes in the documentation +# rather than with sharp brackets. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen +# will sort the (brief and detailed) documentation of class members so that +# constructors and destructors are listed first. If set to NO (the default) +# the constructors will appear in the respective orders defined by +# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. +# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO +# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = YES + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to +# do proper type resolution of all parameters of a function it will reject a +# match between the prototype and the implementation of a member function even +# if there is only one candidate or it is obvious which candidate to choose +# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen +# will still accept a match between prototype and implementation in such cases. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = NO + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = NO + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = NO + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or macro consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and macros in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 15 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. +# This will remove the Namespaces entry from the Quick Index +# and from the Folder Tree View (if specified). The default is YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. +# You can optionally specify a file name after the option, if omitted +# DoxygenLayout.xml will be used as the name of the layout file. + +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files +# containing the references data. This must be a list of .bib files. The +# .bib extension is automatically appended if omitted. Using this command +# requires the bibtex tool to be installed. See also +# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style +# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this +# feature you need bibtex and perl available in the search path. + +CITE_BIB_FILES = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = YES + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# The WARN_NO_PARAMDOC option can be enabled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = YES + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = ./ + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh +# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py +# *.f90 *.f *.for *.vhd *.vhdl + +FILE_PATTERNS = *.h \ + *.txt + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# Note that relative paths are relative to the directory from which doxygen is +# run. + +EXCLUDE = Documentation/ \ + License.txt + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = _* \ + __* + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = ./ \ + CodeTemplates/ + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = * + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = ./ + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. +# If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. +# Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. +# The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty or if +# non of the patterns match the file name, INPUT_FILTER is applied. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) +# and it is also possible to disable source filtering for a specific pattern +# using *.ext= (so without naming a filter). This option only has effect when +# FILTER_SOURCE_FILES is enabled. + +FILTER_SOURCE_PATTERNS = + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C, C++ and Fortran comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. +# Otherwise they will link to the documentation. + +REFERENCES_LINK_SOURCE = NO + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = YES + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. Note that when using a custom header you are responsible +# for the proper inclusion of any scripts and style sheets that doxygen +# needs, which is dependent on the configuration options used. +# It is advised to generate a default header using "doxygen -w html +# header.html footer.html stylesheet.css YourConfigFile" and then modify +# that header. Note that the header is subject to change so you typically +# have to redo this when upgrading to a newer version of doxygen or when +# changing the value of configuration settings such as GENERATE_TREEVIEW! + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = ./DoxygenPages/Style/Footer.htm + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# style sheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = ./DoxygenPages/Style/Style.css + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that +# the files will be copied as-is; there are no commands or markers available. + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. +# Doxygen will adjust the colors in the style sheet and background images +# according to this color. Hue is specified as an angle on a colorwheel, +# see http://en.wikipedia.org/wiki/Hue for more information. +# For instance the value 0 represents red, 60 is yellow, 120 is green, +# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. +# The allowed range is 0 to 359. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of +# the colors in the HTML output. For a value of 0 the output will use +# grayscales only. A value of 255 will produce the most vivid colors. + +HTML_COLORSTYLE_SAT = 120 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to +# the luminance component of the colors in the HTML output. Values below +# 100 gradually make the output lighter, whereas values above 100 make +# the output darker. The value divided by 100 is the actual gamma applied, +# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, +# and 100 does not change the gamma. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting +# this to NO can help when comparing the output of multiple runs. + +HTML_TIMESTAMP = NO + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. + +HTML_DYNAMIC_SECTIONS = YES + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of +# entries shown in the various tree structured indices initially; the user +# can expand and collapse entries dynamically later on. Doxygen will expand +# the tree to such a level that at most the specified number of entries are +# visible (unless a fully collapsed tree already exceeds this amount). +# So setting the number of entries 1 will produce a full collapsed tree by +# default. 0 is a special value representing an infinite number of entries +# and will result in a full expanded tree by default. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. + +DOCSET_PUBLISHER_ID = com.lufa-lib.library.documentation + +# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. + +DOCSET_PUBLISHER_NAME = DeanCamera + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = ../LUFA.chm + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# content. + +CHM_INDEX_ENCODING = + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = YES + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated +# that can be used as input for Qt's qhelpgenerator to generate a +# Qt Compressed Help (.qch) of the generated HTML documentation. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. +# The path specified is relative to the HTML output folder. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#namespace + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#virtual-folders + +QHP_VIRTUAL_FOLDER = doc + +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to +# add. For more information please see +# http://doc.trolltech.com/qthelpproject.html#custom-filters + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see +# +# Qt Help Project / Custom Filters. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's +# filter section matches. +# +# Qt Help Project / Filter Attributes. + +QHP_SECT_FILTER_ATTRS = + +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated +# .qhp file. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files +# will be generated, which together with the HTML files, form an Eclipse help +# plugin. To install this plugin and make it available under the help contents +# menu in Eclipse, the contents of the directory containing the HTML and XML +# files needs to be copied into the plugins directory of eclipse. The name of +# the directory within the plugins directory should be the same as +# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before +# the help appears. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have +# this name. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) +# at top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. Since the tabs have the same information as the +# navigation tree you can set this option to NO if you already set +# GENERATE_TREEVIEW to YES. + +DISABLE_INDEX = YES + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to YES, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). +# Windows users are probably better off using the HTML help feature. +# Since the tree basically has the same information as the tab index you +# could consider to set DISABLE_INDEX to NO when enabling this option. + +GENERATE_TREEVIEW = YES + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values +# (range [0,1..20]) that doxygen will group on one line in the generated HTML +# documentation. Note that a value of 0 will completely suppress the enum +# values from appearing in the overview section. + +ENUM_VALUES_PER_LINE = 1 + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 300 + +# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open +# links to external symbols imported via tag files in a separate window. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory +# to force them to be regenerated. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are +# not supported properly for IE 6.0, but are supported on all modern browsers. +# Note that when changing this option you need to delete any form_*.png files +# in the HTML output before the changes have effect. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax +# (see http://www.mathjax.org) which uses client side Javascript for the +# rendering instead of using prerendered bitmaps. Use this if you do not +# have LaTeX installed or if you want to formulas look prettier in the HTML +# output. When enabled you may also need to install MathJax separately and +# configure the path to it using the MATHJAX_RELPATH option. + +USE_MATHJAX = NO + +# When MathJax is enabled you need to specify the location relative to the +# HTML output directory using the MATHJAX_RELPATH option. The destination +# directory should contain the MathJax.js script. For instance, if the mathjax +# directory is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to +# the MathJax Content Delivery Network so you can quickly see the result without +# installing MathJax. +# However, it is strongly recommended to install a local +# copy of MathJax from http://www.mathjax.org before deployment. + +MATHJAX_RELPATH = http://www.mathjax.org/mathjax + +# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension +# names that should be enabled during MathJax rendering. + +MATHJAX_EXTENSIONS = + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box +# for the HTML output. The underlying search engine uses javascript +# and DHTML and should work on any modern browser. Note that when using +# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets +# (GENERATE_DOCSET) there is already a search function so this one should +# typically be disabled. For large projects the javascript based search engine +# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. + +SEARCHENGINE = YES + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a PHP enabled web server instead of at the web client +# using Javascript. Doxygen will generate the search PHP script and index +# file to put on the web server. The advantage of the server +# based approach is that it scales better to large projects and allows +# full text search. The disadvantages are that it is more difficult to setup +# and does not have live searching capabilities. + +SERVER_BASED_SEARCH = NO + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. +# Note that when enabling USE_PDFLATEX this option is only used for +# generating bitmaps for formulas in the HTML output, but not in the +# Makefile that is written to the output directory. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for +# the generated latex document. The footer should contain everything after +# the last chapter. If it is left blank doxygen will generate a +# standard footer. Notice: only use this tag if you know what you are doing! + +LATEX_FOOTER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +# If LATEX_SOURCE_CODE is set to YES then doxygen will include +# source code with syntax highlighting in the LaTeX output. +# Note that which sources are shown also depends on other settings +# such as SOURCE_BROWSER. + +LATEX_SOURCE_CODE = NO + +# The LATEX_BIB_STYLE tag can be used to specify the style to use for the +# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See +# http://en.wikipedia.org/wiki/BibTeX for more info. + +LATEX_BIB_STYLE = plain + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load style sheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. +# This is useful +# if you want to understand what is going on. +# On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = YES + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = YES + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# pointed to by INCLUDE_PATH will be searched when a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = __DOXYGEN__ \ + PROGMEM \ + EEMEM \ + ATTR_PACKED + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition that +# overrules the definition found in the source code. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all references to function-like macros +# that are alone on a line, have an all uppercase name, and do not end with a +# semicolon, because these will confuse the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. For each +# tag file the location of the external documentation should be added. The +# format of a tag file without this location is as follows: +# +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths +# or URLs. Note that each tag file must have a unique name (where the name does +# NOT include the path). If a tag file is not located in the directory in which +# doxygen is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option also works with HAVE_DOT disabled, but it is recommended to +# install and use dot, since it yields more powerful graphs. + +CLASS_DIAGRAMS = NO + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is +# allowed to run in parallel. When set to 0 (the default) doxygen will +# base this on the number of processors available in the system. You can set it +# explicitly to a value larger than 0 to get control over the balance +# between CPU load and processing speed. + +DOT_NUM_THREADS = 0 + +# By default doxygen will use the Helvetica font for all dot files that +# doxygen generates. When you want a differently looking font you can specify +# the font name using DOT_FONTNAME. You need to make sure dot is able to find +# the font, which can be done by putting it in a standard location or by setting +# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the +# directory containing the font. + +DOT_FONTNAME = FreeSans + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the Helvetica font. +# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to +# set the path where dot can find it. + +DOT_FONTPATH = + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = NO + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = NO + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If the UML_LOOK tag is enabled, the fields and methods are shown inside +# the class node. If there are many fields or methods and many nodes the +# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS +# threshold limits the number of items for each type to make the size more +# managable. Set this to 0 for no limit. Note that the threshold may be +# exceeded by 50% before the limit is enforced. + +UML_LIMIT_NUM_FIELDS = 10 + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will generate a graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = NO + +# If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are svg, png, jpg, or gif. +# If left blank png will be used. If you choose svg you need to set +# HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# visible in IE 9+ (other browsers do not have this requirement). + +DOT_IMAGE_FORMAT = png + +# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to +# enable generation of interactive SVG images that allow zooming and panning. +# Note that this requires a modern browser other than Internet Explorer. +# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you +# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files +# visible. Older versions of IE do not have SVG support. + +INTERACTIVE_SVG = NO + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the +# \mscfile command). + +MSCFILE_DIRS = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 15 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 2 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). + +DOT_TRANSPARENT = YES + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES diff --git a/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/BuildSystem.txt b/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/BuildSystem.txt new file mode 100644 index 00000000..c30a88bb --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/BuildSystem.txt @@ -0,0 +1,846 @@ +/** \file + * + * This file contains special DoxyGen information for the generation of the main page and other special + * documentation pages. It is not a project source file. + */ + +/** \page Page_BuildSystem The LUFA Build System + * + * \section Sec_BuildSystemOverview Overview of the LUFA Build System + * The LUFA build system is an attempt at making a set of re-usable, modular build make files which + * can be referenced in a LUFA powered project, to minimise the amount of code required in an + * application makefile. The system is written in GNU Make, and each module is independant of + * one-another. + * + * For details on the prerequisites needed for Linux and Windows machines to be able to use the LUFA + * build system, see \ref Sec_Prerequisites. + * + * To use a LUFA build system module, simply add an include to your project makefile: + * \code + * include $(LUFA_PATH)/Build/lufa_core.mk + * \endcode + * + * And the associated build module targets will be added to your project's build makefile automatically. + * To call a build target, run make {TARGET_NAME} from the command line, substituting in + * the appropriate target name. + * + * \see \ref Sec_AppConfigParams for a copy of the sample LUFA project makefile. + * + * Each build module may have one or more mandatory parameters (GNU Make variables) which must + * be supplied in the project makefile for the module to work, and one or more optional parameters which + * may be defined and which will assume a sensible default if not. + * + * \section SSec_BuildSystemModules Available Modules + * + * The following modules are included in this LUFA release: + * + * \li \subpage Page_BuildModule_ATPROGRAM - Device Programming + * \li \subpage Page_BuildModule_AVRDUDE - Device Programming + * \li \subpage Page_BuildModule_BUILD - Compiling/Assembling/Linking + * \li \subpage Page_BuildModule_CORE - Core Build System Functions + * \li \subpage Page_BuildModule_CPPCHECK - Static Code Analysis + * \li \subpage Page_BuildModule_DFU - Device Programming + * \li \subpage Page_BuildModule_DOXYGEN - Automated Source Code Documentation + * \li \subpage Page_BuildModule_HID - Device Programming + * \li \subpage Page_BuildModule_SOURCES - LUFA Module Source Code Variables + */ + + /** \page Page_BuildModule_BUILD The BUILD build module + * + * The BUILD LUFA build system module, providing targets for the compilation, + * assembling and linking of an application from source code into binary files + * suitable for programming into a target device. + * + * To use this module in your application makefile, add the following code: + * \code + * include $(LUFA_PATH)/Build/lufa_build.mk + * \endcode + * + * \section SSec_BuildModule_BUILD_Requirements Requirements + * This module requires the the architecture appropriate binaries of the GCC compiler are available in your + * system's PATH variable. The GCC compiler and associated toolchain is distributed in Atmel AVR Studio + * 5.x and Atmel Studio 6.x installation directories, as well as in many third party distribution packages. + * + * \section SSec_BuildModule_BUILD_Targets Targets + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
sizeDisplay size of the compiled application FLASH and SRAM segments.
symbol-sizesDisplay a size-sorted list of symbols from the compiled application, in decimal bytes.
check-sourceDisplay a list of input SRC source files which cannot be found (if any).
libBuild and archive all source files into a library A binary file.
allBuild and link the application into ELF debug and HEX binary files.
elfBuild and link the application into an ELF debug file.
hexBuild and link the application and produce HEX and EEP binary files.
lssBuild and link the application and produce a LSS source code/assembly code mixed listing file.
cleanRemove all intermediatary files and binary output files.
mostlycleanRemove all intermediatary files but preserve any binary output files.
+ * + * \section SSec_BuildModule_BUILD_MandatoryParams Mandatory Parameters + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
TARGETName of the application output file prefix (e.g. TestApplication).
ARCHArchitecture of the target processor (see \ref Page_DeviceSupport).
MCUName of the Atmel processor model (e.g. at90usb1287).
SRCList of relative or absolute paths to the application C (.c), C++ (.cpp) and Assembly (.S) source files.
F_USBSpeed in Hz of the input clock frequency to the target's USB controller.
LUFA_PATHPath to the LUFA library core, either relative or absolute (e.g. ../LUFA-000000/LUFA/).
+ * + * \section SSec_BuildModule_BUILD_OptionalParams Optional Parameters + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
BOARDLUFA board hardware drivers to use (see \ref Page_DeviceSupport).
OPTIMIZATIONOptimization level to use when compiling source files (see GCC manual).
C_STANDARDVersion of the C standard to apply when compiling C++ source files (see GCC manual).
CPP_STANDARDVersion of the C++ standard to apply when compiling C++ source files (see GCC manual).
DEBUG_FORMATFormat of the debug information to embed in the generated object files (see GCC manual).
DEBUG_LEVELLevel of the debugging information to embed in the generated object files (see GCC manual).
F_CPUSpeed of the processor CPU clock, in Hz.
C_FLAGSFlags to pass to the C compiler only, after the automatically generated flags.
CPP_FLAGSFlags to pass to the C++ compiler only, after the automatically generated flags.
ASM_FLAGSFlags to pass to the assembler only, after the automatically generated flags.
CC_FLAGSCommon flags to pass to the C/C++ compiler and assembler, after the automatically generated flags.
LD_FLAGSFlags to pass to the linker, after the automatically generated flags.
OBJDIRDirectory to place the generated object and dependency files. If set to "." the same folder as the source file will be used. + * \note When this option is enabled, all source filenames must be unique.
OBJECT_FILESList of additional object files that should be linked into the resulting binary.
+ * + * \section SSec_BuildModule_BUILD_ProvidedVariables Module Provided Variables + * + * + * + * + * + *
None
+ * + * \section SSec_BuildModule_BUILD_ProvidedMacros Module Provided Macros + * + * + * + * + * + *
None
+ */ + +/** \page Page_BuildModule_CORE The CORE build module + * + * The core LUFA build system module, providing common build system help and information targets. + * + * To use this module in your application makefile, add the following code: + * \code + * include $(LUFA_PATH)/Build/lufa_core.mk + * \endcode + * + * \section SSec_BuildModule_CORE_Requirements Requirements + * This module has no requirements outside a standard *nix shell like environment; the sh + * shell, GNU make and *nix CoreUtils (echo, printf, etc.). + * + * \section SSec_BuildModule_CORE_Targets Targets + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
helpDisplay build system help and configuration information.
list_targetsList all available build targets from the build system.
list_modulesList all available build modules from the build system.
list_mandatoryList all mandatory parameters required by the included modules.
list_optionalList all optional parameters required by the included modules.
list_providedList all variables provided by the included modules.
list_macrosList all macros provided by the included modules.
+ * + * \section SSec_BuildModule_CORE_MandatoryParams Mandatory Parameters + * + * + * + * + * + *
None
+ * + * \section SSec_BuildModule_CORE_OptionalParams Optional Parameters + * + * + * + * + * + *
None
+ * + * \section SSec_BuildModule_CORE_ProvidedVariables Module Provided Variables + * + * + * + * + * + *
None
+ * + * \section SSec_BuildModule_CORE_ProvidedMacros Module Provided Macros + * + * + * + * + * + *
None
+ */ + +/** \page Page_BuildModule_ATPROGRAM The ATPROGRAM build module + * + * The ATPROGRAM programming utility LUFA build system module, providing targets to reprogram an + * Atmel processor FLASH and EEPROM memories with a project's compiled binary output files. + * + * To use this module in your application makefile, add the following code: + * \code + * include $(LUFA_PATH)/Build/lufa_atprogram.mk + * \endcode + * + * \section SSec_BuildModule_ATPROGRAM_Requirements Requirements + * This module requires the atprogram.exe utility to be available in your system's PATH + * variable. The atprogram.exe utility is distributed in Atmel AVR Studio 5.x and Atmel Studio 6.x + * inside the application install folder's "\avrdbg" subdirectory. + * + * \section SSec_BuildModule_ATPROGRAM_Targets Targets + * + * + * + * + * + * + * + * + * + * + *
atprogramProgram the device FLASH memory with the application's executable data.
atprogram-eeProgram the device EEPROM memory with the application's EEPROM data.
+ * + * \section SSec_BuildModule_ATPROGRAM_MandatoryParams Mandatory Parameters + * + * + * + * + * + * + * + * + * + * + *
MCUName of the Atmel processor model (e.g. at90usb1287).
TARGETName of the application output file prefix (e.g. TestApplication).
+ * + * \section SSec_BuildModule_ATPROGRAM_OptionalParams Optional Parameters + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
ATPROGRAM_PROGRAMMERName of the Atmel programmer or debugger tool to communicate with (e.g. jtagice3).
ATPROGRAM_INTERFACEName of the programming interface to use when programming the target (e.g. spi).
ATPROGRAM_PORTName of the communication port to use when when programming with a serially connected tool (e.g. COM2).
+ * + * \section SSec_BuildModule_ATPROGRAM_ProvidedVariables Module Provided Variables + * + * + * + * + * + *
None
+ * + * \section SSec_BuildModule_ATPROGRAM_ProvidedMacros Module Provided Macros + * + * + * + * + * + *
None
+ */ + +/** \page Page_BuildModule_AVRDUDE The AVRDUDE build module + * + * The AVRDUDE programming utility LUFA build system module, providing targets to reprogram an + * Atmel processor FLASH and EEPROM memories with a project's compiled binary output files. + * + * To use this module in your application makefile, add the following code: + * \code + * include $(LUFA_PATH)/Build/lufa_avrdude.mk + * \endcode + * + * \section SSec_BuildModule_AVRDUDE_Requirements Requirements + * This module requires the avrdude utility to be available in your system's PATH + * variable. The avrdude utility is distributed in the old WinAVR project releases for + * Windows (winavr.sourceforge.net) or can be installed on *nix systems via the project's + * source code (https://savannah.nongnu.org/projects/avrdude) or through the package manager. + * + * \section SSec_BuildModule_AVRDUDE_Targets Targets + * + * + * + * + * + * + * + * + * + * + *
avrdudeProgram the device FLASH memory with the application's executable data.
avrdudeProgram the device EEPROM memory with the application's EEPROM data.
+ * + * \section SSec_BuildModule_AVRDUDE_MandatoryParams Mandatory Parameters + * + * + * + * + * + * + * + * + * + * + *
MCUName of the Atmel processor model (e.g. at90usb1287).
TARGETName of the application output file prefix (e.g. TestApplication).
+ * + * \section SSec_BuildModule_AVRDUDE_OptionalParams Optional Parameters + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
AVRDUDE_PROGRAMMERName of the programmer or debugger tool to communicate with (e.g. jtagicemkii).
ATPROGRAM_PORTName of the communication port to use when when programming with the connected tool (e.g. COM2, /dev/ttyUSB0 or usb).
ATPROGRAM_FLAGSAdditional flags to pass to avrdude when programming, applied after the automatically generated flags.
+ * + * \section SSec_BuildModule_AVRDUDE_ProvidedVariables Module Provided Variables + * + * + * + * + * + *
None
+ * + * \section SSec_BuildModule_AVRDUDE_ProvidedMacros Module Provided Macros + * + * + * + * + * + *
None
+ */ + + /** \page Page_BuildModule_CPPCHECK The CPPCHECK build module + * + * The CPPCHECK programming utility LUFA build system module, providing targets to statically + * analyze C and C++ source code for errors and performance/style issues. + * + * To use this module in your application makefile, add the following code: + * \code + * include $(LUFA_PATH)/Build/lufa_cppcheck.mk + * \endcode + * + * \section SSec_BuildModule_CPPCHECK_Requirements Requirements + * This module requires the cppcheck utility to be available in your system's PATH + * variable. The cppcheck utility is distributed through the project's home page + * (http://cppcheck.sourceforge.net) for Windows, and can be installed on *nix systems via + * the project's source code or through the package manager. + * + * \section SSec_BuildModule_CPPCHECK_Targets Targets + * + * + * + * + * + * + * + * + * + * + *
cppcheckStatically analyze the project source code for issues.
cppcheck-configCheck the cppcheck configuration - scan source code and warn about missing header files and other issues.
+ * + * \section SSec_BuildModule_CPPCHECK_MandatoryParams Mandatory Parameters + * + * + * + * + * + * + *
SRCList of source files to statically analyze.
+ * + * \section SSec_BuildModule_CPPCHECK_OptionalParams Optional Parameters + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
CPPCHECK_INCLUDESPath of extra directories to check when attemting to resolve C/C++ header file includes.
CPPCHECK_EXCLUDESPaths or path fragments to exclude when analyzing.
CPPCHECK_MSG_TEMPLATEOutput message template to use when printing errors, warnings and information (see cppcheck documentation).
CPPCHECK_ENABLEAnalysis rule categories to enable (see cppcheck documentation).
CPPCHECK_SUPPRESSSpecific analysis rules to suppress (see cppcheck documentation).
CPPCHECK_FAIL_ON_WARNINGSet to Y to fail the analysis job with an error exit code if warnings are found, N to continue without failing.
CPPCHECK_QUIETSet to Y to suppress all output except warnings and errors, N to show verbose output information.
CPPCHECK_FLAGSExtra flags to pass to cppcheck, after the automatically generated flags.
+ * + * \section SSec_BuildModule_CPPCHECK_ProvidedVariables Module Provided Variables + * + * + * + * + * + *
None
+ * + * \section SSec_BuildModule_CPPCHECK_ProvidedMacros Module Provided Macros + * + * + * + * + * + *
None
+ */ + + /** \page Page_BuildModule_DFU The DFU build module + * + * The DFU programming utility LUFA build system module, providing targets to reprogram an + * Atmel processor FLASH and EEPROM memories with a project's compiled binary output files. + * This module requires a DFU class bootloader to be running in the target, compatible with + * the DFU bootloader protocol as published by Atmel. + * + * To use this module in your application makefile, add the following code: + * \code + * include $(LUFA_PATH)/Build/lufa_dfu.mk + * \endcode + * + * \section SSec_BuildModule_DFU_Requirements Requirements + * This module requires either the batchisp utility from Atmel's FLIP utility, or the open + * source dfu-programmer utility (http://dfu-programmer.sourceforge.net/) to be + * available in your system's PATH variable. On *nix systems the dfu-programmer utility + * can be installed via the project's source code or through the package manager. + * + * \section SSec_BuildModule_DFU_Targets Targets + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
dfuProgram the device FLASH memory with the application's executable data using dfu-programmer.
dfu-eeProgram the device EEPROM memory with the application's EEPROM data using dfu-programmer.
flipProgram the device FLASH memory with the application's executable data using batchisp.
flip-eeProgram the device EEPROM memory with the application's EEPROM data using batchisp.
+ * + * \section SSec_BuildModule_DFU_MandatoryParams Mandatory Parameters + * + * + * + * + * + * + * + * + * + * + *
MCUName of the Atmel processor model (e.g. at90usb1287).
TARGETName of the application output file prefix (e.g. TestApplication).
+ * + * \section SSec_BuildModule_DFU_OptionalParams Optional Parameters + * + * + * + * + * + *
None
+ * + * \section SSec_BuildModule_DFU_ProvidedVariables Module Provided Variables + * + * + * + * + * + *
None
+ * + * \section SSec_BuildModule_DFU_ProvidedMacros Module Provided Macros + * + * + * + * + * + *
None
+ */ + + /** \page Page_BuildModule_DOXYGEN The DOXYGEN build module + * + * The DOXYGEN code documentation utility LUFA build system module, providing targets to generate + * project HTML and other format documentation from a set of source files that include special + * Doxygen comments. + * + * To use this module in your application makefile, add the following code: + * \code + * include $(LUFA_PATH)/Build/lufa_doxygen.mk + * \endcode + * + * \section SSec_BuildModule_DOXYGEN_Requirements Requirements + * This module requires the doxygen utility from the Doxygen website + * (http://www.stack.nl/~dimitri/doxygen/) to be available in your system's PATH + * variable. On *nix systems the doxygen utility can be installed via the project's source + * code or through the package manager. + * + * \section SSec_BuildModule_DOXYGEN_Targets Targets + * + * + * + * + * + * + *
doxygenGenerate project documentation.
+ * + * \section SSec_BuildModule_DOXYGEN_MandatoryParams Mandatory Parameters + * + * + * + * + * + * + *
LUFA_PATHPath to the LUFA library core, either relative or absolute (e.g. ../LUFA-000000/LUFA/).
+ * + * \section SSec_BuildModule_DOXYGEN_OptionalParams Optional Parameters + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
DOXYGEN_CONFName and path of the base Doxygen configuration file for the project.
DOXYGEN_FAIL_ON_WARNINGSet to Y to fail the generation with an error exit code if warnings are found other than unsupported configuration parameters, N to continue without failing.
DOXYGEN_OVERRIDE_PARAMSExtra Doxygen configuration parameters to apply, overriding the corresponding config entry in the project's configuration file (e.g. QUIET=YES).
+ * + * \section SSec_BuildModule_DOXYGEN_ProvidedVariables Module Provided Variables + * + * + * + * + * + *
None
+ * + * \section SSec_BuildModule_DOXYGEN_ProvidedMacros Module Provided Macros + * + * + * + * + * + *
None
+ */ + + /** \page Page_BuildModule_HID The HID build module + * + * The HID programming utility LUFA build system module, providing targets to reprogram an + * Atmel processor's FLASH memory with a project's compiled binary output file. This module + * requires a HID class bootloader to be running in the target, using a protocol compatible + * with the PJRC "HalfKay" protocol (http://www.pjrc.com/teensy/halfkay_protocol.html). + * + * To use this module in your application makefile, add the following code: + * \code + * include $(LUFA_PATH)/Build/lufa_hid.mk + * \endcode + * + * \section SSec_BuildModule_HID_Requirements Requirements + * This module requires either the hid_bootloader_cli utility from the included LUFA HID + * class bootloader API subdirectory, or the teensy_loader_cli utility from PJRC + * (http://www.pjrc.com/teensy/loader_cli.html) to be available in your system's PATH + * variable. + * + * \section SSec_BuildModule_HID_Targets Targets + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
hidProgram the device FLASH memory with the application's executable data using hid_bootloader_cli.
hid-eeProgram the device EEPROM memory with the application's EEPROM data using hid_bootloader_cli and + * a temporary AVR application programmed into the target's FLASH. + * \note This will erase the currently loaded application in the target.
teensyProgram the device FLASH memory with the application's executable data using teensy_loader_cli.
teensy-eeProgram the device EEPROM memory with the application's EEPROM data using teensy_loader_cli and + * a temporary AVR application programmed into the target's FLASH. + * \note This will erase the currently loaded application in the target.
+ * + * \section SSec_BuildModule_HID_MandatoryParams Mandatory Parameters + * + * + * + * + * + * + * + * + * + * + *
MCUName of the Atmel processor model (e.g. at90usb1287).
TARGETName of the application output file prefix (e.g. TestApplication).
+ * + * \section SSec_BuildModule_HID_OptionalParams Optional Parameters + * + * + * + * + * + *
None
+ * + * \section SSec_BuildModule_HID_ProvidedVariables Module Provided Variables + * + * + * + * + * + *
None
+ * + * \section SSec_BuildModule_HID_ProvidedMacros Module Provided Macros + * + * + * + * + * + *
None
+ */ + + /** \page Page_BuildModule_SOURCES The SOURCES build module + * + * The SOURCES LUFA build system module, providing variables listing the various LUFA source files + * required to be build by a project for a given LUFA module. This module gives a way to reference + * LUFA source files symbollically, so that changes to the library structure do not break the library + * makefile. + * + * To use this module in your application makefile, add the following code: + * \code + * include $(LUFA_PATH)/Build/lufa_sources.mk + * \endcode + * + * \section SSec_BuildModule_SOURCES_Requirements Requirements + * None. + * + * \section SSec_BuildModule_SOURCES_Targets Targets + * + * + * + * + * + *
None
+ * + * \section SSec_BuildModule_SOURCES_MandatoryParams Mandatory Parameters + * + * + * + * + * + * + * + * + * + * + *
LUFA_PATHPath to the LUFA library core, either relative or absolute (e.g. ../LUFA-000000/LUFA/).
ARCHArchitecture of the target processor (see \ref Page_DeviceSupport).
+ * + * \section SSec_BuildModule_SOURCES_OptionalParams Optional Parameters + * + * + * + * + * + *
None
+ * + * \section SSec_BuildModule_SOURCES_ProvidedVariables Module Provided Variables + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
LUFA_SRC_USBList of LUFA USB driver source files.
LUFA_SRC_USBCLASSList of LUFA USB Class driver source files.
LUFA_SRC_TEMPERATUREList of LUFA temperature sensor driver source files.
LUFA_SRC_SERIALList of LUFA Serial U(S)ART driver source files.
LUFA_SRC_TWIList of LUFA TWI driver source files.
LUFA_SRC_PLATFORMList of LUFA architecture specific platform management source files.
+ * + * \section SSec_BuildModule_SOURCES_ProvidedMacros Module Provided Macros + * + * + * + * + * + *
None
+ */ diff --git a/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/BuildingLinkableLibraries.txt b/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/BuildingLinkableLibraries.txt new file mode 100644 index 00000000..ff5fdc52 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/BuildingLinkableLibraries.txt @@ -0,0 +1,23 @@ +/** \file + * + * This file contains special DoxyGen information for the generation of the main page and other special + * documentation pages. It is not a project source file. + */ + +/** \page Page_BuildLibrary Building as a Linkable Library + * + * The LUFA library can be built as a proper linkable library (with the extention .a) under AVR-GCC, so that + * the library does not need to be recompiled with each revision of a user project. Instructions for creating + * a library from a given source tree can be found in the AVR-GCC user manual included in the WinAVR install + * /Docs/ directory. + * + * However, building the library is not recommended, as the static (compile-time) options will be + * unable to be changed without a recompilation of the LUFA code. Therefore, if the library is to be built + * from the LUFA source, it should be made to be application-specific and compiled with the static options + * that are required for each project (which should be recorded along with the library). + * + * Normal library use has the library components compiled in at the same point as the application code, as + * demonstrated in the library demos and applications. This is the preferred method, as the library is recompiled + * each time to ensure that all static options for a particular application are applied. + */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/ChangeLog.txt b/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/ChangeLog.txt new file mode 100644 index 00000000..51786b9b --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/ChangeLog.txt @@ -0,0 +1,1444 @@ +/** \file + * + * This file contains special DoxyGen information for the generation of the main page and other special + * documentation pages. It is not a project source file. + */ + + /** \page Page_ChangeLog Project Changelog + * + * \section Sec_ChangeLog120730 Version 120730 + * New: + * - Core: + * - Added new, revamped modular build system with new makefile templates + * - Added support for the BitWizard Multio and Big-Multio boards + * - Added support for the DorkbotPDX Duce board + * - Added support for the Olimex AVR-USB-32U4 board + * - Added support for the Olimex AVR-USB-T32U4 board + * - Added support for the Olimex AVR-ISP-MK2 board + * - Added new Endpoint_ConfigureEndpointTable() function + * - Added new Pipe_ConfigurePipeTable() function + * - Added build test to verify correct compilation of all board drivers using all driver APIs + * - Added build test to verify correct compilation of all bootloaders using all supported devices + * - Added build test to verify that there are no detectable errors in the codebase via static analysis + * - Added new JTAG_ENABLE() macro for the AVR8 architecture + * - Library Applications: + * - Modified the CDC Host demos to set a default CDC Line Encoding on enumerated devices + * - Added Dataflash operational checks and aborts to all projects using the Dataflash to ensure it is working correctly before use + * - Added new SerialToLCD user project contributed by Simon Foster + * - Added new RESET_TOGGLES_LIBUSB_COMPAT compile time option to the AVRISP-MKII clone programmer project (thanks to Robert Spitzenpfeil) + * + * Changed: + * - Core: + * - Android Accessory Host property strings changed from a struct of pointer to an array to prevent unaligned access on greater than 8-bit architectures + * - Audio Device Class driver changed to also require the index of the Audio Control interface within the device, for SET/GET/CUR/MIN/MAX/RES property adjustments + * - Removed variable axis support from the HID_DESCRIPTOR_JOYSTICK() macro due to OS incompatibilities, replaced with fixed 3-axis joystick report structure + * - Removed the old pseudo-scheduler from the library as it was unused and deprecated since the 090810 release + * - Endpoint indexes are now specified as full endpoint addresses within the device in device mode, rather than a logical index + * - The Endpoint_ConfigureEndpoint() function no longer takes an endpoint direction as a parameter, as this is now deduced from the specified full endpoint + * address and type + * - The Endpoint_ConfigureEndpoint() function no longer takes a number of banks as a special mask; the number of banks is now specified as an integer parameter + * - Endpoints are now configured via instances of a new struct USB_Endpoint_Table_t in all device mode class drivers, rather than a list of endpoint parameters + * - Pipe indexes are now specified as full pipe addresses within the host in host mode, rather than a logical index + * - The Pipe_ConfigurePipe() function no longer takes an pipe token as a parameter, as this is now deduced from the specified full pipe address and type + * - The Pipe_ConfigurePipe() function no longer takes a number of banks as a special mask; the number of banks is now specified as an integer parameter + * - Pipes are now configured via instances of a new struct USB_Pipe_Table_t in all host mode class drivers, rather than a list of pipe parameters + * - Added support for various assert and debugging macros for the UC3 devices + * - Changed MIDI event structure MIDI_EventPacket_t to use a single field for the combined virtual cable index and command ID, to prevent bitfield packing issues + * on some architectures (thanks to Darren Gibbs) + * - Changed board LED driver implementations of LEDs_ToggleLEDs() for the AVR8 architecture to use the fast PIN register toggle alternative function for speed + * - Library Applications: + * - Raised the guard bits in the AVRISP-MKII clone project when in PDI and TPI to 32, to prevent communication errors on low quality connections to a target + * - Added additional bootloader API data to expose the bootloader start address and class to the DFU and CDC class bootloaders + * - Reverted AVRISP-MKII clone project watchdog based command timeout patch in favour of a hardware timer, to allow for use in devices with WDTRST fuse programmed + * - The library bootloaders will now correctly start the user application after a watchdog-based application start, even if the /HWB line is held low externally + * during the reset phase + * - Increased endpoint polling interval for all demos and projects to 5ms, as 1ms was causing some enumeration issues on some machines (thanks to Riku Salminen) + * + * Fixed: + * - Core: + * - Fixed possible enumeration error if the user application selects a pipe other than the default Control pipe between the Powered and Default states of + * the host state machine + * - Fixed incorrect call to the user callback CALLBACK_Audio_Device_GetSetInterfaceProperty() in the Audio Class device driver (thanks to Tiit Ratsep) + * - Fixed compile error for the UC3 architecture when INTERRUPT_CONTROL_ENDPOINT is specified (thanks to Andrus Aaslaid) + * - Fixed compile error if LEDs_Disable() is called and BOARD=NONE is set (thanks to Sam Lin) + * - Fixed inverted LED logic in the OLIMEX162 board LED driver + * - Fixed incorrect reponse to GET STATUS requests in device mode if NO_DEVICE_SELF_POWER or NO_DEVICE_REMOTE_WAKEUP tokens are defined (thanks to Georg Glock) + * - Fixed inverted LED logic in the USB2AX board LED driver + * - Fixed possible deadlock in the CDC device driver if the USB connection is dropped while the CDC_REQ_SetLineEncoding control request is being processed by + * the stack (thanks to Jonathan Hudgins) + * - Fixed broken MIDI host driver MIDI_Host_ReceiveEventPacket() function due to not unfreezing the MIDI data IN pipe before use (thanks to Michael Brown) + * - Fixed swapped Little Endian/Big Endian endpoint and pipe write code for the UC3 devices (thanks to Andrew Chu) + * - Fixed the JTAG_DISABLE() macro clearing all other bits in MCUSR when called + * - Fixed incorrect Micropendous board LED driver LEDs_SetAllLEDs() and LEDs_ChangeLEDs() function implementations (thanks to MitchJS) + * - Fixed endianess issues in the RNDIS host class driver for UC3 devices (thanks to Andrew Chu) + * - Library Applications: + * - Fixed error in the AVRISP-MKII programmer when ISP mode is used at 64KHz (thanks to Ben R. Porter) + * - Fixed AVRISP-MKII programmer project failing to compile for the U4 chips when VTARGET_ADC_CHANNEL is defined to an invalid channel and NO_VTARGET_DETECT is + * defined (thanks to Steven Morehouse) + * - Fixed AVRISP-MKII programmer project reset line polarity inverted when the generated EEP file is loaded into the USB AVR's EEPROM and avr-dude is used + * - Fixed CDC and DFU bootloaders failing to compile when the bootloader section size is 8KB or more (thanks to Georg Glock) + * - Fixed CDC and DFU bootloaders API function offsets incorrect on some devices (thanks to Rod DeMay) + * - Fixed incorrect DFU version number reported to the host in the DFU bootloader descriptors (thanks to Georg Glock) + * - Fixed incorrect version hundredths value encoding in VERSION_BCD() macro (thanks to Georg Glock) + * - Fixed invalid configuration descriptor in the low level KeyboardMouse device demo (thanks to Jun Wako) + * - Fixed CDC and DFU bootloaders API page erase and write function failures (thanks to Martin Lambert) + * + * \section Sec_ChangeLog120219 Version 120219 + * New: + * - Core: + * - Added support for the XMEGA A3BU Xplained board + * - Added support for the new B series XMEGA devices + * - Added support for version 2 of the Teensy boards (thanks to Christoph Redecker) + * - Added support for the USB2AX boards, hardware revision 1-3 + * - Added new Android Accessory Host class driver + * - Added new USB_Host_GetDescriptor(), USB_Host_GetDeviceConfiguration() and USB_Host_GetInterfaceAltSetting() functions + * - Added new CALLBACK_Audio_Device_GetSetInterfaceProperty() callback to the Audio Device Class driver + * - Added new LEDs_Disable(), Buttons_Disable() and Joystick_Disable() functions to the board hardware drivers + * - Added support for the Micropendous family of boards (Arduino-like revisions 1 and 2, DIP, 32U2, A, 1, 2, 3 and 4) + * - Added INVERTED_VBUS_ENABLE_LINE and NO_AUTO_VBUS_MANAGEMENT compile time options (thanks to Opendous Inc.) + * - Added support for the Atmel XMEGA B1 Xplained board + * - Added Serial USART peripheral driver for the XMEGA architecture + * - Added Master Mode SPI USART peripheral driver for the XMEGA and AVR8 architectures + * - Added build test to verify correct compilation of as many modules as possible under as many architectures as possible under the C and C++ languages + * - Added build test to verify correct compilation of the USB driver when forced into single USB mode under as many architectures as possible + * - Library Applications: + * - Added User Application APIs to the CDC and DFU class bootloaders + * - Added INVERTED_ISP_MISO compile time option to the AVRISP-MKII clone project (thanks to Chuck Rohs) + * - Added new Android Accessory Host demo (thanks to Opendous Inc.) + * + * Changed: + * - Core: + * - When automatic PLL management mode is enabled on the U4 series AVR8 chips, the PLL is now configured for 48MHz and not + * a divided 96MHz, to lower power consumption and to keep the system within the datasheet specs for 3.3V operation (thanks to Scott Vitale) + * - Added Class, ClassDevice, ClassHost and ClassCommon to the internal class driver source filenames to prevent ambiguities + * - Altered the Mass Storage Host class driver so that SCSI data STALLs from the attached device can be recovered from automatically without + * having to reset the Mass Storage interface + * - USB_CONFIG_ATTR_BUSPOWERED constant renamed to USB_CONFIG_ATTR_RESERVED, as this was misnamed (thanks to NXP Semiconductors) + * - Reordered board name definition indexes so that a mispelled BOARD compile option will default to BOARD_USER rather than BOARD_USBKEY + * - Altered the HID class driver to only try to construct at maximum one packet per USB frame, to reduce CPU usage + * - All USB Class Driver configuration struct values are now non-const, to allow for run-time modifications if required before configuring an instance + * - Library Applications: + * - Altered the Mass Storage Host LowLevel demo so that SCSI data STALLs from the attached device can be recovered from automatically without + * having to reset the Mass Storage interface + * - Updated the AVRISP-MKII Clone programmer project to be compatible with the latest version of AVR Studio (version 5.1) + * - Changed the AVRISP-MKII Clone programmer project to report a fixed 3.3V VTARGET voltage on USB AVRs lacking an ADC instead of 5V to prevent + * warnings in AVR Studio 5.1 when programming XMEGA devices + * - Allow serial strings to be generated on the older AVR8 devices which do not explicitly state they contain unique values in the datasheet, + * as this appears to be implemented in hardware + * + * Fixed: + * - Core: + * - Fixed ring buffer size limited to 255 elements, instead of the intended 65535 elements. + * - Fixed CDC class drivers not saving and sending all 16-bits of the control line states (thanks to Matthew Swabey) + * - Fixed race conditions in the CDC, HID and Mass Storage class drivers when processing some control requests + * - Fixed misspelled HID_KEYBOARD_MODIFIER_* macros in the HID class driver (thanks to Laszlo Monda) + * - Fixed broken AVR32 endpoint/pipe communications when ORDERED_EP_CONFIG compile time option is not enabled (thanks to Matthias Jahr) + * - Fixed broken compilation for the AVR32 devices if the NO_SOF_EVENTS compile time option was not enabled (thanks to Matthias Jahr) + * - Fixed compiler warning on GCC with \c -wundef compile flag is used (thanks to Georg Glock) + * - Fixed incorrect implementation of LEDs_ToggleLEDs() for the Adafruit-U4 board (thanks to Caroline Saliman) + * - Fixed broken compilation of LUFA under C++ compilers when the Serial peripheral module header file is included in a C++ source file + * - Fixed missing semicolon in the UC3 architecture host pipe functions + * - Fixed failed compilation for the XMEGA architecture if USB_DEVICE_ONLY us not specified + * - Fixed UC3 architecture ignoring the pipe size when Pipe_ConfigurePipe() is called + * - Library Applications: + * - Added reliability patches to the AVRISP-MKII Clone project's PDI/TPI protocols (thanks to Justin Mattair) + * - Fixed AVRISP-MKII Clone compile warning on AVR8 U4 targets even when NO_VTARGET_DETECT is enabled + * - Fixed AVRISP-MKII Clone failing to start application firmware once a TPI programming session is exited + * - Fixed DFU class bootloader not resetting the LED pins as high impedance inputs when a software jump to the user applications is requested + * - Fixed AVRISP-MKII Clone timing out on long programming commands such as programming the EEPROM on an ATMEGA8 (thanks to Martin Kelling) + * - Fixed invalid PID value used in the TempDataLogger project host application (thanks to Anupam Pathak) + * + * \section Sec_ChangeLog111009 Version 111009 + * New: + * - Core: + * - Added USE_LUFA_CONFIG_HEADER compile time option to include a LUFAConfig.h header in the user director for LUFA configuration + * tokens as an alternative to tokens defined in the project makefile + * - Added new USB_Host_SetInterfaceAltSetting() convenience function for the selection of an interface's alternative setting + * - Added Audio class control request definitions + * - Added new CALLBACK_Audio_Device_GetSetEndpointProperty() callback to the Audio Device Class driver to allow for endpoint control manipulations + * such as data sample rates + * - Added support for the Audio class GET STATUS request in the Audio Device Class driver so that it is correctly ACKed when sent by the host + * - Added new EVENT_Audio_Device_StreamStartStop() event to the Audio Device Class driver to detect stream start/stop events + * - Added board driver support for the Busware TUL board + * - Added board hardware driver support for the EVK1100 board + * - Added board hardware driver support for the EVK1104 board + * - Added new Host mode Audio Class driver + * - Added new SPI_GetCurrentMode() function to the SPI peripheral driver + * - Added RingBuffer_GetFreeCount() function to the Ring Buffer driver + * - Added new HID_Host_SetIdlePeriod() function to the HID Host Class driver + * - Added new USB_Host_ConfigurationNumber global variable to indicate the selected configuration in an attached device + * - Added new USB_Host_GetDeviceStatus() function to the host standard request function set + * - Added AVR USB XMEGA architecture port (currently incomplete/experimental) + * - Added new STRINGIFY() and STRINGIFY_EXPANDED() convenience macros + * - Added new JTAG_DISABLE() macro for the AVR8 architecture + * - Added Device Qualifier standard descriptor structure definitions USB_StdDescriptor_DeviceQualifier_t and USB_Descriptor_DeviceQualifier_t + * - Library Applications: + * - Added RNDIS device mode to the Webserver project + * - Added new incomplete AndroidAccessoryHost Host LowLevel demo + * - Added new HIDReportViewer project + * - Added new MediaControl project + * - Added new AudioInputHost Host ClassDriver demo + * - Added new AudioOutputHost Host ClassDriver demo + * - Added new AudioInputHost Host LowLevel demo + * - Added new AudioOutputHost Host LowLevel demo + * - Added new "checksource" target to all library project makefiles + * - Added new VTARGET_USE_INTERNAL_REF configuration option to the AVRISP-MKII clone project (thanks to Volker Bosch) + * + * Changed: + * - Core: + * - Altered the definition of the USB_Audio_Descriptor_Format_t descriptor so that the user is now responsible for supplying + * the supported audio sampling rates, to allow for multiple audio interfaces with different numbers of supported rates and/or + * continuous sample rates + * - Pipe_BoundEndpointNumber() has been renamed to Pipe_GetBoundEndpointAddress(), and now returns the correct endpoint direction + * as part of the endpoint address + * - Renamed global state variables that are specific to a certain USB mode to clearly indicate which mode the variable relates to, + * by changing the USB_* prefix to USB_Device_* or USB_Host_* + * - Removed the HOST_STATE_WaitForDeviceRemoval and HOST_STATE_Suspended host state machine states, as these are no longer required + * - Altered the USB_Host_SetDeviceConfiguration() function to update the global Host state machine state and the new + * USB_Host_ConfigurationNumber global as required + * - Added endian correcting code to the library USB class drivers for multiple architecture support + * - Removed the ENDPOINT_DESCRIPTOR_DIR_* macros, replaced by ENDPOINT_DIR_* instead + * - Renamed the JTAG_DEBUG_ASSERT() macro to JTAG_ASSERT() + * - Added variable number of axis to HID_DESCRIPTOR_JOYSTICK() for multi-axis joysticks above just X and Y + * - Renamed USB_Host_ClearPipeStall() to USB_Host_ClearEndpointStall() as the function works on an endpoint address within the attached device, + * and not a Pipe within the host + * - The MS_Host_ResetMSInterface() now performs a full Mass Storage reset sequence to prevent data corruption in the event of a device + * lock up or timeout (thanks to David Lyons) + * - Added endian-correction to the CDC driver's Line Encoding control request handlers. + * - Library Applications: + * - Modified the Low Level and Class Driver AudioInput and AudioOutput demos to support multiple audio sample rates + * - Updated all host mode demos and projects to use the EVENT_USB_Host_DeviceEnumerationComplete() event callback for device configuration + * instead of manual host state machine manipulations in the main application task + * - Changed the reports in the GenericHID device demos to control the board LEDs, to reduce user confusion over the callback routines + * - Added reliability patches to the AVRISP-MKII Clone project's ISP and PDI/TPI protocols (thanks to Justin Mattair) + * + * Fixed: + * - Core: + * - Large number of documentation and code comment corrections (thanks to Andrey from Microsin.ru) + * - Fixed possibility of the AVR's SPI interface being pulled out of master mode if the /SS pin is a input and pulled low (thanks + * to Andrey from Microsin.ru) + * - Fixed compile error when FIXED_CONTROL_ENDPOINT_SIZE compile time option was disabled, and a USE_*_DESCRIPTORS compile time + * option was not enabled on the AVR8s + * - Fixed lack of C++ compatibility in some internal header files causing compile errors when using LUFA in C++ projects + * - Fixed error in the pipe unordered allocation algorithm for the AVR8 devices breaking compatibility with some devices + * - Fixed USB_USBTask not being called internally in stream transfers between packets when Partial Stream Transfers are used + * - Fixed swapped TWI_ADDRESS_READ and TWI_ADDRESS_WRITE values + * - Fixed TWI_ReadPacket() not releasing the TWI bus on read completion + * - Fixed optimization error in the HID Parser item value USB_SetHIDReportItemInfo() and USB_GetHIDReportItemInfo() routines if the report item was + * \c NULL (which should be allowable according to the API) + * - Fixed HID Parser CALLBACK_HIDParser_FilterHIDReportItem() callback function not being passed a cacheable report item pointer + * - Fixed HID Parser's largest report size bit count not including the size of the last parsed report item + * - Fixed HID host driver's largest HID report size count corrupt when the number of report bits exceeds 255 + * - Library Applications: + * - Fixed incorrect signature in the CDC and DFU class bootloaders for the ATMEGA8U2 + * - Fixed KeyboardHost and KeyboardHostWithParser demos displaying incorrect values when numerical keys were pressed + * - Fixed compile errors in the incomplete BluetoothHost demo application (thanks to Timo Lindfors) + * - Fixed incorrect Dataflash buffer use in the DataflashManager_WriteBlocks_RAM() function of several demos/projects (thanks to Jeremy Willden) + * - Fixed incorrect logging interval (always 500ms longer than requested) in the TempDataLogger project + * - Fixed incorrect buffer size check in the USBtoSerial project (thanks to Yuri A Nikiforov) + * - Fixed port state table corruption in the TCP layer of the RNDIS Ethernet device demos + * + * \section Sec_ChangeLog110528 Version 110528 + * New: + * - Core: + * - Added new ORDERED_EP_CONFIG compile time option to restrict endpoint/pipe configuration to ascending order + * in exchange for a smaller compiled program binary size + * - Added a new general RingBuff.h miscellaneous ring buffer library driver header + * - Added new GCC_FORCE_POINTER_ACCESS() macro to correct GCC's mishandling of struct pointer accesses + * - Added new GCC_MEMORY_BARRIER() macro to prevent instruction reordering across boundaries + * - Added basic driver example use code to the library documentation + * - Added new Endpoint_Null_Stream() and Pipe_Null_Stream() functions + * - Added new ADC_GET_CHANNEL_MASK() convenience macro + * - Added new HID report item macros (with HID_RI_ prefix) to allow for easy creation and editing of HID report descriptors + * - Added new HID_DESCRIPTOR_MOUSE(), HID_DESCRIPTOR_KEYBOARD(), HID_DESCRIPTOR_JOYSTICK() and HID_DESCRIPTOR_VENDOR() macros + * for easy automatic creation of basic USB HID device reports + * - Added new MAX() and MIN() convenience macros + * - Added new Serial_SendData() function to the Serial driver + * - Added board driver support for the Sparkfun ATMEGA8U2 breakout board + * - Added TWI baud rate prescaler and bit length parameters to the TWI_Init() function (thanks to Thomas Herlinghaus) + * - Internal restructuring for eventual multiple architecture ports + * - Added AVR32 UC3 architecture port (currently incomplete/experimental) + * - Added new architecture independent functions to enable, disable, save and restore the Global Interrupt Enable flags + * - Added new RNDIS Device Class Driver packet send and receive functions + * - Library Applications: + * - Added ability to write protect Mass Storage disk write operations from the host OS + * - Added new MIDIToneGenerator project + * - Added new KeyboardMouseMultiReport Device ClassDriver demo + * - Added new VirtualSerialMassStorage Device ClassDriver demo + * - Added HID class bootloader, compatible with a modified version of the command line Teensy loader from PJRC.com + * - Added LED flashing to the CDC and DFU class bootloaders to indicate when they are running + * + * Changed: + * - Core: + * - Unordered Endpoint/Pipe configuration is now allowed once again by default via the previous reconfig workaround + * - Refactored Host mode Class Driver *_Host_ConfigurePipes() routines to be more space efficient when compiled + * - Added new *_ENUMERROR_PipeConfigurationFailed error codes for the *_Host_ConfigurePipes() routines + * - The USARTStream global is now public and documented in the SerialStream module, allowing for the serial USART + * stream to be accessed via its handle rather than via the implicit stdout and stdin streams + * - The FAST_STREAM_TRANSFERS compile time option has been removed due to lack of use and low cost/benefit ratio + * - Altered all endpoint/pipe stream transfers so that the new BytesProcessed parameter now points to a location + * where the number of bytes in the transfer that have been completed can be stored (or NULL if entire transaction + * should be performed in one chunk) + * - The NO_STREAM_CALLBACKS compile time option has now been removed due to the new partial stream transfer feature + * - Changed over all project and demo HID report descriptors to use the new HID report item macros + * - Moved the HIDParser.c source file to the LUFA/Drivers/USB/Class/Common/ directory from the LUFA/Drivers/USB/Class/Host/ + * - Added support to the HID parser for extended USAGE items that contain the usage page as well as the usage index + * - Removed the SerialStream driver, rolled functionality into the regular Serial peripheral driver via the new + * Serial_CreateStream() and Serial_CreateBlockingStream() functions + * - Renamed the low level Serial byte send/receive functions, to be consistent with the CDC class driver byte functions + * - Altered the behaviour of the serial byte reception function so that is is non-blocking, and now returns a negative + * value if no character is received (to remain consistent with the CDC class driver byte reception routines) + * - Renamed the PRNT_Host_SendString(), CDC_Host_SendString() and CDC_Device_SendString() functions to *_SendData(), and + * added new versions of the *_SendString() routines that expect a null terminated string instead + * - Renamed all driver termination *_ShutDown() functions to the more logical name *_Disable() + * - Reduced latency for executing the Start-Of-Frame events (if enabled in the user application) + * - Removed Pipe_ClearErrorFlags(), pipe error flags are now automatically cleared when Pipe_ClearError() is called + * - Endpoint_ResetFIFO() renamed to Endpoint_ResetEndpoint(), to be consistent with the Pipe_ResetPipe() function name + * - Implemented on-demand PLL clock generation for the U4, U6 and U7 series USB AVRs when automatic PLL mode is specified + * - F_CLOCK changed to F_USB to be more descriptive, and applicable on future architecture ports + * - Renamed all low level Endpoint_Read_*, Endpoint_Write_* and Endpoint_Discard_* functions to use the number of bits instead of + * a symbolic size (Byte, Word, DWord) so that the function names are applicable and correct across all architectures + * - Renamed all low level Pipe_Read_*, Pipe_Write_* and Pipe_Discard_* functions to use the number of bits instead of + * a symbolic size (Byte, Word, DWord) so that the function names are applicable and correct across all architectures + * - Separated out board drivers by architecture in the library internals for better organisation + * - Library Applications: + * - Changed the XPLAINBridge software UART to use the regular timer CTC mode instead of the alternative CTC mode + * via the Input Capture register, to reduce user confusion + * - Combined page and word ISP programming mode code in the AVRISP-MKII clone project to reduce compiled size and + * increase maintainability of the code + * - Changed over library projects to use the new general ring buffer library driver module + * - Added new high level TWI packet read/write commands, altered behaviour of the TWI_StartTransmission() function + * - Changed TempDataLogger project's DS1307 driver to simplify the function interface and prevent a possible race condition + * - Changed AVRISP-MKII project to use the Watchdog interrupt for command timeouts, to reduce CPU usage and free timer 0 + * for other uses + * - Updated the software USART code in the XPLAIN Bridge application so that the incoming bits are sampled at their mid-point + * instead of starting point, to give maximum reliability (thanks to Anton Staaf) + * + * Fixed: + * - Core: + * - Fixed broken USBFOO board drivers due to missing BOARD_USBFOO define + * - Fixed HID host class driver incorrectly binding to HID devices that do not have an OUT endpoint + * - Fixed incorrect definition of the HID_KEYBOARD_SC_D constant in the HID class driver (thanks to Opendous Inc.) + * - Fixed incorrect definition of the HID_KEYBOARD_SC_RIGHT_ARROW constant in the HID class driver (thanks to Joby Taffey) + * - Fixed incorrect endpoint initialisation order in the several device demos (thanks to Rick Drolet) + * - Fixed inverted Minimus board LEDs + * - Fixed incorrect byte ordering in the Audio_Device_WriteSample24 function (thanks to WZab) + * - Fixed several functions in the Host mode Still Image Class driver returning an error code from the incorrect + * error code enum (thanks to Daniel Seibert) + * - Fixed ReportID not being removed from the feature/out report data array in the HID class driver when Report IDs are used + * - Fixed incorrect BUTTONS_BUTTON1 definition for the Minimus board + * - Fixed Still Image Host class driver exiting the descriptor search routine prematurely if the data pipes (but not event pipe) + * is found + * - Fixed missing call to Pipe_SetInfiniteINRequests() in the Pipe_ConfigurePipe() routine + * - Fixed Remote Wakeup broken on the AVRs due to the mechanism only operating when the SUSPI bit is set (thanks to Holger Steinhaus) + * - Fixed possible invalid program execution when in host mode if corrupt descriptor lengths are supplied by the attached device + * - Library Applications: + * - Fixed Benito project discarding incoming data from the USB virtual serial port when the USART is busy + * - Fixed broken DFU bootloader, added XPLAIN support for bootloader start when XCK jumpered to ground + * - Fixed broken HID_REQ_GetReport request handler in the Low Level GenericHID demo + * - Fixed possible lost data in the XPLAINBridge, USBtoSerial and Benito projects when the host exceeds the packet + * timeout period on received packets as set by USB_STREAM_TIMEOUT_MS (thanks to Justin Rajewski) + * - Fixed possible programming problem in the AVRISP-MKII clone project when programming specific patterns into a target + * memory space that is only byte (not page) addressable + * - Fixed errors in the incomplete Test and Measurement device demo preventing proper operation (thanks to Pavel Plotnikov) + * - Fixed programming errors in the AVRISP-MKII project when the programming packet is a round multiple of the endpoint bank + * size under avrdude (thanks to Steffan Woltjer) + * + * + * \section Sec_ChangeLog101122 Version 101122 + * New: + * - Core: + * - Added new SCSI_ASENSE_NOT_READY_TO_READY_CHANGE constant to the Mass Storage class driver, to indicate when a previously + * not ready removable medium has now become ready for the host's use (thanks to Martin Degelsegger) + * - Moved the Pipe and Endpoint stream related code to two new USB library core source files EndpointStream.c and PipeStream.c + * - Added new USB_Device_GetFrameNumber() and USB_Host_GetFrameNumber() functions to retrieve the current USB frame number + * - Added new USB_Host_EnableSOFEvents(), USB_Host_DisableSOFEvents() and EVENT_USB_Host_StartOfFrame() for the user application + * handling of USB Start of Frame events while in USB Host mode + * - Added new PRNT_Host_BytesReceived(), PRNT_Host_ReceiveByte(), PRNT_Host_SendByte() and PRNT_Host_Flush() functions to the + * Print Host Class driver + * - Added class specific descriptor alternative struct type defines with standard USB-IF element naming + * - Added new project makefile template to the library and moved board driver stub files into in a new "CodeTemplates" directory + * - Added board hardware driver support for the Adafruit U4 breakout board + * - Added board hardware driver support for the Arduino Uno development board + * - Added board hardware driver support for the Blackcat USB JTAG board (thanks to the PSGroove team) + * - Added board hardware driver support for the Busware BUI development board + * - Added board hardware driver support for the Busware CUL V3 868MHZ radio board (thanks to Dirk Tostmann) + * - Added board hardware driver support for the Kernel Concepts USBFOO development board + * - Added board hardware driver support for the Linnix UDIP development board + * - Added board hardware driver support for the Olimex AVR-USB-162 development board (thanks to Steve Fawcett) + * - Added board hardware driver support for the Maximus board (thanks to the PSGroove team) + * - Added board hardware driver support for the Microsin AVR-USB162 breakout board + * - Added board hardware driver support for the Minimus board (thanks to the PSGroove team) + * - Added new NO_CLASS_DRIVER_AUTOFLUSH compile time option to disable automatic flushing of interfaces when the USB management + * tasks for each driver is called + * - Added standard keyboard HID report scan-code defines (thanks to Laszlo Monda) + * - Added new Pipe_GetBusyBanks(), Endpoint_GetBusyBanks() and Endpoint_AbortPendingIN() functions + * - Library Applications: + * - Added default test tone generation mode to the Device mode AudioInput demos + * - Added new NO_BLOCK_SUPPORT, NO_EEPROM_BYTE_SUPPORT, NO_FLASH_BYTE_SUPPORT and NO_LOCK_BYTE_WRITE_SUPPORT compile time options to the + * CDC class bootloader + * - Added new XCK_RESCUE_CLOCK_ENABLE compile time option to the AVRISP-MKII clone programmer project (thanks to Tom Light) + * + * Changed: + * - Core: + * - Removed complicated logic for the Endpoint_ConfigureEndpoint() function to use inlined or function called versions + * depending of if the given bank size is a compile time constant, as the compiler does a better job of optimizing + * with basic code + * - Changed the signature of the CALLBACK_USB_GetDescriptor() callback function so that the descriptor pointer is const, to remove + * the need for extra casting inside the callback (thanks to Jonathan Kollasch) + * - Reduced HOST_DEVICE_SETTLE_DELAY_MS to 1000ms down from 1500ms to improve device compatibility while in USB Host mode + * - Removed the EVENT_USB_InitFailure() event, not specifying a USB mode correctly now defaults to UID selection mode + * - Renamed and moved class driver common constant definitions to make the naming scheme more uniform + * - Moved the USB mode specifier constants into a new enum, so that they are semantically related to one another + * - Renamed ENDPOINT_DOUBLEBANK_SUPPORTED() to ENDPOINT_BANKS_SUPPORTED() and changed it to return the maximum number of supported banks for + * the given endpoint + * - Better algorithm to extract and convert the internal device serial number into a string descriptor (if present) + * - All USB class drivers are now automatically included when LUFA/Drivers/USB.h is included, and no longer need to be separately included + * - The MIDI class drivers now automatically flushes the MIDI interface when the MIDI class driver's USBTask() function is called + * - Renamed the EVENT_USB_Device_UnhandledControlRequest() event to EVENT_USB_Device_ControlRequest() as it is now fired before the library + * request handlers, not afterwards + * - Library Applications: + * - Changed over all device demos to use a clearer algorithm for the configuring of the application's endpoints + * - Added missing DataflashManager_CheckDataflashOperation() function to the MassStorageKeyboard demo, removed redundant + * SCSI_Codes.h file as these values are part of the MassStorage Class Driver + * - Added compile time error to the AVRISP-MKII project when built for the U4 chips, as the default VTARGET detection ADC channel + * does not exist on these chips (thanks to Marco) + * - Changed all Device mode LowLevel demos and Device Class drivers so that the control request is acknowledged and any data + * transferred as quickly as possible without any processing in between sections, so that long callbacks or event handlers will + * not break communications with the host by exceeding the maximum control request stage timeout period + * - Changed over all demos, drivers and internal functions to use the current frame number over the Start of Frame flag where possible + * to free up the Start of Frame flag for interrupt use in the user application + * - All project makefiles now correctly clean intermediate build files from assembly and C++ sources (thanks to Daniel Czigany) + * - Changed default value for the reset polarity parameter in the AVRISP-MKII project so that it defaults to active low drive + * - Changed configuration descriptor parser for all host mode projects and class drivers to ensure better compatibility with devices + * - All LowLevel demos changed to use the constants and types defined in the USB class drivers + * - Changed AudioInput and AudioOutput demos to reload the next sample via an interrupt rather than polling the sample timer + * - Rescue clock of the AVRISP-MKII moved to the AVR's OCR1A pin, so that the clock can be generated at all times + * - Changed ClassDriver MIDI demos to process all incoming events in a loop until the bank becomes empty rather than one at a time + * - Changed LowLevel MIDI demos to only clear the incoming event bank once it has become empty to support packed event packets + * + * Fixed: + * - Core: + * - Fixed USB_GetHIDReportItemInfo() function modifying the given report item's data when the report item does not exist + * within the supplied report of a multiple report HID device + * - Fixed critical pipe/endpoint memory allocation issue where the bank memory address space could be silently overlapped + * in the USB controller if the endpoints or pipes were allocated in anything other than ascending order (thanks to Martin Degelsegger) + * - Added LEDs_ToggleLEDs() function to several board LED drivers which were missing it (thanks to Andrei Krainev) + * - Fixed SET FEATURE and CLEAR FEATURE control requests directed at an unconfigured endpoint causing request timeouts + * - Fixed USB_Host_ClearPipeStall() incorrectly determining the endpoint direction from the currently selected pipe + * - Fixed JTAG_DEBUG_POINT() and JTAG_DEBUG_BREAK() macros not compiling under pure C99 standards mode + * - Fixed endpoint selection within the CALLBACK_HID_Device_CreateHIDReport() callback function causing broken GET REPORT requests + * - Fixed incorrect command name for EEPROM memory programming in the makefile dfu-ee target + * - Fixed incorrect LEDs_ChangeLEDs() function in the Benito board LED driver + * - Fixed incorrect USB_DeviceState value when unconfiguring the device without an address set + * - Fixed SPI driver not explicitly setting /SS and MISO pins as inputs when SPI_Init() is called + * - Fixed random enumeration failure while in device mode due to interrupts causing the Set Address request to exceed maximum timings + * - Fixed MIDI_Host_Flush() not aborting early when the specified MIDI host interface was not configured + * - Fixed MIDI class driver send routines silently discarding packets if the endpoint or pipe is busy (thanks to Robin Green) + * - Library Applications: + * - Fixed MassStorage based demos and projects resetting the SCSI sense values before the command is executed, leading to + * missed SCSI sense values when the host retrieves the sense key (thanks to Martin Degelsegger) + * - Fixed USBtoSerial and Benito project SetLineEncoding calls failing if the USART is busy, due to the RX ISR delaying the control + * request handler + * - Fixed LowLevel PrinterHost demo not sending control requests to the attached printer with the correct printer interface wIndex value + * - Fixed incorrect signature reported in the CDC class bootloader for the ATMEGA32U2 + * - Fixed BootloaderCDC project failing on some operating systems due to removed Line Encoding options (thanks to Alexey Belyaev) + * - Fixed broken FLASH/EEPROM programming in the AVRISP-MKII clone project when writing in non-paged mode and the polling byte cannot be used + * - Fixed ISR definition conflict in the XPLAIN bridge between the software UART and the AVRISP-MKII ISP modules + * - Fixed USBtoSerial and XPLAINBridge demos discarding data from the PC if the send buffer becomes full + * - Fixed broken input in the MagStripe reader project due to an incorrect HID report descriptor + * - Fixed incorrect PollingIntervalMS values in the demo/project/bootloader endpoint descriptors (thanks to MCS Electronics) + * - Fixed AVRISP-MKII clone project not starting the target's program automatically after exiting TPI programming mode + * + * + * \section Sec_ChangeLog100807 Version 100807 + * New: + * - Added new ADC_DisableChannel() function (thanks to Mich Davis) + * - Added new VTARGET_REF_VOLTS and VTARGET_SCALE_FACTOR compile time defines to the AVRISP-MKII programmer project to set + * the VTARGET reference voltage and scale factor + * - Added new pgm_read_ptr() macro to Common.h for reading of pointers out of flash memory space + * - Added new SWAPENDIAN_16() and SWAPENDIAN_32() macros to Common.h for statically initialized variables at compile time + * - Added new Drivers/USB/LowLevel/Device.c file to house Device mode specific functions that are more complicated than simple macros + * - Added new AVRStudio 4 project files for all library demos, projects and bootloaders + * - Added ability to set the serial baud rate via the user's terminal in the XPLAINBridge project + * - Added new LUFA module variables for the different source modules in the core library makefile to simplify project makefiles + * - Added start of a new Test and Measurement class demo (thanks to Peter Lawrence) + * - Added new SPI_ORDER_* data order masks to the SPI peripheral driver + * - Added support to the AVRISP-MKII project for ISP speeds slower than 125KHz via a new software SPI driver + * - Added support for the new button/LED on the latest model USBTINY-MKII + * + * Changed: + * - The RingBuff library code has been replaced in the XPLAINBridge, Benito and USBtoSerial projects with an ultra lightweight + * ring buffer to help improve the reliability of the projects + * - The EEPROM stream read/write functions now use eeprom_update_byte() instead of eeprom_write_byte(), so that only + * changed bytes are written to EEPROM to preserve its lifespan + * - Changed over the AVRISP-MKII and TemperatureDataLogger projects to use eeprom_update_byte() when writing non-volatile + * parameters to EEPROM to preserve its lifespan + * - Removed unused line encoding data and control requests from the CDC Bootloader code, to save space + * - Renamed SERIAL_STREAM_ASSERT() macro to STDOUT_ASSERT() + * - The USB_Device_IsRemoteWakeupSent() and USB_Device_IsUSBSuspended() macros have been deleted, as they are now obsolete + * - Rewrote the implementation of the SwapEndian_16() and SwapEndian_32() functions so that they compile down in most instances to + * minimal loads and stores rather than complicated shifts + * - The software UART in the XPLAINBridge has been largely altered to try to improve upon its performance and reliability + * - The USBtoSerial and Benito projects now flushes received data via a flush timer, so that several bytes can be transmitted at once + * - Removed the automated checking of event names in the demo, project and bootloader makefiles due to inconsistencies between the + * behaviour of the command line tools used to perform the check on each platform + * - Internal USB driver source files renamed and moved to ease future possible architecture ports + * - All internal pseudo-function macros have been converted to true inline functions for type-safety and readability + * - Changed LED indicator masks for the AVRISP-MKII project, so that there are defined roles for each LED + * - Altered the CDC Device and Host Class drivers' receive byte routines, so that no data is indicated by the function returning a + * negative value (thanks to Andreas Paulin) + * - Added auto flushing of OUT data to the CDC Host Class driver's USBTask function to automatically flush the send pipe buffer + * + * Fixed: + * - Fixed AVRISP project sending a LOAD EXTENDED ADDRESS command to 128KB AVRs after programming or reading from + * the last page of FLASH (thanks to Gerard Sexton) + * - Fixed AVRISP project not sending a full erase-and-write EEPROM command to XMEGA targets when writing to the EEPROM + * instead of the split write-only command (thanks to Tim Margush) + * - Fixed RNDISEthernet demos crashing when calculating checksums for Ethernet/TCP packets of more than ~500 bytes due to + * an overflow in the checksum calculation loop (thanks to Kevin Malec) + * - Fixed XPLAINBridge project not correctly reading the XMEGA's supply voltage when reporting back to the host + * - Fixed incorrect signature for the ATMEGA32U2 in the DFU bootloader (thanks to Axel Rohde) + * - Fixed internal device serial not being accessible on the ATMEGAXXU2 AVRs (thanks to Axel Rohde) + * - Fixed void pointer arithmetic in ConfigDescriptor.h breaking C++ compatibility (thanks to Michael Hennebry) + * - Fixed broken PDI EEPROM Section Erase functionality in the AVRISP-MKII project + * - Fixed USB_Device_SendRemoteWakeup() not working when the USB clock was frozen during USB bus suspend (thanks to Brian Dickman) + * - Fixed occasional lockup of the AVRISP project due to the timeout extension code incorrectly extending the timeout in + * PDI and TPI programming modes infinitely + * - Fixed HID device class driver still using PrevReportINBuffer for GetReport control requests even when it has been + * set to NULL by the user application (thanks to Axel Rohde) + * - Fixed MIDI_Device_SendEventPacket() not correctly waiting for the endpoint to become ready (thanks to Robin Green) + * - Fixed Benito and USBtoSerial projects not turning off the USART before reconfiguring it, which could cause incorrect + * operation to occur (thanks to Bob Paddock) + * - Fixed Serial peripheral driver not turning off the USART before reconfiguring it, which would cause incorrect operation + * to occur (thanks to Bob Paddock) + * - Fixed software application start command broken in the DFU class bootloader when dfu-programmer is used due to application + * start address corruption + * + * + * \section Sec_ChangeLog100513 Version 100513 + * New: + * - Added incomplete MIDIToneGenerator project + * - Added new Relay Controller Board project (thanks to OBinou) + * - Added board hardware driver support for the Teensy, USBTINY MKII, Benito and JM-DB-U2 lines of third party USB AVR boards + * - Added new ATTR_NO_INIT variable attribute for global variables that should not be automatically cleared on startup + * - Added new ENDPOINT_*_BusSuspended error code to the Endpoint function, so that the stream functions early-abort if the bus + * is suspended before or during a transfer + * - Added new EVENT_CDC_Device_BreakSent() event and CDC_Host_SendBreak() function to the Device and Host CDC Class drivers + * - Added ReportType parameter to the HID device class driver CALLBACK_HID_Device_ProcessHIDReport() function so that FEATURE + * reports from the host to the device can be correctly processed + * - Added ReportType parameter to the HID host class driver HID_Host_SendReportByID() function so that FEATURE reports can be + * issued to the attached device + * + * Changed: + * - AVRISP programmer project now has a more robust timeout system + * - Added a timeout value to the TWI_StartTransmission() function, within which the addressed device must respond + * - Webserver project now uses the board LEDs to indicate the current IP configuration state + * - Added ENABLE_TELNET_SERVER compile time option to the Webserver project to disable the TELNET server if desired + * - Increased throughput of the USBtoSerial demo on systems that send multiple bytes per packet (thanks to Opendous Inc.) + * - Double bank CDC endpoints in the XPLAIN Bridge project, re-enable JTAG once the mode selection pin has been sampled. + * - Standardized the naming scheme given to configuration descriptor sub-elements in the Device mode demos, bootloaders + * and projects + * - All Class Driver Host mode demos now correctly set the board LEDs to READY once the enumeration process has completed + * - Added LIBUSB_FILTERDRV_COMPAT compile time option to the AVRISP programmer project to make the code compatible with Windows + * builds of avrdude at the expense of AVRStudio compatibility + * - Removed two-step endpoint/pipe bank clear and switch sequence for smaller, faster endpoint/pipe code + * - The USB_Init() function no longer calls sei() - the user is now responsible for enabling interrupts when they are ready + * for them to be enabled (thanks to Andrei Krainev) + * - The Audio_Device_IsSampleReceived() and Audio_Device_IsReadyForNextSample() functions are now inline, to reduce overhead + * - Removed the cast to uint16_t on the set baud rate in the USBtoSerial project, so that the higher >1M baud rates can be + * selected (thanks to Steffan Woltjer) + * - Removed software PDI and TPI emulation from the AVRISP-MKII clone project as it was very buggy and slow - PDI and TPI must + * now be implemented via separate programming headers + * - The CDC class bootloader now uses a watchdog reset rather than a soft-reset when exited to ensure that all hardware is + * properly reset to their defaults + * - Device mode class driver callbacks are now fired before the control request status stage is sent to prevent the host from + * timing out if another request is immediately fired and the device has a lengthy callback routine + * - The TeensyHID bootloader has been removed, per request from Paul at PJRC + * - The LIBUSB_FILTERDRV_COMPAT compile time option in the XPLAINBridge and AVRISP-MKII projects has been renamed + * LIBUSB_DRIVER_COMPAT, as it applies to all software on all platforms using the libUSB driver + * + * Fixed: + * - Fixed possible device lockup when INTERRUPT_CONTROL_ENDPOINT is enabled and the control endpoint is not properly + * selected when the ISR completes + * - Fixed AVRISP-MKII clone project not correctly issuing LOAD EXTENDED ADDRESS commands when the extended address + * boundary is crossed during programming or read back (thanks to Gerard Sexton) + * - Fixed warnings when building the AVRISP-MKII clone project with the ENABLE_XPROG_PROTOCOL compile time option disabled + * - Fixed software PDI/TPI programming mode in the AVRISP project not correctly toggling just the clock pin + * - Fixed TWI_StartTransmission() corrupting the contents of the GPIOR0 register + * - Fixed TWI driver not aborting when faced with no response after attempting to address a device on the bus + * - Fixed ADC routines not correctly returning the last result when multiple channels were read + * - Fixed ADC routines failing to read the extended channels (Channels 8 to 13, Internal Temperature Sensor) on the + * U4 series USB AVR parts + * - Fixed LowLevel MassStorage demo broken on the U2 series USB AVRs due to unsupported double-banked endpoint modes used + * - Fixed compilation error in the AudioInput demos when MICROPHONE_BIASED_TO_HALF_RAIL is defined (thanks to C. Scott Ananian) + * - Fixed incorrect definition of HID_ALIGN_DATA() causing incorrect HID report item data alignment + * - Fixed Still Image Host class driver not resetting the transaction ID when a new session is opened, fixed driver not sending + * a valid session ID to the device + * - Removed invalid dfu and flip related targets from the bootloaders - bootloaders can only be replaced with an external programmer + * - Fixed Set/Clear Feature requests directed to a non-configured endpoint not returning a stall to the host + * - Fixed HID Device Class Driver not allocating a temporary buffer when the host requests a report via the control endpoint and the + * user has set the PrevReportINBuffer driver configuration element to NULL (thanks to Lars Noschinski) + * - Fixed device state not being reset to DEVICE_STATE_Default if the host sets a 0x00 device address + * - Fixed device not stalling configuration requests before the device's address has been set + * - Fixed possibility of internal signature retrieval being corrupted if an interrupt occurs during a signature byte + * read (thanks to Andrei Krainev) + * - Fixed device state not being reset back to the default state if the host sets the address to 0 + * - Fixed Set Configuration requests not being stalled until the host has set the device's address + * - Fixed Host mode HID class driver not sending the correct report type when HID_Host_SendReportByID() was called and the + * HID_HOST_BOOT_PROTOCOL_ONLY compile time option is set + * - Fixed INTERRUPT_CONTROL_ENDPOINT compile time option preventing other interrupts from occurring while the control endpoint + * request is being processed, causing possible lockups if a USB interrupt occurs during a transfer + * - Remove incorrect Abstract Call Management class specific descriptor from the CDC demos, bootloaders and projects + * + * + * \section Sec_ChangeLog100219 Version 100219 + * + * New: + * - Added TPI programming support for 6-pin ATTINY devices to the AVRISP programmer project (thanks to Tom Light) + * - Added command timeout counter to the AVRISP project so that the device no longer freezes when incorrectly connected + * to a target + * - Added new TemperatureDataLogger application, a USB data logger which writes to the device's dataflash and appears to + * the host as a standard Mass Storage device when inserted + * - Added MIDI event packing support to the MIDI Device and Host mode Class drivers, allowing for multiple MIDI events to + * sent or received in packed form in a single USB packet + * - Added new MIDI send buffer flush routines to the MIDI Device and Host mode Class drivers, to flush packed events + * - Added master mode hardware TWI driver for easy TWI peripheral control + * - Added ADC MUX masks for the standard ADC input channels on all AVR models with an ADC, altered demos to use these masks + * as on some models, the channel number is not identical to its single-ended ADC MUX mask + * - New Webserver project, a RNDIS host USB webserver using the open source uIP TCP/IP network stack and FatFS library + * - New BOARD value option BOARD_NONE (equivalent to not specifying BOARD) which will remove all board hardware drivers which + * do not adversely affect the code operation (currently only the LEDs driver) + * - Added keyboard modifier masks (HID_KEYBOARD_MODIFER_*) and LED report masks (KEYBOARD_LED_*) to the HID class driver and + * Keyboard demos + * - Added .5MHz recovery clock to the AVRISP programmer project when in ISP programming mode to correct mis-set fuses + * + * Changed: + * - Slowed down software USART carried PDI programming in the AVRISP project to prevent transmission errors + * - Renamed the AVRISP project folder to AVRISP-MKII to reduce confusion + * - Renamed the RESET_LINE_* makefile tokens in the AVRISP MKII Project to AUX_LINE_*, as they are not always used for target + * reset + * - Changed over the MassStorageKeyboard Class driver device demo to use Start of Frame events rather than a timer to keep track + * of elapsed milliseconds + * - Inlined currently unused (but standardized) maintenance functions in the Device and Host Class drivers to save space + * - The XPLAINBridge project now selects between a USB to Serial bridge and a PDI programmer on startup, reading the JTAG port's + * TDI pin to determine which mode to use + * - Removed the stream example code from the Low Level VirtualSerial demos, as they were buggy and only served to add clutter + * + * Fixed: + * - Fixed AVRISP project not able to enter programming mode when ISP protocol is used + * - Fixed AVRISP PDI race condition where the guard time between direction changes could be interpreted as a start bit + * - Fixed ADC_IsReadingComplete() returning an inverted result + * - Fixed blocking CDC streams not aborting when the host is disconnected + * - Fixed XPLAIN board Dataflash driver broken due to incorrect preprocessor commands + * - Fixed inverted XPLAIN LED driver output (LED turned on when it was supposed to be turned off, and vice-versa) + * - Fixed Class Driver struct interface numbers in the KeyboardMouse and VirtualSerialMouse demos (thanks to Renaud Cerrato) + * - Fixed invalid USB controller PLL prescaler values for the ATMEGAxxU2 controllers + * - Fixed lack of support for the ATMEGA32U2 in the DFU and CDC class bootloaders + * - Fixed Benito project not resetting the target AVR automatically when programming has completed + * - Fixed DFU bootloader programming not discarding the correct number of filler bytes from the host when non-aligned programming + * ranges are specified (thanks to Thomas Bleeker) + * - Fixed CDC and RNDIS host demos and class drivers - bidirectional endpoints should use two separate pipes, not one half-duplex pipe + * - Fixed Pipe_IsEndpointBound() not taking the endpoint's direction into account + * - Fixed EEPROM and FLASH ISP programming in the AVRISP project + * - Fixed incorrect values of USB_CONFIG_ATTR_SELFPOWERED and USB_CONFIG_ATTR_REMOTEWAKEUP tokens (thanks to Claus Christensen) + * - Fixed SerialStream driver blocking while waiting for characters to be received instead of returning EOF + * - Fixed SerialStream driver not setting stdin to the created serial stream (thanks to Mike Alexander) + * - Fixed USB_GetHIDReportSize() returning the number of bits in the specified report instead of bytes + * - Fixed AVRISP project not extending the command delay after each successful page/word/byte program + * - Fixed accuracy of the SERIAL_UBBRVAL() and SERIAL_2X_UBBRVAL() macros for higher baud rates (thanks to Renaud Cerrato) + * + * + * \section Sec_ChangeLog091223 Version 091223 + * + * New: + * - Added activity LED indicators to the AVRISP project to indicate when the device is busy processing a command + * - The USB target family and allowable USB mode tokens are now public and documented (USB_CAN_BE_*, USB_SERIES_*_AVR) + * - Added new XPLAIN USB to Serial Bridge project (thanks to John Steggall for initial proof-of-concept, David Prentice + * and Peter Danneger for revised software USART code) + * - Added new RNDIS Ethernet Host LowLevel demo + * - Added new RNDIS Ethernet Host Class Driver + * - Added new RNDIS Ethernet Host ClassDriver demo + * - Added CDC_Host_Flush() function to the CDC Host Class driver to flush sent data to the attached device + * - Added PDI programming support for XMEGA devices to the AVRISP programmer project (thanks to Justin Mattair) + * - Added support for the XPLAIN board Dataflash, with new XPLAIN_REV1 board target for the different dataflash used + * on the first revision boards compared to the one mounted on later revisions + * - Added new HID_ALIGN_DATA() macro to return the pre-retrieved value of a HID report item, left-aligned to a given datatype + * - Added new PreviousValue to the HID Report Parser report item structure, for easy monitoring of previous report item values + * - Added new EVK527 board target + * - Added new USB_Host_GetDeviceStringDescriptor() convenience function + * - Added new LEDNotification project to the library, to give a visual LED notification on new events from the host + * - Added new NO_DEVICE_REMOTE_WAKEUP and NO_DEVICE_SELF_POWER compile time options + * + * Changed: + * - Removed code in the Keyboard demos to send zeroed reports between two reports with differing numbers of key codes + * as this relied on non-standard OS driver behaviour to repeat key groups + * - The SCSI_Request_Sense_Response_t and SCSI_Inquiry_Response_t type defines are now part of the Mass Storage Class + * driver common defines, rather than being defined in the Host mode Class driver section only + * - The USB_MODE_HOST token is now defined even when host mode is not available + * - The CALLBACK_HID_Device_CreateHIDReport() HID Device Class driver callback now has a new ReportType parameter to + * indicate the report type to generate + * - All Class Drivers now return false or the "DeviceDisconnected" error code of their respective error enums when a function + * is called when no host/device is connected where possible + * - The HOST_SENDCONTROL_DeviceDisconnect enum value has been renamed to HOST_SENDCONTROL_DeviceDisconnected to be in line + * with the rest of the library error codes + * - Make MIDI device demos also turn off the on board LEDs if MIDI Note On messages are sent with a velocity of zero, + * which some devices use instead of Note Off messages (thanks to Robin Green) + * - The CDC demos are now named "VirtualSerial" instead to indicate the demos' function rather than its implemented USB class, + * to reduce confusion and to be in line with the rest of the LUFA demos + * - The SImage_Host_SendBlockHeader() and SImage_Host_ReceiveBlockHeader() Still Image Host Class driver functions are now public + * + * Fixed: + * - Added missing CDC_Host_CreateBlockingStream() function code to the CDC Host Class driver + * - Fixed incorrect values for REPORT_ITEM_TYPE_* enum values causing corrupt data in the HID Host Parser + * - Fixed misnamed SI_Host_USBTask() and SI_Host_ConfigurePipes() functions + * - Fixed broken USB_GetNextDescriptor() function causing the descriptor to jump ahead double the expected amount + * - Fixed Pipe_IsEndpointBound() not masking the given Endpoint Address against PIPE_EPNUM_MASK + * - Fixed host state machine not enabling Auto VBUS mode when HOST_DEVICE_SETTLE_DELAY_MS is set to zero + * - Fixed misnamed Pipe_SetPipeToken() macro for setting a pipe's direction + * - Fixed CDCHost failing on devices with bidirectional endpoints + * - Fixed USB driver failing to define the PLL prescaler mask for the ATMEGA8U2 and ATMEGA16U2 + * - Fixed HID Parser not distributing the Usage Min and Usage Max values across an array of report items + * - Fixed Mass Storage Host Class driver and Low Level demo not clearing the error condition if an attached device returns a + * STALL to a GET MAX LUN request (thanks to Martin Luxen) + * - Fixed TeensyHID bootloader not properly shutting down the USB interface to trigger a disconnection on the host before resetting + * - Fixed MassStorageHost Class driver demo not having USB_STREAM_TIMEOUT_MS compile time option set properly to prevent slow + * devices from timing out the data pipes + * - Fixed the definition of the Endpoint_BytesInEndpoint() macro for the U4 series AVR parts + * - Fixed MIDI host Class driver MIDI_Host_SendEventPacket() routine not properly checking for Pipe ready before writing + * - Fixed use of deprecated struct initializers, removed library unused parameter warnings when compiled with -Wextra enabled + * - Fixed Still Image Host Class driver truncating the PIMA response code (thanks to Daniel Seibert) + * - Fixed USB_CurrentMode not being reset to USB_MODE_NONE when the USB interface is shut down and both Host and Device modes can be + * used (thanks to Daniel Levy) + * - Fixed TeensyHID bootloader not enumerating to the host correctly (thanks to Clint Fisher) + * - Fixed AVRISP project timeouts not checking for the correct timeout period (thanks to Carl Ott) + * - Fixed STK525 Dataflash driver using incorrect bit-shifting for Dataflash addresses (thanks to Tim Mitchell) + * + * + * \section Sec_ChangeLog091122 Version 091122 + * + * New: + * - Added new Dual Role Keyboard/Mouse demo + * - Added new HID_HOST_BOOT_PROTOCOL_ONLY compile time token to reduce the size of the HID Host Class driver when + * Report protocol is not needed + * - Added new MIDI LowLevel and ClassDriver Host demo, add new MIDI Host Class driver + * - Added new CDC/Mouse ClassDriver device demo + * - Added new Joystick Host ClassDriver and LowLevel demos + * - Added new Printer Host mode Class driver + * - Added new Printer Host mode ClassDriver demo + * - Added optional support for double banked endpoints and pipes in the Device and Host mode Class drivers + * - Added new stream creation function to the CDC Class drivers, to easily make standard I/O streams from CDC Class driver instances + * + * Changed: + * - Removed mostly useless "TestApp" demo, as it was mainly useful only for checking for syntax errors in the library + * - MIDI device demos now receive MIDI events from the host and display note ON messages via the board LEDs + * - Cleanups to the Device mode Mass Storage demo application SCSI routines + * - Changed Audio Class driver sample read/write functions to be inline, to reduce the number of cycles needed to transfer + * samples to and from the device (allowing more time for sample processing and output) + * - Audio class Device mode demos now work at both 16MHz and 8MHz, rather than just at 8MHz + * - The previous USBtoSerial demo has been moved into the projects directory, as it was just a modified CDC demo + * - The Endpoint/Pipe functions now use the const qualifier on the input buffer + * - Changed the CALLBACK_HIDParser_FilterHIDReportItem() callback to pass a HID_ReportItem_t rather than just the current + * item's attributes, to expose more information on the item (including it's type, collection path, etc.) + * - Changed MouseHostWithParser demos to check that the report items have a Mouse usage collection as a parent at some point, + * to prevent Joysticks from enumerating with the demo + * - Corrected the name of the misnamed USB_GetDeviceConfigDescriptor() function to USB_Host_GetDeviceConfigDescriptor(). + * - Keyboard LowLevel/ClassDriver demos now support multiple simultaneous key presses (up to 6) per report + * + * Fixed: + * - Fixed PrinterHost demo returning invalid Device ID data when the attached device does not have a + * device ID (thanks to Andrei Krainev) + * - Changed LUFA_VERSION_INTEGER define to use BCD values, to make comparisons easier + * - Fixed issue in the HID Host class driver's HID_Host_SendReportByID() routine using the incorrect mode (control/pipe) + * to send report to the attached device + * - Fixed ClassDriver AudioOutput device demo not selecting an audio output mode + * - Fixed incorrect SampleFrequencyType value in the AudioInput and AudioOutput ClassDriver demos' descriptors + * - Fixed incorrect event name rule in demo/project/bootloader makefiles + * - Fixed HID device class driver not reselecting the correct endpoint once the user callback routines have been called + * - Corrected HID descriptor in the Joystick Device demos - buttons should be placed outside the pointer collection + * - Fixed HID report parser collection paths invalid due to misplaced semicolon in the free path item search loop + * - Fixed HID host Class driver report send/receive report broken when issued through the control pipe + * - Fixed HOST_STATE_AS_GPIOR compile time option being ignored when in host mode (thanks to David Lyons) + * - Fixed LowLevel Keyboard demo not saving the issues report only after it has been sent to the host + * - Fixed Endpoint_Write_Control_Stream_* functions not sending a terminating IN when given data Length is zero + * + * + * \section Sec_ChangeLog090924 Version 090924 + * + * New: + * - Added new host mode class drivers and matching demos to the library for rapid application development + * - Added flag to the HID report parser to indicate if a device has multiple reports + * - Added new EVENT_USB_Device_StartOfFrame() event, controlled by the new USB_Device_EnableSOFEvents() and + * USB_Device_DisableSOFEvents() macros to give bus-synchronized millisecond interrupts when in USB device mode + * - Added new Endpoint_SetEndpointDirection() macro for bidirectional endpoints + * - Added new AVRISP project, a LUFA powered clone of the Atmel AVRISP-MKII programmer + * - Added ShutDown() functions for all hardware peripheral drivers, so that peripherals can be turned off after use + * - Added new CDC_Device_Flush() command to the device mode CDC Class driver to flush Device->Host data + * - Added extra masks to the SPI driver, changed SPI_Init() so that the clock polarity and sample modes can be set + * - Added new callback to the HID report parser, so that the user application can filter only the items it is interested + * in to be stored into the HIDReportInfo structure to save RAM + * - Added support for the officially recommended external peripheral layout for the BUMBLEB board (thanks to Dave Fletcher) + * - Added new Pipe_IsFrozen() macro to determine if the currently selected pipe is frozen + * - Added new USB_GetHIDReportSize() function to the HID report parser to retrieve the size of a given report by its ID + * - Added new combined Mass Storage and Keyboard demo (thanks to Matthias Hullin) + * + * Changed: + * - SetIdle requests to the HID device driver with a 0 idle period (send changes only) now only affect the requested + * HID interface within the device, not all HID interfaces + * - Added explicit attribute masks to the device mode demos' descriptors + * - Added return values to the CDC and MIDI class driver transmit functions + * - Optimized Endpoint_Read_Word_* and Pipe_Read_Word_* macros to reduce compiled size + * - Added non-null function parameter pointer restrictions to USB Class drivers to improve user code reliability + * - Added new "Common" section to the class drivers, to hold all mode-independent definitions for clarity + * - Moved SCSI command/sense constants into the Mass Storage Class driver, instead of the user-code + * - Altered the SCSI commands in the LowLevel Mass Storage Host to save on FLASH space by reducing function calls + * - Changed the parameters and behaviour of the USB_GetDeviceConfigDescriptor() function so that it now performs size checks + * and data validations internally, to simplify user code + * - Changed HIDParser to only zero out important values in the Parsed HID Report Item Information structure to save cycles + * - The HID report parser now always processed FEATURE items - HID_ENABLE_FEATURE_PROCESSING token now has no effect + * - The HID report parser now always ignores constant-data items, HID_INCLUDE_CONSTANT_DATA_ITEMS token now has no effect + * - The Benito Programmer project now has its own unique VID/PID pair allocated from the Atmel donated LUFA VID/PID pool + * - Add in new invalid event hook check targets to project makefiles to produce compilation errors when invalid event names + * are used in a project + * - The HID Report Parser now gives information on the total length of each report within a HID interface + * - The USE_NONSTANDARD_DESCRIPTOR_NAMES compile time token has been removed - there are now separate USB_Descriptor_* and + * USB_StdDescriptor_* structures for both the LUFA and standardized element naming conventions so both may be used + * + * Fixed: + * - Fixed possible lockup in the CDC device class driver, when the host sends data that is a multiple of the + * endpoint's bank + * - Fixed swapped parameters in the HID state memory copy call while processing a HID PUSH item in the HID report parser + * - Fixed memory corruption HID report parser when too many COLLECTION or PUSH items were processed + * - Fixed HID report parser not resetting the FEATURE item count when a REPORT ID item is encountered + * - Fixed USBtoSerial demos not reading in UDR1 when the USART receives data but the USB interface is not enumerated, + * causing continuous USART receive interrupts + * - Fixed misspelled event name in the Class driver USBtoSerial demo, preventing correct operation + * - Fixed invalid data being returned when a GetStatus request is issued in Device mode with an unhandled data recipient + * - Added hardware USART receive interrupt and software buffering to the Benito project to ensure received data is not + * missed or corrupted + * - Fixed Device mode HID Class driver always sending IN packets, even when nothing to report + * - Fixed Device mode HID Class driver not explicitly initializing the ReportSize parameter to zero before calling callback + * routine, so that ignored callbacks don't cause incorrect data to be sent + * - Fixed StillImageHost not correctly freezing and unfreezing data pipes while waiting for a response block header + * - Fixed error in the PrinterHost demo preventing the full page data from being sent to the attached device (thanks to John Andrews) + * - Fixed CDC based demos and projects' INF driver files under 64 bit versions of Windows (thanks to Ronny Hanson, Thomas Bleeker) + * - Re-add in missing flip, flip-ee, dfu and dfu-ee targets to project makefiles (thanks to Opendous Inc.) + * - Fix allowable F_CPU values comment in project makefiles to more accurately reflect the allowable values on the USB AVRs + * - Fixed DFU and CDC class bootloaders on the series 2 USB AVRs, corrected invalid signatures, added support for the new + * ATMEGAxx2 series 2 variant AVRs to the DFU bootloader + * - Fixed Low Level USBtoSerial demo not storing received characters (thanks to Michael Cooper) + * - Fixed MIDI Device Class driver not sending/receiving MIDI packets of the correct size (thanks to Thomas Bleeker) + * + * + * \section Sec_ChangeLog090810 Version 090810 + * + * New: + * - Added new device class drivers and matching demos to the library for rapid application development + * - Added new PrinterHost demo (thanks to John Andrews) + * - Added USB Missile Launcher project, submitted by Dave Fletcher + * - Added new Benito Arduino Programmer project + * - Added incomplete device and host mode demos for later enhancement + * - Updated MassStorage device block write routines to use ping-pong Dataflash buffering to increase throughput by around 30% + * - Error status LEDs shown when device endpoint configuration fails to complete in all demos and projects + * - Added new USB_Host_SetDeviceConfiguration() convenience function for easy configuration selection of devices while in USB + * host mode + * - Added new USB_Host_ClearPipeStall() convenience function to clear a stall condition on an attached device's endpoint + * - Added new USB_Host_GetDeviceDescriptor() convenience function to retrieve the attached device's Device descriptor + * - Added new Endpoint_ClearStatusStage() convenience function to assist with the status stages of control transfers + * - Added new USE_INTERNAL_SERIAL define for using the unique serial numbers in some AVR models as the USB device's serial number, + * added NO_INTERNAL_SERIAL compile time option to turn off new serial number reading code + * - Added new DATAFLASH_CHIP_MASK() macro to the Dataflash driver, which returns the Dataflash select mask for the given chip index + * - Added new HOST_STATE_WaitForDeviceRemoval host state machine state for non-blocking disabling of device communications until the + * device has been removed (for use when an error occurs or communications with the device have completed) + * - Added new FAST_STREAM_TRANSFERS compile time option for faster stream transfers via multiple bytes copied per stream loop + * - Added stdio stream demo code to the CDC device demos, to show how to create standard streams out of the virtual serial ports + * - Added new EEPROM and FLASH buffer versions of the Endpoint and Pipe stream functions + * - Added new USE_FLASH_DESCRIPTORS and FIXED_NUM_CONFIGURATIONS compile time options + * - Added support for the new ATMEGA32U2, ATMEGA16U2 and ATMEGA8U2 AVR models + * - Added new USB_DeviceState variable to keep track of the current Device mode USB state + * - Added new LEDs_ToggleLEDs() function to the LEDs driver + * - Added new Pipe_BoundEndpointNumber() and Pipe_IsEndpointBound() functions + * - Added new DEVICE_STATE_AS_GPIOR and HOST_STATE_AS_GPIOR compile time options + * - Added 404 Not Found errors to the webserver in the RNDIS demos to indicate invalid URLs + * + * Changed: + * - Deprecated pseudo-scheduler and removed dynamic memory allocator from the library (first no longer needed and second unused) + * - The device-mode CALLBACK_USB_GetDescriptor() function now has an extra parameter so that the memory space in which the requested + * descriptor is located can be specified. This means that descriptors can now be located in multiple memory spaces within a device. + * - Removed vague USB_IsConnected global - test USB_DeviceState or USB_HostState explicitly to gain previous functionality + * - Removed USB_IsSuspended global - test USB_DeviceState against DEVICE_STATE_Suspended instead + * - Extended USB_GetDeviceConfigDescriptor() routine to require the configuration number within the device to fetch + * - Dataflash_WaitWhileBusy() now always ensures that the dataflash is ready for the next command immediately after returning, + * no need to call Dataflash_ToggleSelectedChipCS() afterwards + * - Low level API MIDI device demo no longer blocks if a note change event is sent while the endpoint is not ready + * - Pipe_GetErrorFlags() now returns additional error flags for overflow and underflow errors + * - Pipe stream functions now automatically set the correct pipe token, so that bidirectional pipes can be used + * - Pipe_ConfigurePipe() now automatically defaults IN pipes to accepting infinite IN requests, this can still be changed by calling + * the existing Pipe_SetFiniteINRequests() function + * - Changed F_USB entries in project makefiles to alias to F_CPU by default, as this is the most common case + * - Host mode demos now use sane terminal escape codes, so that text is always readable and events/program output is visually distinguished + * from one another using foreground colours + * - Internal per-device preprocessing conditions changed to per-device series rather than per-controller group for finer-grain + * internal control + * - Interrupts are no longer disabled during the processing of Control Requests on the default endpoint while in device mode + * - AudioOutput demos now always output to board LEDs, regardless of output mode (removed AUDIO_OUT_LEDS project option) + * - Removed SINGLE_DEVICE_CONFIGURATION compile time option in favor of the new FIXED_NUM_CONFIGURATIONS option so that the exact number + * of device configurations can be defined statically + * - Removed VBUS events, as they are already exposed to the user application via the regular device connection and disconnection events + * - Renamed and altered existing events to properly separate out Host and Device mode events + * - All demos switched over from GNU99 standards mode to C99 standards mode, to reduce the dependencies on GCC-only language extensions + * + * Fixed: + * - Changed bootloaders to use FLASHEND rather than the existence of RAMPZ to determine if far FLASH pointers are needed to fix + * bootloaders on some of the USB AVR devices where avr-libc erroneously defines RAMPZ + * - Fixes to MassStorageHost for better device compatibility (increase command timeout, change MassStore_WaitForDataReceived() + * to only unfreeze and check one data pipe at a time) to prevent incorrect device enumerations and freezes while transferring data + * - Make Pipe_ConfigurePipe() mask the given endpoint number against PIPE_EPNUM_MASK to ensure the endpoint IN direction bit is + * cleared to prevent endpoint type corruption + * - Fixed issue opening CDC-ACM ports on hosts when the CDC device tries to send data before the host has set the line encoding + * - Fixed USB_OPT_MANUAL_PLL option being ignored during device disconnects on some models (thanks to Brian Dickman) + * - Fixed documentation mentioning Pipe_GetCurrentToken() function when correct function name is Pipe_GetPipeToken() + * - Fixed ADC driver for the ATMEGA32U4 and ATMEGA16U4 (thanks to Opendous Inc.) + * - Fixed CDCHost demo unfreezing the pipes at the point of configuration, rather than use + * - Fixed MassStorage demo not clearing the reset flag when a Mass Storage Reset is issued while not processing a command + * - Fixed USB_Host_SendControlRequest() not re-suspending the USB bus when initial device ready-wait fails + * - Fixed USB Pad regulator not being disabled on some AVR models when the USB_OPT_REG_DISABLED option is used + * - Fixed Host mode to Device mode UID change not causing a USB Disconnect event when a device was connected + * - Fixed Mouse/Keyboard demos not performing the correct arithmetic on the Idle period at the right times (thanks to Brian Dickman) + * - Fixed GenericHID failing HID class tests due to incorrect Logical Minimum and Logical Maximum values (thanks to Soren Greiner) + * - Fixed incorrect PIPE_EPNUM_MASK mask causing pipe failures on devices with endpoint addresses of 8 and above (thanks to John Andrews) + * - Fixed report data alignment issues in the MouseHostWithParser demo when X and Y movement data size is not a multiple of 8 bits + * - Fixed HID Report Descriptor Parser not correctly resetting internal states when a REPORT ID element is encountered + * - Fixed incorrect BUTTONS_BUTTON1 for the STK526 target + * - Fixed RNDIS demos freezing when more than one connection was attempted simultaneously, causing memory corruption + * - Fixed USBtoSerial demo receiving noise from the USART due to pull-up not being enabled + * + * + * \section Sec_ChangeLog090605 Version 090605 + * + * - Fixed bug in RNDISEthernet and DualCDC demos not using the correct USB_ControlRequest structure for control request data + * - Fixed documentation showing incorrect USB mode support on the supported AVRs list + * - Fixed RNDISEthernet not working under Linux due to Linux requiring an "optional" RNDIS request which was unhandled + * - Fixed Mouse and Keyboard device demos not acting in accordance with the HID specification for idle periods (thanks to Brian Dickman) + * - Removed support for endpoint/pipe non-control interrupts; these did not act in the way users expected, and had many subtle issues + * - Fixed Device Mode not handling Set Feature and Clear Feature Chapter 9 requests that are addressed to the device (thanks to Brian Dickman) + * - Moved control endpoint interrupt handling into the library itself, enable via the new INTERRUPT_CONTROL_ENDPOINT token + * - Fixed CDCHost not clearing configured pipes and resetting configured pipes mask when a partially enumerated invalid CDC + * interface is skipped + * - Clarified the size of library tokens which accept integer values in the Compile Time Tokens page, values now use the smallest datatype + * inside the library that is able to hold their defined value to save space + * - Removed DESCRIPTOR_ADDRESS() macro as it was largely superfluous and only served to obfuscate code + * - Rewritten event system to remove all macros, to make user code clearer + * - Fixed incorrect ENDPOINT_EPNUM_MASK mask preventing endpoints above EP3 from being selected (thanks to Jonathan Oakley) + * - Removed STREAM_CALLBACK() macro - callbacks now use regular function definitions to clarify user code + * - Removed DESCRIPTOR_COMPARATOR() macro - comparators should now use regular function definitions to clarify user code + * - USB_IsConnected is now cleared before the USB_Disconnect() event is fired in response to VBUS being removed + * - Fixed incorrect PID value being used in the USBtoSerial project (thanks to Phill) + * - Deleted StdDescriptors.c, renamed USB_GetDescriptor() to CALLBACK_USB_GetDescriptor, moved ConfigDescriptor.c/.h from the + * LUFA/Drivers/USB/Class/ directory to LUFA/Drivers/USB/HighLevel/ in preparation for the new USB class APIs + * - Moved out each demos' functionality library files (e.g. Ring Buffer library) to /Lib directories for a better directory structure + * - Removed Tx interrupt from the USBtoSerial demo; now sends characters via polling to ensure more time for the Rx interrupt + * - Fixed possible enumeration errors from spin-loops which may fail to exit if the USB connection is severed before the exit condition + * becomes true + * + * + * \section Sec_ChangeLog090510 Version 090510 + * + * - Added new GenericHIDHost demo + * - Corrections to the KeyboardHost and MouseHost demos' pipe handling to freeze and unfreeze the data pipes at the point of use + * - KeyboardHost, MouseHost and GenericHIDHost demos now save and restore the currently selected pipe inside the pipe ISR + * - Changed GenericHID device demo to use the LUFA scheduler, added INTERRUPT_DATA_ENDPOINT and INTERRUPT_CONTROL_ENDPOINT compile + * time options + * - All comments in the library, bootloaders, demos and projects have now been spell-checked and spelling mistakes/typos corrected + * - Added new PIMA_DATA_SIZE() define to the Still Image Host demo + * - Add call to MassStore_WaitForDataReceived() in MassStore_GetReturnedStatus() to ensure that the CSW has been received in the + * extended MSC timeout period before continuing, to prevent long processing delays from causing the MassStore_GetReturnedStatus() + * to early-abort (thanks to Dmitry Maksimov) + * - Move StdRequestType.h, StreamCallbacks.h, USBMode.h from the LowLevel USB driver directory to the HighLevel USB driver directory, + * where they are more suited + * - Removed all binary constants and replaced with decimal or hexadecimal constants so that unpatched GCC compilers can still build the + * code without having to be itself patched and recompiled first + * - Added preprocessor checks and documentation to the bootloaders giving information about missing SIGNATURE_x defines due to + * outdated avr-libc versions. + * - Added support to the CDCHost demo for devices with multiple CDC interfaces which are not the correct ACM type preceding the desired + * ACM CDC interface + * - Fixed GenericHID demo not starting USB and HID management tasks when not using interrupt driven modes (thanks to Carl Kjeldsen) + * - Fixed RNDISEthenet demo checking the incorrect message field for packet size constraints (thanks to Jonathan Oakley) + * - Fixed WriteNextReport code in the GenericHIDHost demo using incorrect parameter types and not selecting the correct endpoint + * - Adjusted sample CTC timer calculations in the AudioOutput and AudioInput demos to match the CTC calculations in the AVR datasheet, + * and to fix instances where rounding caused the endpoint to underflow (thanks to Robin Theunis) + * - The USB_Host_SendControlRequest() function no longer automatically selects the Control pipe (pipe 0), so that other control type + * pipes can be used with the function + * - The USB Host management task now saves and restores the currently selected pipe before and after the task completes + * - Fixed GenericHIDHost demo report write routine incorrect for control type requests (thanks to Andrei Krainev) + * - Removed Endpoint_ClearCurrentBank() and Pipe_ClearCurrentBank() in favor of new Endpoint_ClearIN(), Endpoint_ClearOUT(), + * Pipe_ClearIN() and Pipe_ClearOUT() macros (done to allow for the detection of packets of zero length) + * - Renamed *_ReadWriteAllowed() macros to *_IsReadWriteAllowed() to remain consistent with the rest of the LUFA API + * - Endpoint_IsSetupReceived() macro has been renamed to Endpoint_IsSETUPReceived(), Endpoint_ClearSetupReceived() macro has been + * renamed to Endpoint_ClearSETUP(), the Pipe_IsSetupSent() macro has been renamed to Pipe_IsSETUPSent() and the + * Pipe_ClearSetupSent() macro is no longer applicable and should be removed - changes made to compliment the new endpoint and pipe + * bank management API + * - Updated all demos, bootloaders and projects to use the new endpoint and pipe management APIs (thanks to Roman Thiel from Curetis AG) + * - Updated library doxygen documentation, added groups, changed documentation macro functions to real functions for clarity + * - Removed old endpoint and pipe aliased read/write/discard routines which did not have an explicit endian specifier for clarity + * - Removed the ButtLoadTag.h header file, as no one used for its intended purpose anyway + * - Renamed the main Drivers/AT90USBXXX directory to Drivers/Peripheral, renamed the Serial_Stream driver to SerialStream + * - Fixed CDC and USBtoSerial demos freezing where buffers were full while still transmitting or receiving (thanks to Peter Hand) + * - Removed "Host_" section of the function names in ConfigDescriptor.h, as most of the routines can now be used in device mode on the + * device descriptor + * - Renamed functions in the HID parser to have a "USB_" prefix and the acronym "HID" in the name + * - Fixed incorrect HID interface class and subclass values in the Mouse and KeyboardMouse demos (thanks to Brian Dickman) + * - Capitalized the "Descriptor_Search" and "Descriptor_Search_Comp" prefixes of the values in the DSearch_Return_ErrorCodes_t and + * DSearch_Comp_Return_ErrorCodes_t enums + * - Removed "ERROR" from the enum names in the endpoint and pipe stream error code enums + * - Renamed the USB_PowerOnErrorCodes_t enum to USB_InitErrorCodes_t, renamed the POWERON_ERROR_NoUSBModeSpecified enum value to + * USB_INITERROR_NoUSBModeSpecified + * - Renamed USB_PowerOnFail event to USB_InitFailure + * - Renamed OTG.h header functions to be more consistent with the rest of the library API + * - Changed over all deprecated GCC structure tag initializers to the standardized C99 format (thanks to Mike Alexander) + * - USB_HostRequest renamed to USB_ControlRequest, entire control request header is now read into USB_ControlRequest in Device mode + * rather than having the library pass only partially read header data to the application + * - The USB_UnhandledControlPacket event has had its parameters removed, in favor of accessing the new USB_ControlRequest structure + * - The Endpoint control stream functions now correctly send a ZLP to the host when less data than requested is sent + * - Fixed USB_RemoteWakeupEnabled flag never being set (the REMOTE WAKEUP Set Feature request was not being handled) + * - Renamed the FEATURELESS_CONTROL_ONLY_DEVICE compile-time token to CONTROL_ONLY_DEVICE + * - Endpoint configuration is now refined to give better output when all configurations have static inputs - removed the now useless + * STATIC_ENDPOINT_CONFIGURATION compile time token + * - Fixed SPI driver init function not clearing SPI2X bit when not needed + * - Fixed PREVENT ALLOW MEDIUM REMOVAL command issuing in the MassStorageHost demo using incorrect parameters (thanks to Mike Alex) + * - Fixed MassStorageHost demo broken due to an incorrect if statement test in MassStore_GetReturnedStatus() + * - Fixed reversed signature byte ordering in the CDC bootloader (thanks to Johannes Raschke) + * - Changed PIPE_CONTROLPIPE_DEFAULT_SIZE from 8 to 64 to try to prevent problems with faulty devices which do not respect the given + * wLength value when reading in the device descriptor + * - Fixed missing semicolon in the ATAVRUSBRF01 LED board driver code (thanks to Morten Lund) + * - Changed LED board driver code to define dummy LED masks for the first four board LEDs, so that user code can be compiled for boards + * with less than four LEDs without code modifications (thanks to Morten Lund) + * - Changed HWB board driver to Buttons driver, to allow for the support of future boards with more than one mounted GPIO button + * - Serial driver now correctly calculates the baud register value when in double speed mode + * - Init function of the Serial driver is now static inline to product smaller code for the common-case of static init values + * + * + * \section Sec_ChangeLog090401 Version 090401 + * + * - Fixed MagStripe project configuration descriptor containing an unused (blank) endpoint descriptor + * - Incorporated makefile changes by Denver Gingerich to retain compatibility with stock (non-WinAVR) AVR-GCC installations + * - Fixed makefile EEPROM programming targets programming FLASH data in addition to EEPROM data + * - LUFA devices now enumerate correctly with LUFA hosts + * - Fixed Configuration Descriptor search routine freezing when a comparator returned a failure + * - Removed HID report item serial dump in the MouseHostWithParser and KeyboardHostWithParser - useful only for debugging, and + * slowed down the enumeration of HID devices too much + * - Increased the number of bits per track which can be read in the MagStripe project to 8192 when compiled for the AT90USBXXX6/7 + * - Fixed KeyboardMouse demo discarding the wIndex value in the REQ_GetReport request + * - USBtoSerial demo now discards all Rx data when not connected to a USB host, rather than buffering characters for transmission + * next time the device is attached to a host. + * - Added new F_USB compile time constant to the library and makefiles, to give the raw input clock (used to feed the PLL before any + * clock prescaling is performed) frequency, so that the PLL prescale mask can be determined + * - Changed stream wait timeout counter to be 16-bit, so that very long timeout periods can be set for correct communications with + * badly designed hosts or devices which greatly exceed the USB specification limits + * - Mass Storage Host demo now uses a USB_STREAM_TIMEOUT_MS of two seconds to maintain compatibility with poorly designed devices + * - Function attribute ATTR_ALWAYSINLINE renamed to ATTR_ALWAYS_INLINE to match other function attribute macro naming conventions + * - Added ATTR_ALWAYS_INLINE attribute to several key inlined library components, to ensure they are inlined in all circumstances + * - Removed SetSystemClockPrescaler() macro, the clock_prescale_set() avr-libc macro has been corrected in recent avr-libc versions + * - Fixed incorrect/missing control status stage transfers on demos, bootloaders and applications (thanks to Nate Lawson) + * - The NO_CLEARSET_FEATURE_REQUEST compile time token has been renamed to FEATURELESS_CONTROL_ONLY_DEVICE, and its function expanded + * to also remove parts of the Get Status chapter 9 request to further reduce code usage + * - Makefile updated to include output giving the currently selected BOARD parameter value + * - Board Dataflash driver now allows for dataflash ICs which use different shifts for setting the current page/byte address (thanks + * to Kenneth Clubb) + * - Added DataflashManager_WriteBlocks_RAM() and DataflashManager_ReadBlocks_RAM() functions to the MassStorage demo, to allow for easy + * interfacing with a FAT library for dataflash file level access + * - Corrected CDC class bootloader to fix a few bugs, changed address counter to store x2 addresses for convenience + * - Fixed typos in the SPI driver SPI_SPEED_FCPU_DIV_64 and SPI_SPEED_FCPU_DIV_128 masks (thanks to Markus Zocholl) + * - Keyboard and Mouse device demos (normal, data interrupt and fully interrupt driven) combined into unified keyboard and mouse demos + * - Keyboard and Mouse host demos (normal and data interrupt driven) combined into unified keyboard and mouse demos + * - Removed AVRISP_Programmer project due to code quality concerns + * - Fixed CDC demo not sending an empty packet after each transfer to prevent the host from buffering incoming data + * - Fixed documentation typos and preprocessor checks relating to misspellings of the USE_RAM_DESCRIPTORS token (thanks to Ian Gregg) + * - Fixed USBTask.h not conditionally including HostChapter9.h only when USB_CAN_BE_HOST is defined (thanks to Ian Gregg) + * - Fixed incorrect ADC driver init register manipulation (thanks to Tobias) + * - Added new GenericHID device demo application + * - Fixed Still Image Host SImage_SendData() function not clearing the pipe bank after sending data + * + * + * \section Sec_ChangeLog090209 Version 090209 + * + * - PWM timer mode in AudioOut demo changed to Fast PWM for speed + * - Updated Magstripe project to work with the latest hardware revision + * - Fixed library not responding to the BCERRI flag correctly in host mode, leading to device lockups + * - Fixed library handling Get Descriptor requests when not addressed as standard requests to the device or interface (thanks to + * Nate Lawson) + * - Fixed serious data corruption issue in MassStorage demo dataflash write routine + * - Added new NO_CLEARSET_FEATURE_REQUEST compile time token + * - USB task now restores previous global interrupt state after execution, rather than forcing global interrupts to be enabled + * - Fixed USB_DeviceEnumerationComplete event firing after each configuration change, rather than once after the initial configuration + * - Added ENDPOINT_DOUBLEBANK_SUPPORTED() macros to Endpoint.h, altered ENDPOINT_MAX_SIZE() to allow user to specify endpoint + * - ENDPOINT_MAX_ENDPOINTS changed to ENDPOINT_TOTAL_ENDPOINTS, PIPE_MAX_PIPES changed to PIPE_TOTAL_PIPES + * - Endpoint and Pipe non-control stream functions now ensure endpoint or pipe is ready before reading or writing + * - Changed Teensy bootloader to use a watchdog reset when exiting rather than a software jump + * - Fixed integer promotion error in MassStorage and MassStorageHost demos, corrupting read/write transfers + * - SPI_SendByte is now SPI_TransferByte, added new SPI_SendByte and SPI_ReceiveByte functions for fast one-way transfer + * - MassStorage demo changed to use new fast one-way SPI transfers to increase throughput + * - MassStorage handling of Mass Storage Reset class request improved + * - Altered MassStorage demo dataflash block read code for speed + * - Added USB_IsSuspended global flag + * - Simplified internal Dual Mode (OTG) USB library code to reduce code size + * - Extended stream timeout period to 100ms from 50ms + * - Mass Storage Host demo commands now all return an error code from the Pipe_Stream_RW_ErrorCodes_t enum + * - Added SubErrorCode parameter to the USB_DeviceEnumerationFailed event + * - VBUS drop interrupt now disabled during the manual-to-auto VBUS delivery handoff + * - Simplified low level backend so that device/host mode initialization uses the same code paths + * - Added workaround for faulty Mass Storage devices which do not implement the required GET_MAX_LUN request + * - Removed buggy Telnet application from the RNDIS demo + * - Moved Mass Storage class requests in the Mass Storage Host demo to wrapper functions in MassStoreCommands.c + * - Fixed incorrect SCSI command size value in the Request Sense command in MassStoreCommands.c + * - Added SetProtocol request to HID class non-parser Mouse and Keyboard demos to force devices to use the correct Boot Protocol + * - Added new "dfu" and "flip" programming targets to project makefiles + * - HID_PARSE_Sucessful enum member typo corrected to HID_PARSE_Successful + * - Changed COLLECTION item structures in the HID descriptor parser to include the collection's Usage Page value + * - Serial driver now sets Tx line as output, enables pull-up on Rx line + * - Fixed smaller USB AVRs raising multiple connection and disconnection events when NO_LIMITED_CONTROLLER_CONNECT is disabled + * - Added HOST_DEVICE_SETTLE_DELAY_MS to give the host delay after a device is connected before it is enumerated + * - Fixed KeyboardHostWithParser demo linking against the wrong global variables + * - Completed doxygen documentation of remaining library bootloaders, demos and projects + * - Fixed incorrect bootloader start address in the TeensyHID bootloader + * - Added HWB button whole-disk ASCII dump functionality to MassStoreHost demo + * - Replaced printf_P(PSTR("%c"), {Variable}) calls with putchar() for speed and size savings + * - Serial driver now accepts baud rates over 16-bits in size, added double speed flag option + * - Fixed incorrect callback abort return value in Pipe.c + * - Added new flip-ee and dfu-ee makefile targets (courtesy of Opendous Inc.) + * - Removed reboot-on-disconnect code from the TeensyHID bootloader, caused problems on some systems + * - Fixed AudioOutput and AudioInput demos looping on the endpoint data, rather than processing a sample at a time and returning + * each time the task runs to allow for other tasks to execute + * - Added support for the Atmel ATAVRUSBRF01 board + * - Added AVRISP Programmer Project, courtesy of Opendous Inc. + * - Fixed CDC Host demo not searching through both CDC interfaces for endpoints + * - Fixed incorrect Product String descriptor length in the DFU class bootloader + * + * + * \section Sec_ChangeLog081224 Version 081224 + * + * - MyUSB name changed to LUFA, the Lightweight USB Framework for AVRs + * - Fixed Mass Storage Host demo's MassStore_SendCommand() delay in the incorrect place + * - Fixed USBtoSerial demo not calling ReconfigureUSART() after a change in the line encoding + * - Fixed infinite loop in host mode Host-to-Device control transfers with data stages + * - HID report parser now supports devices with multiple reports in one interface via Report IDs + * - Fixed RZUSBSTICK board LED driver header incorrect macro definition order causing compile errors + * - Calling USB_Init() when the USB interface is already configured now forces a complete interface reset + * and re-enumeration - fixes MyUSB DFU bootloader not switching to app code correctly when soft reset used + * - Fixed "No newline at end of file" warning when stream callbacks are enabled + * - DFU bootloader now uses fixed signature bytes per device, rather than reading them out dynamically for size + * - Added new FIXED_CONTROL_ENDPOINT_SIZE and USE_SINGLE_DEVICE_CONFIGURATION switches to statically define certain values to + * reduce compiled binary size + * - Added new NO_LIMITED_CONTROLLER_CONNECT switch to prevent the library from trying to determine bus connection + * state from the suspension and wake up events on the smaller USB AVRs + * - Added summary of all library compile time tokens to the documentation + * - Added overview of the LUFA scheduler to the documentation + * - Removed MANUAL_PLL_CONTROL compile time token, replaced with a mask for the USB_Init() Options parameter + * - CDC bootloader now uses the correct non-far or far versions of the pgm_* functions depending on if RAMPZ is defined + * - Doxygen documentation now contains documentation on all the projects, bootloaders and most demos included with the library + * - CDC bootloader now runs user application when USB disconnected rather than waiting for a hard reset + * - MouseHostWithParser and KeyboardHostWithParser now support multiple-report devices + * - RNDIS demo can now close connections correctly using the new TCP_APP_CLOSECONNECTION() macro - used in Webserver + * - Fixed the DFU bootloader, no longer freezes up when certain files are programmed into an AVR, made reading/writing faster + * - Fixed mouse/joystick up/down movements reversed - HID mouse X/Y coordinates use a left-handed coordinate system, not a normal + * right-handed system + * - Added stub code to the CDC and USBtoSerial demos showing how to read and set the RS-232 handshake lines - not currently used in + * the demos, but the example code and supporting defines are now in place + * - Interrupts are now disabled when processing a control request in device mode, to avoid exceeding the strict control request + * timing requirements. + * - All demos now use a central StatusUpdate() function rather than direct calls to the board LED functions, so that the demos can + * easily be altered to show different LED combinations (or do something else entirely) as the demo's status changes + * - Removed LED commands from the CDC bootloader, unused by most AVR910 programming software + * - Fixed RNDIS demo ICMP ping requests echoing back incorrect data + * - Added DHCP server code to RNDIS demo, allowing for hands-free auto configuration on any PC + * - Fixed DFU bootloader PID value for the ATMEGA16U4 AVR + * - Endpoint and Pipe configuration functions now return an error code indicating success or failure + * - USB Reset in device mode now resets and disables all device endpoints + * - Added intermediate states to the host mode state machine, reducing the USB task blocking time to no more than 1ms explicitly per + * invocation when in host mode + * - Added support for the ATMEGA32U6 microcontroller + * - Added STATIC_ENDPOINT_CONFIGURATION compile time option, enabled in the bootloaders to minimize space usage + * - Removed redundant code from the USB device GetStatus() chapter 9 processing routine + * - Added new TeensyHID bootloader, compatible with the Teensy HID protocol (http://www.pjrc.com/teensy/) + * - Versions are now numbered by release dates, rather than arbitrary major/minor revision numbers + * - USB_RemoteWakeupEnabled is now correctly set and cleared by SetFeature and ClearFeature requests from the host + * - Changed prototype of GetDescriptor, so that it now returns the descriptor size (or zero if the descriptor doesn't exist) + * rather than passing the size back to the caller through a parameter and returning a boolean + * + * + * \section Sec_ChangeLog153 Version 1.5.3 (081002) + * + * - Fixed CDC bootloader using pgmspace macros for some descriptors inappropriately + * - Updated all Mouse and Keyboard device demos to include boot protocol support (now works in BIOS) + * - Renamed bootloader directories to remove spaces, which were causing build problems on several OSes + * - Removed serial number strings from all but the MassStore demo where it is required - users were not + * modifying the code to either omit the descriptor or use a unique serial per device causing problems + * when multiple units of the same device were plugged in at the same time + * - AudioOutput and AudioInput demos now correctly silence endpoints when not enabled by the host + * - Added KeyboardMouse demo (Keyboard and Mouse functionality combined into a single demo) + * - Added DriverStubs directory to house board level driver templates, to make MyUSB compatible custom board + * driver creation easier + * - Extended MassStorage demo to support multiple LUNs, 2 by default + * - Fixed incorrect device address mask, preventing the device from enumerating with addresses larger than 63 + * - Fixed incorrect data direction mask in the GetStatus standard request, preventing it from being handled + * - Fixed incorrect GetStatus standard request for endpoints, now returns the endpoint STALL status correctly + * - Added in new USB_RemoteWakeupEnabled and USB_CurrentlySelfPowered flags rather than using fixed values + * - Added DualCDC demo to demonstrate the use of Interface Association Descriptors + * - Added pipe NAK detection and clearing API + * - Added pipe status change (NAK, STALL, etc.) interrupt API + * - Fixed MassStorageHost demo so that it no longer freezes randomly when issuing several commands in a row + * - Host demos configuration descriptor routines now return a unique error code when the returned data does + * not have a valid configuration descriptor header + * - Added Endpoint_WaitUntilReady() and Pipe_WaitUntilReady() functions + * - Stream functions now have software timeouts, timeout period can be set by the USB_STREAM_TIMEOUT_MS token + * - All demos now pass the USB.org automated Chapter 9 device compliance tests + * - All HID demos now pass the USB.org automated HID compliance tests + * - Polling interval of the interrupt endpoint in the CDC based demos changed to 0xFF to fix problems on Linux systems + * - Changed stream functions to accept a new callback function, with NO_STREAM_CALLBACKS used to disable all callbacks + * - Mass Storage demo dataflash management routines changed to use the endpoint stream functions + * - Added AVRStudio project files for each demo in addition to the existing Programmer's Notepad master project file + * - Re-added call to ReconfigureUSART() in USBtoSerial SetLineCoding request, so that baud rate changes + * are reflected in the hardware (change was previously lost) + * + * + * \section Sec_ChangeLog152 Version 1.5.2 (080731) + * + * - Fixed SwapEndian_32() function in Common.h so that it now works correctly (wrong parameter types) + * - Updated RNDIS demo - notification endpoint is no longer blocking so that it works with faulty Linux RNDIS + * implementations (where the notification endpoint is ignored in favor of polling the control endpoint) + * - Fixed incorrect Vendor Description string return size in RNDIS demo for the OID_GEN_VENDOR_DESCRIPTION OID token + * - Added very basic TCP/IP stack and HTTP/TELNET servers to RNDIS demo + * - Fixed DFU bootloader exit causing programming software to complain about failed writes + * - Fixed DFU bootloader EEPROM programming mode wiping first flash page + * - Fixed Clear/Set Feature device standard request processing code (fixing MassStorage demo in the process) + * - Added support for the ATMEGA16U4 AVR microcontroller + * - Library license changed from LGPLv3 to MIT license + * + * + * \section Sec_ChangeLog151 Version 1.5.1 (080707) + * + * - Changed host demos to enable the host function task on the firing of the USB_DeviceEnumerationComplete event + * rather than the USB_DeviceAttached event + * - HID Usage Stack now forcefully cleared after an IN/OUT/FEATURE item has been completely processed to remove + * any referenced but not created usages + * - Changed USB_INT_DisableAllInterrupts() and USB_INT_ClearAllInterrupts(), USB_Host_GetNextDescriptorOfType(), + * USB_Host_GetNextDescriptorOfTypeBefore(), USB_Host_GetNextDescriptorOfTypeAfter() to normal functions (from inline) + * - Fixed USBtoSerial demo not sending data, only receiving + * - Fixed main makefile to make all by default, fixed MagStripe directory case to prevent case-sensitive path problems + * - ConfigDescriptor functions made normal, instead of static inline + * - Pipe/Endpoint *_Ignore_* functions changed to *_Discard_*, old names still present as aliases + * - Fixed ENDPOINT_MAX_SIZE define to be correct on limited USB controller AVRs + * - Changed endpoint and pipe size translation routines to use previous IF/ELSE IF cascade code, new algorithmic + * approach was buggy and caused problems + * - Bootloaders now compile with -fno-inline-small-functions option to reduce code size + * - Audio demos now use correct endpoint sizes for full and limited controller USB AVRs, double banking in all cases + * to be in line with the specification (isochronous endpoints MUST be double banked) + * - Added Interface Association descriptor to StdDescriptors.h, based on the relevant USB2.0 ECN + * - Fixed MIDI demo, corrected Audio Streaming descriptor to follow the MIDI-specific AS structure + * - Fixed HID class demo descriptors so that the HID interface's protocol is 0x00 (required for non-boot protocol HID + * devices) to prevent problems on hosts expecting the boot protocol functions to be supported + * - Added read/write control stream functions to Endpoint.h + * - Fixed AudioOut demo not setting port pins to inputs on USB disconnect properly + * - Added RNDISEthernet demo application + * + * + * \section Sec_ChangeLog150 Version 1.5.0 (080610) + * + * - Fixed MIDI demo, now correctly waits for the endpoint to be ready between multiple note messages + * - Added CDC Host demo application + * - Added KeyboardFullInt demo application + * - Endpoint and Pipe creation routines now mask endpoint/pipe size with the size mask, to remove transaction + * size bits not required for the routines (improves compatibility with devices) + * - Fixed AudioInput demo - now correctly sends sampled audio to the host PC + * - Fixed AudioOutput demo once more -- apparently Windows requires endpoint packets to be >=192 bytes + * - Shrunk round-robbin scheduler code slightly via the use of struct pointers rather than array indexes + * - Fixed off-by-one error when determining if the Usage Stack is full inside the HID Report parser + * - Renamed Magstripe.h to MagstripeHW.h and moved driver out of the library and into the MagStripe demo folder + * - Added preprocessor checks to enable C linkage on the library components when used with a C++ compiler + * - Added Still Image Host demo application + * - The USB device task now restores the previously selected endpoint, allowing control requests to be transparently + * handled via interrupts while other endpoints are serviced through polling + * - Fixed device signature being sent in reverse order in the CDC bootloader + * - Host demos now have a separate ConfigDescriptor.c/.h file for configuration descriptor processing + * - HostWithParser demos now have a separate HIDReport.c/.h file for HID report processing and dumping + * - Removed non-mandatory commands from MassStorage demo to save space, fixed SENSE ResponseCode value + * - CDC demos now send empty packets after sending a full one to prevent buffering issues on the host + * - Updated demo descriptors to use VID/PID values donated by Atmel + * - Added DoxyGen documentation to the source files + * - Fixed Serial_IsCharReceived() definition, was previously reversed + * - Removed separate USB_Descriptor_Language_t descriptor, USB_Descriptor_String_t is used instead + * - Removed unused Device Qualifier descriptor structure + * - Renamed the USB_CreateEndpoints event to the more appropriate USB_ConfigurationChanged + * - Fixed MassStorageHost demo reading in the block data in reverse + * - Removed outdated typedefs in StdRequestType.h, superseded by the macro masks + * - Corrected OTG.h is now included when the AVR supports both Host and Device modes, for creating OTG products + * - USB_DeviceEnumerationComplete event is now also fired when in device mode and the host has finished its enumeration + * - Interrupt driven demos now properly restore previously selected endpoint when ISR is complete + * - The value of USB_HOST_TIMEOUT_MS can now be overridden in the user project makefile to a custom fixed timeout value + * - Renamed USB_Host_SOFGeneration_* macros to more friendly USB_Host_SuspendBus(), USB_Host_ResumeBus() + * and USB_Host_IsBusSuspended() + * - Renamed *_*_Is* macros to *_Is* to make all flag checking macros consistent, Pipe_SetInterruptFreq() is now + * Pipe_SetInterruptPeriod() to use the correct terminology + * - UnicodeString member of USB_Descriptor_String_t struct changed to an ordinary int array type, so that the GCC + * Unicode strings (prefixed with an L before the opening quotation mark) can be used instead of explicit arrays + * of ASCII characters + * - Fixed Endpoint/Pipes being configured incorrectly if the maximum endpoint/pipe size for the selected USB AVR + * model was given as the bank size + * - HID device demos now use a true raw array for the HID report descriptor rather than a struct wrapped array + * - Added VERSION_BCD() macro, fixed reported HID and USB version numbers in demo descriptors + * - Cleaned up GetDescriptor device chapter 9 handler function + * - Added GET_REPORT class specific request to HID demos to make them complaint to the HID class + * - Cleaned up setting of USB_IsInitialized and USB_IsConnected values to only when needed + * - Removed Atomic.c and ISRMacro.h; the library was already only compatible with recent avr-lib-c for other reasons + * - All demos and library functions now use USB standardized names for the USB data (bRequest, wLength, etc.) + * - Added USE_NONSTANDARD_DESCRIPTOR_NAMES token to switch back to the non-standard descriptor element names + * + * + * \section Sec_ChangeLog141 Version 1.4.1 (090519) + * + * - Enhanced KeyboardWithParser demo, now prints out pressed alphanumeric characters like the standard demo + * - Fixed MassStorage demo, read/writes using non mode-10 commands now work correctly + * - Corrected version number in Version.h + * + * + * \section Sec_ChangeLog140 Version 1.4.0 (090505) + * + * - Added HID Report Parser API to the library + * - Added Mouse and Keyboard host demo applications, using the new HID report parser engine + * - Added MouseFullInt demo, which demonstrates a fully interrupt (including control requests) mouse device + * - Fixed incorrect length value in the audio control descriptor of the AudioOutput and AudioInput demos + * - Added MIDI device demo application to the library + * - Fixed problem preventing USB devices from being resumed from a suspended state + * - Added new CDC class bootloader to the library, based on the AVR109 bootloader protocol + * - Added header to each demo application indicating the mode, class, subclass, standards used and supported speed + * - Functions expecting endpoint/pipe numbers are no longer automatically masked against ENDPOINT_EPNUM_MASK or + * PIPE_PIPENUM_MASK - this should be manually added to code which requires it + * - Fixed DFU class bootloader - corrected frequency of flash page writes, greatly reducing programming time + * - Renamed AVR_HOST_GetDeviceConfigDescriptor() to USB_Host_GetDeviceConfigDescriptor() and AVR_HOST_GetNextDescriptor() + * to USB_Host_GetNextDescriptor() + * - Added new USB_Host_GetNextDescriptorOfTypeBefore() and USB_Host_GetNextDescriptorOfTypeAfter() routines + * - Moved configuration descriptor routines to MyUSB/Drivers/USB/Class/, new accompanying ConfigDescriptors.c file + * - Added new configuration descriptor comparator API for more powerful descriptor parsing, updated host demos to use the + * new comparator API + * - Fixed MassStorageHost demo capacity printout, and changed data read/write mode from little-endian to the correct + * big-endian for SCSI devices + * - Fixed macro/function naming consistency; USB_HOST is now USB_Host, USB_DEV is now USB_Device + * - Added better error reporting to host demos + * - Added 10 microsecond delay after addressing devices in host mode, to prevent control stalls + * + * + * \section Sec_ChangeLog132 Version 1.3.2 (080401) + * + * - Added call to ReconfigureUSART() in USBtoSerial SetLineCoding request, so that baud rate changes + * are reflected in the hardware + * - Fixed CDC and USBtoSerial demos - Stream commands do not work for control endpoints, and the + * GetLineCoding request had an incorrect RequestType mask preventing it from being processed + * - Improved reliability of the USBtoSerial demo, adding a busy wait while the buffer is full + * - Device control endpoint size is now determined from the device's descriptors rather than being fixed + * - Separated out SPI code into new SPI driver in AT90USBXXX driver directory + * - Bootloader now returns correct PID for the selected USB AVR model, not just the AT90USB128X PID + * - Added support for the RZUSBSTICK board + * - Bicolour driver removed in favor of generic LEDs driver + * - Added support for the ATMEGA32U4 AVR + * - Added MANUAL_PLL_CONTROL compile time option to prevent the USB library from manipulating the PLL + * + * + * \section Sec_ChangeLog131 Version 1.3.1 (080319) + * + * - Fixed USB to Serial demo - class value in the descriptors was incorrect + * - Control endpoint size changed from 64 bytes to 8 bytes to save on USB FIFO RAM and to allow low + * speed mode devices to enumerate properly + * - USB to Serial demo data endpoints changed to dual-banked 16 byte to allow the demo to work + * on USB AVRs with limited USB FIFO RAM + * - Changed demo endpoint numbers to use endpoints 3 and 4 for double banking, to allow limited + * USB device controller AVRs (AT90USB162, AT90USB82) to function correctly + * - Updated Audio Out demo to use timer 1 for AVRs lacking a timer 3 for the PWM output + * - Fixed incorrect USB_DEV_OPT_HIGHSPEED entry in the Mass Storage device demo makefile + * - Optimized Mass Storage demo for a little extra transfer speed + * - Added LED indicators to the Keyboard demo for Caps Lock, Num Lock and Scroll Lock + * - Added Endpoint_Read_Stream, Endpoint_Write_Stream, Pipe_Read_Stream and Pipe_Write_Stream functions + * (including Big and Little Endian variants) + * - Made Dataflash functions inline for speed, removed now empty Dataflash.c driver file + * - Added new SetSystemClockPrescaler() macro (thanks to Joerg Wunsch) + * - Fixed Endpoint_ClearStall() to function correctly on full USB controller AVRs (AT90USBXXX6/7) + * - Endpoint_Setup_In_Clear() and Endpoint_Setup_Out_Clear() no longer set FIFOCON, in line with the + * directives in the datasheet + * - Fixed PLL prescaler defines for all AVR models and frequencies + * - Fixed ENDPOINT_INT_IN and ENDPOINT_INT_OUT definitions + * - Added interrupt driven keyboard and mouse device demos + * - Combined USB_Device_ClearFeature and USB_Device_SetFeature requests into a single routine for code + * size savings + * - Added missing Pipe_GetCurrentPipe() macro to Pipe.h + * + * + * \section Sec_ChangeLog130 Version 1.3.0 (080307) + * + * - Unnecessary control endpoint config removed from device mode + * - Fixed device standard request interpreter accidentally processing some class-specific requests + * - Added USE_RAM_DESCRIPTORS and USE_EEPROM_DESCRIPTORS compile time options to instruct the library + * to use descriptors stored in RAM or EEPROM rather than flash memory + * - All demos now disable watchdog on startup, in case it has been enabled by fuses or the bootloader + * - USB_DEV_OPT_LOWSPEED option now works correctly + * - Added ability to set the USB options statically for a binary size reduction via the USE_STATIC_OPTIONS + * compile time define + * - USB_Init no longer takes a Mode parameter if compiled for a USB device with no host mode option, or + * if forced to a particular mode via the USB_HOST_ONLY or USB_DEVICE_ONLY compile time options + * - USB_Init no longer takes an Options parameter if options statically configured by USE_STATIC_OPTIONS + * - Endpoint_Ignore_* and Pipe_Ignore_* made smaller by making the dummy variable non-volatile so that the + * compiler can throw away the result more efficiently + * - Added in an optional GroupID value to each scheduler entry, so that groups of tasks can once again be + * controlled by the new Scheduler_SetGroupTaskMode() routine + * - Added support for AT90USB162 and AT90USB82 AVR models + * - Added support for the STK525 and STK526 boards + * - Added support for custom board drivers to be supplied by selecting the board type as BOARD_USER, and + * placing board drivers in {Application Directory}/Board/ + * - PLL is now stopped and USB clock is frozen when detached from host in device mode, to save power + * - Joystick defines are now in synch with the schematics - orientation will be rotated for the USBKEY + * - Fixed USB_DEV_IsUSBSuspended() - now checks the correct register + * - Fixed data transfers to devices when in host mode + * - Renamed USB_DEV_OPT_HIGHSPEED to USB_DEV_OPT_FULLSPEED and USB_HOST_IsDeviceHighSpeed() to + * USB_HOST_IsDeviceFullSpeed() to be in line with the official USB speed names (to avoid confusion with + * the real high speed mode, which is unavailable on the USB AVRs) + * + * + * \section Sec_ChangeLog120 Version 1.2.0 (080204) + * + * - Added USB_DeviceEnumerationComplete event for host mode + * - Added new Scheduler_Init routine to prepare the scheduler, so that tasks can be started and + * stopped before the scheduler has been started (via Scheduler_Start) + * - Connection events in both Device and Host mode are now interrupt-driven, allowing the USB management + * task to be stopped when the USB is not connected to a host or device + * - All demos updated to stop the USB task when not in use via the appropriate USB events + * - Mass Storage Host demo application updated to function correctly with all USB flash disks + * - Mass Storage Host demo application now prints out the capacity and number of LUNs in the attached + * device, and prints the first block as hexadecimal numbers rather than ASCII characters + * - Endpoint and Pipe clearing routines now clear the Endpoint/Pipe interrupt and status flags + * - Shifted error handling code in the host enum state machine to a single block, to reduce code complexity + * - Added in DESCRIPTOR_TYPE, DESCRIPTOR_SIZE and DESCRIPTOR_CAST macros to make config descriptor processing + * clearer in USB hosts and DESCRIPTOR_ADDRESS for convenience in USB devices + * - Added in alloca macro to common.h, in case the user is using an old version of avr-lib-c missing the macro + * + * + * \section Sec_ChangeLog110 Version 1.1.0 (080125) + * + * - Fixed DCONNI interrupt being enabled accidentally after a USB reset + * - Fixed DDISCI interrupt not being disabled when a device is not connected + * - Added workaround for powerless pull-up devices causing false disconnect interrupts + * - Added USB_DeviceEnumerationFailed event for Host mode + * - AVR_HOST_GetDeviceConfigDescriptor routine no longer modifies ConfigSizePtr if a valid buffer + * pointer is passed + * - Added ALLOCABLE_BYTES to DynAlloc, and added code to make the size of key storage variables + * dependant on size of memory parameters passed in via the user project's makefile + * - Fixed incorrect device reset routine being called in USBTask + * - Devices which do not connect within the standard 300mS are now supported + * - Removed incorrect ATTR_PURE from Scheduler_SetTaskMode(), which was preventing tasks from being + * started/stopped, as well as USB_InitTaskPointer(), which was breaking dual device/host USB projects + * - Changed scheduler to use the task name rather than IDs for setting the task mode, eliminating the + * need to have a task ID list + * - ID transition interrupt now raises the appropriate device/host disconnect event if device attached + * - Fixed double VBUS change (and VBUS -) event when detaching in device mode + * - Added ability to disable ANSI terminal codes by the defining of DISABLE_TERMINAL_CODES in makefile + * - Removed return from ConfigurePipe and ConfigureEndpoint functions - use Pipe_IsConfigured() and + * Endpoint_IsConfigured() after calling the config functions to determine success + */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/CompileTimeTokens.txt b/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/CompileTimeTokens.txt new file mode 100644 index 00000000..966ddd0f --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/CompileTimeTokens.txt @@ -0,0 +1,223 @@ +/** \file + * + * This file contains special DoxyGen information for the generation of the main page and other special + * documentation pages. It is not a project source file. + */ + +/** \page Page_TokenSummary Summary of Compile Tokens + * + * The following lists all the possible tokens which can be defined in a project makefile, and passed to the + * compiler via the -D switch, to alter the LUFA library code. These tokens may alter the library behaviour, + * or remove features unused by a given application in order to save flash space. + * + * \note If the \c USE_LUFA_CONFIG_HEADER token is defined, the library will include a header file named \c LUFAConfig.h located + * in the user directory where the below compile time tokens may be defined. This allows for an alternative to makefile + * defined tokens for configuring the library. + * + * \section Sec_SummaryNonUSBTokens Non USB Related Tokens + * This section describes compile tokens which affect non-USB sections of the LUFA library. + * + * - DISABLE_TERMINAL_CODES - (\ref Group_Terminal) - All Architectures \n + * If an application contains ANSI terminal control codes listed in TerminalCodes.h, it might be desired to remove them + * at compile time for use with a terminal which is non-ANSI control code aware, without modifying the source code. If + * this token is defined, all ANSI control codes in the application code from the TerminalCodes.h header are removed from + * the source code at compile time. + * + * + * \section Sec_SummaryUSBClassTokens USB Class Driver Related Tokens + * This section describes compile tokens which affect USB class-specific drivers in the LUFA library. + * + * - HID_HOST_BOOT_PROTOCOL_ONLY - (\ref Group_USBClassHIDHost) - All Architectures \n + * By default, the USB HID Host class driver is designed to work with HID devices using either the Boot or Report HID + * communication protocols. On devices where the Report protocol is not used (i.e. in applications where only basic + * Mouse or Keyboard operation is desired, using boot compatible devices), the code responsible for the Report protocol + * mode can be removed to save space in the compiled application by defining this token. When defined, it is still necessary + * to explicitly put the attached device into Boot protocol mode via a call to \ref HID_Host_SetBootProtocol(). + * + * - HID_STATETABLE_STACK_DEPTH=x - (\ref Group_HIDParser) - All Architectures \n + * HID reports may contain PUSH and POP elements, to store and retrieve the current HID state table onto a stack. This + * allows for reports to save the state table before modifying it slightly for a data item, and then restore the previous + * state table in a compact manner. This token may be defined to a non-zero 8-bit value to give the maximum depth of the state + * table stack. If not defined, this defaults to the value indicated in the HID.h file documentation. + * + * - HID_USAGE_STACK_DEPTH=x - (\ref Group_HIDParser) - All Architectures \n + * HID reports generally contain many USAGE elements, which are assigned to INPUT, OUTPUT and FEATURE items in succession + * when multiple items are defined at once (via REPORT COUNT elements). This allows for several items to be defined with + * different usages in a compact manner. This token may be defined to a non-zero 8-bit value to set the maximum depth of the + * usage stack, indicating the maximum number of USAGE items which can be stored temporarily until the next INPUT, OUTPUT + * and FEATURE item. If not defined, this defaults to the value indicated in the HID.h file documentation. + * + * - HID_MAX_COLLECTIONS=x - (\ref Group_HIDParser) - All Architectures \n + * HID reports generally contain several COLLECTION elements, used to group related data items together. Collection information + * is stored separately in the processed usage structure (and referred to by the data elements in the structure) to save space. + * This token may be defined to a non-zero 8-bit value to set the maximum number of COLLECTION items which can be processed by the + * parser into the resultant processed report structure. If not defined, this defaults to the value indicated in the HID.h file + * documentation. + * + * - HID_MAX_REPORTITEMS=x - (\ref Group_HIDParser) - All Architectures \n + * All HID reports contain one or more INPUT, OUTPUT and/or FEATURE items describing the data which can be sent to and from the HID + * device. Each item has associated usages, bit offsets in the item reports and other associated data indicating the manner in which + * the report data should be interpreted by the host. This token may be defined to a non-zero 8-bit value to set the maximum number of + * data elements which can be stored in the processed HID report structure, including INPUT, OUTPUT and (if enabled) FEATURE items. + * If a item has a multiple count (i.e. a REPORT COUNT of more than 1), each item in the report count is placed separately in the + * processed HID report table. If not defined, this defaults to the value indicated in the HID.h file documentation. + * + * - HID_MAX_REPORT_IDS=x - (\ref Group_HIDParser) - All Architectures \n + * HID reports may contain several report IDs, to logically distinguish grouped device data from one another - for example, a combination + * keyboard and mouse might use report IDs to separate the keyboard reports from the mouse reports. In order to determine the size of each + * report, and thus know how many bytes must be read or written, the size of each report (IN, OUT and FEATURE) must be calculated and + * stored. This token may be defined to a non-zero 8-bit value to set the maximum number of report IDs in a device which can be processed + * and their sizes calculated/stored into the resultant processed report structure. If not defined, this defaults to the value indicated in + * the HID.h file documentation. + * + * - NO_CLASS_DRIVER_AUTOFLUSH - (\ref Group_USBClassDrivers) - All Architectures \n + * Many of the device and host mode class drivers automatically flush any data waiting to be written to an interface, when the corresponding + * USB management task is executed. This is usually desirable to ensure that any queued data is sent as soon as possible once and new data is + * constructed in the main program loop. However, if flushing is to be controlled manually by the user application via the *_Flush() commands, + * the compile time token may be defined in the application's makefile to disable automatic flushing during calls to the class driver USB + * management tasks. + * + * + * \section Sec_SummaryUSBTokens General USB Driver Related Tokens + * This section describes compile tokens which affect USB driver stack as a whole in the LUFA library. + * + * - ORDERED_EP_CONFIG - (\ref Group_EndpointManagement , \ref Group_PipeManagement) - AVR8, UC3 \n + * The USB AVRs do not allow for Endpoints and Pipes to be configured out of order; they must be configured in an ascending order to + * prevent data corruption issues. However, by default LUFA employs a workaround to allow for unordered Endpoint/Pipe initialization. This compile + * time token may be used to restrict the initialization order to ascending indexes only in exchange for a smaller compiled binary size. Use + * caution when applied to applications using the library USB Class drivers; the user application must ensure that all endpoints and pipes are + * allocated sequentially. + * + * - USE_STATIC_OPTIONS=x - (\ref Group_USBManagement) - All Architectures \n + * By default, the USB_Init() function accepts dynamic options at runtime to alter the library behaviour, including whether the USB pad + * voltage regulator is enabled, and the device speed when in device mode. By defining this token to a mask comprised of the USB options + * mask defines usually passed as the Options parameter to USB_Init(), the resulting compiled binary can be decreased in size by removing + * the dynamic options code, and replacing it with the statically set options. When defined, the USB_Init() function no longer accepts an + * Options parameter. + * + * - USB_DEVICE_ONLY - (\ref Group_USBManagement) - All Architectures \n + * For the USB AVR models supporting both device and host USB modes, the USB_Init() function contains a Mode parameter which specifies the + * mode the library should be initialized to. If only device mode is required, the code for USB host mode can be removed from the binary to + * save space. When defined, the USB_Init() function no longer accepts a Mode parameter. This define is irrelevant on smaller USB AVRs which + * do not support host mode. + * + * - USB_HOST_ONLY - (\ref Group_USBManagement) - All Architectures \n + * Same as USB_DEVICE_ONLY, except the library is fixed to USB host mode rather than USB device mode. Not available on some USB AVR models. + * + * - USB_STREAM_TIMEOUT_MS=x - (\ref Group_USBManagement) - All Architectures \n + * When endpoint and/or pipe stream functions are used, by default there is a timeout between each transfer which the connected device or host + * must satisfy, or the stream function aborts the remaining data transfer. This token may be defined to a non-zero 16-bit value to set the timeout + * period for stream transfers, specified in milliseconds. If not defined, the default value specified in LowLevel.h is used instead. + * + * - NO_LIMITED_CONTROLLER_CONNECT - (\ref Group_Events) - AVR8 Only \n + * On the smaller USB AVRs, the USB controller lacks VBUS events to determine the physical connection state of the USB bus to a host. In lieu of + * VBUS events, the library attempts to determine the connection state via the bus suspension and wake up events instead. This however may be + * slightly inaccurate due to the possibility of the host suspending the bus while the device is still connected. If accurate connection status is + * required, the VBUS line of the USB connector should be routed to an AVR pin to detect its level, so that the USB_DeviceState global + * can be accurately set and the \ref EVENT_USB_Device_Connect() and \ref EVENT_USB_Device_Disconnect() events manually raised by the RAISE_EVENT macro. + * When defined, this token disables the library's auto-detection of the connection state by the aforementioned suspension and wake up events. + * + * - NO_SOF_EVENTS - (\ref Group_Events) - All Architectures \n + * By default, there exists a LUFA application event for the start of each USB frame while the USB bus is not suspended in either host or device mode. + * This event can be selectively enabled or disabled by calling the appropriate device or host mode function. When this compile time token is defined, + * the ability to receive USB Start of Frame events via the \ref EVENT_USB_Device_StartOfFrame() or \ref EVENT_USB_Host_StartOfFrame() events is removed, + * reducing the compiled program's binary size. + * + * + * \section Sec_SummaryUSBDeviceTokens USB Device Mode Driver Related Tokens + * This section describes compile tokens which affect USB driver stack of the LUFA library when used in Device mode. + * + * - USE_RAM_DESCRIPTORS - (\ref Group_StdDescriptors) - AVR8 Only \n + * Define this token to indicate to the USB driver that all device descriptors are stored in RAM, rather than being located in any one + * of the AVR's memory spaces. RAM descriptors may be desirable in applications where the descriptors need to be modified at runtime. + * + * - USE_FLASH_DESCRIPTORS - (\ref Group_StdDescriptors) - AVR8 Only \n + * Similar to USE_RAM_DESCRIPTORS, but all descriptors are stored in the AVR's FLASH memory rather than RAM. + * + * - USE_EEPROM_DESCRIPTORS - (\ref Group_StdDescriptors) - AVR8 Only \n + * Similar to USE_RAM_DESCRIPTORS, but all descriptors are stored in the AVR's EEPROM memory rather than RAM. + * + * - NO_INTERNAL_SERIAL - (\ref Group_StdDescriptors) - All Architectures \n + * Some AVR models contain a unique serial number which can be used as the device serial number, while in device mode. This allows + * the host to uniquely identify the device regardless of if it is moved between USB ports on the same computer, allowing allocated + * resources (such as drivers, COM Port number allocations) to be preserved. This is not needed in many apps, and so the code that + * performs this task can be disabled by defining this option and passing it to the compiler via the -D switch. + * + * - FIXED_CONTROL_ENDPOINT_SIZE=x - (\ref Group_EndpointManagement) - All Architectures \n + * By default, the library determines the size of the control endpoint (when in device mode) by reading the device descriptor. + * Normally this reduces the amount of configuration required for the library, allows the value to change dynamically (if + * descriptors are stored in EEPROM or RAM rather than flash memory) and reduces code maintenance. However, this token can be + * defined to a non-zero value instead to give the size in bytes of the control endpoint, to reduce the size of the compiled + * binary. + * + * - DEVICE_STATE_AS_GPIOR - (\ref Group_Device) - AVR8 Only \n + * One of the most frequently used global variables in the stack is the USB_DeviceState global, which indicates the current state of + * the Device State Machine. To reduce the amount of code and time required to access and modify this global in an application, this token + * may be defined to a value between 0 and 2 to fix the state variable into one of the three general purpose IO registers inside the AVR + * reserved for application use. When defined, the corresponding GPIOR register should not be used within the user application except + * implicitly via the library APIs. + * + * - FIXED_NUM_CONFIGURATIONS=x - (\ref Group_Device) - All Architectures \n + * By default, the library determines the number of configurations a USB device supports by reading the device descriptor. This reduces + * the amount of configuration required to set up the library, and allows the value to change dynamically (if descriptors are stored in + * EEPROM or RAM rather than flash memory) and reduces code maintenance. However, this value may be fixed via this token in the project + * makefile to reduce the compiled size of the binary at the expense of flexibility. + * + * - CONTROL_ONLY_DEVICE - (\ref Group_Device) - All Architectures \n + * In some limited USB device applications, there are no device endpoints other than the control endpoint; i.e. all device communication + * is through control endpoint requests. Defining this token will remove several features related to the selection and control of device + * endpoints internally, saving space. Generally, this is usually only useful in (some) bootloaders and is best avoided. + * + * - MAX_ENDPOINT_INDEX - (\ref Group_Device) - XMEGA Only \n + * Defining this value to the highest index (not address - this excludes the direction flag) endpoint within the device will restrict the + * number of FIFOs created internally for the endpoint buffers, reducing the total RAM usage. + * + * - INTERRUPT_CONTROL_ENDPOINT - (\ref Group_USBManagement) - All Architectures \n + * Some applications prefer to not call the USB_USBTask() management task regularly while in device mode, as it can complicate code significantly. + * Instead, when device mode is used this token can be passed to the library via the -D switch to allow the library to manage the USB control + * endpoint entirely via USB controller interrupts asynchronously to the user application. When defined, USB_USBTask() does not need to be called + * when in USB device mode. + * + * - NO_DEVICE_REMOTE_WAKEUP - (\ref Group_Device) - All Architectures \n + * Many devices do not require the use of the Remote Wakeup features of USB, used to wake up the USB host when suspended. On these devices, + * the code required to manage device Remote Wakeup can be disabled by defining this token and passing it to the library via the -D switch. + * + * - NO_DEVICE_SELF_POWER - (\ref Group_Device) - All Architectures \n + * USB devices may be bus powered, self powered, or a combination of both. When a device can be both bus powered and self powered, the host may + * query the device to determine the current power source, via \ref USB_Device_CurrentlySelfPowered. For solely bus powered devices, this global + * and the code required to manage it may be disabled by passing this token to the library via the -D switch. + * + * + * \section Sec_SummaryUSBHostTokens USB Host Mode Driver Related Tokens + * + * This section describes compile tokens which affect USB driver stack of the LUFA library when used in Host mode. + * + * - HOST_STATE_AS_GPIOR - (\ref Group_Host) - AVR8 Only \n + * One of the most frequently used global variables in the stack is the USB_HostState global, which indicates the current state of + * the Host State Machine. To reduce the amount of code and time required to access and modify this global in an application, this token + * may be defined to a value between 0 and 2 to fix the state variable into one of the three general purpose IO registers inside the AVR + * reserved for application use. When defined, the corresponding GPIOR register should not be used within the user application except + * implicitly via the library APIs. + * + * - USB_HOST_TIMEOUT_MS=x - (\ref Group_Host) - All Architectures \n + * When a control transfer is initiated in host mode to an attached device, a timeout is used to abort the transfer if the attached + * device fails to respond within the timeout period. This token may be defined to a non-zero 16-bit value to set the timeout period for + * control transfers, specified in milliseconds. If not defined, the default value specified in Host.h is used instead. + * + * - HOST_DEVICE_SETTLE_DELAY_MS=x - (\ref Group_Host) - All Architectures \n + * Some devices require a delay of up to 5 seconds after they are connected to VBUS before the enumeration process can be started, or + * they will fail to enumerate correctly. By placing a delay before the enumeration process, it can be ensured that the bus has settled + * back to a known idle state before communications occur with the device. This token may be defined to a 16-bit value to set the device + * settle period, specified in milliseconds. If not defined, the default value specified in Host.h is used instead. + * + * - INVERTED_VBUS_ENABLE_LINE - (\ref Group_Host) - All Architectures \n + * If enabled, this will indicate that the USB target VBUS line polarity is inverted; i.e. it should be pulled low to enable VBUS to the + * target, and pulled high to stop the target VBUS generation. + * + * \attention On AVR8 architecture devices, this compile time option requires \c NO_AUTO_VBUS_MANAGEMENT to be set. + * + * - NO_AUTO_VBUS_MANAGEMENT - (\ref Group_Host) - All Architectures \n + * Disables the automatic management of VBUS to the target, i.e. automatic shut down in the even of an overcurrent situation. When enabled, VBUS + * is enabled while the USB controller is initialized in USB Host mode. + */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/CompilingApps.txt b/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/CompilingApps.txt new file mode 100644 index 00000000..85912b56 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/CompilingApps.txt @@ -0,0 +1,50 @@ +/** \file + * + * This file contains special DoxyGen information for the generation of the main page and other special + * documentation pages. It is not a project source file. + */ + +/** \page Page_CompilingApps Compiling the Demos, Bootloaders and Projects + * + * The following details how to compile the included LUFA demos, applications and bootloaders using AVR-GCC. + * + * \section Sec_Prerequisites Prerequisites + * Before you can compile any of the LUFA library code or demos, you will need a recent distribution of avr-libc (1.6.2+) + * and the AVR-GCC (4.2+) compiler. A standard "coreutils" package for your system is also required for command line + * compilation of LUFA based applications. + * + * \subsection SSec_PreqWindows Windows Prerequisites + * On Windows, you will need a copy of the latest Atmel Toolchain, either downloaded and installed as a standalone + * package, or installed as part of Atmel Studio. You will need to ensure that the "bin" directory of the toolchain + * is available in your system's PATH environment variable. + * + * In addition, you will need to install a ported version of the ZSH or BASH *nix shells, and a standard set of *nix + * utilities such as cut, find and sed. These can be found in the "basic" system package of the + * of the MinGW installer (http://www.mingw.org). Once installed, add the "msys\1.0\bin" of the MinGW installation + * folder is added to your system's PATH environment variable. + * + * The bootloaders currently also require the "bc" application, which can be installed from + * http://gnuwin32.sourceforge.net/downlinks/bc.php. Once installed add the "GnuWin32\bin" path of the GnuWin32 + * installation folder to your system's PATH environment variable. + * + * \subsection SSec_PreqLinux Linux Prerequisites + * On Linux systems you will need to install the latest Linux distribution of the standalone Atmel Toolchain from the + * Atmel website for general development, or use the latest avr-libc and avr-gcc packages for your chosen distribution's + * package manager. For full device support, the Atmel standalone package is recommended. + * + * \section Sec_Compiling Compiling a LUFA Application + * Compiling the LUFA demos, applications and/or bootloaders is very simple. LUFA comes with makefile scripts for + * each individual demo, bootloader and project folder, as well as scripts in the Demos/, Bootloaders/, Projects/ + * and the LUFA root directory. Compilation of projects can be started from any of the above directories, with a build + * started from an upper directory in the directory structure executing build of all child directories under it. This + * means that while a build inside a particular demo directory will build only that particular demo, a build started from + * the /Demos/ directory will build all LUFA demo projects sequentially. + * + * To build a project from the source via the command line, the command "make all" should be executed from the command + * line in the directory of interest. To remove compiled files (including the binary output, all intermediately files and all + * diagnostic output files), execute "make clean". Once a "make all" has been run and no errors were encountered, the + * resulting binary will be located in the generated ".HEX" file. If your project makes use of pre-initialized EEPROM + * variables, the generated ".EEP" file will contain the project's EEPROM data. + * + * \see \ref Page_BuildSystem for information on the LUFA build system. + */ diff --git a/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/ConfiguringApps.txt b/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/ConfiguringApps.txt new file mode 100644 index 00000000..f126e69b --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/ConfiguringApps.txt @@ -0,0 +1,104 @@ +/** \file + * + * This file contains special DoxyGen information for the generation of the main page and other special + * documentation pages. It is not a project source file. + */ + +/** \page Page_ConfiguringApps Configuring the Demos, Bootloaders and Projects + * + * If the target microcontroller model, architecture, clock speed, board or other settings are different from the current + * settings, they must be changed and the project recompiled from the source code before being programmed into the microcontroller. + * Most project configuration options are located in the makefile build script inside each LUFA application's folder, + * however some demo or application-specific configuration settings are located in one or more of the source files of the project. + * See each project's individual documentation for application-specific configuration values. + * + * Each project "makefile" contains all the script and configuration data required to compile each project. When opened with + * any regular basic text editor such as Notepad or WordPad (ensure that the save format is a pure ASCII text format) the + * build configuration settings may be altered. + * + * \see \ref Page_BuildSystem for information on the LUFA build system. + * + * \section Sec_AppConfigParams The Default Application Template + * + * Below is a copy of the default LUFA application makefile, which can be used as a template for each application. + * + * \verbinclude makefile_template + * + * Inside each makefile, a number of configuration variables are listed with the syntax " = ". For + * each application, the important standard variables which should be altered are: + * + * - MCU, the target processor model + * - ARCH, the target microcontroller architecture + * - BOARD, the target board hardware + * - F_CPU, the target CPU master clock frequency, after any prescaling + * - F_USB, the target raw input clock to the USB module of the processor + * - OPTIMIZATION, the level of optimization to compile with + * - TARGET, the name of the target output binary and other files + * - SRC, the list of source files to compile/assemble/link + * - LUFA_PATH, the path to the LUFA library core source code + * - CC_FLAGS, the common command line flags to pass to the C/C++ compiler, assembler and linker + * - LD_FLAGS, the command line flags to pass to the linker + * + * These values should be changed to reflect the build hardware. + * + * \subsection SSec_MCU The MCU Parameter + * This parameter indicates the target microcontroller model for the compiled application. This should be set to the model of the target + * microcontroller (such as the AT90USB1287, or the ATMEGA32U4), in all lower-case (e.g. "at90usb1287"). Note that not all demos support all the + * microcontroller models and architectures, as they may make use of peripherals or modes only present in some devices. + * + * For supported processor models, see \ref Page_DeviceSupport. + * + * \subsection SSec_ARCH The ARCH Parameter + * This parameter indicates the target microcontroller architecture the library is to be compiled for. Different microcontroller + * architectures require different source files to be compiled into the final binary, and so this option must be set to the correct + * architecture for the selected platform. + * + * For supported processor architectures, see \ref Page_DeviceSupport. + * + * \subsection SSec_BOARD The BOARD Parameter + * This parameter indicates the target board hardware for the compiled application. Some LUFA library drivers are board-specific, + * such as the LED driver, and the library needs to know the layout of the target board. If you are using one of the board models listed + * on the main library page, change this parameter to the board name in all UPPER-case. + * + * If you are not using any board-specific drivers in the LUFA library, or you are using a custom board layout, change this to read + * "USER" (no quotes) instead of a standard board name. If the USER board type is selected and the application makes use of one or more + * board-specific hardware drivers inside the LUFA library, then the appropriate stub drives files should be copied from the \c /CodeTemplates/DriverStubs/ + * directory into a /Board/ folder inside the application directory, and the stub driver completed with the appropriate code to drive the + * custom board's hardware. + * + * For boards with built in hardware driver support within the LUFA library, see \ref Page_DeviceSupport. + * + * \subsection SSec_F_CPU The F_CPU Parameter + * This parameter indicates the target microcontroller's main CPU clock frequency, in Hz. This is used by many libraries (and applications) for + * timing related purposes, and should reflect the actual CPU speed after any prescaling or adjustments are performed. + * + * \subsection SSec_F_USB The F_USB Parameter + * This parameter indicates the raw input clock frequency to the USB module within the microcontroller in Hz. This may be very different on some platforms + * to the main CPU clock or other peripheral/bus clocks. + * + * \subsection SSec_OPTIMIZATION The OPTIMIZATION Parameter + * This parameter indicates the level of optimization to use when compiling the application. This will allow you to compile with an optimization level + * supported by GCC, from 0 (no optimization) to 3 (fastest runtime optimization) or s (smallest size). + * + * \subsection SSec_TARGET The TARGET Parameter + * This parameter indicates the application target name, which is used as the base filename for the build binary and debugging files. This will be the + * name of the output files once linked together into the final application, ready to load into the target. + * + * \subsection SSec_SRC The SRC Parameter + * This parameter indicates the source files used to compile the application, as a list of C (*.c), C++ (*.cpp) and Assembly (*.S) files. Note that + * all assembly files must end in a capital .S extension, as lowercase .s files are reserved for GCC intermediate files. + * + * \subsection SSec_LUFA_PATH The LUFA_PATH Parameter + * As each LUFA program requires the LUFA library source code to compile correctly, the application must know where the LUFA library is located. This + * value specifies the path to the LUFA library core. This path may be relative or absolute, however note than even under Windows based systems the + * forward-slash (/) path seperator must be used. + * + * \subsection SSec_CC_FLAGS The CC_FLAGS Parameter + * This parameter lists the compiler flags passed to the C/C++ compiler, the assembler and the linker. These are used as-is directly to GCC and thus + * must match GCC's command line options as given in the GCC manual. This variable may be used to define tokens directly on the command line, enable or + * disable warnings, adjust the target-specific tuning parameters or other options. + * + * \subsection SSec_LD_FLAGS The LD_FLAGS Parameter + * This parameter lists the linker flags passed exclusively to the linker. These are used as-is directly to GCC and thus must match GCC's command line + * linker options as given in the GCC manual. This variable may be used to create or relocate custom data sections, or enable linker specific behaviors. + */ diff --git a/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/DevelopingWithLUFA.txt b/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/DevelopingWithLUFA.txt new file mode 100644 index 00000000..becd58e5 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/DevelopingWithLUFA.txt @@ -0,0 +1,23 @@ +/** \file + * + * This file contains special DoxyGen information for the generation of the main page and other special + * documentation pages. It is not a project source file. + */ + +/** + * \page Page_DevelopingWithLUFA Developing With LUFA + * + * This section of the manual contains information on LUFA development, such as Getting Started information, + * information on compile-time tuning of the library and other developer-related sections. + * + * Subsections: + * \li \subpage Page_BuildSystem - The LUFA Buildsystem + * \li \subpage Page_TokenSummary - Summary of Compile Time Tokens + * \li \subpage Page_Migration - Migrating from an Older LUFA Version + * \li \subpage Page_VIDPID - Allocated USB VID and PID Values + * \li \subpage Page_BuildLibrary - Building as a Linkable Library + * \li \subpage Page_ExportingLibrary - Exporting LUFA for IDE Use + * \li \subpage Page_WritingBoardDrivers - How to Write Custom Board Drivers + * \li \subpage Page_SoftwareBootloaderStart - How to jump to the bootloader in software + */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/DeviceSupport.txt b/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/DeviceSupport.txt new file mode 100644 index 00000000..18e808f4 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/DeviceSupport.txt @@ -0,0 +1,432 @@ +/** \file + * + * This file contains special DoxyGen information for the generation of the main page and other special + * documentation pages. It is not a project source file. + */ + +/** + * \page Page_DeviceSupport Device and Hardware Support + * + * Atmel Microcontrollers: + * \li \subpage Page_AVR8Support - Atmel AVR8 Support + * \li \subpage Page_UC3Support - Atmel AVR32 UC3 Support + * \li \subpage Page_XMEGASupport - Atmel XMEGA Support + */ + +/** + * \page Page_AVR8Support Atmel 8-Bit AVR (AVR8) Support + * + * \section Sec_AVR8Support_Devices Supported Microcontroller Models + * + * Currently supported AVR8 models: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
PartUSB Device ModeUSB Host Mode
AT90USB82YesNo
ATMEGA8U2YesNo
AT90USB162YesNo
ATMEGA16U2YesNo
ATMEGA16U4YesNo
ATMEGA32U2YesNo
ATMEGA32U4YesNo
ATMEGA32U6YesNo
AT90USB646YesNo
AT90USB647YesYes
AT90USB1286YesNo
AT90USB1287YesYes
+ * + * \section Sec_AVR8Support_Boards Supported Atmel Boards + * Currently supported Atmel AVR8 boards (see \ref Group_BoardTypes): + * - AT90USBKEY + * - ATAVRUSBRF01 + * - EVK527 + * - RZUSBSTICK + * - STK525 + * - STK526 + * - XPLAIN (Original green board, not the newer blue XPLAINED family boards) + * + * \section Sec_AVR8Support_ThirdParty Supported Third Party Models + * Currently supported third-party boards (see \ref Group_BoardTypes for makefile \c BOARD constant names): + * - Adafruit U4 Breakout Board + * - Arduino Uno + * - Bitwizard Multio and Big-Multio + * - Busware BUI + * - Busware CUL V3 + * - Busware TUL + * - DorkbotPDX Duce + * - Fletchtronics Bumble-B (using manufacturer recommended peripheral layout) + * - Kernel Concepts USBFOO + * - Linnix UDIP + * - MattairTech JM-DB-U2 + * - Maximus USB + * - Micropendous Boards (Micropendous-32U2, Micropendous-1, Micropendous-2) + * - Microsin AVR-USB162 + * - Minimus USB + * - Olimex AVR-USB-162 + * - Olimex AVR-USB-32U4 + * - Olimex AVR-USB-T32U4 + * - Olimex AVR-ISP-MK2 + * - Paranoid Studio's US2AX (V1, V2 and V3 hardware revisions) + * - PJRC Teensy (1.x and 2.x versions) + * - Sparkfun U2 Breakout Board + * - TCNISO Blackcat USB JTAG + * - Tempusdictum Benito + * - Tom's USBTINY-MKII (all revisions and versions) + * - Custom User Boards (with Board Drivers if desired, see \ref Page_WritingBoardDrivers) + */ + +/** + * \page Page_UC3Support Atmel 32-Bit UC3 AVR (UC3) + * + * \warning The AVR32 UC3 device support is currently experimental, and is included for preview purposes only. + * + * \section Sec_UC3Support_Devices Supported Microcontroller Models + * + * Currently supported UC3 models: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
PartUSB Device ModeUSB Host Mode
AT32UC3A064YesYes
AT32UC3A164YesYes
AT32UC3A364YesYes
AT32UC3A364SYesYes
AT32UC3A464YesYes
AT32UC3A464SYesYes
AT32UC3B064YesYes
AT32UC3B164YesYes
AT32UC3A0128YesYes
AT32UC3A1128YesYes
AT32UC3A3128YesYes
AT32UC3A3128SYesYes
AT32UC3A4128YesYes
AT32UC3A4128SYesYes
AT32UC3B0128YesYes
AT32UC3B1128YesYes
AT32UC3A0256YesYes
AT32UC3A1256YesYes
AT32UC3A3256YesYes
AT32UC3A3256SYesYes
AT32UC3A4256YesYes
AT32UC3A4256SYesYes
AT32UC3B0256YesYes
AT32UC3B1256YesYes
AT32UC3A0512YesYes
AT32UC3A1512YesYes
AT32UC3B0512YesYes
AT32UC3B1512YesYes
+ * + * \section Sec_UC3Support_Boards Supported Atmel Boards + * + * Currently supported Atmel UC3 boards (see \ref Group_BoardTypes): + * - EVK1100 + * - EVK1101 + * - EVK1104 + * + * \section Sec_UC3Support_ThirdParty Supported Third Party Models + * + * Currently supported third-party boards (see \ref Group_BoardTypes for makefile \c BOARD constant names): + * - Custom User Boards (with Board Drivers if desired, see \ref Page_WritingBoardDrivers) + */ + +/** + * \page Page_XMEGASupport Atmel USB XMEGA AVR (XMEGA) + * + * \warning The XMEGA device support is currently experimental (incomplete and/or non-functional), and is included for preview purposes only. + * + * \section Sec_XMEGASupport_Devices Supported Microcontroller Models + * + * Currently supported XMEGA models: + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
PartUSB Device ModeUSB Host Mode
ATXMEGA16A4UYesNo
ATXMEGA32A4UYesNo
ATXMEGA64A4UYesNo
ATXMEGA128A4UYesNo
ATXMEGA64A3UYesNo
ATXMEGA128A3UYesNo
ATXMEGA192A3UYesNo
ATXMEGA256A3UYesNo
ATXMEGA256A3BUYesNo
ATXMEGA128A1UYesNo
ATXMEGA64B3YesNo
ATXMEGA128B3YesNo
ATXMEGA64B1YesNo
ATXMEGA128B1YesNo
ATXMEGA64C3YesNo
ATXMEGA128C3YesNo
ATXMEGA192C3YesNo
ATXMEGA256C3YesNo
ATXMEGA384C3YesNo
ATXMEGA16C4YesNo
ATXMEGA32C4YesNo
+ * + * \section Sec_XMEGASupport_Boards Supported Atmel Boards + * Currently supported Atmel XMEGA boards (see \ref Group_BoardTypes): + * - XMEGA A3BU Xplained + * - XMEGA B1 Xplained + * + * \section Sec_XMEGASupport_ThirdParty Supported Third Party Models + * Currently supported third-party boards (see \ref Group_BoardTypes for makefile \c BOARD constant names): + * - Custom User Boards (with Board Drivers if desired, see \ref Page_WritingBoardDrivers) + */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/DirectorySummaries.txt b/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/DirectorySummaries.txt new file mode 100644 index 00000000..b0422467 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/DirectorySummaries.txt @@ -0,0 +1,80 @@ +/** \file + * + * This file contains special DoxyGen information for the generation of the main page and other special + * documentation pages. It is not a project source file. + */ + +/** \dir Platform + * \brief Platform specific drivers. + * + * This folder contains platform specific drivers and defines for various supported architectures. These may or may + * not be used in a LUFA application, and are provided for convenience purposes. + * + * \dir Drivers + * \brief Library hardware and software drivers. + * + * This folder contains all the library hardware and software drivers for each supported board, architecture and + * microcontroller model. + * + * \dir Drivers/Misc + * \brief Miscellaneous driver files. + * + * This folder contains drivers for aspects other than the USB interface, board hardware or microcontroller peripherals. + * + * \dir Drivers/Peripheral + * \brief Microcontroller peripheral driver files. + * + * This folder contains drivers for various low level microcontroller peripherals, usually located on the microcontroller + * die within the same physical chip. + * + * \dir Drivers/USB + * \brief USB controller peripheral driver files. + * + * This folder contains the complete LUFA USB stack and controller files, including the core driver and stack, as well + * as the USB class driver implementations. + * + * \dir Drivers/USB/Core + * \brief Core USB driver files. + * + * This folder contains the core USB stack and controller driver files, to correctly implement USB functionality on the + * target architecture and microcontroller model. This + * + * \dir Drivers/USB/Class + * \brief USB Class helper driver files. + * + * This folder contains drivers for implementing functionality of standardized USB classes. These are not used directly by the library, + * but provide a standard and library-maintained way of implementing functionality from some of the defined USB classes without extensive + * development effort. Is is recommended that these drivers be used where possible to reduce maintenance of user applications. + * + * \dir Drivers/USB/Class/Device + * \brief USB Device Class helper driver files. + * + * Device mode drivers for the standard USB classes. + * + * \dir Drivers/USB/Class/Host + * \brief USB Host Class helper driver files. + * + * Host mode drivers for the standard USB classes. + * + * \dir Drivers/Board + * \brief Board hardware driver files. + * + * This folder contains drivers for interfacing with the physical hardware on supported commercial boards, primarily from + * the Atmel corporation. Header files in this folder should be included in user applications requiring the functionality of + * hardware placed on supported boards. + * + * \dir CodeTemplates + * \brief Code templates for use in LUFA powered applications. + * + * This contains code templates for board drivers, sample LUFA project makefiles and other similar templates that can be copied into + * a LUFA powered application and modified to speed up development. + * + * \dir CodeTemplates/DriverStubs + * \brief Driver stub header files for custom boards, to allow the LUFA board drivers to operate. + * + * This contains stub files for the LUFA board drivers. If the LUFA board drivers are used with board hardware other than those + * directly supported by the library, the BOARD parameter of the application's makefile can be set to "USER", and these stub files + * copied to the "/Board/" directory of the application's folder. When fleshed out with working driver code for the custom board, + * the corresponding LUFA board APIs will work correctly with the non-standard board hardware. + */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/Donating.txt b/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/Donating.txt new file mode 100644 index 00000000..7e947c2a --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/Donating.txt @@ -0,0 +1,24 @@ +/** \file + * + * This file contains special DoxyGen information for the generation of the main page and other special + * documentation pages. It is not a project source file. + */ + +/** + * \page Page_Donating Donating to Support This Project + * + * \image html Images/Author.jpg "Dean Camera, LUFA Developer" + * + * I am a 23 year old Atmel Applications Engineer, living in Trondheim, Norway and working on LUFA in my spare time. + * The development and support of this library requires much effort from myself, as I am the sole developer, maintainer + * and supporter. Please consider donating a small amount to support this and my future Open Source projects - All + * donations are greatly appreciated. + * + * Note that commercial entities can remove the attribution portion of the LUFA license by a one-time fee - see + * \ref Page_LicenseInfo for more details (Note: Please do NOT pay this in advance through the donation link below - + * contact author for payment details.). + * + * \image html "http://www.pledgie.com/campaigns/6927.png?skin_name=chrome" + * Donate to this project via PayPal - Thanks in Advance! + */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/ExportingLibrary.txt b/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/ExportingLibrary.txt new file mode 100644 index 00000000..65d7fc92 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/ExportingLibrary.txt @@ -0,0 +1,106 @@ +/** \file + * + * This file contains special DoxyGen information for the generation of the main page and other special + * documentation pages. It is not a project source file. + */ + +/** \page Page_ExportingLibrary Exporting the Library for IDE Use + * + * While LUFA was designed to allow for easy compilation in a makefile driven environment, + * it is possible to export the library into a form suitable for drop-in use inside of an + * IDE. + * + * \section Sec_LibraryExport Exporting the Library + * An export of the library is at its most basic, a direct copy of the main "LUFA" source folder from the + * root download folder; this contains the library core which can be re-used within external projects. + * However, as many IDEs attempt to automatically compile all included source files, it is neccesary to + * exclude some directories and files from the library core export to allow for easier integration into + * an IDE project. + * + * \subsection SSec_ManualExport Manual Export + * To manually export the library core, copy over the main LUFA library folder from the LUFA root directory, + * renaming as desired. Within the library core folder, the following directories should be removed or + * excluded from your IDE import: + * - Documentation/ + * - DoxygenPages/ + * - CodeTemplates/ + * + * If required, files from the CodeTemplates/ subdirectory may be copied to your IDE project as needed. + * + * The resulting copy of the library may then be imported into your chosen IDE according to the instructions + * shown in \ref Sec_LibraryImport. + * + * \subsection SSec_AutomaticExport Automatic Export + * If desired, the steps indicated in \ref SSec_ManualExport may be automatically performed, by running the + * command make export_tar from the command line. This will generate two .tar files in the + * current directory, named LUFA_YYMMDD.tar and LUFA_YYMMDD_Code_Templates.tar (where + * "YYMMDD" is the version of the library being exported). The first archive contains the exported LUFA core + * with the non-required files removed, while the second contains an archived copy of the code template files + * for the current LUFA version. + * + * The resulting archived copy of the library may then be extracted to your chosen IDE project source directory + * and imported according to the instructions shown in \ref Sec_LibraryImport. + * + * \section Sec_LibraryImport Importing the Library + * An exported copy of the library may be imported wholesale into an IDE project, if the instructions detailed + * in \ref Sec_LibraryExport are followed. + * + * Specific instructions for importing an exported version of LUFA into various IDEs are listed below. + * + * \subsection SSec_AS56_Import Importing into AVRStudio 5/Atmel Studio 6 + * To import LUFA into a new or existing project, the following steps must be followed. + * + * \subsubsection SSSec_AS56_Import_Step1 Copy over the exported library + * Copy over the exported library archive created via the steps listed in \ref Sec_LibraryExport to your AS5/AS6 + * project directory. + * + * \image html Images/AS5_AS6_Import/AS5_AS6_Import_Step1.png + * + * \subsubsection SSSec_AS56_Import_Step2 Extract exported library + * Extract out the contents of the archive to a new folder. This may be any name you wish, however keep in mind + * that this name will need to be referenced within your user application under most circumstances. It is + * suggested that this folder be named "LUFA", or "LUFA" followed by the version string for easy reference. + * + * \image html Images/AS5_AS6_Import/AS5_AS6_Import_Step2.png + * + * \subsubsection SSSec_AS56_Import_Step3 Add the library files + * Open your AVRStudio 5/Atmel Studio 6 project. From the "Solution Explorer" pane, click the "Show All Files" + * button on the toolbar to display ghosted icons of files and folders located in the project source directory + * that are not currently added to the project. + * + * \image html Images/AS5_AS6_Import/AS5_AS6_Import_Step3.png + * + * Right-click the ghosted version of the extracted LUFA export folder in the Solution Explorer pane, and + * choose the "Add to Project" option from the context menu. This will add the entire LUFA source tree to the + * current project. + * + * \subsubsection SSSec_AS56_Import_Step4 Open Project Toolchain Properties + * In the Solution Explorer pane, click the project node, and press the "Properties" button in the toolbar to + * open the Project Properties window. This window allows you to configure the various project global compiler, + * assembler and linker options. + * + * \image html Images/AS5_AS6_Import/AS5_AS6_Import_Step4.png + * + * Click the "Toolchain" tab on the left side of the Project Properties window. + * + * \subsubsection SSSec_AS56_Import_Step5 Configure Project Toolchain Properties + * + * In the GNU C Compiler section, open the "Symbols" page. Click the "Add Item" button to the top-right of the + * "Defined Symbols" section to add new symbols. + * + * At a minimum, you will need to define the following symbols (for more information on these symbols, see + * \ref Page_ConfiguringApps): + * - ARCH + * - F_CPU + * - F_USB + * - BOARD + * \image html Images/AS5_AS6_Import/AS5_AS6_Import_Step5_1.png + * + * Next, open the GNU C Compiler section's "Optimization" page. Ensure that the option to prepare functions for + * garbage collection is enabled. + * \image html Images/AS5_AS6_Import/AS5_AS6_Import_Step5_2.png + * + * Finally, in the GNU C Linker section, open the "Optimization" page. Ensure that the option to garbage collect + * unused sections is selected. + * \image html Images/AS5_AS6_Import/AS5_AS6_Import_Step5_3.png + */ diff --git a/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/FutureChanges.txt b/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/FutureChanges.txt new file mode 100644 index 00000000..9660a473 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/FutureChanges.txt @@ -0,0 +1,49 @@ +/** \file + * + * This file contains special DoxyGen information for the generation of the main page and other special + * documentation pages. It is not a project source file. + */ + + /** \page Page_FutureChanges Future Changes + * + * Below is a list of future changes which are proposed for the LUFA library, but not yet started/complete. + * This gives an unordered list of future changes which may be available in future releases of the library. + * If you have an item to add to this list, please contact the library author via email, the LUFA mailing list, + * or post your suggestion as an enhancement request to the project bug tracker. + * + * Targeted for Future Releases: + * - Code Features + * -# Add hub support when in Host mode for multiple devices + * -# Investigate virtual hubs when in device mode instead of composite devices + * -# Re-add interrupt Pipe/Endpoint support + * -# Update stream APIs to use DMA transfers on supported architectures + * -# Pull out third party libraries into a separate folder and reference them as required + * -# Add a LUFA_YIELD macro for integration into a third-party RTOS + * -# Abstract out Mass Storage byte send/receive to prevent low level API use in projects + * -# Fix HID report parser usage support for array types + * -# Make HOST_DEVICE_SETTLE_DELAY_MS a global variable that can be changed + * -# Add MANDATORY_EVENT_FUNCTIONS compile time option + * -# Add watchdog support to the library and apps/bootloaders + * - Testing/Verification + * -# Re-run USBIF test suite on all classes to formally verify operation + * -# Implement automated functional testing of all demos + * - Documentation/Support + * -# Add detailed overviews of how each demo works + * -# Add board overviews + * -# Write LUFA tutorials + * - Demos/Projects + * -# Device/Host USB bridge + * -# Finish incomplete demos and projects + * -# Add class driver support for Test and Measurement class + * -# Add class driver support for EEM class + * -# Add class driver support for ECM class + * -# Add class driver generic HID report host demo + * -# Implement flow control for USB to Serial project + * - Ports + * -# Port all demos to multiple architectures + * -# Finish USB XMEGA port + * -# Add AVR32 UC3C, UC3D and UC3L support + * -# Atmel ARM7 series microcontrollers + * -# Other (commercial) C compilers + */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/GettingStarted.txt b/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/GettingStarted.txt new file mode 100644 index 00000000..b62a7cae --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/GettingStarted.txt @@ -0,0 +1,25 @@ +/** \file + * + * This file contains special DoxyGen information for the generation of the main page and other special + * documentation pages. It is not a project source file. + */ + +/** \page Page_GettingStarted Getting Started + * + * Out of the box, LUFA contains a large number of pre-made class demos for you to test, experiment with and + * ultimately build upon for your own projects. All the demos (where possible) come pre-configured to build and + * run correctly on the AT90USB1287 AVR microcontroller, mounted on the Atmel USBKEY board and running at an 8MHz + * master clock. This is due to two reasons; one, it is the hardware the author possesses, and two, it is the most + * popular Atmel USB demonstration board to date. To learn how to reconfigure, recompile and program the included + * LUFA applications using different settings, see the subsections below. + * + * Most of the included demos in the /Demos/ folder come in both ClassDriver and LowLevel varieties. If you are new + * to LUFA, it is highly recommended that you look at the ClassDriver versions first, which use the pre-made USB + * Class Drivers (\ref Group_USBClassDrivers) to simplify the use of the standard USB classes in user applications. + * + * Subsections: + * \li \subpage Page_ConfiguringApps - How to Configure the Included Demos, Projects and Bootloaders + * \li \subpage Page_CompilingApps - How to Compile the Included Demos, Projects and Bootloaders + * \li \subpage Page_ProgrammingApps - How to Program an AVR with the Included Demos, Projects and Bootloaders + */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/Groups.txt b/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/Groups.txt new file mode 100644 index 00000000..3a3509d3 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/Groups.txt @@ -0,0 +1,38 @@ +/** \file + * + * This file contains special DoxyGen information for the generation of the main page and other special + * documentation pages. It is not a project source file. + */ + +/** \defgroup Group_BoardDrivers Board Drivers + * + * Functions, macros, variables, enums and types related to the control of physical board hardware. + */ + +/** \defgroup Group_PeripheralDrivers On-chip Peripheral Drivers + * + * Functions, macros, variables, enums and types related to the control of AVR subsystems. + */ + +/** \defgroup Group_MiscDrivers Miscellaneous Drivers + * + * Miscellaneous driver Functions, macros, variables, enums and types. + */ + +/** \defgroup Group_PlatformDrivers_AVR8 AVR8 + * \ingroup Group_PlatformDrivers + * + * Drivers relating to the AVR8 architecture platform, such as clock setup and interrupt management. + */ + +/** \defgroup Group_PlatformDrivers_XMEGA XMEGA + * \ingroup Group_PlatformDrivers + * + * Drivers relating to the XMEGA architecture platform, such as clock setup and interrupt management. + */ + +/** \defgroup Group_PlatformDrivers_UC3 UC3 + * \ingroup Group_PlatformDrivers + * + * Drivers relating to the UC3 architecture platform, such as clock setup and interrupt management. + */ diff --git a/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/Images/AS5_AS6_Import/AS5_AS6_Import_Step1.png b/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/Images/AS5_AS6_Import/AS5_AS6_Import_Step1.png new file mode 100644 index 0000000000000000000000000000000000000000..4f0c26f374ca20ea74c22fc47a66264cb8d1897a GIT binary patch literal 98201 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�Qmf0fBjLJ~U8);@9@%%svH$AUGTvKBo5^ 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
FPqH^r|^y4RA)#RWsuiSb%AAf1zTW*g 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 YNg#YQXZJ!({000eE2zt(WnTsU57kNqO#lD@ literal 0 HcmV?d00001 diff --git a/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/Images/AS5_AS6_Import/AS5_AS6_Import_Step2.png b/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/Images/AS5_AS6_Import/AS5_AS6_Import_Step2.png new file mode 100644 index 0000000000000000000000000000000000000000..6e309ae4151a4e02a859aca3a48319dd43807a2b GIT binary patch literal 100532 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

=!Im=ymD169iP`vb+hF_v1fa#4de6_>3K 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

N`w6 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 HhtK{GPaXat literal 0 HcmV?d00001 diff --git a/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/Images/AS5_AS6_Import/AS5_AS6_Import_Step5_2.png b/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/Images/AS5_AS6_Import/AS5_AS6_Import_Step5_2.png new file mode 100644 index 0000000000000000000000000000000000000000..078f4ec8d7b3b3920c1a65a7b0b52d8fbee3b7d9 GIT binary patch literal 28918 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 literal 0 HcmV?d00001 diff --git a/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/Images/AS5_AS6_Import/AS5_AS6_Import_Step5_3.png b/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/Images/AS5_AS6_Import/AS5_AS6_Import_Step5_3.png new file mode 100644 index 0000000000000000000000000000000000000000..8a8571bd86868ef9a1bfb12214138c17221c4bd8 GIT binary patch literal 23561 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 F|JfK#>ahR- literal 0 HcmV?d00001 diff --git a/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/Images/LUFA.png b/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/Images/LUFA.png new file mode 100644 index 0000000000000000000000000000000000000000..54fa1a66433491cb4b8cd9f5cdc6269f928f901c GIT binary patch literal 10296 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 v$pN2bPDNB8 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 literal 0 HcmV?d00001 diff --git a/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/KnownIssues.txt b/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/KnownIssues.txt new file mode 100644 index 00000000..0d63a03d --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/KnownIssues.txt @@ -0,0 +1,44 @@ +/** \file + * + * This file contains special DoxyGen information for the generation of the main page and other special + * documentation pages. It is not a project source file. + */ + + /** \page Page_KnownIssues Known Issues + * The following are known issues present in each official LUFA release. This list should contain all known + * issues in the library. Most of these issues should be corrected in the future release - see + * \ref Page_FutureChanges for a list of planned changes in future releases. + * + * \section Sec_KnownIssues120730 Version 120730 + * - AVR8 Architecture + * - No known issues. + * - UC3 Architecture + * \warning The UC3 device support is currently experimental (incomplete and/or non-functional), and is included for preview purposes only. \n + * + * - No demos, bootloaders or projects have been ported for the UC3 devices in the current release, + * although the architecture is supported in the LUFA core library. + * - DMA transfers to and from the USB controller are not yet implemented for this release. + * - The UC3C, UC3D and UC3L sub-families of UC3 are not currently supported by the library due to their + * altered USB controller design. + * - The various \c CreateStream() functions for creating standard \c compatible virtual file + * streams are not available on the UC3 architecture, due to a lack of suitable library support. + * - XMEGA Architecture + * \warning The XMEGA device support is currently experimental (incomplete and/or non-functional), and is included for preview purposes only. + * + * - No demos, bootloaders or projects have been ported for the XMEGA devices in the current release, + * although the architecture is supported in the LUFA core library. + * - Endpoints of more than 64 bytes are not currently supported in this release. + * - Isochronous endpoints are not currently supported in this release. As a result, the audio class + * cannot be used on XMEGA devices. + * - Multiple-bank endpoints are not currently supported in this release. + * - Early revisions of the ATXMEGA128A1U are incompatible with LUFA, due to their various errata + * relating to the USB controller. + * - Architecture Independent + * - The HID parser fails for array type elements that have a MIN and MAX usage applied; each element + * in the array will receive a unique incrementing usage from the MIN value, up to MAX. + * - The LUFA library is not watchdog aware, and thus timeouts are possible if short periods are used + * and a lengthy USB operation is initiated. + * - Build System + * - No known issues. + */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/LUFAPoweredProjects.txt b/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/LUFAPoweredProjects.txt new file mode 100644 index 00000000..c3bf3db9 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/LUFAPoweredProjects.txt @@ -0,0 +1,181 @@ +/** \file + * + * This file contains special DoxyGen information for the generation of the main page and other special + * documentation pages. It is not a project source file. + */ + +/** \page Page_LUFAPoweredProjects User Projects Powered by LUFA + * + * LUFA is currently in use all around the world, in many applications both commercial and non-commercial. Below is a + * list of known public LUFA powered projects, which all use the LUFA library in some way. Feel free to visit each project's + * home page for more information on each project. + * + * If you have a project that you would like to add to this list, please contact me via the details on the main page of this + * documentation. + * + * \section Sec_BoardsUsingLUFA AVR-USB Development Boards Using LUFA + * + * The following is a list of known AVR USB development boards, which recommend using LUFA for the USB stack. Some of these + * are open design, and all are available for purchase as completed development boards suitable for project development. + * + * \li AVR-USB-162, a USBKEY-like development board for the AT90USB162: http://olimex.com/dev/avr-usb-162.html + * \li Benito #7, a no-frills USB board: http://www.dorkbotpdx.org/wiki/benito + * \li Duce, the sucessor to the Benito #7: http://dorkbotpdx.org/wiki/duce + * \li JM-DB-U2, an ATMEGA32U2 development board: http://u2.mattair.net/index.html + * \li Micropendous, an open design/source set of AVR USB development boards: http://micropendous.org/ + * \li Microsin AVR-USB162 breakout board, a DIY AT90USB162 development board: http://microsin.ru/content/view/685/44/ + * \li Minimus USB, a board specially designed for PSGroove: http://www.minimususb.com/ + * \li Nanduino, a do-it-yourself AT90USB162 board: http://www.makestuff.eu/wordpress/?page_id=569 + * \li Sparkfun ATMEGA8U2 breakout board: http://www.sparkfun.com/products/10277 + * \li Teensy and Teensy++, two other AVR USB development boards: http://www.pjrc.com/teensy/index.html + * \li U2DIL/U4DIL, a set of DIP layout USB AVR boards: http://www.reworld.eu/re/en/products/u2dil/ + * \li USB2AX, a tiny USB to serial converter board: http://paranoidstudio.assembla.com/wiki/show/paranoidstudio/USB2AX + * \li USBFOO 2, AT90USB162 based development board: http://shop.kernelconcepts.de/product_info.php?products_id=102 + * + * \section Sec_LUFAProjects Projects Using LUFA (Hobbyist) + * + * The following are known hobbyist projects using LUFA. Most are open source, and show off interesting ways that the LUFA library + * can be incorporated into many different applications. + * + * \li Accelerometer Game Joystick: http://www.crictor.co.il/he/episodes/joystick/ + * \li Arcade Controller: http://fletchtronics.net/arcade-controller-made-petunia + * \li Arcade Joystick: http://jamie.lentin.co.uk/embedded/arcade-joystick/ + * \li AttoBasic AVR BASIC interpreter: http://www.cappels.org/dproj/AttoBasic2_1/AttoBasic_2.1_with_USB_and_Arduino_support.html + * \li AVR USB Modem, a 3G Wireless Modem host: http://code.google.com/p/avrusbmodem/ + * \li Bicycle POV: http://www.code.google.com/p/bicycleledpov/ + * \li Bluetooth Explorerbot: http://code.google.com/p/bluetooth-explorerbot/ + * \li Bus Ninja, an AVR clone of the popular BusPirate project: http://blog.hodgepig.org/busninja/ + * \li CAMTRIG, a remote Camera Trigger device: http://code.astraw.com/projects/motmot/camtrig + * \li CD Driver Emulator Dongle for ISO Files: http://cdemu.blogspot.com/ + * \li ClockTamer, a configurable clock generator: http://code.google.com/p/clock-tamer/ + * \li Collection of alternative Arduino Uno firmwares: http://hunt.net.nz/users/darran/ + * \li Computer controlled LED matrix (Russian): http://we.easyelectronics.ru/AVR/nebolshoy-primer-s-lufa-hidapi.html + * \li CULFW, a 868MHz RF packet encoder/decoder: http://www.koeniglich.de/culfw/culfw.html + * \li Dashkey, a custom PC keyboard controller: http://geekhack.org/showwiki.php?title=Island:19096 + * \li DIY PS3 controller emulator: https://code.google.com/p/diyps3controller/ + * \li EMuSer, a USB-RS422 adapter for E-Mu samplers: http://www.emxp.net/EMuSer.htm + * \li Estick JTAG, an ARM JTAG debugger: http://code.google.com/p/estick-jtag/ + * \li "Fingerlicking Wingdinger" (WARNING: Bad language if no Javascript), a MIDI controller: http://noisybox.net/electronics/wingdinger/ + * \li Flyatar, a real-time fly tracking system: https://github.com/peterpolidoro/Flyatar + * \li FootJoy, a 22 button, 6-axis josystick with keyboard and mouse modes: https://bitbucket.org/sirbrialliance/foot-joy/ + * \li Gamecube controller to USB adapter: https://www.facebook.com/media/set/?set=a.10150202447076304.310536.688776303&l=df53851c50 + * \li Garmin GPS USB to NMEA standard serial sentence translator: http://github.com/nall/garmin-transmogrifier/tree/master + * \li Generic HID Device Creator: http://generichid.sourceforge.net/ + * \li Generic HID Open Source Framework: http://www.waitingforfriday.com/index.php/USB_Generic_HID_Open_Source_Framework_for_Atmel_AVR_and_Windows + * \li Ghetto Drum, a MIDI drum controller: http://noisybox.net/art/gdrum/ + * \li GPS enabled lap timer for vehicles: http://www.assembla.com/code/ironlung/subversion/nodes/trunk/LapTimer + * \li Hardware Volume Control: https://github.com/davidk/hw-volume-control + * \li Hiduino, a USB-MIDI replacement firmware for the Arduino Uno: http://code.google.com/p/hiduino/ + * \li Ikea RGB LED USB modification: http://slashhome.se/p/projects/id/ikea_dioder_usb/#project + * \li IR Remote to Keyboard decoder: http://netzhansa.blogspot.com/2010/04/our-living-room-hi-fi-setup-needs-mp3.html + * \li Jukebox panic button: http://thinkl33t.co.uk/the-panic-button + * \li LED Panel controller: http://projects.peterpolidoro.net/caltech/panelscontroller/panelscontroller.htm + * \li Linux Secure Storage Dongle: http://github.com/TomMD/teensy + * \li LUFA powered DDR dance mat (French): http://logicien-parfait.fr/dokuwiki/doku.php?id=projet:ddr_repair + * \li MakeTV Episode Dispenser: http://www.youtube.com/watch?v=BkWUi18hl3g + * \li MidiMonster, a USB-to-MIDI gateway board: http://www.dorkbotpdx.org/wiki/midimonster + * \li MIDI Theremin: http://baldwisdom.com/usb-midi-controller-theremin-style-on-arduino-uno/ + * \li MIDI interface hack of a toy Guitar: http://blog.x37v.info/2011/06/26/toy-guitar-hacked-midi-conroller + * \li MiniBloq, a graphical Ardunio programming environment : http://minibloq.org/ + * \li MiXley, a port of the Teacup 3D printer firmware for the USB AVRs: http://codaset.com/michielh/mixley + * \li Mobo 4.3, a USB controlled all band (160-10m) HF SDR transceiver: http://sites.google.com/site/lofturj/mobo4_3 + * \li Moco, a native Arduino Uno MIDI replacement firmware: http://web.mac.com/kuwatay/morecat_lab./MocoLUFA.html + * \li Motherboard BIOS flasher: http://www.coreboot.org/InSystemFlasher + * \li Multi-button Joystick (French): http://logicien-parfait.fr/dokuwiki/doku.php?id=projet:joystick + * \li Music Playing Alarm Clock (Tutorial): http://www.instructables.com/id/Music-Playing-Alarm-Clock/ + * \li Nehebkau, Laptop Controlled Keyboard and Mouse: http://www.frank-zhao.com/cache/nehebkau.php + * \li NeroJTAG, a JTAG dongle: https://github.com/makestuff/neroJtag + * \li NES Controller USB modification: http://projects.peterpolidoro.net/video/NESUSB.htm + * \li Nikon wireless camera remote control (Norwegian): http://hekta.org/~hpe1119/ + * \li Opendous-JTAG, an open source ARM JTAG debugger: http://code.google.com/p/opendous-jtag/ + * \li Openkubus, an open source hardware-based authentication dongle: http://code.google.com/p/openkubus/ + * \li Orbee, a USB connected RGB Orb for notifications: http://www.franksworkshop.com.au/Electronics/Orbee/Orbee.htm + * \li PPM signal generator over USB: https://github.com/G33KatWork/USBPPM + * \li Programmable keyboard controller: http://41j.com/blog/2011/10/a-programmable-keyboard-controller/ + * \li Programmable XBOX controller: http://richard-burke.dyndns.org/wordpress/pan-galactic-gargantuan-gargle-brain-aka-xbox-360-usb-controller/ + * \li PSGroove, a Playstation 3 Homebrew dongle: http://github.com/psgroove + * \li PS/2 to USB adapter: https://github.com/makestuff/p2ukbd + * \li Reprap with LUFA, a LUFA powered 3D printer: http://code.google.com/p/at90usb1287-code-for-arduino-and-eclipse/ + * \li RFPirate, a RF experimentation platform: https://github.com/ebuller/RF-Pirate + * \li RF Transciever using the MRF49XA: http://alternet.us.com/?page_id=1494 + * \li SD Card reader: http://elasticsheep.com/2010/04/teensy2-usb-mass-storage-with-an-sd-card/ + * \li SDR1, a Software Defined Radio firmware: https://code.google.com/p/sdr-mk1/ + * \li SEGA Megadrive/Genesis Development Cartridge: http://www.makestuff.eu/wordpress/?page_id=398 + * \li Serial Line bus analyser: http://www.pjrc.com/teensy/projects/SerialAnalyzer.html + * \li SNES custom FLASH ROM: http://electrifiedfoolingmachine.co/?page_id=633 + * \li Smartcard Detective: https://code.google.com/p/smartcarddetective/ + * \li SmartportVHD Apple II Mass Storage adapter: http://pcedric3.free.fr/SmartportVHD/ + * \li Single LED Matrix Display: http://guysoft.wordpress.com/2009/10/08/bumble-b/ + * \li Simple USB LED Controller: https://github.com/scottbez1/sulc + * \li Stripe Snoop, a Magnetic Card reader: http://www.ossguy.com/ss_usb/ + * \li Stylophone, with USB MIDI connectivity: http://www.waitingforfriday.com/index.php/Stylophone_Studio_5 + * \li Teensy SD Card .WAV file player: http://elasticsheep.com/2010/04/teensy2-usb-wav-player-part-1/ + * \li Touchscreen Input Device: http://capnstech.blogspot.com/2010/07/touchscreen-update.html + * \li UDFS, a BBC Micro USB disk filing system: https://github.com/makestuff/udfs + * \li Universal USB AVR Module: http://usbavr.bplaced.net/ + * \li USB2AX, a USB to Dynamixel network adapter: http://paranoidstudio.assembla.com/wiki/show/paranoidstudio/USB2AX + * \li USB Infrared Receiver/Transmitter: http://vaton4.web2001.cz/ + * \li USB Interface for Playstation Portable Devices: http://forums.ps2dev.org/viewtopic.php?t=11001 + * \li USB MIDI to DMX controller: http://github.com/hanshuebner/miDiMX + * \li USB powered Geiger Counter: http://uhrheber.wordpress.com/2011/04/28/a-usb-powered-geiger-counter-for-the-z2-and-other-computers/ + * \li Userial, a USB to Serial converter with SPI, I2C and other protocols: http://www.tty1.net/userial/ + * \li Wireless MIDI Guitar system: http://www.ise.pw.edu.pl/~wzab/wireless_guitar_system/ + * \li Xnormidi, a C MIDI library: http://x37v.info/projects/xnormidi + * \li XUM1541, a Commodore 64 floppy drive to USB adapter: http://www.root.org/~nate/c64/xum1541/ + * \li Zeus, a touch screen computer for music manipulation: http://www.benbengler.com/developments_zeus.html + * + * \section Sec_LUFACommercialProjects Projects Using LUFA (Commercial) + * + * The following is a list of known commercial products using LUFA. Some of these are open source, although many are "black-box" + * solutions with no source code given. Those companies which have purchased a Commercial License to LUFA (see \ref Page_LicenseInfo) + * are not listed here unless specifically requested. + * + * \li Arduino Uno, the official Arduino board: http://www.arduino.cc + * \li ARPS Locator: http://la3t.hamradio.no/lab//?id=tracker_en + * \li AsTeRICS assistive technologies project, HID actuator: http://www.asterics.eu + * \li Ceberus, a MadCatz Xbox 360 arcade stick modifier: http://www.phreakmods.com/products/cerberus + * \li CFFA3000, a CompactFlash interface for the Apple II: http://www.dreher.net/CFforAppleII + * \li Digital Survey Instruments Magnetometer and Pointer: http://www.digitalsurveyinstruments.com/ + * \li FinchRobot, a robot designed for educational use: http://www.finchrobot.com/ + * \li HummingBird Kit, a robotics learning platform: http://www.hummingbirdkit.com/ + * \li Penguino, an Arduino Board With On-Board LUFA Powered Debugger/Programmer: http://wiki.icy.com.au/PenguinoAVR + * \li PIR-1, an IR control interface for consumer electronics: http://www.promixis.com/pir-1.php + * \li PIR-4, a USB Connected 4 port IR transmitter: http://promixis.com/pir-4.php + * \li KeyGlove, an alternative input system: http://www.keyglove.net/ + * \li Many of Busware's Products: http://www.busware.de/ + * \li MIDIFighter, a USB-MIDI controller: http://www.midifighter.com/ + * \li Norduino, a wireless Arduino: http://norduino.robomotic.com/norduino-is-now-usb-hid/ + * \li Olimex AVR-ISP-MK2, an AVRISP-MKII Clone AVR Programmer: https://www.olimex.com/dev/avr-isp-mk2.html + * \li Retrode, a USB Games Console Cartridge Reader: http://www.retrode.org + * \li RFI21.1EU UHF RFID reader: http://www.metra.cz/rfid/uhf-rfid-ctecky/rfi21-1eu-uhf-rfid-ctecka.htm + * \li SmartCardDetective, a Smart Card analysis tool: http://www.smartcarddetective.com/ + * \li USBTINY-MKII, an AVRISP-MKII Clone AVR Programmer: http://tom-itx.dyndns.org:81/~webpage/boards/USBTiny_Mkii/USBTiny_Mkii_index.php + * \li UDS18B20 USB Temperature sensor: http://toughlog.org/uds18b20/ + * \li VMeter, a USB MIDI touch strip controller: http://www.vmeter.net/ + * \li XMEGA Development Board, using LUFA as an On-Board Programmer: http://xmega.mattair.net/ + * \li Zeptoprog, a multifunction AVR programmer: http://www.mattairtech.com/index.php/featured/zeptoprog.html + * + * \section Sec_LUFAPublications Publications Mentioning LUFA + * The following are published magazines which have either mentioned or featured the LUFA library. + * + * \li Elektor Magazine, "My First AVR-USB" by Antoine Authier (feature), January 2010 Issue + * \li Elektor Magazine, "USB is Cool/Sucks" by Jerry Jacobs and Chris Vossen (minor mention), January 2010 Issue + * \li Elektor Magazine, "20 x Open Source" by Jens Nickel, March 2010 Issue + * \li Circuit Cellar Magazine, "Advanced USB Design Debugging" by Collin O'Flynn, August 2010 Issue + * + * \section Sec_LUFANotableMentions Other Notable Mentions of LUFA + * The following are non-magazine but notable mentions of the LUFA library. + * + * \li Adafruit "Ask an Engineer", 7th November 2010 + * \li Arduino 2010 Keynote speech + * \li The Amp Hour podcast blog #11 + * \li Blackhat 2011 conference, "Exploiting USB Devices with Arduino" + * + * \section Sec_PortsAndForks Non-Official LUFA Ports and Forks + * The following are unofficial forks of the LUFA codebase, which implement different features such as support for + * additional architectures. + * + * \li NXP's official "nxpusblib" LUFA fork, for LPC devices: http://www.lpcware.com/content/project/nxpusblib + * \li Kevin Mehall's LUFA port to the NXP LPC13xx: https://github.com/kevinmehall/LUFA-LPC13xx + * + */ diff --git a/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/LibraryResources.txt b/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/LibraryResources.txt new file mode 100644 index 00000000..a85d59c1 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/LibraryResources.txt @@ -0,0 +1,34 @@ +/** \file + * + * This file contains special DoxyGen information for the generation of the main page and other special + * documentation pages. It is not a project source file. + */ + +/** + * \page Page_Resources Library Resources + * + * \section Sec_UnofficialResources Unofficial Resources + * Unofficial Russian LUFA documentation translation: http://microsin.ru/Download.cnt/doc/LUFA/ \n + * Tutorial for LUFA USB Control Transfers: http://www.avrbeginners.net/new/tutorials/usb-control-transfers-with-lufa/ + * + * \section Sec_ProjectPages LUFA Related Webpages + * Project Homepage: http://www.lufa-lib.org \n + * Commercial Licenses: http://www.lufa-lib.org/license \n + * Author's Website: http://www.fourwalledcubicle.com \n + * Development Blog: http://www.fourwalledcubicle.com/blog \n + * + * \section Sec_ProjectHelp Assistance With LUFA + * Support Mailing List: http://www.lufa-lib.org/support \n + * Author's Email: dean [at] fourwalledcubicle [dot] com \n + * + * \section Sec_InDevelopment Latest In-Development Source Code + * Issue Tracker: http://www.lufa-lib.org/tracker \n + * Public SVN Repository: http://www.lufa-lib.org/svn \n + * Public GIT Repository: http://www.lufa-lib.org/git \n + * Latest Repository Source Archive: http://www.lufa-lib.org/latest-archive \n + * Commit RSS Feed: http://www.lufa-lib.org/rss \n + * + * \section Sec_USBResources USB Resources + * USB-IF Website: http://www.usb.org \n + */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/LicenseInfo.txt b/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/LicenseInfo.txt new file mode 100644 index 00000000..091ce943 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/LicenseInfo.txt @@ -0,0 +1,22 @@ +/** \file + * + * This file contains special DoxyGen information for the generation of the main page and other special + * documentation pages. It is not a project source file. + */ + +/** + * \page Page_LicenseInfo Source Code License + * + * The LUFA library is currently released under the MIT license, included below. + * + * Commercial entities can opt out of the public disclosure clause in this license + * for a one-time US$1500 payment. This provides a non-exclusive modified MIT licensed which + * allows for the free use of the LUFA library, bootloaders and (where the sole copyright + * is attributed to Dean Camera) demos without public disclosure within an organization, in + * addition to three free hours of consultation with the library author, and priority support. + * Please visit the Commercial License link on \ref Page_Resources for more information on + * ordering a commercial license for your company. + * + * \verbinclude License.txt + */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/MainPage.txt b/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/MainPage.txt new file mode 100644 index 00000000..ce351ad3 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/MainPage.txt @@ -0,0 +1,52 @@ +/** \file + * + * This file contains special DoxyGen information for the generation of the main page and other special + * documentation pages. It is not a project source file. + */ + +/** + * \mainpage + * + * \image html Images/LUFA.png + *

+ * \n + * + * \n + * + * LUFA is donationware. For author and donation information, see \ref Page_Donating. + * + * LUFA is an open-source USB library for the USB-enabled AVR microcontrollers, released under the MIT license (see \ref Page_LicenseInfo). + * It supports a large number of USB AVR models and boards (see \ref Page_DeviceSupport). It is designed to provide an easy to use, + * feature rich framework for the development of USB peripherals and hosts. + * + * LUFA focuses on the microcontroller side of USB development only; it includes no PC host USB driver development facilities - other projects + * such as the Windows Driver Development Kit, Windows USB Device Mode Framework and libusb may be of interest for developing custom OS drivers. + * While custom USB devices can be made with LUFA using such tools, the included demos all use the inbuilt OS drivers for each USB class for + * simplicity. + * + * The library is currently in a stable release, suitable for download and incorporation into user projects for + * both host and device modes. For information about the project progression, see the blog link at \ref Page_Resources. + * + * LUFA is written specifically for the free AVR-GCC compiler, and uses several GCC-only extensions to make the + * library API more streamlined and robust. You can download AVR-GCC for free in a convenient windows package, + * from the the WinAVR website (see \ref Page_Resources). + * + * The only required AVR peripherals for LUFA is the USB controller itself and interrupts - LUFA does not require the use of the + * microcontroller's timers or other hardware, leaving more hardware to the application developer. + * + * Accompanying LUFA in the download package is a set of example demo applications, plus several Bootloaders of different classes + * and open source LUFA powered projects. + * + * Subsections: + * \li \subpage Page_LicenseInfo - Project source license and commercial use information + * \li \subpage Page_Donating - Donating to support this project + * \li \subpage Page_DeviceSupport - Current Device and Hardware Support + * \li \subpage Page_ChangeLog - Project Changelog + * \li \subpage Page_KnownIssues - Known Issues + * \li \subpage Page_FutureChanges - Planned Changes to the Library + * \li \subpage Page_GettingStarted - Getting started with LUFA + * \li \subpage Page_DevelopingWithLUFA - Developing with LUFA + * \li \subpage Page_LUFAPoweredProjects - Other Projects Using LUFA + * \li \subpage Page_Resources - LUFA and USB Related Resources + */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/MigrationInformation.txt b/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/MigrationInformation.txt new file mode 100644 index 00000000..7a08ad23 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/MigrationInformation.txt @@ -0,0 +1,674 @@ +/** \file + * + * This file contains special DoxyGen information for the generation of the main page and other special + * documentation pages. It is not a project source file. + */ + +/** \page Page_Migration Migrating from Older Versions + * + * Below is migration information for updating existing projects based on previous versions of the LUFA library + * to the next version released. It does not indicate all new additions to the library in each version change, only + * areas relevant to making older projects compatible with the API changes of each new release. + * + * \section Sec_Migration120730 Migrating from 120219 to 120730 + * Device Mode + * - The device mode Audio Class driver now requires an additional configuration parameter, the Audio Control interface index. Existing applications should + * be adjusted to specify the additional configuration parameter. + * - The HID_DESCRIPTOR_JOYSTICK() macro no longer takes a variable number of axis as a parameter, due to OS incompatibilities; this macro now uses a fixed + * 3 axis of data. User applications should update their calls to this macro and their report structures to suit a fixed 3-axis joystick report. If a user + * application requires more than 3 axis' of data, a custom report descriptor will need to be constructed by hand. + * - The \ref Endpoint_ConfigureEndpoint() function no longer takes in masks for the banks and direction; the number of banks is now an integer argument, and + * the direction is obtained from the full endpoint address within the device. Applications calling Endpoint_ConfigureEndpoint() should update their API + * call to use a full endpoint address (including ENDPOINT_DIR_IN or ENDPOINT_DIR_OUT direction in the MSB of the endpoint address) and an integer number + * of banks. + * - All endpoint functions now operate on full endpoint addresses within the device, rather than a directionless endpoint index. Applications should update + * their API calls to use full endpoint addresses when required within the device. + * - All device mode class drivers have been updated to use a new unified endpoint description structure for all endpoints; existing applications will need + * to update their class driver struct instantiation to match the new scheme (see \ref USB_Endpoint_Table_t). + * - The \c ENDPOINT_BANKS_SUPPORTED() and \c ENDPOINT_MAX_ENDPOINT_SIZE() macros have been removed, as these do not function correctly with the new addressing + * scheme for the endpoint APIs. Please refer to the target device's datasheet for the maximum bank size of each endpoint. + * - The MIDI class driver \ref MIDI_EventPacket_t event packet no longer contains seperate \c CableIndex and \c Command entries; these have been combined + * into a single \c Event element which can be contructed using the new macro \ref MIDI_EVENT(). Existing applications should use the new macro and structure + * element name. + * + * Host Mode + * - The Android Accessory Host class driver property strings are now a array of \c char* rather than a struct of named pointers. Existing applications + * should use C99 Designated Initializers with the property string indexes located in \ref AOA_Strings_t instead. + * - The \ref Pipe_ConfigurePipe() function no longer takes in masks for the banks and token; the number of banks is now an integer argument, and the token + * is now inferred from the full pipe address within the device, and the pipe type. Applications calling Pipe_ConfigurePipe() should update their API + * call to use a full pipe address (including PIPE_DIR_IN or PIPE_DIR_OUT direction in the MSB of the pipe address) and an integer number of banks. + * - All pipe functions now operate on full pipe addresses within the device, rather than a directionless pipe index. Applications should update their API + * calls to use full pipe addresses when required within the device. + * - All host mode class drivers have been updated to use a new unified pipe description structure for all pipes; existing applications will need to update + * their class driver struct instantiation to match the new scheme (see \ref USB_Pipe_Table_t). + * - The MIDI class driver \ref MIDI_EventPacket_t event packet no longer contains seperate \c CableIndex and \c Command entries; these have been combined + * into a single \c Event element which can be contructed using the new macro \ref MIDI_EVENT(). Existing applications should use the new macro and structure + * element name. + * - The library "LUFA/Drivers/USB/Core/ConfigDescriptor.c" source file has been renamed "LUFA/Drivers/USB/Core/ConfigDescriptors.c" as this was clashing with + * files in some low level host mode demo applications, preventing parallel project builds. If you are referencing the project source files directly instead + * of using the makefile module names, you will need to adjust your project makefile. + * + * \section Sec_Migration120219 Migrating from 111009 to 120219 + * USB Core + * - The HID_KEYBOARD_MODIFER_* macros in the HID class driver have been corrected to HID_KEYBOARD_MODIFIER_* (note the spelling of "modifier"). + * Existing applications should switch over to the correctly spelled macro names. + * - The names of the USB Device and USB Host class driver files have changed; a new "ClassDevice" and "ClassHost" postfix has been added to the + * respective class driver files. Projects referencing the class driver source files by filename rather than the LUFA_SRC_USBCLASS makefile + * variable should append these postfixes to the source file names. Projects including the USB class driver dispatch headers directly should either + * switch to including the main USB driver header instead, or use the updated header filenames. + * - The USB_CONFIG_ATTR_BUSPOWERED constant has been renamed to USB_CONFIG_ATTR_RESERVED, as this was misnamed. All devices must set this bit in + * the Configuration descriptor's attributes field. As all devices are assumed to be bus-powered unless stated otherwise with the + * USB_CONFIG_ATTR_SELFPOWERED flag a replacement constant for bus powered devices is not provided. + * + * Device Mode + * - The device mode Audio class driver now requires a new user application callback, \ref CALLBACK_Audio_Device_GetSetInterfaceProperty(). + * Existing applications must implement this new callback, however if no audio entities are defined in the audio device's descriptors, + * this function may be hard-coded to always return false for previous behaviour to be retained. + * + * \section Sec_Migration111009 Migrating from 110528 to 111009 + * Non-USB Library Components + * - The \c JTAG_DEBUG_ASSERT() macro has been renamed \ref JTAG_ASSERT() to be consistent with \ref STDOUT_ASSERT(). + * + * USB Core + * - By default, unordered Endpoint and Pipe configuration is now allowed once again, via the previous workaround of + * reconfiguring all Endpoints/Pipes in order each time a new Endpoint/Pipe is created. To minimize the compiled program + * size, the new \c ORDERED_EP_CONFIG compile time option may be defined in the project makefile to restrict the ordering + * in exchange for a smaller compiled binary size. + * - The previous \c F_CLOCK symbol, required in the project makefile, has been renamed to \c F_USB. This is due to the previous name + * being far too generic for use in future architecture ports, where multiple clock domains are used. + * + * Device Mode + * - The Endpoint stream functions now all require a \c BytesProcessed parameter instead of the previous callback parameter. + * This should be set to \c NULL to retain previous behaviour of the functions, or point to a location where the number of bytes + * processed in the current transaction can be stored. If the \c BytesProcessed parameter is non \c NULL, each time the endpoint + * bank becomes full and the packet is sent, the routine will exit with the new \ref ENDPOINT_RWSTREAM_IncompleteTransfer + * error code to allow the user application to determine when to send the next chunk of data. + * - The \ref CDC_Device_SendString() function now expects a null terminated string instead of an explicit length. Existing code + * should use the new \ref CDC_Device_SendData() function, or remove the length parameter from the function call. + * - The \c Endpoint_ResetFIFO() function has been renamed to \ref Endpoint_ResetEndpoint(), to make the API function names more + * consistent. Existing applications using the old function name should simply replace it with a call to the new function name. + * - The \c Endpoint_*_Byte() functions have been renamed Endpoint_*_8() to ensure they are correct across all architectures. Existing + * code using these functions should replace the previous function names with the new function names. + * - The \c Endpoint_*_Word() functions have been renamed Endpoint_*_16() to ensure they are correct across all architectures. Existing + * code using these functions should replace the previous function names with the new function names. + * - The \c Endpoint_*_DWord() functions have been renamed Endpoint_*_32() to ensure they are correct across all architectures. Existing + * code using these functions should replace the previous function names with the new function names. + * - The Device mode RNDIS class driver no longer stores the incoming and outgoing packets in the class driver instance; the user is + * now expected to manually define a storage location for the packet data. Packets must now be sent and received manually via a call + * to \ref RNDIS_Device_ReadPacket() and/or \ref RNDIS_Device_SendPacket(). + * - The definition of the Audio class \ref USB_Audio_Descriptor_Format_t has been altered, to remove the fixed singular + * audio sample rate in the descriptor definition, and to rename the \c SampleFrequencyType to the more appropriate + * \c TotalDiscreteSampleRates. Existing applications will need to add an array of \ref USB_Audio_SampleFreq_t elements + * immediately following any \ref USB_Audio_Descriptor_Format_t descriptors, and insert the appropriate sampling rates + * supported by the device, as well as rename the descriptor elements to match the updated element names. + * - The device mode Audio class driver now requires a new user application callback, \ref CALLBACK_Audio_Device_GetSetEndpointProperty(). + * Existing applications must implement this new callback, however if multiple sample rates or pitch control is not used, + * this function may be hard-coded to always return false for previous behaviour to be retained. + * - The \c USB_ConfigurationNumber, \c USB_RemoteWakeupEnabled and \c USB_CurrentlySelfPowered globals have been renamed to + * \ref USB_Device_ConfigurationNumber, \ref USB_Device_RemoteWakeupEnabled and \ref USB_Device_CurrentlySelfPowered to clearly indicate + * the USB mode they relate to. Existing applications using these variables should rename all references to the previous names. + * - The \c ENDPOINT_DESCRIPTOR_DIR_IN and \c ENDPOINT_DESCRIPTOR_DIR_OUT macros have now been replaced by \ref ENDPOINT_DIR_IN and + * \ref ENDPOINT_DIR_OUT to improve code clarity. + * - The \ref HID_DESCRIPTOR_JOYSTICK() macro now takes an additional (first) parameter indicating the number of axis in the joystick. + * + * Host Mode + * - The Pipe stream functions now all require a \c BytesProcessed parameter instead of the previous callback parameter. + * This should be set to \c NULL to retain previous behaviour of the functions, or point to a location where the number of bytes + * processed in the current transaction can be stored. If the BytesProcessed parameter is non \c NULL, each time the pipe + * bank becomes full and the packet is sent, the routine will exit with the new \ref PIPE_RWSTREAM_IncompleteTransfer + * error code to allow the user application to determine when to send the next chunk of data. + * - The \ref PRNT_Host_SendString() and \ref CDC_Host_SendString() functions now expect a null terminated string instead of an explicit + * length. Existing code should use the new \ref PRNT_Host_SendData() and \ref CDC_Host_SendData() functions, or remove the + * length parameter from the function call. + * - The \c Pipe_ClearErrorFlags() function has been removed, as the pipe error flags are now automatically cleared when the + * \ref Pipe_ClearError() function is called. + * - The \c Pipe_*_Byte() functions have been renamed Pipe_*_8() to ensure they are correct across all architectures. Existing code using + * these functions should replace the previous function names with the new function names. + * - The \c Pipe_*_Word() functions have been renamed Pipe_*_16() to ensure they are correct across all architectures. Existing code using + * these functions should replace the previous function names with the new function names. + * - The \c Pipe_*_DWord() functions have been renamed Pipe_*_32() to ensure they are correct across all architectures. Existing code using + * these functions should replace the previous function names with the new function names. + * - The \c USB_Host_ClearPipeStall() function has been renamed to USB_Host_ClearEndpointStall(), as it operates on a full endpoing address + * within the attached device and not a pipe within the host. Existing code using the old function name should update the function calls and + * check for correct usage. + * + * \section Sec_Migration101122 Migrating from 100807 to 101122 + * USB Core + * - A new USB driver source file, \c Drivers/USB/HighLevel/EndpointStream.c now exists. This source file should be added + * to all project makefiles using the USB driver of LUFA, or the makefile should be updated to use the new module source + * variables. + * - A new USB driver source file, \c Drivers/USB/HighLevel/PipeStream.c now exists. This source file should be added to all + * project makefiles using the USB driver of LUFA, or the makefile should be updated to use the new module source variables. + * - The \c EVENT_USB_InitFailure() event has been removed, as the \ref USB_Init() function will no longer fail; if not USB mode is + * specified, the controller will default to UID selection mode. + * - The USB mode specifier constants have been moved into a new enum and renamed. Existing projects should use the equivalent + * value in the new \ref USB_Modes_t enum. + * - All class driver headers are now included as part of the standard \c LUFA/Drivers/USB/USB.h master dispatch header, and should + * no longer be included separately. Class driver module source files must still be added as a separate module in the project's + * makefile if used. + * + * Device Mode + * - Endpoints MUST be allocated in ascending order to ensure that bank corruption does not occur. Ensure that your user application + * allocated endpoints in ascending order - or if your application uses the USB device mode class drivers, ensure that each instance's + * endpoint indexes are not overlapped with other interface's endpoints. + * - The signature for the \ref CALLBACK_USB_GetDescriptor() callback has changed, the \c void** \c const \c DescriptorAddress parameter is + * now \c const \c void** \c const \c DescriptorAddress. Existing applications should update their callback signatures to match this, and + * eliminate any casting of descriptor pointers to a non \c const pointer. + * - The names of the class specific descriptor type defines in the USB Class drivers have changed - refer to the driver documentation + * for each class driver for the new class specific descriptor type names. + * - The \c ENDPOINT_DOUBLEBANK_SUPPORTED() macro is has been renamed \c ENDPOINT_BANKS_SUPPORTED() and now returns the total number of + * banks supported by the given endpoint. Existing code should switch to the new naming scheme, and test that the return value of the + * macro is equal to or greater than 2 to regain the previous functionality. + * - The \c EVENT_USB_Device_UnhandledControlRequest() event is now named \ref EVENT_USB_Device_ControlRequest() and fires before (not after) + * the internal library event handlers. Existing code should rename the event handlers in the user application to match the new event + * name, and should ensure that the new execution order does not affect the application's operation. + * + * Host Mode + * - Pipes MUST be allocated in ascending order to ensure that bank corruption does not occur. Ensure that your user application + * allocated pipes in ascending order - or if your application uses the USB host mode class drivers, ensure that each instance's + * pipe indexes are not overlapped with other interface's pipes. + * - The \c PRNT_Host_SendData() function has been renamed to \ref PRNT_Host_SendString(). Existing applications should simply + * replace all references to the obsolete function name with the new function name. + * - The names of the class specific descriptor type defines in the USB Class drivers have changed - refer to the driver documentation + * for each class driver for the new class specific descriptor type names. + * - The Still Image Host class' function prefix has been changed from \c SImage_ to \c SI_, to remain consistent with the rest of the + * driver's enums, type defines and constants. + * + * \section Sec_Migration100807 Migrating from 100513 to 100807 + * + * Non-USB Library Components + * - The Dataflash board driver stub file has changed, as dataflash functions previously located in the internal + * Dataflash driver of the library have now been moved to the individual board files. Existing drivers can + * copy-paste the new functions from the board Dataflash stub driver. + * + * USB Core + * - A new USB driver source file, \c Drivers/USB/LowLevel/Device.c now exists. This source file should be added to all project + * makefiles using the USB driver of LUFA, or the makefile should be updated to use the new module source variables. + * - The \c Drivers/USB/LowLevel/DevChapter9.c source file has moved to \c Drivers/USB/HighLevel/DeviceStandardReq.c - this should + * be updated in all project makefiles, or the makefile should be updated to use the new module source variables. + * - The \c Drivers/USB/LowLevel/HostChapter9.h source file has moved to \c Drivers/USB/HighLevel/HostStandardReq.c - this should + * be updated in all project makefiles, or the makefile should be updated to use the new module source variables. + * - The \c Drivers/USB/LowLevel/LowLevel.c source file has moved to \c Drivers/LowLevel/USBController.c - this should be updated + * in all project makefiles, or the makefile should be updated to use the new module source variables. + * + * Device Mode + * - The \c USB_Device_IsRemoteWakeupSent() macro has been removed, as the remote wakeup request is now fully handled by the + * enhanced \ref USB_Device_SendRemoteWakeup() function. Existing code may now discard any checks to \c USB_Device_IsRemoteWakeupSent(). + * - The \c USB_Device_IsUSBSuspended() macro has been removed, as it is obsolete. Existing code should compare \ref USB_DeviceState + * to see if it the device is in the \ref DEVICE_STATE_Suspended state instead. + * - The \ref CDC_Device_ReceiveByte() function has changed, and now returns a signed 16-bit integer, with -1 indicating no data was + * received. This allows for more efficient coding, as a call to \ref CDC_Device_BytesReceived() is no longer needed if the exact + * number of queued bytes received is not needed. + * + * Host Mode + * - The \ref CDC_Host_ReceiveByte() function has changed, and now returns a signed 16-bit integer, with -1 indicating no data was + * received. This allows for more efficient coding, as a call to \ref CDC_Host_BytesReceived() is no longer needed if the exact + * number of queued bytes received is not needed. + * - The \ref CDC_Host_USBTask() now calls \ref CDC_Host_Flush() automatically, flushing any queued data to the attached device. Manual + * flushing of the interface is no longer needed if the flushes should be in sync with calls to \ref CDC_Host_USBTask(). + * + * \section Sec_Migration100513 Migrating from 100219 to 100513 + * + * Non-USB Library Components + * - The \ref TWI_StartTransmission() function now takes in a timeout period, expressed in milliseconds, within which the addressed + * device must respond or the function will abort. + * + * Device Mode + * - The \ref USB_Init() function no longer calls \c sei() to enable global interrupts, as the user application may need + * to perform other initialization before it is ready to handle global interrupts. The user application is now responsible + * for enabling global interrupts before or shortly after calling \ref USB_Init() to ensure that the enumeration process + * functions correctly. + * - The \c USBInterrupt.c USB driver source file has been relocated from \c LUFA/Drivers/USB/HighLevel/ to \c LUFA/Drivers/USB/LowLevel. + * Projects must update their makefile SRC values accordingly. + * - The HID Device Class driver's function signature for the \ref CALLBACK_HID_Device_ProcessHIDReport() function has been changed, to + * allow for a new \c ReportType parameter. This new parameter must be added in all user applications using the Device mode HID Class + * Driver, but may be ignored unless Host-to-Device FEATURE HID reports are used. + * + * Host Mode + * - The \ref USB_Init() function no longer calls \c sei() to enable global interrupts, as the user application may need + * to perform other initialization before it is ready to handle global interrupts. The user application is now responsible + * for enabling global interrupts before or shortly after calling \ref USB_Init() to ensure that the enumeration process + * functions correctly. + * - The \c USBInterrupt.c USB driver source file has been relocated from \c LUFA/Drivers/USB/HighLevel/ to \c LUFA/Drivers/USB/LowLevel. + * Projects must update their makefile \c SRC values accordingly. + * - The HID Host Class driver's function signature for the \ref HID_Host_SendReportByID() function has been changed, to allow for a new + * ReportType parameter. Existing calls to this function should substitute \c REPORT_ITEM_TYPE_Out as this parameter's value. + * + * \section Sec_Migration100219 Migrating from 091223 to 100219 + * + * Non-USB Library Components + * - Due to some ADC channels not being identical to their ADC MUX selection masks for single-ended conversions on some AVR models, + * the ADC driver now has explicit masks for each of the standard ADC channels (see \ref Group_ADC). These masks should be used + * when calling the ADC functions to ensure proper operation across all AVR models. Note that the \ref ADC_SetupChannel() function + * is an exception, and should always be called with a channel number rather than a channel mask. + * + * Host Mode + * - The MIDI Host Class driver send and receive routines now operate on packed events, where multiple MIDI events may be + * packed into a single USB packet. This means that the sending of MIDI events will now be delayed until the MIDI send + * pipe bank is full. To override this new behaviour and revert to the previous behaviour, the user application may manually + * flush the queued event(s) to the device by calling \ref MIDI_Host_Flush(). + * - The \ref Pipe_IsEndpointBound() function now takes the endpoint's direction into account, by checking if the MSB of the endpoint's address + * is set to denote IN endpoints. If the previous functionality where the direction is to be discounted is required, mask the endpoint + * address against the \ref PIPE_EPNUM_MASK token before calling \ref Pipe_IsEndpointBound(). + * + * Device Mode + * - The MIDI Device Class driver send and receive routines now operate on packed events, where multiple MIDI events may be + * packed into a single USB packet. This means that the sending of MIDI events will now be delayed until the MIDI send + * endpoint bank is full. To override this new behaviour and revert to the previous behaviour, the user application may manually + * flush the queued event(s) to the host by calling \ref MIDI_Device_Flush(). + * + * \section Sec_Migration091223 Migrating from 091122 to 091223 + * + * Host Mode + * - The Still Image Host Class driver \ref SI_Host_USBTask() and \ref SI_Host_ConfigurePipes() functions were misnamed, and are + * now named \c SImage_Host_USBTask() and \c SImage_Host_ConfigurePipes() respectively. + * - The \c HOST_SENDCONTROL_DeviceDisconnect enum value has been renamed to \ref HOST_SENDCONTROL_DeviceDisconnected to be in + * line with the rest of the library error codes. + * - The HID Parser item usages no longer contain separate minimum and maximum values, as this was a violation of the HID + * specification. Instead, the values are distributed evenly across each item as its usage value, to ensure that all items + * can be distinguished from one-another. + * + * Device Mode + * - The \ref CALLBACK_HID_Device_CreateHIDReport() HID Device Class driver callback now has a new \c ReportType parameter to + * indicate the report type to generate. Existing applications may simply add and ignore this additional parameter. + * + * \section Sec_Migration091122 Migrating from 090924 to 091122 + * + * Host Mode + * - The \c HID_PARSE_UsageStackOverflow HID parser error constant is now named \ref HID_PARSE_UsageListOverflow + * - The \ref CALLBACK_HIDParser_FilterHIDReportItem() HID Parser callback now passes a complete \ref HID_ReportItem_t to the + * user application, instead of just its attributes. + * - The \c USB_GetDeviceConfigDescriptor() function was incorrectly named and is now called \ref USB_Host_GetDeviceConfigDescriptor(). + * + * \section Sec_Migration090924 Migrating from 090810 to 090924 + * + * Non-USB Library Components + * - The \c ADC_Off() function has been renamed to \c ADC_ShutDown() to be consistent with the rest of the library. + * - The \ref SPI_Init() routine's parameters have changed, so that the clock polarity and data sampling modes can be set. See + * the \ref SPI_Init() function documentation for more details + * - The \ref Dataflash_Init() routine no longer initializes the SPI bus - the SPI bus should be initialized manually via a + * call to \ref SPI_Init() before using the Dataflash driver + * + * Host Mode + * - The \c USB_GetDeviceConfigDescriptor() function's parameters and behaviour has changed; the user is required to + * preallocate the largest allowable buffer, and pass the size of the buffer to the function. This allows for a single + * call to the function to retrieve, size check and validate the Configuration Descriptor rather than having the user + * application perform these intermediary steps. + * - The HID report parser now requires a mandatory callback in the user code, to filter only the items the application + * is interested in into the processed HID report item structure to save RAM. See \ref CALLBACK_HIDParser_FilterHIDReportItem(). + * - The HID report parser now always parses FEATURE and always ignores constant-data items - the \c HID_ENABLE_FEATURE_PROCESSING + * and \c HID_INCLUDE_CONSTANT_DATA_ITEMS compile time tokens now have no effect. + * - The \c USE_NONSTANDARD_DESCRIPTOR_NAMES compile time token has been removed - there are now separate \c USB_Descriptor_* + * and \c USB_StdDescriptor_* structures for both the LUFA and standardized element naming conventions so that both may be used in + * the one project. For existing projects using the standardized names, change all code to use the \c USB_StdDescriptor_* variants. + * + * Device Mode + * - The \c USE_NONSTANDARD_DESCRIPTOR_NAMES compile time token has been removed - there are now separate \c USB_Descriptor_* + * and \c USB_StdDescriptor_* structures for both the LUFA and standardized element naming conventions so that both may be used in + * the one project. For existing projects using the standardized names, change all code to use the \c USB_StdDescriptor_* variants. + * + * \section Sec_Migration090810 Migrating from 090605 to 090810 + * + * All + * - The "Simple Scheduler" has been deprecated, as it was little more than an abstracted loop and caused much confusion. + * User applications using the scheduler should switch to regular loops instead. The scheduler code will be removed in a future + * release. + * - The "Dynamic Memory Block Allocator" has been removed, as it was unused in (and unrelated to) the LUFA library and never + * used in user applications. + * + * Non-USB Library Components + * - The \c ATTR_NOINLINE function attribute macro has been renamed to \ref ATTR_NO_INLINE to be in line with the rest of the function attribute + * macro names. + * + * Library Demos + * - Most demos now have a corresponding Class Driver implementation, which uses the new internal library class drivers for the standard + * USB classes. This allows for more rapid device and host development, and so should be used in preference to the low level APIs where + * possible so that fixes to the class drivers propagate to all applications which use them automatically with each new LUFA release. + * + * Host Mode + * - The \c HIDParser.c module has moved from \c LUFA/Drivers/USB/Class/ to \c LUFA/Drivers/USB/Class/Host/. + * - The \c USB_GetDeviceConfigDescriptor() function now requires the desired configuration index within the device as its first + * parameter, to add support for multi-configuration devices. Existing code should use a configuration index of 1 to indicate the + * first configuration descriptor within the device. + * - The non-standard "Ready" host state has been removed. Existing \ref HOST_STATE_Configured code should be moved to the end of + * the existing \ref HOST_STATE_Addressed state, and the existing HOST_STATE_Ready state code should be moved to the \ref HOST_STATE_Configured + * state. + * - The \c USB_IsConnected global has been removed, as it is too vague for general use. Test \ref USB_HostState explicitly to ensure the host is + * in the desired state instead. + * - The USB event names have been changed and their firing conditions changed to properly separate out Host mode events from Device mode + * events. See the \ref Group_Events page for details on the new event names and firing conditions. + * + * Device Mode + * - The \ref CALLBACK_USB_GetDescriptor() function now takes an extra parameter to specify the descriptor's memory space so that + * descriptors in mixed memory spaces can be used. The previous functionality can be returned by defining the \c USE_FLASH_DESCRIPTORS + * token in the project makefile to fix all descriptors into FLASH space and remove the extra function parameter. + * - The \c USB_IsSuspended global has been removed - test \ref USB_DeviceState against \ref DEVICE_STATE_Suspended instead. + * - The \c USB_IsConnected global has been removed, as it is too vague for general use. Test \ref USB_DeviceState explicitly to ensure the device + * is in the desired state instead. + * - The VBUS events have been removed, as they are already exposed to the user via the \c USB_Connect and \c USB_Disconnect events. + * - The USB event names have been changed and their firing conditions changed to properly separate out Host mode events from Device mode + * events. See the \ref Group_Events page for details on the new event names and firing conditions. + * + * \section Sec_Migration090605 Migrating from 090510 to 090605 + * + * Device Mode + * - Support for non-control data endpoint interrupts has been dropped due to many issues in the implementation. All existing + * projects using interrupts on non-control endpoints should switch to polling. For control interrupts, the library can + * manage the control endpoint via interrupts automatically by compiling with the \c INTERRUPT_CONTROL_ENDPOINT token defined. + * - The \c DESCRIPTOR_ADDRESS() macro has been removed. User applications should use normal casts to obtain a descriptor's memory + * address. + * - The library events system has been rewritten, so that all macros have been removed to allow for clearer user code. See + * \ref Group_Events for new API details. + * - The \c STREAM_CALLBACK() macro has been removed. User applications should replace all instances of the macro with regular + * function signatures of a function accepting no arguments and returning a \c uint8_t value. + * - The \c Event_DeviceError() event no longer exists, as its sole caller (unlinked \c USB_GetDescriptor() function) now produces a + * compilation error rather than a runtime error. The \c StdDescriptors.c file no longer exists as a result, and should be removed + * from project makefiles. + * - The \c USB_GetDescriptor() function has been renamed to \ref CALLBACK_USB_GetDescriptor() to be in line with the new \c CALLBACK_ + * function prefixes for functions which must be implemented in the user application. + * + * Host Mode + * - Support for non-control data pipe interrupts has been dropped due to many issues in the implementation. All existing + * projects using interrupts on non-control pipes should switch to polling. + * - The library events system has been rewritten, so that all macros have been removed to allow for clearer user code. See + * \ref Group_Events for new API details. + * - The \c STREAM_CALLBACK() macro has been removed. User applications should replace all instances of the macro with regular + * function signatures of a function accepting no arguments and returning a \c uint8_t value. + * - The \c DESCRIPTOR_COMPARATOR() macro has been removed. User applications should replace all instances of the macro with + * regular function signatures of a function accepting a void pointer to the descriptor to test, and returning a \c uint8_t value. + * + * \section Sec_Migration090510 Migrating from 090401 to 090510 + * + * All + * - The \c ButtLoadTag.h header has been removed, as it was never used for its intended purpose. Projects should either remove all + * \c BUTTLOADTAG() elements, or download and extract \c ButtLoadTag.h header from the ButtLoad project. + * - The \c Drivers/AT90USBXXX/ directory has been renamed to \c Drivers/Peripheral/. + * - The \c Serial_Stream driver has been renamed to \c SerialStream to remain consistent with the rest of the library naming scheme. + * - The HWB driver has changed to the \c Buttons driver. See the board Buttons driver documentation for the new API. + * + * Dual Role Mode + * - The \c USB_PowerOnFail event has been renamed to \c USB_InitFailure. + * - The functions in \c OTG.h have been renamed to remain more consistent with the library API. See the functions in \c OTG.h for more + * details. + * + * Device Mode + * - The \c Endpoint_ClearCurrentBank() macro has been removed, and is now replaced with the \ref Endpoint_ClearIN(), \ref Endpoint_ClearOUT() + * macros. See \c Endpoint.h documentation for more details on the new endpoint management macros. + * - The \c Endpoint_ReadWriteAllowed() macro has been renamed to \ref Endpoint_IsReadWriteAllowed() to be more consistent with the rest of + * the API naming scheme. + * - The \c Endpoint_IsSetupINReady() and \c Endpoint_IsSetupOUTReceived() macros have been renamed to \ref Endpoint_IsINReady() and + * \ref Endpoint_IsOUTReceived() respectively. + * - The \c Endpoint_IsSetupReceived() macro has been renamed to \ref Endpoint_IsSETUPReceived(). + * - The \c Endpoint_ClearSetupReceived() macro has been renamed to \ref Endpoint_ClearSETUP(). + * - All endpoint read/write/discard aliases which did not have an explicitly endianness specifier (such as \c Endpoint_Read_Word()) have + * been removed for clarity. Existing projects should use the \c _LE suffix on such calls to use the explicit Little Endian versions. + * - The \c USB_UnhandledControlPacket event no longer has any parameters. User code should no longer attempt to read in the remainder of + * the Control Request header as all Control Request header data is now preloaded by the library and made available in the + * USB_ControlRequest structure. + * - The \c FEATURELESS_CONTROL_ONLY_DEVICE token has been renamed to \c CONTROL_ONLY_DEVICE. + * - The \c STATIC_ENDPOINT_CONFIGURATION is no longer applicable as the library will apply this optimization when appropriate automatically. + * - The values of the \ref Endpoint_Stream_RW_ErrorCodes_t and \ref Endpoint_ControlStream_RW_ErrorCodes_t enums have had the \c ERROR_ portion + * of their names removed. + * + * Host Mode + * - The \ref USB_Host_SendControlRequest() function no longer automatically selects the Control pipe (pipe 0) to allow it to be used on + * other control type pipes. Care should be taken to ensure that the Control pipe is always selected before the function is called + * in existing projects where the Control pipe is to be operated on. + * - The USB Host management task now saves and restores the currently selected pipe before and after the task runs. Projects no longer + * need to manage this manually when calling the USB management task. + * - The \c Pipe_ClearCurrentBank() macro has been removed, and is now replaced with the Pipe_ClearIN(), Pipe_ClearOUT() macros. See + * Pipe.h documentation for more details on the new pipe management macros. + * - The \c Pipe_ReadWriteAllowed() macro has been renamed to \ref Pipe_IsReadWriteAllowed() to be more consistent with the rest of the API + * naming scheme. + * - The \c Pipe_IsSetupINReceived() and \c Pipe_IsOutReady() macros have been renamed to \ref Pipe_IsINReceived() and \ref Pipe_IsOUTReady() + * respectively. + * - The new \ref Pipe_ClearSETUP() macro should be used to send SETUP transactions, rather than the previous \c Pipe_ClearSetupOUT() macro. + * - The \c Pipe_IsSetupSent() macro has been renamed to \ref Pipe_IsSETUPSent(). + * - The \c Pipe_ClearSetupSent() macro is no longer applicable and should be removed. + * - All pipe read/write/discard aliases which did not have an explicitly endianness specifier (such as \c Pipe_Read_Word()) have + * been removed for clarity. Existing projects should use the \c _LE suffix on such calls to use the explicit Little Endian versions. + * - The \c Host_IsResetBusDone() macro has been renamed to \c Host_IsBusResetComplete(). + * - The \c Pipe_Ignore_Word() and \c Pipe_Ignore_DWord() functions have been renamed to \c Pipe_Discard_Word() and \c Pipe_Discard_DWord() + * to remain consistent with the rest of the pipe API. + * - It is no longer needed to manually include the headers from \c LUFA/Drivers/USB/Class, as they are now included along with the rest + * of the USB headers when \c LUFA/Drivers/USB/USB.h is included. + * - Functions in the \c ConfigDescriptor.h header file no longer have \c Host_ as part of their names. + * - The \c ProcessHIDReport() has been renamed to \ref USB_ProcessHIDReport(), \c GetReportItemInfo() has been renamed to \ref USB_GetHIDReportItemInfo() + * and \c SetReportItemInfo() has been renamed to \ref USB_GetHIDReportItemInfo(). + * - The values of the \ref DSearch_Return_ErrorCodes_t and \ref DSearch_Comp_Return_ErrorCodes_t enums have had their respective \c Descriptor_Search + * and \c Descriptor_Search_Comp prefixes changed to all caps. + * - The \c USB_HostRequest global has been renamed to \ref USB_ControlRequest, and is used in Device mode also. The \c USB_Host_Request_Header_t + * structure type has been renamed to \ref USB_Request_Header_t. + * - The values of the \ref Pipe_Stream_RW_ErrorCodes_t enum have had the \c ERROR_ portion of their names removed. + * + * \section Sec_Migration090401 Migrating from 090209 to 090401 + * + * All + * - LUFA projects must now give the raw input clock frequency (before any prescaling) as a compile time constant \c F_USB, + * defined in the project makefile and passed to the compiler via the -D switch. + * - The makefile EEPROM programming targets for FLIP and dfu-programmer no longer program in the FLASH data in addition to the + * EEPROM data into the device. If both are to be programmed, both the EEPROM and FLASH programming targets must be called. + * - As the avr-libc macro has been corrected in recent avr-libc distributions, the \c SetSystemClockPrescaler() macro has been removed. + * Include \c and call \c clock_prescale_set(clock_div_1); instead on recent avr-libc distributions. + * + * Library Demos + * - The USBtoSerial demo now discards all data when not connected to a host, rather than buffering it for later transmission. + * + * Non-USB Library Components + * - The \c ATTR_ALWAYSINLINE function attribute macro has been renamed to \ref ATTR_ALWAYS_INLINE. + * - Custom board Dataflash drivers now require the implementation of \ref Dataflash_SelectChipFromPage() and \ref Dataflash_SendAddressBytes(). + * + * Device Mode + * - The \c NO_CLEARSET_FEATURE_REQUEST compile time token has been renamed to \c FEATURELESS_CONTROL_ONLY_DEVICE, and its function expanded + * to also remove parts of the Get Status chapter 9 request to further reduce code usage. On all applications currently using the + * \c NO_CLEARSET_FEATURE_REQUEST compile time token, it can be replaced with the \c FEATURELESS_CONTROL_ONLY_DEVICE token with no further + * modifications required. + * + * \section Sec_Migration090209 Migrating from 081217 to 090209 + * + * Device Mode + * - The \c ENDPOINT_MAX_ENDPOINTS constant has been renamed to the more appropriate name of \c ENDPOINT_TOTAL_ENDPOINTS. + * - The \c USB_STREAM_TIMEOUT_MS stream timeout default period has been extended to 100ms. This can be overridden in the user + * makefile if desired to restore the previous 50ms timeout. + * + * Host Mode + * - The \c PIPE_MAX_ENDPOINTS constant has been renamed to the more appropriate name of \c PIPE_TOTAL_ENDPOINTS. + * - The \c USB_STREAM_TIMEOUT_MS stream timeout default period has been extended to 100ms. This can be overridden in the user + * makefile if desired to restore the previous 50ms timeout. + * - The \c USB_DeviceEnumerationFailed event now contains a second \c SubErrorCode parameter, giving the error code of the function + * which failed. + * - The \c HID_PARSE_Sucessful enum member constant name has been corrected to \ref HID_PARSE_Successful. + * + * Non-USB Library Components + * - The previous \c SPI_SendByte() functionality is now located in \ref SPI_TransferByte(). \ref SPI_SendByte() now discards the return byte + * for speed, to compliment the new \ref SPI_ReceiveByte() function. If bidirectional SPI transfers are required, calls to \ref SPI_SendByte() + * should be changed to \ref SPI_TransferByte(). + * - The serial driver now sets the Tx line as an output explicitly, and enables the pull-up of the Rx line. + * - The \ref Serial_Init() and \c SerialStream_Init() functions now take a second \c DoubleSpeed parameter, which indicates if the USART + * should be initialized in double speed mode - useful in some circumstances for attaining baud rates not usually possible at the given AVR + * clock speed. + * + * \section Sec_Migration171208 Migrating from V1.5.3 to 081217 + * + * All + * - The MyUSB project name has been changed to LUFA (Lightweight Framework for USB AVRs). All references to MyUSB, including macro names, + * have been changed to LUFA. + * + * Library Demos + * - The ReconfigureUSART() routine in the USBtoSerial demo was not being called after new line encoding + * parameters were set by the host. Projects built on the USBtoSerial code should update to the latest version. + * - The HID Parser now supports multiple report (on a single endpoint) HID devices. The MouseHostWithParser and + * KeyboardHostWithPaser demos use the updated API functions to function correctly on such devices. Projects + * built on either "WithParser" demo should update to the latest code. + * - The RNDIS demo TCP stack has been modified so that connections can be properly closed. It is still not + * recommended that the MyUSB RNDIS demo TCP/IP stack be used for anything other than demonstration purposes, + * as it is neither a full nor a standards compliant implementation. + * + * Non-USB Library Components + * - The Serial_IsCharReceived() macro has been changed to the correct spelling of Serial_IsCharReceived() in Serial.h. + * + * Device Mode + * - The MANUAL_PLL_CONTROL compile time token has been removed, and replaced with a USB_OPT_MANUAL_PLL mask + * to be used in the Options parameter of the USB_Init() function. + * - Calling USB_Init() now forces a complete USB interface reset and enumeration, even if the USB interface is + * currently initialized. + * - Interrupts are now disabled when processing control requests, to avoid problems with interrupts causing the library + * or user request processing code to exceed the strict USB timing requirements on control transfers. + * - The USB Reset event now resets and disables all device endpoints. If user code depends on endpoints remaining configured + * after a Reset event, it should be altered to explicitly re-initialize all user endpoints. + * - The prototype for the GetDescriptor function has been changed, as the return value was redundant. The function now + * returns the size of the descriptor, rather than passing it back via a parameter, or returns NO_DESCRIPTOR if the specified + * descriptor does not exist. + * - The NO_DESCRIPTOR_STRING macro has been renamed NO_DESCRIPTOR, and is now also used as a possible return value for the + * GetDescriptor function. + * + * Host Mode + * - The MANUAL_PLL_CONTROL compile time token has been removed, and replaced with a USB_OPT_MANUAL_PLL mask + * to be used in the Options parameter of the USB_Init() function. + * - The HID report parser now supports multiple Report IDs. The HID report parser GetReportItemInfo() and + * SetReportItemInfo() routines now return a boolean, set if the requested report item was located in the + * current report. If sending a report to a multi-report device, the first byte of the report is automatically + * set to the report ID of the given report item. + * - Calling USB_Init() now forces a complete USB interface reset and enumeration, even if the USB interface is + * currently initialized. + * + * \section Sec_Migration152 Migrating from V1.5.2 to V1.5.3 + * + * Library Demos + * - Previously, all demos contained a serial number string descriptor, filled with all zeros. A serial number + * string is required in Mass Storage devices, or devices which are to retain settings when moved between + * ports on a machine. As people were not changing the serial number value, this was causing conflicts and so + * the serial number descriptor has been removed from all but the Mass Storage demo, which requires it. + * - The AudioOut and AudioIn demos did not previously silence their endpoints when the host has deactivated + * them. Projects built upon either demo should upgrade to the latest code. + * - The FEATURE_ENDPOINT macro has been renamed FEATURE_ENDPOINT_HALT, and is now correctly documented. + * - The MassStoreHost demo contained errors which caused it to lock up randomly on certain devices. Projects built + * on the MassStoreDemo code should update to the latest version. + * - The Interrupt type endpoint in the CDC based demos previously had a polling interval of 0x02, which caused + * problems on some Linux systems. This has been changed to 0xFF, projects built on the CDC demos should upgrade + * to the latest code. + * - The HID keyboard and mouse demos were not previously boot mode compatible. To enable boot mode support, projects + * built on the keyboard or mouse demos (or derivatives) should upgrade to the latest code. + * - The Mass Storage demo was not previously standards compliant. Projects built on the Mass Storage demo should + * upgrade to the latest code. + * - The USART was not being reconfigured after the host sent new encoding settings in the USBtoSerial demo. This was + * previously discovered and fixed, but the change was lost. Projects built on the USBtoSerial demo should update + * to the latest code. + * + * Device Mode + * - The endpoint non-control stream functions now have a default timeout of 50ms between packets in the stream. + * If this timeout is exceeded, the function returns the new ENDPOINT_RWSTREAM_ERROR_Timeout error value. The + * timeout value can be overridden by defining the USB_STREAM_TIMEOUT_MS in the project makefile to the desired + * timeout duration in ms. + * - Rather than returning fixed values, the flags indicating if the device has Remote Wakeup currently enabled + * and/or is self-powered are now accessed and set through the new USB_RemoteWakeupEnabled and + * USB_CurrentlySelfPowered macros. See the DevChapter9.h documentation for more details. + * - All endpoint stream functions now require an extra Callback function parameter. Existing code may be updated + * to either supply NO_STREAM_CALLBACK as the extra parameter, or disable stream callbacks altogether by passing + * the token NO_STREAM_CALLBACKS to the compiler using the -D switch. + * + * Host Mode + * - The pipe non-control stream functions now have a default timeout of 50ms between packets in the stream. + * If this timeout is exceeded, the function returns the new PIPE_RWSTREAM_ERROR_Timeout error value. The + * timeout value can be overridden by defining the USB_STREAM_TIMEOUT_MS in the project makefile to the desired + * timeout duration in ms. + * - CollectionPath_t has been renamed to HID_CollectionPath_t to be more in line with the other HID parser structures. + * - All pipe stream functions now require an extra Callback function parameter. Existing code may be updated + * to either supply NO_STREAM_CALLBACK as the extra parameter, or disable stream callbacks altogether by passing + * the token NO_STREAM_CALLBACKS to the compiler using the -D switch. + * + * \section Sec_Migration151 Migrating from V1.5.1 to V1.5.2 + * + * Library Demos + * - The RNDIS demo application has been updated so that it is functional on Linux under earlier implementations + * of the RNDIS specification, which had non-standard behaviour. Projects built upon the demo should upgrade + * to the latest code. + * - The DFU class bootloader has had several bugs corrected in this release. It is recommended that where + * possible any existing devices upgrade to the latest bootloader code. + * + * \section Sec_Migration150 Migrating from V1.5.0 to V1.5.1 + * + * Library Demos + * - The USBtoSerial demo was broken in the 1.5.0 release, due to incorrect register polling in place of the + * global "Transmitting" flag. The change has been reverted in this release. Projects built upon the demo + * should upgrade to the latest code. + * - The HID class demos did not implement the mandatory GetReport HID class request. Projects built upon the HID + * demos should upgrade to the latest code. + * - The HID class demos incorrectly reported themselves as boot-protocol enabled HID devices in their descriptors. + * Projects built upon the HID demos should upgrade to the latest code. + * - The MIDI device demo had incorrect AudioStreaming interface descriptors. Projects built upon the MIDI demo + * should upgrade to the latest code. + * - The AudioOut demo did not correctly tristate the speaker pins when USB was disconnected, wasting power. + * Projects built upon the AudioOut demo should upgrade to the latest code. + * + * \section Sec_Migration141 Migrating from V1.4.1 to V1.5.0 + * + * Library Demos + * - Previous versions of the library demos had incorrectly encoded BCD version numbers in the descriptors. To + * avoid such mistakes in the future, the VERSION_BCD macro has been added to StdDescriptors.h. Existing + * projects should at least manually correct the BCD version numbers, or preferably update the descriptors to + * encode the version number in BCD format using the new macro. + * - The mandatory GetReport class-specific request was accidentally omitted from previous versions of the demos + * based on the Human Interface Device (HID) class. This has been corrected, and any user projects based on the + * HID demos should also be updated accordingly. + * - The CDC demos now correctly send an empty packet directly after a full packet, to end the transmission. + * Failure to do this on projects which always or frequently send full packets will cause buffering issues on + * the host OS. All CDC user projects are advised to update their transmission routines in the same manner as + * the library CDC demos. + * - The previous interrupt-driven Endpoint/Pipe demos did not properly save and restore the currently selected + * Endpoint/Pipe when the ISR fired. This has been corrected - user projects based on the interrupt driven + * demos should also update to properly save and restore the selected Endpoint/Pipe. + * + * Non-USB Library Components + * - The Atomic.h and ISRMacro.h header files in MyUSB/Common have been removed, as the library is now only + * compatible with avr-libc library versions newer than the time before the functionality of the deleted + * headers was available. + * + * Device Mode + * - The GetDescriptor function (see StdDescriptors.h) now has a new prototype, with altered parameter names and + * functions. Existing projects will need to update the GetDescriptor implementation to reflect the new API. + * The previously split Type and Index parameters are now passed as the original wValue parameter to the + * function, to make way for the USB specification wIndex parameter which is not the same as the + * previous Index parameter. + * - The USB_UnhandledControlPacket event (see Events.h) now has new parameter names, to be in line with the + * official USB specification. Existing code will need to be altered to use the new parameter names. + * - The USB_CreateEndpoints event (see Events.h) has been renamed to USB_ConfigurationChanged, which is more + * appropriate. It fires in an identical manner to the previously named event, thus the only change to be made + * is the event name itself in the user project. + * - The USB_Descriptor_Language_t structure no longer exists in StdDescriptors.h, as this was a + * pseudo-descriptor modeled on the string descriptor. It is replaced by the true USB_Descriptor_String_t type + * descriptor as indicated in the USB specification, thus all device code must be updated accordingly. + * - The names of several Endpoint macros have been changed to be more consistent with the rest of the library, + * with no implementation changes. This means that existing code can be altered to use the new macro names + * with no other considerations required. See Endpoint.h for the new macro names. + * - The previous version of the MassStorage demo had an incorrect value in the SCSI_Request_Sense_Response_t + * structure named SenseData in SCSI.c which caused some problems with some hosts. User projects based on this + * demo should correct the structure value to maintain compatibility across multiple OS platforms. + * - By default, the descriptor structures use the official USB specification names for the elements. Previous + * versions of the library used non-standard (but more verbose) names, which are still usable in the current + * and future releases when the correct compile time option is enabled. See the StdDescriptors.h file + * documentation for more details. + * + * Host Mode + * - The USB_Host_Request_Header_t structure in HostChapter9.h (used for issuing control requests) has had its + * members renamed to the official USB specification names for requests. Existing code will need to be updated + * to use the new names. + * - The names of several Pipe macros have been changed to be more consistent with the rest of the library, + * with no implementation changes. This means that existing code can be altered to use the new macro names + * with no other considerations required. See Pipe.h for the new macro names. + * - By default, the descriptor structures use the official USB specification names for the elements. Previous + * versions of the library used non-standard (but more verbose) names, which are still usable in the current + * and future releases when the correct compile time option is enabled. See the StdDescriptors.h file + * documentation for more details. + * - The names of the macros in Host.h for controlling the SOF generation have been renamed, see the Host.h + * module documentation for the new macro names. + * + * Dual Role Mode + * - The OTG.h header file has been corrected so that the macros now perform their stated functions. Any existing + * projects using custom headers to fix the broken OTG header should now be altered to once again use the OTG + * header inside the library. + * - The USB_DeviceEnumerationComplete event (see Events.h) now also fires in Device mode, when the host has + * finished enumerating the device. Projects relying on the event only firing in Host mode should be updated + * so that the event action only occurs when the USB_Mode global is set to USB_MODE_HOST. + */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/ProgrammingApps.txt b/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/ProgrammingApps.txt new file mode 100644 index 00000000..6ff18567 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/ProgrammingApps.txt @@ -0,0 +1,30 @@ +/** \file + * + * This file contains special DoxyGen information for the generation of the main page and other special + * documentation pages. It is not a project source file. + */ + +/** \page Page_ProgrammingApps Programming an Application into a USB AVR + * + * Once you have built an application, you will need a way to program in the resulting ".HEX" file (and, if your + * application uses EEPROM variables with initial values, also a ".EEP" file) into your USB AVR. Normally, the + * reprogramming of an AVR device must be performed using a special piece of programming hardware, through one of the + * supported AVR programming protocols - ISP, HVSP, HVPP, JTAG, dW or PDI. This can be done through a custom programmer, + * a third party programmer, or an official Atmel AVR tool - for more information, see the atmel.com website. + * + * Alternatively, you can use the bootloader. From the Atmel factory, each USB AVR comes preloaded with the Atmel + * DFU (Device Firmware Update) class bootloader, a small piece of AVR firmware which allows the remainder of the + * AVR to be programmed through a non-standard interface such as the serial USART port, SPI, or (in this case) USB. + * Bootloaders have the advantage of not requiring any special hardware for programming, and cannot usually be erased + * or broken without an external programming device. They have disadvantages however; they cannot change the fuses of + * the AVR (special configuration settings that control the operation of the chip itself) and a small portion of the + * AVR's FLASH program memory must be reserved to contain the bootloader firmware, and thus cannot be used by the + * loaded application. + * + * If you wish to use the DFU bootloader to program in your application, refer to your DFU programmer's documentation. + * Atmel provides a free utility called FLIP which is USB AVR compatible, and an open source (Linux compatible) + * alternative exists called "dfu-programmer". + * + * \see \ref Page_BuildModule_DFU for information on the LUFA build system DFU module, for automatic DFU bootloader + * programming makefile targets. + */ diff --git a/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/SoftwareBootloaderJump.txt b/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/SoftwareBootloaderJump.txt new file mode 100644 index 00000000..32846610 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/SoftwareBootloaderJump.txt @@ -0,0 +1,71 @@ +/** \file + * + * This file contains special DoxyGen information for the generation of the main page and other special + * documentation pages. It is not a project source file. + */ + +/** + * \page Page_SoftwareBootloaderStart Entering the Bootloader via Software + * + * A common requirement of many applications is the ability to jump to the programmed bootloader of a chip + * on demand, via the code's firmware (i.e. not as a result of any physical user interaction with the + * hardware). This might be required because the device does not have any physical user input, or simply + * just to streamline the device upgrade process on the host PC. + * + * The following C code snippets may be used to enter the bootloader upon request by the user application. + * By using the watchdog to physically reset the controller, it is ensured that all system hardware is + * completely reset to their defaults before the bootloader is run. This is important; since bootloaders + * are written to occupy a very limited space, they usually make assumptions about the register states based + * on the default values after a hard-reset of the chip. + * + * \section Sec_SoftareBootAVR8 AVR8 Architecture + * The following software bootloader jump code is written for the AVR8 architecture. + * + * \code + * #include + * #include + * #include + * + * #include + * #include + * + * uint32_t Boot_Key ATTR_NO_INIT; + * + * #define MAGIC_BOOT_KEY 0xDC42ACCA + * #define BOOTLOADER_START_ADDRESS (FLASH_SIZE_BYTES - BOOTLOADER_SEC_SIZE_BYTES) + * + * void Bootloader_Jump_Check(void) ATTR_INIT_SECTION(3); + * void Bootloader_Jump_Check(void) + * { + * // If the reset source was the bootloader and the key is correct, clear it and jump to the bootloader + * if ((MCUSR & (1 << WDRF)) && (Boot_Key == MAGIC_BOOT_KEY)) + * { + * Boot_Key = 0; + * ((void (*)(void))BOOTLOADER_START_ADDRESS)(); + * } + * } + * + * void Jump_To_Bootloader(void) + * { + * // If USB is used, detach from the bus and reset it + * USB_Disable(); + * + * // Disable all interrupts + * cli(); + * + * // Wait two seconds for the USB detachment to register on the host + * Delay_MS(2000); + * + * // Set the bootloader key to the magic value and force a reset + * Boot_Key = MAGIC_BOOT_KEY; + * wdt_enable(WDTO_250MS); + * for (;;); + * } + * \endcode + * + * Note that the bootloader magic key can be any arbitrary value. The FLASH_SIZE_BYTES and + * BOOTLOADER_SEC_SIZE_BYTES tokens should be replaced with the total flash size of the AVR + * in bytes, and the allocated size of the bootloader section for the target AVR. + * + */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/Style/Footer.htm b/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/Style/Footer.htm new file mode 100644 index 00000000..c6de4e64 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/Style/Footer.htm @@ -0,0 +1,35 @@ + + + + + + + + + \ No newline at end of file diff --git a/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/Style/Style.css b/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/Style/Style.css new file mode 100644 index 00000000..b0b8464b --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/Style/Style.css @@ -0,0 +1,1123 @@ +@media print + { + #top + { + display:none; + } + + #side-nav + { + display:none; + } + + #nav-path + { + display:none; + } + + body + { + overflow:visible; + } + + h1,h2,h3,h4,h5,h6 + { + page-break-after:avoid; + } + + .summary + { + display:none; + } + + .memitem + { + page-break-inside:avoid; + } + + #doc-content + { + display:inline; + height:auto !important; + margin-left:0 !important; + overflow:inherit; + width:auto !important; + } + + .fragment + { + background-color: #FFFFFF !important; + } +} + +body,table,div,p,dl +{ + font-family:Lucida Grande, Verdana, Geneva, Arial, sans-serif; + font-size:13px; + line-height:1.3; +} + +div.contents p +{ + padding-left:12px; +} + +div.contents table.memberdecls,.paramname +{ + font-family:Consolas, Monaco, courier, sans-serif; + font-size:105%; + padding-right:20px; +} + +.title +{ + font-size:150%; + font-weight:bold; + margin:10px 2px; +} + +h1 +{ + font-size:25px; + margin-bottom:10px; +} + +h2 +{ + color:#42657B; + font-family:Lucida Grande, Verdana, Geneva, Arial, sans-serif; + font-size:17px; +} + +h3 +{ + font-family:Lucida Grande, Verdana, Geneva, Arial, sans-serif; + font-size:15px; +} + +h4 +{ + font-family:Lucida Grande, Verdana, Geneva, Arial, sans-serif; + font-size:13px; +} + +dt +{ + font-weight:bold; +} + +div.multicol +{ + -moz-column-count:3px; + -moz-column-gap:1em; + -webkit-column-count:3px; + -webkit-column-gap:1em; +} + +p.startli,p.startdd,p.starttd +{ + margin-top:2px; +} + +p.endli +{ + margin-bottom:0; +} + +p.enddd +{ + margin-bottom:4px; +} + +p.endtd +{ + margin-bottom:2px; +} + +caption +{ + font-weight:bold; +} + +span.legend +{ + font-size:70%; + text-align:center; +} + +h3.version +{ + font-size:90%; + text-align:center; +} + +div.qindex,div.navtab +{ + background-color:#EAEFF7; + border:1px solid #9EB3DC; + text-align:center; +} + +div.qindex,div.navpath +{ + line-height:140%; + width:100%; +} + +div.navtab +{ + margin-right:15px; +} + +a +{ + color:#355594; + font-weight:normal; + text-decoration:none; +} + +.contents a:visited +{ + color:#3D62AB; +} + +a:hover +{ + text-decoration:underline; +} + +a.qindex +{ + font-weight:bold; +} + +a.qindexHL +{ + background-color:#97ADD9; + border:1px double #7F9BD1; + color:#ffffff; + font-weight:bold; +} + +.contents a.qindexHL:visited +{ + color:#ffffff; +} + +a.el +{ + font-weight:bold; +} + +a.code,a.code:visited +{ + color:#4665A2; +} + +a.codeRef,a.codeRef:visited +{ + color:#4665A2; +} + +dl.el +{ + margin-left:-1cm; +} + +pre.fragment { + border: 1px solid #C4CFE5; + background-color: #FBFCFD; + padding: 4px 6px; + margin: 4px 8px 4px 2px; + overflow: auto; + word-wrap: break-word; + font-size: 9pt; + line-height: 125%; + font-family: monospace, fixed; + font-size: 105%; +} + +div.fragment { + padding: 4px; + margin: 4px; + background-color: #FBFCFD; + border: 1px solid #C4CFE5; +} + +div.line { + font-family: monospace, fixed; + font-size: 13px; + min-height: 13px; + line-height: 1.0; + text-wrap: unrestricted; + white-space: -moz-pre-wrap; /* Moz */ + white-space: -pre-wrap; /* Opera 4-6 */ + white-space: -o-pre-wrap; /* Opera 7 */ + white-space: pre-wrap; /* CSS3 */ + word-wrap: break-word; /* IE 5.5+ */ + text-indent: -53px; + padding-left: 53px; + padding-bottom: 0px; + margin: 0px; +} + +span.lineno { + padding-right: 4px; + text-align: right; + border-right: 2px solid #0F0; + background-color: #E8E8E8; + white-space: pre; +} +span.lineno a { + background-color: #D8D8D8; +} + +span.lineno a:hover { + background-color: #C8C8C8; +} + +div.ah +{ + -moz-border-radius:.5em; + -moz-box-shadow:rgba(0, 0, 0, 0.15) 2px 2px 2px; + -webkit-border-radius:.5em; + -webkit-box-shadow:2px 2px 3px #999; + background-color:black; + background-image:0; + border:solid thin #333; + border-radius:0.5em; + box-shadow:2px 2px 3px #999; + color:#ffffff; + font-weight:bold; + margin-bottom:3px; + margin-top:3px; + padding:0.2em; +} + +div.groupHeader +{ + font-weight:bold; + margin-left:16px; + margin-top:12px; +} + +div.groupText +{ + font-style:italic; + margin-left:16px; +} + +body +{ + background-color:white; + color:black; + margin:0; +} + +div.contents +{ + margin-left:8px; + margin-right:8px; + margin-top:10px; +} + +td.indexkey +{ + background-color:#EAEFF7; + border:1px solid #C1CEE8; + font-weight:bold; + margin:2px 0; + padding:2px 10px; + vertical-align:top; + white-space:nowrap; +} + +td.indexvalue +{ + background-color:#EAEFF7; + border:1px solid #C1CEE8; + margin:2px 0; + padding:2px 10px; +} + +tr.memlist +{ + background-color:#EDF1F8; +} + +p.formulaDsp +{ + text-align:center; +} + +img.formulaInl +{ + vertical-align:middle; +} + +div.center +{ + margin-bottom:0; + margin-top:0; + padding:0; + text-align:center; +} + +div.center img +{ + border:0; +} + +address.footer +{ + padding-right:12px; + text-align:right; +} + +img.footer +{ + border:0; + vertical-align:middle; +} + +span.keyword +{ + color:#008000; +} + +span.keywordtype +{ + color:#604020; +} + +span.keywordflow +{ + color:#e08000; +} + +span.comment +{ + color:#008000; +} + +span.preprocessor +{ + color:#806020; +} + +span.stringliteral +{ + color:#002080; +} + +span.charliteral +{ + color:#008080; +} + +span.vhdldigit +{ + color:#ff00ff; +} + +span.vhdlchar +{ + color:#000000; +} + +span.vhdlkeyword +{ + color:#700070; +} + +span.vhdllogic +{ + color:#ff0000; +} + +blockquote +{ + background-color:#F6F8FC; + border-left:2px solid #97ADD9; + margin:0 24px 0 4px; + padding:0 12px 0 16px; +} + +td.tiny +{ + font-size:75%; +} + +.dirtab +{ + border:1px solid #9EB3DC; + border-collapse:collapse; + padding:4px; +} + +th.dirtab +{ + background:#EAEFF7; + font-weight:bold; +} + +hr +{ + border:none; + border-top:1px solid #4067B4; + height:0; +} + +hr.footer +{ + height:1px; +} + +table.memberdecls +{ + border-spacing:0; + padding:0; +} + +.mdescLeft,.mdescRight,.memItemLeft,.memItemRight,.memTemplItemLeft,.memTemplItemRight,.memTemplParams +{ + background-color:#F9FAFC; + border:none; + margin:4px; + padding:1px 0 0 8px; +} + +.mdescLeft,.mdescRight +{ + color:#555; + padding:0 8px 4px; +} + +.memItemLeft,.memItemRight,.memTemplParams +{ + border-top:1px solid #C1CEE8; +} + +.memItemLeft,.memTemplItemLeft +{ + white-space:nowrap; +} + +.memItemRight +{ + width:100%; +} + +.memTemplParams +{ + color:#3D62AB; + white-space:nowrap; +} + +.memtemplate +{ + color:#3D62AB; + font-size:80%; + font-weight:normal; + margin-left:9px; +} + +.memnav +{ + background-color:#EAEFF7; + border:1px solid #9EB3DC; + margin:2px 15px 2px 2px; + padding:2px; + text-align:center; +} + +.mempage +{ + width:100%; +} + +.memitem +{ + margin-bottom:10px; + margin-right:5px; + padding:0; +} + +.memname +{ + font-weight:bold; + margin-left:6px; + white-space:nowrap; +} + +.memproto,dl.reflist dt +{ + -moz-border-radius-topleft:8px; + -moz-border-radius-topright:8px; + -moz-box-shadow:rgba(0, 0, 0, 0.15) 5px 5px 5px; + -webkit-border-top-left-radius:8px; + -webkit-border-top-right-radius:8px; + -webkit-box-shadow:5px 5px 5px rgba(0, 0, 0, 0.15); + background-color:#E1E7F4; + background-image:url('nav_f.png'); + background-repeat:repeat-x; + border-left:1px solid #A3B7DE; + border-right:1px solid #A3B7DE; + border-top:1px solid #A3B7DE; + border-top-left-radius:8px; + border-top-right-radius:8px; + box-shadow:5px 5px 5px rgba(0, 0, 0, 0.15); + color:#20335A; + font-weight:bold; + padding:6px 0; + text-shadow:0 1px 1px rgba(255, 255, 255, 0.9); +} + +.memdoc,dl.reflist dd +{ + -moz-border-radius-bottomleft:8px; + -moz-border-radius-bottomright:8px; + -moz-box-shadow:rgba(0, 0, 0, 0.15) 5px 5px 5px; + -webkit-border-bottom-left-radius:8px; + -webkit-border-bottom-right-radius:8px; + -webkit-box-shadow:5px 5px 5px rgba(0, 0, 0, 0.15); + background-color:#FBFCFD; + background-image:0 color-stop(0.6,#FFFFFF), color-stop(0.60,#FFFFFF), color-stop(0.95,#F6F8FC), to(#EDF1F8)); + border-bottom:1px solid #A3B7DE; + border-bottom-left-radius:8px; + border-bottom-right-radius:8px; + border-left:1px solid #A3B7DE; + border-right:1px solid #A3B7DE; + border-top-width:0; + box-shadow:5px 5px 5px rgba(0, 0, 0, 0.15); + padding:2px 5px; +} + +dl.reflist dt +{ + padding:5px; +} + +dl.reflist dd +{ + margin:0 0 10px; + padding:5px; +} + +.paramkey +{ + text-align:right; +} + +.paramtype +{ + white-space:nowrap; +} + +.paramname +{ + color:#602020; + white-space:nowrap; +} + +.paramname em +{ + font-style:normal; +} + +.params,.retval,.exception,.tparams +{ + border-spacing:6px 2px; +} + +.params .paramname,.retval .paramname +{ + font-weight:bold; + vertical-align:top; +} + +.params .paramtype +{ + font-style:italic; + vertical-align:top; +} + +.params .paramdir +{ + font-family:"courier new",courier,monospace; + vertical-align:top; +} + +.ftvtree +{ + font-family:sans-serif; + margin:0; +} + +.directory +{ + font-size:9pt; + font-weight:bold; + margin:5px; +} + +.directory h3 +{ + font-size:11pt; + margin:1em 0 0; +} + +.directory > h3 +{ + margin-top:0; +} + +.directory p +{ + margin:0; + white-space:nowrap; +} + +.directory div +{ + display:none; + margin:0; +} + +.directory img +{ + vertical-align:-30%; +} + +.directory-alt +{ + font-size:100%; + font-weight:bold; +} + +.directory-alt h3 +{ + font-size:11pt; + margin:1em 0 0; +} + +.directory-alt > h3 +{ + margin-top:0; +} + +.directory-alt p +{ + margin:0; + white-space:nowrap; +} + +.directory-alt div +{ + display:none; + margin:0; +} + +.directory-alt img +{ + vertical-align:-30%; +} + +div.dynheader +{ + margin-top:8px; +} + +address +{ + color:#253B67; + font-style:normal; +} + +table.doxtable +{ + border-collapse:collapse; + margin-bottom:4px; + margin-top:4px; +} + +table.doxtable td,table.doxtable th +{ + border:1px solid #273F6D; + padding:3px 7px 2px; +} + +table.doxtable th +{ + background-color:#304D86; + color:#FFFFFF; + font-size:110%; + padding-bottom:4px; + padding-top:5px; +} + +table.fieldtable +{ + -moz-border-radius:4px; + -moz-box-shadow:rgba(0, 0, 0, 0.15) 2px 2px 2px; + -webkit-border-radius:4px; + -webkit-box-shadow:2px 2px 2px rgba(0, 0, 0, 0.15); + border:1px solid #A3B7DE; + border-radius:4px; + border-spacing:0; + box-shadow:2px 2px 2px rgba(0, 0, 0, 0.15); + margin-bottom:10px; + width:100%; +} + +.fieldtable td,.fieldtable th +{ + padding:3px 7px 2px; +} + +.fieldtable td.fieldtype,.fieldtable td.fieldname +{ + border-bottom:1px solid #A3B7DE; + border-right:1px solid #A3B7DE; + vertical-align:top; + white-space:nowrap; +} + +.fieldtable td.fielddoc +{ + border-bottom:1px solid #A3B7DE; + width:100%; +} + +.fieldtable tr:last-child td +{ + border-bottom:none; +} + +.fieldtable th +{ + -moz-border-radius-topleft:4px; + -moz-border-radius-topright:4px; + -webkit-border-top-left-radius:4px; + -webkit-border-top-right-radius:4px; + background-color:#E1E7F4; + background-image:url('nav_f.png'); + background-repeat:repeat-x; + border-bottom:1px solid #A3B7DE; + border-top-left-radius:4px; + border-top-right-radius:4px; + color:#20335A; + font-size:90%; + padding-bottom:4px; + padding-top:5px; + text-align:left; +} + +.tabsearch +{ + background-image:url('tab_b.png'); + font-size:13px; + height:36px; + left:10px; + overflow:hidden; + top:0; + z-index:101; +} + +.navpath ul +{ + background-image:url('tab_b.png'); + background-repeat:repeat-x; + border:solid 1px #BFCCE8; + color:#839ED2; + font-size:11px; + height:30px; + line-height:30px; + margin:0; + overflow:hidden; + padding:0; +} + +.navpath li +{ + background-image:url('bc_s.png'); + background-position:right; + background-repeat:no-repeat; + color:#2F4B83; + float:left; + list-style-type:none; + padding-left:10px; + padding-right:15px; +} + +.navpath li.navelem a +{ + display:block; + height:32px; + outline:none; + text-decoration:none; +} + +.navpath li.navelem a:hover +{ + color:#6081C5; +} + +.navpath li.footer +{ + background-image:none; + background-position:right; + background-repeat:no-repeat; + color:#2F4B83; + float:right; + font-size:8pt; + list-style-type:none; + padding-left:10px; + padding-right:15px; +} + +div.summary +{ + float:right; + font-size:8pt; + padding-right:5px; + text-align:right; + width:50%; +} + +div.summary a +{ + white-space:nowrap; +} + +div.ingroups +{ + font-size:8pt; + margin-left:5px; + padding-left:5px; + text-align:left; + width:50%; +} + +div.ingroups a +{ + white-space:nowrap; +} + +div.header +{ + background-color:#F9FAFC; + background-image:url('nav_h.png'); + background-repeat:repeat-x; + border-bottom:1px solid #C1CEE8; + margin:0; +} + +div.headertitle +{ + padding:5px 5px 5px 7px; +} + +dl +{ + padding:0 0 0 10px; +} + +dl.section +{ + border-left:4px solid; + padding:0 0 0 6px; +} + +dl.note +{ + border-color:#D0C000; +} + +dl.warning,dl.attention +{ + border-color:#FF0000; +} + +dl.pre,dl.post,dl.invariant +{ + border-color:#00D000; +} + +dl.deprecated +{ + border-color:#505050; +} + +dl.todo +{ + border-color:#00C0E0; +} + +dl.test +{ + border-color:#3030E0; +} + +dl.bug +{ + border-color:#C08050; +} + +dl.section dd +{ + margin-bottom:6px; +} + +#projectlogo +{ + border-collapse:separate; + text-align:center; + vertical-align:bottom; + padding-left: 20px; +} + +#projectlogo img +{ + border:0 none; +} + +#projectname +{ + font:280% Arial, sans-serif; + margin:0; + padding-left:20px; +} + +#projectbrief +{ + font:120% Tahoma, Arial, sans-serif; + margin:0; + padding:0; +} + +#projectnumber:before +{ + content:"Version "; +} + +#projectnumber +{ + font:50% Tahoma, Arial, sans-serif; + margin:0; + padding:0; +} + +#titlearea +{ + margin:0; + padding:0; + width:100%; + background-color:#E1E7F4; + background-image:url('nav_f.png'); + background-repeat:repeat-x; + color:#20335A; + font-weight:bold; + text-shadow:0 1px 1px rgba(255, 255, 255, 0.9); +} + +.image +{ + text-align:center; +} + +.dotgraph +{ + text-align:center; +} + +.mscgraph +{ + text-align:center; +} + +.caption +{ + font-weight:bold; +} + +div.zoom +{ + border:1px solid #8AA3D4; +} + +dl.citelist +{ + margin-bottom:50px; +} + +dl.citelist dt +{ + color:#2C477C; + float:left; + font-weight:bold; + margin-right:10px; + padding:5px; +} + +dl.citelist dd +{ + margin:2px 0; + padding:5px 0; +} + +div.toc +{ + background-color:#F4F6FB; + border:1px solid #D6DFF0; + border-radius:7px 7px 7px 7px; + float:right; + height:auto; + margin:0 20px 10px 10px; + padding:14px 25px; + width:200px; +} + +div.toc li +{ + background:url("bdwn.png") no-repeat scroll 0 5px transparent; + font:10px/1.2 Verdana,DejaVu Sans,Geneva,sans-serif; + margin-top:5px; + padding-left:10px; + padding-top:2px; +} + +div.toc h3 +{ + border-bottom:0 none; + color:#3D62AB; + font:bold 12px/1.2 Arial,FreeSans,sans-serif; + margin:0; +} + +div.toc ul +{ + border:medium none; + list-style:none outside none; + padding:0; +} + +div.toc li.level1 +{ + margin-left:0; +} + +div.toc li.level2 +{ + margin-left:15px; +} + +div.toc li.level3 +{ + margin-left:30px; +} + +div.toc li.level4 +{ + margin-left:45px; +} diff --git a/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/VIDAndPIDValues.txt b/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/VIDAndPIDValues.txt new file mode 100644 index 00000000..ae9c7d44 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/VIDAndPIDValues.txt @@ -0,0 +1,424 @@ +/** \file + * + * This file contains special DoxyGen information for the generation of the main page and other special + * documentation pages. It is not a project source file. + */ + +/** \page Page_VIDPID VID and PID values + * + * \section Sec_VIDPID_Allocations VID and PID Allocations + * The LUFA library uses VID/PID combinations generously donated by Atmel. The following VID/PID combinations + * are used within the LUFA demos, and thus may be re-used by derivations of each demo. Free PID values may be + * used by future LUFA demo projects. + * + * These VID/PID values should not be used in commercial designs under any circumstances. Private projects + * may use the following values freely, but must accept any collisions due to other LUFA derived private projects + * sharing identical values. It is suggested that private projects using interfaces compatible with existing + * demos share the same VID/PID value. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
+ * VID + * + * PID + * + * Usage + *
+ * 0x03EB + * + * 0x2040 + * + * Test VID/PID (See below) + *
+ * 0x03EB + * + * 0x2041 + * + * Mouse Demo Application + *
+ * 0x03EB + * + * 0x2042 + * + * Keyboard Demo Application + *
+ * 0x03EB + * + * 0x2043 + * + * Joystick Demo Application + *
+ * 0x03EB + * + * 0x2044 + * + * CDC Demo Application + *
+ * 0x03EB + * + * 0x2045 + * + * Mass Storage Demo Application + *
+ * 0x03EB + * + * 0x2046 + * + * Audio Output Demo Application + *
+ * 0x03EB + * + * 0x2047 + * + * Audio Input Demo Application + *
+ * 0x03EB + * + * 0x2048 + * + * MIDI Demo Application + *
+ * 0x03EB + * + * 0x2049 + * + * MagStripe Project + *
+ * 0x03EB + * + * 0x204A + * + * CDC Bootloader + *
+ * 0x03EB + * + * 0x204B + * + * USB to Serial Demo Application + *
+ * 0x03EB + * + * 0x204C + * + * RNDIS Demo Application + *
+ * 0x03EB + * + * 0x204D + * + * Combined Keyboard and Mouse Demo Application + *
+ * 0x03EB + * + * 0x204E + * + * Dual CDC Demo Application + *
+ * 0x03EB + * + * 0x204F + * + * Generic HID Demo Application + *
+ * 0x03EB + * + * 0x2060 + * + * Benito Programmer Project + *
+ * 0x03EB + * + * 0x2061 + * + * Combined Mass Storage and Keyboard Demo + *
+ * 0x03EB + * + * 0x2062 + * + * Combined CDC and Mouse Demo + *
+ * 0x03EB + * + * 0x2063 + * + * Mass Storage/HID Interface Datalogger Project + *
+ * 0x03EB + * + * 0x2064 + * + * Interfaceless Control-Only LUFA Devices + *
+ * 0x03EB + * + * 0x2065 + * + * Test and Measurement Demo + *
+ * 0x03EB + * + * 0x2066 + * + * Multiple Report Keyboard/Mouse HID Demo + *
+ * 0x03EB + * + * 0x2067 + * + * HID Class Bootloader + *
+ * 0x03EB + * + * 0x2068 + * + * Virtual Serial/Mass Storage Demo + *
+ * 0x03EB + * + * 0x2069 + * + * Webserver Project + *
+ * 0x03EB + * + * 0x206A + * + * Media Control Project + *
+ * 0x03EB + * + * 0x206B + * + * Currently Unallocated + *
+ * 0x03EB + * + * 0x206C + * + * Currently Unallocated + *
+ * 0x03EB + * + * 0x206D + * + * Currently Unallocated + *
+ * 0x03EB + * + * 0x206E + * + * Currently Unallocated + *
+ * 0x03EB + * + * 0x206F + * + * Currently Unallocated + *
+ * + * \section Sec_Test_VIDPID The Test VID/PID Combination + * For use in testing of LUFA powered devices during development only, by non-commercial entities. + * All devices must accept collisions on this VID/PID range (from other in-development LUFA devices) + * to be resolved by using a unique release number in the Device Descriptor. No devices using this + * VID/PID combination may be released to the general public. + */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/WritingBoardDrivers.txt b/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/WritingBoardDrivers.txt new file mode 100644 index 00000000..1b332690 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/DoxygenPages/WritingBoardDrivers.txt @@ -0,0 +1,27 @@ +/** \file + * + * This file contains special DoxyGen information for the generation of the main page and other special + * documentation pages. It is not a project source file. + */ + +/** \page Page_WritingBoardDrivers Writing LUFA Board Drivers + * + * LUFA ships with several basic pre-made board drivers, to control hardware present on the supported board + * hardware - such as Dataflash ICs, LEDs, Joysticks, or other hardware peripherals. When compiling an application + * which makes use of one or more board drivers located in LUFA/Drivers/Board, you must also indicate what board + * hardware you are using in your project makefile. This is done by defining the BOARD macro using the -D switch + * passed to the compiler, with a constant of BOARD_{Name}. For example -DBOARD=BOARD_USBKEY instructs the + * compiler to use the USBKEY board hardware drivers. + * + * If your application does not use *any* board level drivers, you can omit the definition of the BOARD macro. + * However, some users may wish to write their own custom board hardware drivers which are to remain compatible + * with the LUFA hardware API. To do this, the BOARD macro should be defined to the value BOARD_USER. This indicates + * that the board level drivers should be located in a folder named "Board" located inside the application's folder. + * + * When used, the driver stub files located in the LUFA/CodeTemplates/DriverStubs folder should be copied to the user + * Board/ directory, and fleshed out to include the values and code needed to control the custom board hardware. Once + * done, the existing LUFA board level APIs (accessed in the regular LUFA/Drivers/Board/ folder) will redirect to the + * user board drivers, maintaining code compatibility and allowing for a different board to be selected through the + * project makefile with no code changes. + */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/ADAFRUITU4/LEDs.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/ADAFRUITU4/LEDs.h new file mode 100644 index 00000000..c18054f8 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/ADAFRUITU4/LEDs.h @@ -0,0 +1,135 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific LED driver header for the Adafruit U4 Breakout board. + * \copydetails Group_LEDs_ADAFRUITU4 + * + * \note This file should not be included directly. It is automatically included as needed by the LEDs driver + * dispatch header located in LUFA/Drivers/Board/LEDs.h. + */ + +/** \ingroup Group_LEDs + * \defgroup Group_LEDs_ADAFRUITU4 ADAFRUITU4 + * \brief Board specific LED driver header for the Adafruit U4 Breakout board. + * + * Board specific LED driver header for the Adafruit U4 Breakout board (http://ladyada.net/products/atmega32u4breakout). + * + * + * + * + *
NameColorInfoActive LevelPort Pin
LEDS_LED1GreenGeneral IndicatorHighPORTE.6
+ * + * @{ + */ + +#ifndef __LEDS_ADAFRUITU4_H__ +#define __LEDS_ADAFRUITU4_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_LEDS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/LEDS.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** LED mask for the first LED on the board. */ + #define LEDS_LED1 (1 << 6) + + /** LED mask for all the LEDs on the board. */ + #define LEDS_ALL_LEDS LEDS_LED1 + + /** LED mask for the none of the board LEDs. */ + #define LEDS_NO_LEDS 0 + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void LEDs_Init(void) + { + DDRE |= LEDS_ALL_LEDS; + PORTE &= ~LEDS_ALL_LEDS; + } + + static inline void LEDs_Disable(void) + { + DDRE &= ~LEDS_ALL_LEDS; + PORTE &= ~LEDS_ALL_LEDS; + } + + static inline void LEDs_TurnOnLEDs(const uint8_t LEDMask) + { + PORTE |= LEDMask; + } + + static inline void LEDs_TurnOffLEDs(const uint8_t LEDMask) + { + PORTE &= ~LEDMask; + } + + static inline void LEDs_SetAllLEDs(const uint8_t LEDMask) + { + PORTE = ((PORTE & ~LEDS_ALL_LEDS) | LEDMask); + } + + static inline void LEDs_ChangeLEDs(const uint8_t LEDMask, + const uint8_t ActiveMask) + { + PORTE = ((PORTE & ~LEDMask) | ActiveMask); + } + + static inline void LEDs_ToggleLEDs(const uint8_t LEDMask) + { + PINE = LEDMask; + } + + static inline uint8_t LEDs_GetLEDs(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t LEDs_GetLEDs(void) + { + return (PORTE & LEDS_ALL_LEDS); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/ATAVRUSBRF01/Buttons.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/ATAVRUSBRF01/Buttons.h new file mode 100644 index 00000000..3470890b --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/ATAVRUSBRF01/Buttons.h @@ -0,0 +1,103 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific Buttons driver header for the Atmel ATAVRUSBRF01. + * \copydetails Group_Buttons_ATAVRUSBRF01 + * + * \note This file should not be included directly. It is automatically included as needed by the Buttons driver + * dispatch header located in LUFA/Drivers/Board/Buttons.h. + */ + +/** \ingroup Group_Buttons + * \defgroup Group_Buttons_ATAVRUSBRF01 ATAVRUSBRF01 + * \brief Board specific Buttons driver header for the Atmel ATAVRUSBRF01. + * + * Board specific Buttons driver header for the Atmel ATAVRUSBRF01. + * + * + * + * + *
NameInfoActive LevelPort Pin
BUTTONS_BUTTON1HWB ButtonLowPORTD.7
+ * + * @{ + */ + +#ifndef __BUTTONS_ATAVRUSBRF01_H__ +#define __BUTTONS_ATAVRUSBRF01_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_BUTTONS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/Buttons.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Button mask for the first button on the board. */ + #define BUTTONS_BUTTON1 (1 << 7) + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void Buttons_Init(void) + { + DDRD &= ~BUTTONS_BUTTON1; + PORTD |= BUTTONS_BUTTON1; + } + + static inline void Buttons_Disable(void) + { + DDRD &= ~BUTTONS_BUTTON1; + PORTD &= ~BUTTONS_BUTTON1; + } + + static inline uint8_t Buttons_GetStatus(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t Buttons_GetStatus(void) + { + return ((PIND & BUTTONS_BUTTON1) ^ BUTTONS_BUTTON1); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/ATAVRUSBRF01/LEDs.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/ATAVRUSBRF01/LEDs.h new file mode 100644 index 00000000..17b42715 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/ATAVRUSBRF01/LEDs.h @@ -0,0 +1,139 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific LED driver header for the Atmel ATAVRUSBRF01. + * \copydetails Group_LEDs_ATAVRUSBRF01 + * + * \note This file should not be included directly. It is automatically included as needed by the LEDs driver + * dispatch header located in LUFA/Drivers/Board/LEDs.h. + */ + +/** \ingroup Group_LEDs + * \defgroup Group_LEDs_ATAVRUSBRF01 ATAVRUSBRF01 + * \brief Board specific LED driver header for the Atmel ATAVRUSBRF01. + * + * Board specific LED driver header for the Atmel ATAVRUSBRF01. + * + * + * + * + * + *
NameColorInfoActive LevelPort Pin
LEDS_LED1GreenRX LEDHighPORTD.0
LEDS_LED2RedTX LEDHighPORTD.1
+ * + * @{ + */ + +#ifndef __LEDS_ATAVRUSBRF01_H__ +#define __LEDS_ATAVRUSBRF01_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_LEDS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/LEDS.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** LED mask for the first LED on the board. */ + #define LEDS_LED1 (1 << 0) + + /** LED mask for the second LED on the board. */ + #define LEDS_LED2 (1 << 1) + + /** LED mask for all the LEDs on the board. */ + #define LEDS_ALL_LEDS (LEDS_LED1 | LEDS_LED2) + + /** LED mask for none of the board LEDs. */ + #define LEDS_NO_LEDS 0 + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void LEDs_Init(void) + { + DDRD |= LEDS_ALL_LEDS; + PORTD &= ~LEDS_ALL_LEDS; + } + + static inline void LEDs_Disable(void) + { + DDRD &= ~LEDS_ALL_LEDS; + PORTD &= ~LEDS_ALL_LEDS; + } + + static inline void LEDs_TurnOnLEDs(const uint8_t LEDMask) + { + PORTD |= (LEDMask & LEDS_ALL_LEDS); + } + + static inline void LEDs_TurnOffLEDs(const uint8_t LEDMask) + { + PORTD &= ~(LEDMask & LEDS_ALL_LEDS); + } + + static inline void LEDs_SetAllLEDs(const uint8_t LEDMask) + { + PORTD = (PORTD & ~LEDS_ALL_LEDS) | (LEDMask & LEDS_ALL_LEDS); + } + + static inline void LEDs_ChangeLEDs(const uint8_t LEDMask, + const uint8_t ActiveMask) + { + PORTD = ((PORTD & ~LEDMask) | ActiveMask); + } + + static inline void LEDs_ToggleLEDs(const uint8_t LEDMask) + { + PIND = LEDMask; + } + + static inline uint8_t LEDs_GetLEDs(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t LEDs_GetLEDs(void) + { + return (PORTD & LEDS_ALL_LEDS); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/BENITO/Buttons.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/BENITO/Buttons.h new file mode 100644 index 00000000..cecaca07 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/BENITO/Buttons.h @@ -0,0 +1,103 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific Buttons driver header for the Tempusdictum Benito. + * \copydetails Group_Buttons_BENITO + * + * \note This file should not be included directly. It is automatically included as needed by the Buttons driver + * dispatch header located in LUFA/Drivers/Board/Buttons.h. + */ + +/** \ingroup Group_Buttons + * \defgroup Group_Buttons_BENITO BENITO + * \brief Board specific Buttons driver header for the Tempusdictum Benito. + * + * Board specific Buttons driver header for the Tempusdictum Benito (http://dorkbotpdx.org/wiki/benito). + * + * + * + * + *
NameInfoActive LevelPort Pin
BUTTONS_BUTTON1HWB ButtonLowPORTD.7
+ * + * @{ + */ + +#ifndef __BUTTONS_BENITO_H__ +#define __BUTTONS_BENITO_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_BUTTONS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/Buttons.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Button mask for the first button on the board. */ + #define BUTTONS_BUTTON1 (1 << 7) + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void Buttons_Init(void) + { + DDRD &= ~BUTTONS_BUTTON1; + PORTD |= BUTTONS_BUTTON1; + } + + static inline void Buttons_Disable(void) + { + DDRD &= ~BUTTONS_BUTTON1; + PORTD &= ~BUTTONS_BUTTON1; + } + + static inline uint8_t Buttons_GetStatus(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t Buttons_GetStatus(void) + { + return ((PIND & BUTTONS_BUTTON1) ^ BUTTONS_BUTTON1); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/BENITO/LEDs.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/BENITO/LEDs.h new file mode 100644 index 00000000..dc3d85df --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/BENITO/LEDs.h @@ -0,0 +1,139 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific LED driver header for the Tempusdictum Benito. + * \copydetails Group_LEDs_BENITO + * + * \note This file should not be included directly. It is automatically included as needed by the LEDs driver + * dispatch header located in LUFA/Drivers/Board/LEDs.h. + */ + +/** \ingroup Group_LEDs + * \defgroup Group_LEDs_BENITO BENITO + * \brief Board specific LED driver header for the Tempusdictum Benito. + * + * Board specific LED driver header for the Tempusdictum Benito (http://dorkbotpdx.org/wiki/benito). + * + * + * + * + * + *
NameColorInfoActive LevelPort Pin
LEDS_LED1GreenTX LEDLowPORTC.7
LEDS_LED2RedRX LEDLowPORTC.6
+ * + * @{ + */ + +#ifndef __LEDS_BENITO_H__ +#define __LEDS_BENITO_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_LEDS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/LEDS.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** LED mask for the first LED on the board. */ + #define LEDS_LED1 (1 << 7) + + /** LED mask for the second LED on the board. */ + #define LEDS_LED2 (1 << 6) + + /** LED mask for all the LEDs on the board. */ + #define LEDS_ALL_LEDS (LEDS_LED1 | LEDS_LED2) + + /** LED mask for none of the board LEDs. */ + #define LEDS_NO_LEDS 0 + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void LEDs_Init(void) + { + DDRC |= LEDS_ALL_LEDS; + PORTC |= LEDS_ALL_LEDS; + } + + static inline void LEDs_Disable(void) + { + DDRC &= ~LEDS_ALL_LEDS; + PORTC &= ~LEDS_ALL_LEDS; + } + + static inline void LEDs_TurnOnLEDs(const uint8_t LEDMask) + { + PORTC &= ~LEDMask; + } + + static inline void LEDs_TurnOffLEDs(const uint8_t LEDMask) + { + PORTC |= LEDMask; + } + + static inline void LEDs_SetAllLEDs(const uint8_t LEDMask) + { + PORTC = ((PORTC | LEDS_ALL_LEDS) & ~LEDMask); + } + + static inline void LEDs_ChangeLEDs(const uint8_t LEDMask, + const uint8_t ActiveMask) + { + PORTC = ((PORTC | LEDMask) & ~ActiveMask); + } + + static inline void LEDs_ToggleLEDs(const uint8_t LEDMask) + { + PINC = LEDMask; + } + + static inline uint8_t LEDs_GetLEDs(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t LEDs_GetLEDs(void) + { + return (PORTC & LEDS_ALL_LEDS); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/BIGMULTIO/LEDs.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/BIGMULTIO/LEDs.h new file mode 100644 index 00000000..d003680d --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/BIGMULTIO/LEDs.h @@ -0,0 +1,161 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific LED driver header for the Bitwizard Big-Multio. + * \copydetails Group_LEDs_BIGMULTIO + * + * \note This file should not be included directly. It is automatically included as needed by the LEDs driver + * dispatch header located in LUFA/Drivers/Board/LEDs.h. + */ + +/** \ingroup Group_LEDs + * \defgroup Group_LEDs_BIGMULTIO BIGMULTIO + * \brief Board specific LED driver header for the Bitwizard Big-Multio. + * + * Board specific LED driver header for the Bitwizard Big-Multio (http://www.bitwizard.nl/wiki/index.php/Usbbigmultio). + * + * + * + * + * + * + *
NameColorInfoActive LevelPort Pin
LEDS_LED1UnknownLED0HighPORTF.6
LEDS_LED2UnknownLED1HighPORTF.7
LEDS_LED3UnknownLED2HighPORTE.2
+ * + * @{ + */ + +#ifndef __LEDS_BIGMULTIO_H__ +#define __LEDS_BIGMULTIO_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_LEDS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/LEDS.h instead. + #endif + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Macros: */ + #define LEDS_PORTF_LEDS (LEDS_LED1 | LEDS_LED2) + #define LEDS_PORTE_LEDS LEDS_LED3 + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** LED mask for the first LED on the board. */ + #define LEDS_LED1 (1 << 6) + + /** LED mask for the second LED on the board. */ + #define LEDS_LED2 (1 << 7) + + /** LED mask for the second LED on the board. */ + #define LEDS_LED3 (1 << 2) + + /** LED mask for all the LEDs on the board. */ + #define LEDS_ALL_LEDS (LEDS_LED1 | LEDS_LED2 | LEDS_LED3) + + /** LED mask for none of the board LEDs. */ + #define LEDS_NO_LEDS 0 + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void LEDs_Init(void) + { + DDRF |= LEDS_PORTF_LEDS; + DDRE |= LEDS_PORTE_LEDS; + + PORTF &= ~LEDS_PORTF_LEDS; + PORTE &= ~LEDS_PORTE_LEDS; + } + + static inline void LEDs_Disable(void) + { + DDRF &= ~LEDS_PORTF_LEDS; + DDRE &= ~LEDS_PORTE_LEDS; + + PORTF &= ~LEDS_PORTF_LEDS; + PORTE &= ~LEDS_PORTE_LEDS; + } + + static inline void LEDs_TurnOnLEDs(const uint8_t LEDMask) + { + PORTF |= (LEDMask & LEDS_PORTF_LEDS); + PORTE |= (LEDMask & LEDS_PORTE_LEDS); + } + + static inline void LEDs_TurnOffLEDs(const uint8_t LEDMask) + { + PORTF &= ~(LEDMask & LEDS_PORTF_LEDS); + PORTE &= ~(LEDMask & LEDS_PORTE_LEDS); + } + + static inline void LEDs_SetAllLEDs(const uint8_t LEDMask) + { + PORTF = (PORTF & ~LEDS_PORTF_LEDS) | (LEDMask & LEDS_PORTF_LEDS); + PORTE = (PORTE & ~LEDS_PORTE_LEDS) | (LEDMask & LEDS_PORTE_LEDS); + } + + static inline void LEDs_ChangeLEDs(const uint8_t LEDMask, + const uint8_t ActiveMask) + { + PORTF = (PORTF & ~(LEDMask & LEDS_PORTF_LEDS)) | (ActiveMask & LEDS_PORTF_LEDS); + PORTE = (PORTE & ~(LEDMask & LEDS_PORTE_LEDS)) | (ActiveMask & LEDS_PORTE_LEDS); + } + + static inline void LEDs_ToggleLEDs(const uint8_t LEDMask) + { + PINF = (LEDMask & LEDS_PORTF_LEDS); + PINE = (LEDMask & LEDS_PORTE_LEDS); + } + + static inline uint8_t LEDs_GetLEDs(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t LEDs_GetLEDs(void) + { + return ((PORTF & LEDS_PORTF_LEDS) | (PORTE & LEDS_PORTE_LEDS)); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/BLACKCAT/LEDs.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/BLACKCAT/LEDs.h new file mode 100644 index 00000000..778bc321 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/BLACKCAT/LEDs.h @@ -0,0 +1,139 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific LED driver header for the BLACKCAT USB JTAG. + * \copydetails Group_LEDs_BLACKCAT + * + * \note This file should not be included directly. It is automatically included as needed by the LEDs driver + * dispatch header located in LUFA/Drivers/Board/LEDs.h. + */ + +/** \ingroup Group_LEDs + * \defgroup Group_LEDs_BLACKCAT BLACKCAT + * \brief Board specific LED driver header for the BLACKCAT USB JTAG. + * + * Board specific LED driver header for the TCNISO Blackcat USB JTAG (http://www.embeddedcomputers.net/products/BlackcatUSB). + * + * + * + * + * + *
NameColorInfoActive LevelPort Pin
LEDS_LED1UnknownLED0HighPORTD.6
LEDS_LED2UnknownLED1HighPORTD.3
+ * + * @{ + */ + +#ifndef __LEDS_BLACKCAT_H__ +#define __LEDS_BLACKCAT_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_LEDS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/LEDS.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** LED mask for the first LED on the board. */ + #define LEDS_LED1 (1 << 6) + + /** LED mask for the second LED on the board. */ + #define LEDS_LED2 (1 << 3) + + /** LED mask for all the LEDs on the board. */ + #define LEDS_ALL_LEDS (LEDS_LED1 | LEDS_LED2) + + /** LED mask for none of the board LEDs. */ + #define LEDS_NO_LEDS 0 + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void LEDs_Init(void) + { + DDRD |= LEDS_ALL_LEDS; + PORTD &= ~LEDS_ALL_LEDS; + } + + static inline void LEDs_Disable(void) + { + DDRD &= ~LEDS_ALL_LEDS; + PORTD &= ~LEDS_ALL_LEDS; + } + + static inline void LEDs_TurnOnLEDs(const uint8_t LEDMask) + { + PORTD |= LEDMask; + } + + static inline void LEDs_TurnOffLEDs(const uint8_t LEDMask) + { + PORTD &= ~LEDMask; + } + + static inline void LEDs_SetAllLEDs(const uint8_t LEDMask) + { + PORTD = ((PORTD & ~LEDS_ALL_LEDS) | LEDMask); + } + + static inline void LEDs_ChangeLEDs(const uint8_t LEDMask, + const uint8_t ActiveMask) + { + PORTD = ((PORTD & ~LEDMask) | ActiveMask); + } + + static inline void LEDs_ToggleLEDs(const uint8_t LEDMask) + { + PIND = LEDMask; + } + + static inline uint8_t LEDs_GetLEDs(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t LEDs_GetLEDs(void) + { + return (PORTD & LEDS_ALL_LEDS); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/BUI/LEDs.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/BUI/LEDs.h new file mode 100644 index 00000000..cc0c01c8 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/BUI/LEDs.h @@ -0,0 +1,143 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific LED driver header for the Busware BUI. + * \copydetails Group_LEDs_BUI + * + * \note This file should not be included directly. It is automatically included as needed by the LEDs driver + * dispatch header located in LUFA/Drivers/Board/LEDs.h. + */ + +/** \ingroup Group_LEDs + * \defgroup Group_LEDs_BUI BUI + * \brief Board specific LED driver header for the Busware BUI. + * + * Board specific LED driver header for the Busware BUI (http://www.busware.de/tiki-index.php?page=BUI). + * + * + * + * + * + * + *
NameColorInfoActive LevelPort Pin
LEDS_LED1RedRGB LEDHighPORTC.2
LEDS_LED2GreenRGB LEDHighPORTC.3
LEDS_LED3BlueRGB LEDHighPORTC.4
+ * + * @{ + */ + +#ifndef __LEDS_BUI_H__ +#define __LEDS_BUI_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + +/* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_LEDS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/LEDS.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** LED mask for the first LED on the board. */ + #define LEDS_LED1 (1 << 2) + + /** LED mask for the second LED on the board. */ + #define LEDS_LED2 (1 << 3) + + /** LED mask for the third LED on the board. */ + #define LEDS_LED3 (1 << 4) + + /** LED mask for all the LEDs on the board. */ + #define LEDS_ALL_LEDS (LEDS_LED1 | LEDS_LED2 | LEDS_LED3) + + /** LED mask for none of the board LEDs. */ + #define LEDS_NO_LEDS 0 + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void LEDs_Init(void) + { + DDRC |= LEDS_ALL_LEDS; + PORTC &= ~LEDS_ALL_LEDS; + } + + static inline void LEDs_Disable(void) + { + DDRC &= ~LEDS_ALL_LEDS; + PORTC &= ~LEDS_ALL_LEDS; + } + + static inline void LEDs_TurnOnLEDs(const uint8_t LEDMask) + { + PORTC |= LEDMask; + } + + static inline void LEDs_TurnOffLEDs(const uint8_t LEDMask) + { + PORTC &= ~LEDMask; + } + + static inline void LEDs_SetAllLEDs(const uint8_t LEDMask) + { + PORTC = (PORTC & ~LEDS_ALL_LEDS) | LEDMask; + } + + static inline void LEDs_ChangeLEDs(const uint8_t LEDMask, + const uint8_t ActiveMask) + { + PORTC = (PORTC & ~LEDMask) | ActiveMask; + } + + static inline void LEDs_ToggleLEDs(const uint8_t LEDMask) + { + PINC = LEDMask; + } + + static inline uint8_t LEDs_GetLEDs(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t LEDs_GetLEDs(void) + { + return (PORTC & LEDS_ALL_LEDS); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/BUMBLEB/Buttons.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/BUMBLEB/Buttons.h new file mode 100644 index 00000000..96d1eee6 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/BUMBLEB/Buttons.h @@ -0,0 +1,105 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific Buttons driver header for the Fletchtronics BUMBLEB. + * \copydetails Group_Buttons_BUMBLEB + * + * \note This file should not be included directly. It is automatically included as needed by the Buttons driver + * dispatch header located in LUFA/Drivers/Board/Buttons.h. + */ + +/** \ingroup Group_Buttons + * \defgroup Group_Buttons_BUMBLEB BUMBLEB + * \brief Board specific Buttons driver header for the Fletchtronics BUMBLEB. + * + * Board specific buttons driver header for the Fletchtronics BUMBLEB (http://fletchtronics.net/bumble-b). The BUMBLEB + * third-party board does not include any on-board peripherals, but does have an officially recommended external peripheral + * layout for buttons, LEDs and a Joystick. + * + * + * + * + *
NameInfoActive LevelPort Pin
BUTTONS_BUTTON1HWB ButtonLowPORTD.7
+ * + * @{ + */ + +#ifndef __BUTTONS_BUMBLEB_H__ +#define __BUTTONS_BUMBLEB_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_BUTTONS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/Buttons.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Button mask for the first button on the board. */ + #define BUTTONS_BUTTON1 (1 << 7) + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void Buttons_Init(void) + { + DDRD &= ~BUTTONS_BUTTON1; + PORTD |= BUTTONS_BUTTON1; + } + + static inline void Buttons_Disable(void) + { + DDRD &= ~BUTTONS_BUTTON1; + PORTD &= ~BUTTONS_BUTTON1; + } + + static inline uint8_t Buttons_GetStatus(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t Buttons_GetStatus(void) + { + return ((PIND & BUTTONS_BUTTON1) ^ BUTTONS_BUTTON1); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/BUMBLEB/Joystick.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/BUMBLEB/Joystick.h new file mode 100644 index 00000000..92c7a2e7 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/BUMBLEB/Joystick.h @@ -0,0 +1,123 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific joystick driver header for the Fletchtronics BUMBLEB. + * \copydetails Group_Joystick_BUMBLEB + * + * \note This file should not be included directly. It is automatically included as needed by the joystick driver + * dispatch header located in LUFA/Drivers/Board/Joystick.h. + */ + +/** \ingroup Group_Joystick + * \defgroup Group_Joystick_BUMBLEB BUMBLEB + * \brief Board specific joystick driver header for the Fletchtronics BUMBLEB. + * + * Board specific joystick driver header for the Fletchtronics BUMBLEB (http://fletchtronics.net/bumble-b). The BUMBLEB + * third-party board does not include any on-board peripherals, but does have an officially recommended external peripheral + * layout for buttons, LEDs and a Joystick. + * + * + * + * + *
Left Port PinUp Port PinRight Port PinDown Port PinPress Port Pin
PORTD.2PORTD.3PORTD.0PORTD.1PORTD.4
+ * + * @{ + */ + +#ifndef __JOYSTICK_BUMBLEB_H__ +#define __JOYSTICK_BUMBLEB_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_JOYSTICK_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/Joystick.h instead. + #endif + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Macros: */ + #define JOY_MASK ((1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4)) + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Mask for the joystick being pushed in the left direction. */ + #define JOY_LEFT (1 << 2) + + /** Mask for the joystick being pushed in the upward direction. */ + #define JOY_UP (1 << 3) + + /** Mask for the joystick being pushed in the right direction. */ + #define JOY_RIGHT (1 << 0) + + /** Mask for the joystick being pushed in the downward direction. */ + #define JOY_DOWN (1 << 1) + + /** Mask for the joystick being pushed inward. */ + #define JOY_PRESS (1 << 4) + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void Joystick_Init(void) + { + DDRD &= ~JOY_MASK; + PORTD |= JOY_MASK; + } + + static inline void Joystick_Disable(void) + { + DDRD &= ~JOY_MASK; + PORTD &= ~JOY_MASK; + } + + static inline uint8_t Joystick_GetStatus(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t Joystick_GetStatus(void) + { + return (uint8_t)(~PIND & JOY_MASK); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/BUMBLEB/LEDs.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/BUMBLEB/LEDs.h new file mode 100644 index 00000000..dff06978 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/BUMBLEB/LEDs.h @@ -0,0 +1,149 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific LED driver header for the Fletchtronics BUMBLEB. + * \copydetails Group_LEDs_BUMBLEB + * + * \note This file should not be included directly. It is automatically included as needed by the LEDs driver + * dispatch header located in LUFA/Drivers/Board/LEDs.h. + */ + +/** \ingroup Group_LEDs + * \defgroup Group_LEDs_BUMBLEB BUMBLEB + * \brief Board specific LED driver header for the Fletchtronics BUMBLEB. + * + * Board specific LED driver header for the Fletchtronics BUMBLEB (http://fletchtronics.net/bumble-b). The BUMBLEB + * third-party board does not include any on-board peripherals, but does have an officially recommended external + * peripheral layout for buttons, LEDs and a Joystick. + * + * + * + * + * + * + * + *
NameColorInfoActive LevelPort Pin
LEDS_LED1N/AUser SuppliedHighPORTB.4
LEDS_LED2N/AUser SuppliedHighPORTB.5
LEDS_LED3N/AUser SuppliedHighPORTB.6
LEDS_LED4N/AUser SuppliedHighPORTB.7
+ * + * @{ + */ + +#ifndef __LEDS_BUMBLEB_H__ +#define __LEDS_BUMBLEB_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_LEDS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/LEDS.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** LED mask for the first LED on the board. */ + #define LEDS_LED1 (1 << 4) + + /** LED mask for the second LED on the board. */ + #define LEDS_LED2 (1 << 5) + + /** LED mask for the third LED on the board. */ + #define LEDS_LED3 (1 << 6) + + /** LED mask for the fourth LED on the board. */ + #define LEDS_LED4 (1 << 7) + + /** LED mask for all the LEDs on the board. */ + #define LEDS_ALL_LEDS (LEDS_LED1 | LEDS_LED2 | LEDS_LED3 | LEDS_LED4) + + /** LED mask for none of the board LEDs. */ + #define LEDS_NO_LEDS 0 + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void LEDs_Init(void) + { + DDRB |= LEDS_ALL_LEDS; + PORTB &= ~LEDS_ALL_LEDS; + } + + static inline void LEDs_Disable(void) + { + DDRB &= ~LEDS_ALL_LEDS; + PORTB &= ~LEDS_ALL_LEDS; + } + + static inline void LEDs_TurnOnLEDs(const uint8_t LedMask) + { + PORTB |= LedMask; + } + + static inline void LEDs_TurnOffLEDs(const uint8_t LedMask) + { + PORTB &= ~LedMask; + } + + static inline void LEDs_SetAllLEDs(const uint8_t LedMask) + { + PORTB = ((PORTB & ~LEDS_ALL_LEDS) | LedMask); + } + + static inline void LEDs_ChangeLEDs(const uint8_t LedMask, + const uint8_t ActiveMask) + { + PORTB = ((PORTB & ~LedMask) | ActiveMask); + } + + static inline void LEDs_ToggleLEDs(const uint8_t LEDMask) + { + PINB = LEDMask; + } + + static inline uint8_t LEDs_GetLEDs(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t LEDs_GetLEDs(void) + { + return (PORTB & LEDS_ALL_LEDS); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/CULV3/Buttons.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/CULV3/Buttons.h new file mode 100644 index 00000000..6f6933b0 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/CULV3/Buttons.h @@ -0,0 +1,103 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific LED driver header for the Busware CULV3. + * \copydetails Group_LEDs_CULV3 + * + * \note This file should not be included directly. It is automatically included as needed by the Buttons driver + * dispatch header located in LUFA/Drivers/Board/LEDs.h. + */ + +/** \ingroup Group_Buttons + * \defgroup Group_Buttons_CULV3 CULV3 + * \brief Board specific Buttons driver header for the Busware CULV3. + * + * Board specific Buttons driver header for the Busware CUL V3 (http://busware.de/tiki-index.php?page=CUL). + * + * + * + * + *
NameInfoActive LevelPort Pin
BUTTONS_BUTTON1HWB ButtonLowPORTE.2
+ * + * @{ + */ + +#ifndef __BUTTONS_CULV3_H__ +#define __BUTTONS_CULV3_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_BUTTONS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/Buttons.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Button mask for the first button on the board. */ + #define BUTTONS_BUTTON1 (1 << 2) + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void Buttons_Init(void) + { + DDRE &= ~BUTTONS_BUTTON1; + PORTE |= BUTTONS_BUTTON1; + } + + static inline void Buttons_Disable(void) + { + DDRE &= ~BUTTONS_BUTTON1; + PORTE &= ~BUTTONS_BUTTON1; + } + + static inline uint8_t Buttons_GetStatus(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t Buttons_GetStatus(void) + { + return ((PINE & BUTTONS_BUTTON1) ^ BUTTONS_BUTTON1); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/CULV3/LEDs.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/CULV3/LEDs.h new file mode 100644 index 00000000..86700d14 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/CULV3/LEDs.h @@ -0,0 +1,135 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific LED driver header for the Busware CUL V3. + * \copydetails Group_LEDs_CULV3 + * + * \note This file should not be included directly. It is automatically included as needed by the LEDs driver + * dispatch header located in LUFA/Drivers/Board/LEDs.h. + */ + +/** \ingroup Group_LEDs + * \defgroup Group_LEDs_CULV3 CULV3 + * \brief Board specific LED driver header for the Busware CUL V3. + * + * Board specific LED driver header for the Busware CUL V3 (http://busware.de/tiki-index.php?page=CUL). + * + * + * + * + *
NameColorInfoActive LevelPort Pin
LEDS_LED1YellowGeneral IndicatorHighPORTE.6
+ * + * @{ + */ + +#ifndef __LEDS_CULV3_H__ +#define __LEDS_CULV3_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_LEDS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/LEDS.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** LED mask for the first LED on the board. */ + #define LEDS_LED1 (1 << 6) + + /** LED mask for all the LEDs on the board. */ + #define LEDS_ALL_LEDS LEDS_LED1 + + /** LED mask for the none of the board LEDs. */ + #define LEDS_NO_LEDS 0 + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void LEDs_Init(void) + { + DDRE |= LEDS_ALL_LEDS; + PORTE &= ~LEDS_ALL_LEDS; + } + + static inline void LEDs_Disable(void) + { + DDRE &= ~LEDS_ALL_LEDS; + PORTE &= ~LEDS_ALL_LEDS; + } + + static inline void LEDs_TurnOnLEDs(const uint8_t LEDMask) + { + PORTE |= LEDMask; + } + + static inline void LEDs_TurnOffLEDs(const uint8_t LEDMask) + { + PORTE &= ~LEDMask; + } + + static inline void LEDs_SetAllLEDs(const uint8_t LEDMask) + { + PORTE = ((PORTE & ~LEDS_ALL_LEDS) | LEDMask); + } + + static inline void LEDs_ChangeLEDs(const uint8_t LEDMask, + const uint8_t ActiveMask) + { + PORTE = ((PORTE & ~LEDMask) | ActiveMask); + } + + static inline void LEDs_ToggleLEDs(const uint8_t LEDMask) + { + PINE = LEDMask; + } + + static inline uint8_t LEDs_GetLEDs(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t LEDs_GetLEDs(void) + { + return (PORTE & LEDS_ALL_LEDS); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/DUCE/LEDs.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/DUCE/LEDs.h new file mode 100644 index 00000000..0d31b481 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/DUCE/LEDs.h @@ -0,0 +1,147 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific LED driver header for the DorkbotPDX Duce. + * \copydetails Group_LEDs_DUCE + * + * \note This file should not be included directly. It is automatically included as needed by the LEDs driver + * dispatch header located in LUFA/Drivers/Board/LEDs.h. + */ + +/** \ingroup Group_LEDs + * \defgroup Group_LEDs_DUCE DUCE + * \brief Board specific LED driver header for the DorkbotPDX Duce. + * + * Board specific LED driver header for the DorkbotPDX Duce (http://dorkbotpdx.org/wiki/duce). + * + * + * + * + * + * + * + *
NameColorInfoActive LevelPort Pin
LEDS_LED1RedBicolor Indicator 1HighPORTC.4
LEDS_LED2GreenBicolor Indicator 1HighPORTC.5
LEDS_LED3RedBicolor Indicator 2HighPORTC.6
LEDS_LED4GreenBicolor Indicator 2HighPORTC.7
+ * + * @{ + */ + +#ifndef __LEDS_DUCE_H__ +#define __LEDS_DUCE_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_LEDS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/LEDS.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** LED mask for the first LED on the board. */ + #define LEDS_LED1 (1 << 4) + + /** LED mask for the second LED on the board. */ + #define LEDS_LED2 (1 << 5) + + /** LED mask for the third LED on the board. */ + #define LEDS_LED3 (1 << 6) + + /** LED mask for the fourth LED on the board. */ + #define LEDS_LED4 (1 << 7) + + /** LED mask for all the LEDs on the board. */ + #define LEDS_ALL_LEDS (LEDS_LED1 | LEDS_LED2 | LEDS_LED3 | LEDS_LED4) + + /** LED mask for none of the board LEDs. */ + #define LEDS_NO_LEDS 0 + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void LEDs_Init(void) + { + DDRC |= LEDS_ALL_LEDS; + PORTC &= ~LEDS_ALL_LEDS; + } + + static inline void LEDs_Disable(void) + { + DDRC &= ~LEDS_ALL_LEDS; + PORTC &= ~LEDS_ALL_LEDS; + } + + static inline void LEDs_TurnOnLEDs(const uint8_t LEDMask) + { + PORTC |= LEDMask; + } + + static inline void LEDs_TurnOffLEDs(const uint8_t LEDMask) + { + PORTC &= ~LEDMask; + } + + static inline void LEDs_SetAllLEDs(const uint8_t LEDMask) + { + PORTC = ((PORTC & ~LEDS_ALL_LEDS) | LEDMask); + } + + static inline void LEDs_ChangeLEDs(const uint8_t LEDMask, + const uint8_t ActiveMask) + { + PORTC = ((PORTC & ~LEDMask) | ActiveMask); + } + + static inline void LEDs_ToggleLEDs(const uint8_t LEDMask) + { + PINC = LEDMask; + } + + static inline uint8_t LEDs_GetLEDs(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t LEDs_GetLEDs(void) + { + return (PORTC & LEDS_ALL_LEDS); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/EVK527/Buttons.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/EVK527/Buttons.h new file mode 100644 index 00000000..82cb204e --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/EVK527/Buttons.h @@ -0,0 +1,103 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific Buttons driver header for the Atmel EVK527. + * \copydetails Group_Buttons_EVK527 + * + * \note This file should not be included directly. It is automatically included as needed by the Buttons driver + * dispatch header located in LUFA/Drivers/Board/Buttons.h. + */ + +/** \ingroup Group_Buttons + * \defgroup Group_Buttons_EVK527 EVK527 + * \brief Board specific Buttons driver header for the Atmel EVK527. + * + * Board specific Buttons driver header for the Atmel EVK527. + * + * + * + * + *
NameInfoActive LevelPort Pin
BUTTONS_BUTTON1HWB ButtonLowPORTE.2
+ * + * @{ + */ + +#ifndef __BUTTONS_EVK527_H__ +#define __BUTTONS_EVK527_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_BUTTONS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/Buttons.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Button mask for the first button on the board. */ + #define BUTTONS_BUTTON1 (1 << 2) + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void Buttons_Init(void) + { + DDRE &= ~BUTTONS_BUTTON1; + PORTE |= BUTTONS_BUTTON1; + } + + static inline void Buttons_Disable(void) + { + DDRE &= ~BUTTONS_BUTTON1; + PORTE &= ~BUTTONS_BUTTON1; + } + + static inline uint8_t Buttons_GetStatus(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t Buttons_GetStatus(void) + { + return ((PINE & BUTTONS_BUTTON1) ^ BUTTONS_BUTTON1); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/EVK527/Dataflash.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/EVK527/Dataflash.h new file mode 100644 index 00000000..53af7418 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/EVK527/Dataflash.h @@ -0,0 +1,220 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific Dataflash driver header for the Atmel EVK527. + * \copydetails Group_Dataflash_EVK527 + * + * \note This file should not be included directly. It is automatically included as needed by the dataflash driver + * dispatch header located in LUFA/Drivers/Board/Dataflash.h. + */ + +/** \ingroup Group_Dataflash + * \defgroup Group_Dataflash_EVK527 EVK527 + * \brief Board specific Dataflash driver header for the Atmel EVK527. + * + * Board specific Dataflash driver header for the Atmel EVK527. + * + * + * + * + *
NameInfoSelect PinSPI Port
DATAFLASH_CHIP1AT45DB321C (4MB)PORTE.6SPI0
+ * + * @{ + */ + +#ifndef __DATAFLASH_EVK527_H__ +#define __DATAFLASH_EVK527_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + #include "../../../Misc/AT45DB321C.h" + #include "../../../Peripheral/SPI.h" + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_DATAFLASH_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/Dataflash.h instead. + #endif + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Macros: */ + #define DATAFLASH_CHIPCS_MASK (1 << 6) + #define DATAFLASH_CHIPCS_DDR DDRE + #define DATAFLASH_CHIPCS_PORT PORTE + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Constant indicating the total number of dataflash ICs mounted on the selected board. */ + #define DATAFLASH_TOTALCHIPS 1 + + /** Mask for no dataflash chip selected. */ + #define DATAFLASH_NO_CHIP DATAFLASH_CHIPCS_MASK + + /** Mask for the first dataflash chip selected. */ + #define DATAFLASH_CHIP1 0 + + /** Internal main memory page size for the board's dataflash IC. */ + #define DATAFLASH_PAGE_SIZE 512 + + /** Total number of pages inside the board's dataflash IC. */ + #define DATAFLASH_PAGES 8192 + + /* Inline Functions: */ + /** Initializes the dataflash driver so that commands and data may be sent to an attached dataflash IC. + * The microcontroller's SPI driver MUST be initialized before any of the dataflash commands are used. + */ + static inline void Dataflash_Init(void) + { + DATAFLASH_CHIPCS_DDR |= DATAFLASH_CHIPCS_MASK; + DATAFLASH_CHIPCS_PORT |= DATAFLASH_CHIPCS_MASK; + } + + /** Sends a byte to the currently selected dataflash IC, and returns a byte from the dataflash. + * + * \param[in] Byte Byte of data to send to the dataflash + * + * \return Last response byte from the dataflash + */ + static inline uint8_t Dataflash_TransferByte(const uint8_t Byte) ATTR_ALWAYS_INLINE; + static inline uint8_t Dataflash_TransferByte(const uint8_t Byte) + { + return SPI_TransferByte(Byte); + } + + /** Sends a byte to the currently selected dataflash IC, and ignores the next byte from the dataflash. + * + * \param[in] Byte Byte of data to send to the dataflash + */ + static inline void Dataflash_SendByte(const uint8_t Byte) ATTR_ALWAYS_INLINE; + static inline void Dataflash_SendByte(const uint8_t Byte) + { + SPI_SendByte(Byte); + } + + /** Sends a dummy byte to the currently selected dataflash IC, and returns the next byte from the dataflash. + * + * \return Last response byte from the dataflash + */ + static inline uint8_t Dataflash_ReceiveByte(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT; + static inline uint8_t Dataflash_ReceiveByte(void) + { + return SPI_ReceiveByte(); + } + + /** Determines the currently selected dataflash chip. + * + * \return Mask of the currently selected Dataflash chip, either \ref DATAFLASH_NO_CHIP if no chip is selected + * or a DATAFLASH_CHIPn mask (where n is the chip number). + */ + static inline uint8_t Dataflash_GetSelectedChip(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT; + static inline uint8_t Dataflash_GetSelectedChip(void) + { + return (DATAFLASH_CHIPCS_PORT & DATAFLASH_CHIPCS_MASK); + } + + /** Selects the given dataflash chip. + * + * \param[in] ChipMask Mask of the Dataflash IC to select, in the form of DATAFLASH_CHIPn mask (where n is + * the chip number). + */ + static inline void Dataflash_SelectChip(const uint8_t ChipMask) ATTR_ALWAYS_INLINE; + static inline void Dataflash_SelectChip(const uint8_t ChipMask) + { + DATAFLASH_CHIPCS_PORT = ((DATAFLASH_CHIPCS_PORT & ~DATAFLASH_CHIPCS_MASK) | ChipMask); + } + + /** Deselects the current dataflash chip, so that no dataflash is selected. */ + static inline void Dataflash_DeselectChip(void) ATTR_ALWAYS_INLINE; + static inline void Dataflash_DeselectChip(void) + { + Dataflash_SelectChip(DATAFLASH_NO_CHIP); + } + + /** Selects a dataflash IC from the given page number, which should range from 0 to + * ((DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS) - 1). For boards containing only one + * dataflash IC, this will select DATAFLASH_CHIP1. If the given page number is outside + * the total number of pages contained in the boards dataflash ICs, all dataflash ICs + * are deselected. + * + * \param[in] PageAddress Address of the page to manipulate, ranging from + * 0 to ((DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS) - 1). + */ + static inline void Dataflash_SelectChipFromPage(const uint16_t PageAddress) + { + Dataflash_DeselectChip(); + + if (PageAddress >= DATAFLASH_PAGES) + return; + + Dataflash_SelectChip(DATAFLASH_CHIP1); + } + + /** Toggles the select line of the currently selected dataflash IC, so that it is ready to receive + * a new command. + */ + static inline void Dataflash_ToggleSelectedChipCS(void) + { + uint8_t SelectedChipMask = Dataflash_GetSelectedChip(); + + Dataflash_DeselectChip(); + Dataflash_SelectChip(SelectedChipMask); + } + + /** Spin-loops while the currently selected dataflash is busy executing a command, such as a main + * memory page program or main memory to buffer transfer. + */ + static inline void Dataflash_WaitWhileBusy(void) + { + Dataflash_ToggleSelectedChipCS(); + Dataflash_SendByte(DF_CMD_GETSTATUS); + while (!(Dataflash_ReceiveByte() & DF_STATUS_READY)); + Dataflash_ToggleSelectedChipCS(); + } + + /** Sends a set of page and buffer address bytes to the currently selected dataflash IC, for use with + * dataflash commands which require a complete 24-bit address. + * + * \param[in] PageAddress Page address within the selected dataflash IC + * \param[in] BufferByte Address within the dataflash's buffer + */ + static inline void Dataflash_SendAddressBytes(uint16_t PageAddress, + const uint16_t BufferByte) + { + Dataflash_SendByte(PageAddress >> 5); + Dataflash_SendByte((PageAddress << 3) | (BufferByte >> 8)); + Dataflash_SendByte(BufferByte); + } + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/EVK527/Joystick.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/EVK527/Joystick.h new file mode 100644 index 00000000..266b1490 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/EVK527/Joystick.h @@ -0,0 +1,130 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific joystick driver header for the Atmel EVK527. + * \copydetails Group_Joystick_EVK527 + * + * \note This file should not be included directly. It is automatically included as needed by the joystick driver + * dispatch header located in LUFA/Drivers/Board/Joystick.h. + */ + +/** \ingroup Group_Joystick + * \defgroup Group_Joystick_EVK527 EVK527 + * \brief Board specific joystick driver header for the Atmel EVK527. + * + * Board specific joystick driver header for the Atmel EVK527. + * + * + * + * + *
Left Port PinUp Port PinRight Port PinDown Port PinPress Port Pin
PORTF.4PORTF.5PORTF.7PORTC.6PORTF.6
+ * + * @{ + */ + +#ifndef __JOYSTICK_EVK527_H__ +#define __JOYSTICK_EVK527_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_JOYSTICK_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/Joystick.h instead. + #endif + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Macros: */ + #define JOY_FMASK ((1 << 4) | (1 << 5) | (1 << 6) | (1 << 7)) + #define JOY_CMASK (1 << 6) + + #define JOY_PORTC_MASK_SHIFT 3 + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Mask for the joystick being pushed in the left direction. */ + #define JOY_LEFT (1 << 4) + + /** Mask for the joystick being pushed in the right direction. */ + #define JOY_RIGHT (1 << 7) + + /** Mask for the joystick being pushed in the upward direction. */ + #define JOY_UP (1 << 5) + + /** Mask for the joystick being pushed in the downward direction. */ + #define JOY_DOWN ((1 << 6) >> JOY_PORTC_MASK_SHIFT) + + /** Mask for the joystick being pushed inward. */ + #define JOY_PRESS (1 << 6) + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void Joystick_Init(void) + { + DDRF &= ~JOY_FMASK; + DDRC &= ~JOY_CMASK; + + PORTF |= JOY_FMASK; + PORTC |= JOY_CMASK; + } + + static inline void Joystick_Disable(void) + { + DDRF &= ~JOY_FMASK; + DDRC &= ~JOY_CMASK; + + PORTF &= ~JOY_FMASK; + PORTC &= ~JOY_CMASK; + } + + static inline uint8_t Joystick_GetStatus(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t Joystick_GetStatus(void) + { + return (((uint8_t)~PINF & JOY_FMASK) | (((uint8_t)~PINC & JOY_CMASK) >> JOY_PORTC_MASK_SHIFT)); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/EVK527/LEDs.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/EVK527/LEDs.h new file mode 100644 index 00000000..58483a9b --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/EVK527/LEDs.h @@ -0,0 +1,143 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific LED driver header for the Atmel EVK527. + * \copydetails Group_LEDs_EVK527 + * + * \note This file should not be included directly. It is automatically included as needed by the LEDs driver + * dispatch header located in LUFA/Drivers/Board/LEDs.h. + */ + +/** \ingroup Group_LEDs + * \defgroup Group_LEDs_EVK527 EVK527 + * \brief Board specific LED driver header for the Atmel EVK527. + * + * Board specific LED driver header for the Atmel EVK527. + * + * + * + * + * + * + *
NameColorInfoActive LevelPort Pin
LEDS_LED1GreenGeneral IndicatorHighPORTD.5
LEDS_LED2GreenGeneral IndicatorHighPORTD.6
LEDS_LED3GreenGeneral IndicatorHighPORTD.7
+ * + * @{ + */ + +#ifndef __LEDS_EVK527_H__ +#define __LEDS_EVK527_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_LEDS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/LEDS.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** LED mask for the first LED on the board. */ + #define LEDS_LED1 (1 << 5) + + /** LED mask for the second LED on the board. */ + #define LEDS_LED2 (1 << 6) + + /** LED mask for the third LED on the board. */ + #define LEDS_LED3 (1 << 7) + + /** LED mask for all the LEDs on the board. */ + #define LEDS_ALL_LEDS (LEDS_LED1 | LEDS_LED2 | LEDS_LED3) + + /** LED mask for none of the board LEDs. */ + #define LEDS_NO_LEDS 0 + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void LEDs_Init(void) + { + DDRD |= LEDS_ALL_LEDS; + PORTD &= ~LEDS_ALL_LEDS; + } + + static inline void LEDs_Disable(void) + { + DDRD &= ~LEDS_ALL_LEDS; + PORTD &= ~LEDS_ALL_LEDS; + } + + static inline void LEDs_TurnOnLEDs(const uint8_t LEDMask) + { + PORTD |= LEDMask; + } + + static inline void LEDs_TurnOffLEDs(const uint8_t LEDMask) + { + PORTD &= ~LEDMask; + } + + static inline void LEDs_SetAllLEDs(const uint8_t LEDMask) + { + PORTD = ((PORTD & ~LEDS_ALL_LEDS) | LEDMask); + } + + static inline void LEDs_ChangeLEDs(const uint8_t LEDMask, + const uint8_t ActiveMask) + { + PORTD = ((PORTD & ~LEDMask) | ActiveMask); + } + + static inline void LEDs_ToggleLEDs(const uint8_t LEDMask) + { + PIND = LEDMask; + } + + static inline uint8_t LEDs_GetLEDs(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t LEDs_GetLEDs(void) + { + return (PORTD & LEDS_ALL_LEDS); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/JMDBU2/Buttons.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/JMDBU2/Buttons.h new file mode 100644 index 00000000..67783ca2 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/JMDBU2/Buttons.h @@ -0,0 +1,103 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific Buttons driver header for the Mattairtech JM-DB-U2. + * \copydetails Group_Buttons_JMDBU2 + * + * \note This file should not be included directly. It is automatically included as needed by the Buttons driver + * dispatch header located in LUFA/Drivers/Board/Buttons.h. + */ + +/** \ingroup Group_Buttons + * \defgroup Group_Buttons_JMDBU2 JMDBU2 + * \brief Board specific Buttons driver header for the Mattairtech JM-DB-U2. + * + * Board specific Buttons driver header for the Mattairtech JM-DB-U2 (http://u2.mattair.net/index.html). + * + * + * + * + *
NameInfoActive LevelPort Pin
BUTTONS_BUTTON1HWB ButtonLowPORTD.7
+ * + * @{ + */ + +#ifndef __BUTTONS_JMDBU2_H__ +#define __BUTTONS_JMDBU2_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_BUTTONS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/Buttons.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Button mask for the first button on the board. */ + #define BUTTONS_BUTTON1 (1 << 7) + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void Buttons_Init(void) + { + DDRD &= ~BUTTONS_BUTTON1; + PORTD |= BUTTONS_BUTTON1; + } + + static inline void Buttons_Disable(void) + { + DDRD &= ~BUTTONS_BUTTON1; + PORTD &= ~BUTTONS_BUTTON1; + } + + static inline uint8_t Buttons_GetStatus(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t Buttons_GetStatus(void) + { + return ((PIND & BUTTONS_BUTTON1) ^ BUTTONS_BUTTON1); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/JMDBU2/LEDs.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/JMDBU2/LEDs.h new file mode 100644 index 00000000..d64cdad6 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/JMDBU2/LEDs.h @@ -0,0 +1,135 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific LED driver header for the Mattairtech JM-DB-U2. + * \copydetails Group_LEDs_JMDBU2 + * + * \note This file should not be included directly. It is automatically included as needed by the LEDs driver + * dispatch header located in LUFA/Drivers/Board/LEDs.h. + */ + +/** \ingroup Group_LEDs + * \defgroup Group_LEDs_JMDBU2 JMDBU2 + * \brief Board specific LED driver header for the Mattairtech JM-DB-U2. + * + * Board specific LED driver header for the Mattairtech JM-DB-U2 (http://u2.mattair.net/index.html). + * + * + * + * + *
NameColorInfoActive LevelPort Pin
LEDS_LED1GreenGeneral IndicatorHighPORTD.4
+ * + * @{ + */ + +#ifndef __LEDS_JMDBU2_H__ +#define __LEDS_JMDBU2_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_LEDS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/LEDS.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** LED mask for the first LED on the board. */ + #define LEDS_LED1 (1 << 4) + + /** LED mask for all the LEDs on the board. */ + #define LEDS_ALL_LEDS LEDS_LED1 + + /** LED mask for none of the board LEDs. */ + #define LEDS_NO_LEDS 0 + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void LEDs_Init(void) + { + DDRD |= LEDS_ALL_LEDS; + PORTD &= ~LEDS_ALL_LEDS; + } + + static inline void LEDs_Disable(void) + { + DDRD &= ~LEDS_ALL_LEDS; + PORTD &= ~LEDS_ALL_LEDS; + } + + static inline void LEDs_TurnOnLEDs(const uint8_t LEDMask) + { + PORTD |= LEDMask; + } + + static inline void LEDs_TurnOffLEDs(const uint8_t LEDMask) + { + PORTD &= ~LEDMask; + } + + static inline void LEDs_SetAllLEDs(const uint8_t LEDMask) + { + PORTD = ((PORTD & ~LEDS_ALL_LEDS) | LEDMask); + } + + static inline void LEDs_ChangeLEDs(const uint8_t LEDMask, + const uint8_t ActiveMask) + { + PORTD = ((PORTD & ~LEDMask) | ActiveMask); + } + + static inline void LEDs_ToggleLEDs(const uint8_t LEDMask) + { + PIND = LEDMask; + } + + static inline uint8_t LEDs_GetLEDs(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t LEDs_GetLEDs(void) + { + return (PORTD & LEDS_ALL_LEDS); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/MAXIMUS/LEDs.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/MAXIMUS/LEDs.h new file mode 100644 index 00000000..932bfa14 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/MAXIMUS/LEDs.h @@ -0,0 +1,139 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific LED driver header for the Maximus. + * \copydetails Group_LEDs_MAXIMUS + * + * \note This file should not be included directly. It is automatically included as needed by the LEDs driver + * dispatch header located in LUFA/Drivers/Board/LEDs.h. + */ + +/** \ingroup Group_LEDs + * \defgroup Group_LEDs_MAXIMUS MAXIMUS + * \brief Board specific LED driver header for the Maximus. + * + * Board specific LED driver header for the Maximus (http://www.avrusb.com/). + * + * + * + * + * + *
NameColorInfoActive LevelPort Pin
LEDS_LED1GreenLGHighPORTB.6
LEDS_LED2RedLRHighPORTB.7
+ * + * @{ + */ + +#ifndef __LEDS_MAXIMUS_H__ +#define __LEDS_MAXIMUS_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_LEDS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/LEDS.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** LED mask for the first LED on the board. */ + #define LEDS_LED1 (1 << 6) + + /** LED mask for the second LED on the board. */ + #define LEDS_LED2 (1 << 7) + + /** LED mask for all the LEDs on the board. */ + #define LEDS_ALL_LEDS (LEDS_LED1 | LEDS_LED2) + + /** LED mask for the none of the board LEDs. */ + #define LEDS_NO_LEDS 0 + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void LEDs_Init(void) + { + DDRB |= LEDS_ALL_LEDS; + PORTB &= ~LEDS_ALL_LEDS; + } + + static inline void LEDs_Disable(void) + { + DDRB &= ~LEDS_ALL_LEDS; + PORTB &= ~LEDS_ALL_LEDS; + } + + static inline void LEDs_TurnOnLEDs(const uint8_t LEDMask) + { + PORTB |= LEDMask; + } + + static inline void LEDs_TurnOffLEDs(const uint8_t LEDMask) + { + PORTB &= ~LEDMask; + } + + static inline void LEDs_SetAllLEDs(const uint8_t LEDMask) + { + PORTB = ((PORTB & ~LEDS_ALL_LEDS) | LEDMask); + } + + static inline void LEDs_ChangeLEDs(const uint8_t LEDMask, + const uint8_t ActiveMask) + { + PORTB = ((PORTB & ~LEDMask) | ActiveMask); + } + + static inline void LEDs_ToggleLEDs(const uint8_t LEDMask) + { + PINB = LEDMask; + } + + static inline uint8_t LEDs_GetLEDs(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t LEDs_GetLEDs(void) + { + return (PORTB & LEDS_ALL_LEDS); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/MICROPENDOUS/Buttons.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/MICROPENDOUS/Buttons.h new file mode 100644 index 00000000..36a7bebe --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/MICROPENDOUS/Buttons.h @@ -0,0 +1,208 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific Buttons driver header for the Micropendous series boards. + * \copydetails Group_Buttons_MICROPENDOUS_32U2 + * + * \note This file should not be included directly. It is automatically included as needed by the Buttons driver + * dispatch header located in LUFA/Drivers/Board/Buttons.h. + */ + +/** \ingroup Group_Buttons + * \defgroup Group_Buttons_MICROPENDOUS_A MICROPENDOUS_A + * \brief Board specific Button driver header for the Micropendous A (https://code.google.com/p/micropendous/wiki/MicropendousA). + * + * See \ref Group_Buttons_MICROPENDOUS_32U2 for more details. + */ + +/** \ingroup Group_Buttons + * \defgroup Group_Buttons_MICROPENDOUS_1 MICROPENDOUS_1 + * \brief Board specific Button driver header for the Micropendous 1 (https://code.google.com/p/micropendous/wiki/Micropendous1). + * + * See \ref Group_Buttons_MICROPENDOUS_32U2 for more details. + */ + +/** \ingroup Group_Buttons + * \defgroup Group_Buttons_MICROPENDOUS_2 MICROPENDOUS_2 + * \brief Board specific Button driver header for the Micropendous 2 (https://code.google.com/p/micropendous/wiki/Micropendous2). + * + * See \ref Group_Buttons_MICROPENDOUS_32U2 for more details. + */ + +/** \ingroup Group_Buttons + * \defgroup Group_Buttons_MICROPENDOUS_3 MICROPENDOUS_3 + * \brief Board specific Button driver header for the Micropendous 3 (https://code.google.com/p/micropendous/wiki/Micropendous3). + * + * See \ref Group_Buttons_MICROPENDOUS_32U2 for more details. + */ + +/** \ingroup Group_Buttons + * \defgroup Group_Buttons_MICROPENDOUS_4 MICROPENDOUS_4 + * \brief Board specific Button driver header for the Micropendous 4 (https://code.google.com/p/micropendous/wiki/Micropendous4). + * + * See \ref Group_Buttons_MICROPENDOUS_32U2 for more details. + */ + +/** \ingroup Group_Buttons + * \defgroup Group_Buttons_MICROPENDOUS_DIP MICROPENDOUS_DIP + * \brief Board specific Button driver header for the Micropendous DIP (https://code.google.com/p/micropendous/wiki/MicropendousDIP). + * + * See \ref Group_Buttons_MICROPENDOUS_32U2 for more details. + */ + +/** \ingroup Group_Buttons + * \defgroup Group_Buttons_MICROPENDOUS_REV1 MICROPENDOUS_REV1 + * \brief Board specific Button driver header for the Micropendous Arduino-like Revision 1 (https://code.google.com/p/micropendous/wiki/Micropendous). + * + * See \ref Group_Buttons_MICROPENDOUS_32U2 for more details. + */ + +/** \ingroup Group_Buttons + * \defgroup Group_Buttons_MICROPENDOUS_REV2 MICROPENDOUS_REV2 + * \brief Board specific Button driver header for the Micropendous Arduino-like Revision 2 (https://code.google.com/p/micropendous/wiki/Micropendous). + * + * See \ref Group_Buttons_MICROPENDOUS_32U2 for more details. + */ + +/** \ingroup Group_Buttons + * \defgroup Group_Buttons_MICROPENDOUS_32U2 MICROPENDOUS_32U2 + * \brief Board specific Buttons driver header for the Micropendous 32U2. + * + * \note There are multiple supported Micropendous boards, compile with BOARD = MICROPENDOUS_{VERSION}. + * + * Board specific Buttons driver header for the Micropendous 32U2 (https://code.google.com/p/micropendous/wiki/Micropendous_32U2). + * + * BOARD_MICROPENDOUS_1 and BOARD_MICROPENDOUS_32U2: + * + * + * + *
NameInfoActive LevelPort Pin
BUTTONS_BUTTON1HWB ButtonLowPORTD.7
+ * + * Other Revisions: + * + * + * + *
NameInfoActive LevelPort Pin
BUTTONS_BUTTON1HWB ButtonLowPORTE.2
+ * + * @{ + */ + +#ifndef __BUTTONS_MICROPENDOUS_H__ +#define __BUTTONS_MICROPENDOUS_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_BUTTONS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/Buttons.h instead. + #endif + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + #if (BOARD == BOARD_MICROPENDOUS_32U2) + #define _BOARD_BUTTON1_MASK (1 << 7) + #define _BOARD_BUTTON_PORTLETTER D + #elif (BOARD == BOARD_MICROPENDOUS_A) + #define _BOARD_BUTTON1_MASK (1 << 2) + #define _BOARD_BUTTON_PORTLETTER E + #elif (BOARD == BOARD_MICROPENDOUS_1) + #define _BOARD_BUTTON1_MASK (1 << 7) + #define _BOARD_BUTTON_PORTLETTER D + #elif (BOARD == BOARD_MICROPENDOUS_2) + #define _BOARD_BUTTON1_MASK (1 << 2) + #define _BOARD_BUTTON_PORTLETTER E + #elif (BOARD == BOARD_MICROPENDOUS_3) + #define _BOARD_BUTTON1_MASK (1 << 2) + #define _BOARD_BUTTON_PORTLETTER E + #elif (BOARD == BOARD_MICROPENDOUS_4) + #define _BOARD_BUTTON1_MASK (1 << 2) + #define _BOARD_BUTTON_PORTLETTER E + #elif (BOARD == BOARD_MICROPENDOUS_DIP) + #define _BOARD_BUTTON1_MASK (1 << 2) + #define _BOARD_BUTTON_PORTLETTER E + #elif (BOARD == BOARD_MICROPENDOUS_REV1) + #define _BOARD_BUTTON1_MASK (1 << 2) + #define _BOARD_BUTTON_PORTLETTER E + #elif (BOARD == BOARD_MICROPENDOUS_REV2) + #define _BOARD_BUTTON1_MASK (1 << 2) + #define _BOARD_BUTTON_PORTLETTER E + #endif + + #define _BOARD_BUTTON_CONCAT2(Reg, Letter) Reg ## Letter + #define _BOARD_BUTTON_CONCAT(Reg, Letter) _BOARD_BUTTON_CONCAT2(Reg, Letter) + + #define _BOARD_BUTTON_PORT _BOARD_BUTTON_CONCAT(PORT, _BOARD_BUTTON_PORTLETTER) + #define _BOARD_BUTTON_PIN _BOARD_BUTTON_CONCAT(PIN, _BOARD_BUTTON_PORTLETTER) + #define _BOARD_BUTTON_DDR _BOARD_BUTTON_CONCAT(DDR, _BOARD_BUTTON_PORTLETTER) + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Button mask for the first button on the board. */ + #define BUTTONS_BUTTON1 _BOARD_BUTTON1_MASK + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void Buttons_Init(void) + { + _BOARD_BUTTON_DDR &= ~BUTTONS_BUTTON1; + _BOARD_BUTTON_PORT |= BUTTONS_BUTTON1; + } + + static inline void Buttons_Disable(void) + { + _BOARD_BUTTON_DDR &= ~BUTTONS_BUTTON1; + _BOARD_BUTTON_PORT &= ~BUTTONS_BUTTON1; + } + + static inline uint8_t Buttons_GetStatus(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t Buttons_GetStatus(void) + { + return ((_BOARD_BUTTON_PIN & BUTTONS_BUTTON1) ^ BUTTONS_BUTTON1); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/MICROPENDOUS/LEDs.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/MICROPENDOUS/LEDs.h new file mode 100644 index 00000000..eeb33771 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/MICROPENDOUS/LEDs.h @@ -0,0 +1,177 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific LED driver header for the Micropendous-32U2. + * \copydetails Group_LEDs_MICROPENDOUS_32U2 + * + * \note This file should not be included directly. It is automatically included as needed by the LEDs driver + * dispatch header located in LUFA/Drivers/Board/LEDs.h. + */ + +/** \ingroup Group_LEDs + * \defgroup Group_LEDs_MICROPENDOUS_REV1 MICROPENDOUS_REV1 + * \brief Board specific LED driver header for the Micropendous Arduino-like Revision 1 (https://code.google.com/p/micropendous/wiki/Micropendous). + * + * See \ref Group_LEDs_MICROPENDOUS_32U2 for more details. + */ + +/** \ingroup Group_LEDs + * \defgroup Group_LEDs_MICROPENDOUS_REV2 MICROPENDOUS_REV2 + * \brief Board specific LED driver header for the Micropendous Arduino-like Revision 2 (https://code.google.com/p/micropendous/wiki/Micropendous). + * + * See \ref Group_LEDs_MICROPENDOUS_32U2 for more details. + */ + +/** \ingroup Group_LEDs + * \defgroup Group_LEDs_MICROPENDOUS_32U2 MICROPENDOUS_32U2 + * \brief Board specific LED driver header for the Micropendous-32U2. + * + * Board specific LED driver header for the Micropendous 32U2 (https://code.google.com/p/micropendous/wiki/Micropendous_32U2). + * + * BOARD_MICROPENDOUS_32U2: + * + * + * + *
NameColorInfoActive LevelPort Pin
LEDS_LED1GreenGeneral IndicatorHighPORTD.6
+ * + * Other Revisions: + * + * + * + *
NameColorInfoActive LevelPort Pin
LEDS_LED1GreenGeneral IndicatorHighPORTB.1
+ * + * @{ + */ + +#ifndef __LEDS_MICROPENDOUS_H__ +#define __LEDS_MICROPENDOUS_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_LEDS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/LEDS.h instead. + #endif + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + #if (BOARD == BOARD_MICROPENDOUS_32U2) + #define _BOARD_LED1_MASK (1 << 6) + #define _BOARD_LED_PORTLETTER D + #elif (BOARD == BOARD_MICROPENDOUS_REV1) + #define _BOARD_LED1_MASK (1 << 1) + #define _BOARD_LED_PORTLETTER B + #elif (BOARD == BOARD_MICROPENDOUS_REV2) + #define _BOARD_LED1_MASK (1 << 1) + #define _BOARD_LED_PORTLETTER B + #endif + + #define _BOARD_LED_CONCAT2(Reg, Letter) Reg ## Letter + #define _BOARD_LED_CONCAT(Reg, Letter) _BOARD_LED_CONCAT2(Reg, Letter) + + #define _BOARD_LED_PORT _BOARD_LED_CONCAT(PORT, _BOARD_LED_PORTLETTER) + #define _BOARD_LED_PIN _BOARD_LED_CONCAT(PIN, _BOARD_LED_PORTLETTER) + #define _BOARD_LED_DDR _BOARD_LED_CONCAT(DDR, _BOARD_LED_PORTLETTER) + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** LED mask for the first LED on the board. */ + #define LEDS_LED1 _BOARD_LED1_MASK + + /** LED mask for all the LEDs on the board. */ + #define LEDS_ALL_LEDS LEDS_LED1 + + /** LED mask for the none of the board LEDs. */ + #define LEDS_NO_LEDS 0 + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void LEDs_Init(void) + { + _BOARD_LED_DDR |= LEDS_ALL_LEDS; + _BOARD_LED_PORT &= ~LEDS_ALL_LEDS; + } + + static inline void LEDs_Disable(void) + { + _BOARD_LED_DDR &= ~LEDS_ALL_LEDS; + _BOARD_LED_PORT &= ~LEDS_ALL_LEDS; + } + + static inline void LEDs_TurnOnLEDs(const uint8_t LEDMask) + { + _BOARD_LED_PORT |= LEDMask; + } + + static inline void LEDs_TurnOffLEDs(const uint8_t LEDMask) + { + _BOARD_LED_PORT &= ~LEDMask; + } + + static inline void LEDs_SetAllLEDs(const uint8_t LEDMask) + { + _BOARD_LED_PORT = ((_BOARD_LED_PORT & ~LEDS_ALL_LEDS) | LEDMask); + } + + static inline void LEDs_ChangeLEDs(const uint8_t LEDMask, + const uint8_t ActiveMask) + { + _BOARD_LED_PORT = ((_BOARD_LED_PORT & ~LEDMask) | ActiveMask); + } + + static inline void LEDs_ToggleLEDs(const uint8_t LEDMask) + { + _BOARD_LED_PIN = LEDMask; + } + + static inline uint8_t LEDs_GetLEDs(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t LEDs_GetLEDs(void) + { + return (_BOARD_LED_PORT & LEDS_ALL_LEDS); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/MICROSIN162/Buttons.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/MICROSIN162/Buttons.h new file mode 100644 index 00000000..01366a71 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/MICROSIN162/Buttons.h @@ -0,0 +1,103 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific Buttons driver header for the Microsin AVR-USB162 board. + * \copydetails Group_Buttons_MICROSIN162 + * + * \note This file should not be included directly. It is automatically included as needed by the Buttons driver + * dispatch header located in LUFA/Drivers/Board/Buttons.h. + */ + +/** \ingroup Group_Buttons + * \defgroup Group_Buttons_MICROSIN162 MICROSIN162 + * \brief Board specific Buttons driver header for the Microsin AVR-USB162 board. + * + * Board specific Buttons driver header for the Microsin AVR-USB162 board (http://microsin.ru/content/view/685/44/). + * + * + * + * + *
NameInfoActive LevelPort Pin
BUTTONS_BUTTON1HWB ButtonLowPORTD.7
+ * + * @{ + */ + +#ifndef __BUTTONS_MICROSIN162_H__ +#define __BUTTONS_MICROSIN162_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_BUTTONS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/Buttons.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Button mask for the first button on the board. */ + #define BUTTONS_BUTTON1 (1 << 7) + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void Buttons_Init(void) + { + DDRD &= ~BUTTONS_BUTTON1; + PORTD |= BUTTONS_BUTTON1; + } + + static inline void Buttons_Disable(void) + { + DDRD &= ~BUTTONS_BUTTON1; + PORTD &= ~BUTTONS_BUTTON1; + } + + static inline uint8_t Buttons_GetStatus(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t Buttons_GetStatus(void) + { + return ((PIND & BUTTONS_BUTTON1) ^ BUTTONS_BUTTON1); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/MICROSIN162/LEDs.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/MICROSIN162/LEDs.h new file mode 100644 index 00000000..35070364 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/MICROSIN162/LEDs.h @@ -0,0 +1,135 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific LED driver header for the Microsin AVR-USB162 board. + * \copydetails Group_LEDs_MICROSIN162 + * + * \note This file should not be included directly. It is automatically included as needed by the LEDs driver + * dispatch header located in LUFA/Drivers/Board/LEDs.h. + */ + +/** \ingroup Group_LEDs + * \defgroup Group_LEDs_MICROSIN162 MICROSIN162 + * \brief Board specific LED driver header for the Microsin AVR-USB162 board. + * + * Board specific LED driver header for the Microsin AVR-USB162 board (http://microsin.ru/content/view/685/44/). + * + * + * + * + *
NameColorInfoActive LevelPort Pin
LEDS_LED1GreenGeneral IndicatorLowPORTD.4
+ * + * @{ + */ + +#ifndef __LEDS_MICROSIN162_H__ +#define __LEDS_MICROSIN162_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_LEDS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/LEDS.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** LED mask for the first LED on the board. */ + #define LEDS_LED1 (1 << 4) + + /** LED mask for all the LEDs on the board. */ + #define LEDS_ALL_LEDS LEDS_LED1 + + /** LED mask for none of the board LEDs. */ + #define LEDS_NO_LEDS 0 + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void LEDs_Init(void) + { + DDRD |= LEDS_ALL_LEDS; + PORTD |= LEDS_ALL_LEDS; + } + + static inline void LEDs_Disable(void) + { + DDRD &= ~LEDS_ALL_LEDS; + PORTD &= ~LEDS_ALL_LEDS; + } + + static inline void LEDs_TurnOnLEDs(const uint8_t LEDMask) + { + PORTD &= ~LEDMask; + } + + static inline void LEDs_TurnOffLEDs(const uint8_t LEDMask) + { + PORTD |= LEDMask; + } + + static inline void LEDs_SetAllLEDs(const uint8_t LEDMask) + { + PORTD = ((PORTD | LEDS_ALL_LEDS) & ~LEDMask); + } + + static inline void LEDs_ChangeLEDs(const uint8_t LEDMask, + const uint8_t ActiveMask) + { + PORTD = ((PORTD | LEDMask) & ~ActiveMask); + } + + static inline void LEDs_ToggleLEDs(const uint8_t LEDMask) + { + PIND = LEDMask; + } + + static inline uint8_t LEDs_GetLEDs(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t LEDs_GetLEDs(void) + { + return (~PORTD & LEDS_ALL_LEDS); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/MINIMUS/Buttons.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/MINIMUS/Buttons.h new file mode 100644 index 00000000..3f1b592d --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/MINIMUS/Buttons.h @@ -0,0 +1,103 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific Buttons driver header for the MINIMUS. + * \copydetails Group_Buttons_MINIMUS + * + * \note This file should not be included directly. It is automatically included as needed by the Buttons driver + * dispatch header located in LUFA/Drivers/Board/Buttons.h. + */ + +/** \ingroup Group_Buttons + * \defgroup Group_Buttons_MINIMUS MINIMUS + * \brief Board specific Buttons driver header for the MINIMUS. + * + * Board specific Buttons driver header for the MINIMUS. + * + * + * + * + *
NameInfoActive LevelPort Pin
BUTTONS_BUTTON1HWB ButtonLowPORTD.7
+ * + * @{ + */ + +#ifndef __BUTTONS_MINIMUS_H__ +#define __BUTTONS_MINIMUS_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_BUTTONS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/Buttons.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Button mask for the first button on the board. */ + #define BUTTONS_BUTTON1 (1 << 7) + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void Buttons_Init(void) + { + DDRD &= ~BUTTONS_BUTTON1; + PORTD |= BUTTONS_BUTTON1; + } + + static inline void Buttons_Disable(void) + { + DDRD &= ~BUTTONS_BUTTON1; + PORTD &= ~BUTTONS_BUTTON1; + } + + static inline uint8_t Buttons_GetStatus(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t Buttons_GetStatus(void) + { + return ((PIND & BUTTONS_BUTTON1) ^ BUTTONS_BUTTON1); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/MINIMUS/LEDs.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/MINIMUS/LEDs.h new file mode 100644 index 00000000..4889722b --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/MINIMUS/LEDs.h @@ -0,0 +1,143 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific LED driver header for the MINIMUS. + * \copydetails Group_LEDs_MINIMUS + * + * \note This file should not be included directly. It is automatically included as needed by the LEDs driver + * dispatch header located in LUFA/Drivers/Board/LEDs.h. + */ + +/** \ingroup Group_LEDs + * \defgroup Group_LEDs_MINIMUS MINIMUS + * \brief Board specific LED driver header for the MINIMUS. + * + * Board specific LED driver header for the Minimus USB (http://www.minimususb.com/). + * + * + * + * + * + * + *
NameColorInfoActive LevelPort Pin
LEDS_LED1RedGeneral IndicatorLowPORTD.5
LEDS_LED2GreenGeneral IndicatorLowPORTD.6
LEDS_LED3BlueGeneral IndicatorLowPORTD.7
+ * + * @{ + */ + +#ifndef __LEDS_MINIMUS_H__ +#define __LEDS_MINIMUS_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_LEDS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/LEDS.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** LED mask for the first LED on the board. */ + #define LEDS_LED1 (1 << 5) + + /** LED mask for the second LED on the board. */ + #define LEDS_LED2 (1 << 6) + + /** LED mask for the third LED on the board. */ + #define LEDS_LED3 (1 << 7) + + /** LED mask for all the LEDs on the board. */ + #define LEDS_ALL_LEDS (LEDS_LED1 | LEDS_LED2 | LEDS_LED3) + + /** LED mask for the none of the board LEDs. */ + #define LEDS_NO_LEDS 0 + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void LEDs_Init(void) + { + DDRD |= LEDS_ALL_LEDS; + PORTD |= LEDS_ALL_LEDS; + } + + static inline void LEDs_Disable(void) + { + DDRD &= ~LEDS_ALL_LEDS; + PORTD &= ~LEDS_ALL_LEDS; + } + + static inline void LEDs_TurnOnLEDs(const uint8_t LEDMask) + { + PORTD &= ~LEDMask; + } + + static inline void LEDs_TurnOffLEDs(const uint8_t LEDMask) + { + PORTD |= LEDMask; + } + + static inline void LEDs_SetAllLEDs(const uint8_t LEDMask) + { + PORTD = ((PORTD | LEDS_ALL_LEDS) & ~LEDMask); + } + + static inline void LEDs_ChangeLEDs(const uint8_t LEDMask, + const uint8_t ActiveMask) + { + PORTD = ((PORTD & ~LEDMask) | ActiveMask); + } + + static inline void LEDs_ToggleLEDs(const uint8_t LEDMask) + { + PIND = LEDMask; + } + + static inline uint8_t LEDs_GetLEDs(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t LEDs_GetLEDs(void) + { + return (PORTD & LEDS_ALL_LEDS); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/MULTIO/LEDs.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/MULTIO/LEDs.h new file mode 100644 index 00000000..9da56927 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/MULTIO/LEDs.h @@ -0,0 +1,161 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific LED driver header for the Bitwizard Multio. + * \copydetails Group_LEDs_MULTIO + * + * \note This file should not be included directly. It is automatically included as needed by the LEDs driver + * dispatch header located in LUFA/Drivers/Board/LEDs.h. + */ + +/** \ingroup Group_LEDs + * \defgroup Group_LEDs_MULTIO MULTIO + * \brief Board specific LED driver header for the Bitwizard Multio. + * + * Board specific LED driver header for the Bitwizard Multio (http://www.bitwizard.nl/wiki/index.php/USB-multio). + * + * + * + * + * + * + *
NameColorInfoActive LevelPort Pin
LEDS_LED1GreenGeneral IndicatorHighPORTD.0
LEDS_LED2GreenGeneral IndicatorHighPORTC.2
LEDS_LED3GreenGeneral IndicatorHighPORTD.7
+ * + * @{ + */ + +#ifndef __LEDS_MULTIO_H__ +#define __LEDS_MULTIO_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_LEDS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/LEDS.h instead. + #endif + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Macros: */ + #define LEDS_PORTD_LEDS (LEDS_LED1 | LEDS_LED3) + #define LEDS_PORTC_LEDS LEDS_LED2 + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** LED mask for the first LED on the board. */ + #define LEDS_LED1 (1 << 0) + + /** LED mask for the second LED on the board. */ + #define LEDS_LED2 (1 << 2) + + /** LED mask for the second LED on the board. */ + #define LEDS_LED3 (1 << 7) + + /** LED mask for all the LEDs on the board. */ + #define LEDS_ALL_LEDS (LEDS_LED1 | LEDS_LED2 | LEDS_LED3) + + /** LED mask for none of the board LEDs. */ + #define LEDS_NO_LEDS 0 + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void LEDs_Init(void) + { + DDRD |= LEDS_PORTD_LEDS; + DDRC |= LEDS_PORTC_LEDS; + + PORTD &= ~LEDS_PORTD_LEDS; + PORTC &= ~LEDS_PORTC_LEDS; + } + + static inline void LEDs_Disable(void) + { + DDRD &= ~LEDS_PORTD_LEDS; + DDRC &= ~LEDS_PORTC_LEDS; + + PORTD &= ~LEDS_PORTD_LEDS; + PORTC &= ~LEDS_PORTC_LEDS; + } + + static inline void LEDs_TurnOnLEDs(const uint8_t LEDMask) + { + PORTD |= (LEDMask & LEDS_PORTD_LEDS); + PORTC |= (LEDMask & LEDS_PORTC_LEDS); + } + + static inline void LEDs_TurnOffLEDs(const uint8_t LEDMask) + { + PORTD &= ~(LEDMask & LEDS_PORTD_LEDS); + PORTC &= ~(LEDMask & LEDS_PORTC_LEDS); + } + + static inline void LEDs_SetAllLEDs(const uint8_t LEDMask) + { + PORTD = (PORTD & ~LEDS_PORTD_LEDS) | (LEDMask & LEDS_PORTD_LEDS); + PORTC = (PORTC & ~LEDS_PORTC_LEDS) | (LEDMask & LEDS_PORTC_LEDS); + } + + static inline void LEDs_ChangeLEDs(const uint8_t LEDMask, + const uint8_t ActiveMask) + { + PORTD = (PORTD & ~(LEDMask & LEDS_PORTD_LEDS)) | (ActiveMask & LEDS_PORTD_LEDS); + PORTC = (PORTC & ~(LEDMask & LEDS_PORTC_LEDS)) | (ActiveMask & LEDS_PORTC_LEDS); + } + + static inline void LEDs_ToggleLEDs(const uint8_t LEDMask) + { + PIND = (LEDMask & LEDS_PORTD_LEDS); + PINC = (LEDMask & LEDS_PORTC_LEDS); + } + + static inline uint8_t LEDs_GetLEDs(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t LEDs_GetLEDs(void) + { + return ((PORTD & LEDS_PORTD_LEDS) | (PORTC & LEDS_PORTC_LEDS)); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/OLIMEX162/Buttons.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/OLIMEX162/Buttons.h new file mode 100644 index 00000000..9f02729c --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/OLIMEX162/Buttons.h @@ -0,0 +1,103 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific Buttons driver header for the Olimex AVR-USB-162 Development Board. + * \copydetails Group_Buttons_OLIMEX162 + * + * \note This file should not be included directly. It is automatically included as needed by the Buttons driver + * dispatch header located in LUFA/Drivers/Board/Buttons.h. + */ + +/** \ingroup Group_Buttons + * \defgroup Group_Buttons_OLIMEX162 OLIMEX162 + * \brief Board specific Buttons driver header for the Olimex AVR-USB-162 Development Board. + * + * Board specific Buttons driver header for the Olimex AVR-USB-162 Development Board (http://www.olimex.com/dev/avr-usb-162.html). + * + * + * + * + *
NameInfoActive LevelPort Pin
BUTTONS_BUTTON1HWB ButtonLowPORTD.7
+ * + * @{ + */ + +#ifndef __BUTTONS_OLIMEX162_H__ +#define __BUTTONS_OLIMEX162_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_BUTTONS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/Buttons.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Button mask for the first button on the board. */ + #define BUTTONS_BUTTON1 (1 << 7) + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void Buttons_Init(void) + { + DDRD &= ~BUTTONS_BUTTON1; + PORTD |= BUTTONS_BUTTON1; + } + + static inline void Buttons_Disable(void) + { + DDRD &= ~BUTTONS_BUTTON1; + PORTD &= ~BUTTONS_BUTTON1; + } + + static inline uint8_t Buttons_GetStatus(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t Buttons_GetStatus(void) + { + return ((PIND & BUTTONS_BUTTON1) ^ BUTTONS_BUTTON1); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/OLIMEX162/LEDs.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/OLIMEX162/LEDs.h new file mode 100644 index 00000000..0e35eae4 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/OLIMEX162/LEDs.h @@ -0,0 +1,135 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific LED driver header for the Olimex AVR-USB-162. + * \copydetails Group_LEDs_OLIMEX162 + * + * \note This file should not be included directly. It is automatically included as needed by the LEDs driver + * dispatch header located in LUFA/Drivers/Board/LEDs.h. + */ + +/** \ingroup Group_LEDs + * \defgroup Group_LEDs_OLIMEX162 OLIMEX162 + * \brief Board specific LED driver header for the Olimex AVR-USB-162. + * + * Board specific LED driver header for the Olimex AVR-USB-162 (http://www.olimex.com/dev/avr-usb-162.html). + * + * + * + * + *
NameColorInfoActive LevelPort Pin
LEDS_LED1YellowGeneral IndicatorHighPORTD.4
+ * + * @{ + */ + +#ifndef __LEDS_OLIMEX162_H__ +#define __LEDS_OLIMEX162_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_LEDS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/LEDS.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** LED mask for the first LED on the board. */ + #define LEDS_LED1 (1 << 4) + + /** LED mask for all the LEDs on the board. */ + #define LEDS_ALL_LEDS LEDS_LED1 + + /** LED mask for none of the board LEDs. */ + #define LEDS_NO_LEDS 0 + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void LEDs_Init(void) + { + DDRD |= LEDS_ALL_LEDS; + PORTD &= ~LEDS_ALL_LEDS; + } + + static inline void LEDs_Disable(void) + { + DDRD &= ~LEDS_ALL_LEDS; + PORTD &= ~LEDS_ALL_LEDS; + } + + static inline void LEDs_TurnOnLEDs(const uint8_t LEDMask) + { + PORTD |= LEDMask; + } + + static inline void LEDs_TurnOffLEDs(const uint8_t LEDMask) + { + PORTD &= ~LEDMask; + } + + static inline void LEDs_SetAllLEDs(const uint8_t LEDMask) + { + PORTD = ((PORTD & ~LEDS_ALL_LEDS) | LEDMask); + } + + static inline void LEDs_ChangeLEDs(const uint8_t LEDMask, + const uint8_t ActiveMask) + { + PORTD = ((PORTD & ~LEDMask) | ActiveMask); + } + + static inline void LEDs_ToggleLEDs(const uint8_t LEDMask) + { + PIND = LEDMask; + } + + static inline uint8_t LEDs_GetLEDs(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t LEDs_GetLEDs(void) + { + return (PORTD & LEDS_ALL_LEDS); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/OLIMEX32U4/Buttons.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/OLIMEX32U4/Buttons.h new file mode 100644 index 00000000..4ae89ace --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/OLIMEX32U4/Buttons.h @@ -0,0 +1,103 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific Buttons driver header for the Olimex AVR-USB-32U4 Development Board. + * \copydetails Group_Buttons_OLIMEX32U4 + * + * \note This file should not be included directly. It is automatically included as needed by the Buttons driver + * dispatch header located in LUFA/Drivers/Board/Buttons.h. + */ + +/** \ingroup Group_Buttons + * \defgroup Group_Buttons_OLIMEX32U4 OLIMEX32U4 + * \brief Board specific Buttons driver header for the Olimex AVR-USB-32U4 Development Board. + * + * Board specific Buttons driver header for the Olimex AVR-USB-32U4 Development Board (http://www.olimex.com/dev/olimexino-32u4.html). + * + * + * + * + *
NameInfoActive LevelPort Pin
BUTTONS_BUTTON1HWB ButtonLowPORTE.2
+ * + * @{ + */ + +#ifndef __BUTTONS_OLIMEX32U4_H__ +#define __BUTTONS_OLIMEX32U4_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_BUTTONS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/Buttons.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Button mask for the first button on the board. */ + #define BUTTONS_BUTTON1 (1 << 2) + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void Buttons_Init(void) + { + DDRE &= ~BUTTONS_BUTTON1; + PORTE |= BUTTONS_BUTTON1; + } + + static inline void Buttons_Disable(void) + { + DDRE &= ~BUTTONS_BUTTON1; + PORTE &= ~BUTTONS_BUTTON1; + } + + static inline uint8_t Buttons_GetStatus(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t Buttons_GetStatus(void) + { + return ((PINE & BUTTONS_BUTTON1) ^ BUTTONS_BUTTON1); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/OLIMEX32U4/LEDs.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/OLIMEX32U4/LEDs.h new file mode 100644 index 00000000..38dde2c7 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/OLIMEX32U4/LEDs.h @@ -0,0 +1,179 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific LED driver header for the Olimex AVR-USB-32U4. + * \copydetails Group_LEDs_OLIMEX32U4 + * + * \note This file should not be included directly. It is automatically included as needed by the LEDs driver + * dispatch header located in LUFA/Drivers/Board/LEDs.h. + */ + +/** \ingroup Group_LEDs + * \defgroup Group_LEDs_OLIMEX32U4 OLIMEX32U4 + * \brief Board specific LED driver header for the Olimex AVR-USB-32U4. + * + * Board specific LED driver header for the Olimex AVR-USB-32U4 (http://www.olimex.com/dev/olimexino-32u4.html). + * + * + * + * + * + * + * + *
NameColorInfoActive LevelPort Pin
LEDS_LED1GreenTXHighPORTD.5
LEDS_LED2YellowRXHighPORTB.0
LEDS_LED3GreenGeneral Indicator (Default Unconnected)HighPORTE.6
LEDS_LED4YellowGeneral Indicator (Default Unconnected)HighPORTB.5
+ * + * @{ + */ + +#ifndef __LEDS_OLIMEX32U4_H__ +#define __LEDS_OLIMEX32U4_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_LEDS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/LEDS.h instead. + #endif + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Macros: */ + #define LEDS_PORTB_LEDS (LEDS_LED2 | LEDS_LED4) + #define LEDS_PORTD_LEDS (LEDS_LED1) + #define LEDS_PORTE_LEDS (LEDS_LED3) + + #define LEDS_PORTD_MASK_SHIFT 1 + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** LED mask for the first LED on the board. */ + #define LEDS_LED1 ((1 << 5) >> LEDS_PORTD_MASK_SHIFT) + + /** LED mask for the second LED on the board. */ + #define LEDS_LED2 (1 << 0) + + /** LED mask for the third LED on the board. */ + #define LEDS_LED3 (1 << 5) + + /** LED mask for the fourth LED on the board. */ + #define LEDS_LED4 (1 << 6) + + /** LED mask for all the LEDs on the board. */ + #define LEDS_ALL_LEDS (LEDS_LED1 | LEDS_LED2 | LEDS_LED3 | LEDS_LED4) + + /** LED mask for none of the board LEDs. */ + #define LEDS_NO_LEDS 0 + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void LEDs_Init(void) + { + DDRB |= LEDS_PORTB_LEDS; + PORTB &= ~LEDS_PORTB_LEDS; + DDRD |= (LEDS_PORTD_LEDS << LEDS_PORTD_MASK_SHIFT); + PORTD &= ~(LEDS_PORTD_LEDS << LEDS_PORTD_MASK_SHIFT); + DDRE |= LEDS_PORTE_LEDS; + PORTE &= ~LEDS_PORTE_LEDS; + } + + static inline void LEDs_Disable(void) + { + DDRB &= ~LEDS_PORTB_LEDS; + PORTB &= ~LEDS_PORTB_LEDS; + DDRD &= ~(LEDS_PORTD_LEDS << LEDS_PORTD_MASK_SHIFT); + PORTD &= ~(LEDS_PORTD_LEDS << LEDS_PORTD_MASK_SHIFT); + DDRE &= ~LEDS_PORTE_LEDS; + PORTE &= ~LEDS_PORTE_LEDS; + } + + static inline void LEDs_TurnOnLEDs(const uint8_t LEDMask) + { + PORTB |= (LEDMask & LEDS_PORTB_LEDS); + PORTD |= ((LEDMask & LEDS_PORTD_LEDS) << LEDS_PORTD_MASK_SHIFT); + PORTE |= (LEDMask & LEDS_PORTE_LEDS); + } + + static inline void LEDs_TurnOffLEDs(const uint8_t LEDMask) + { + PORTB &= ~(LEDMask & LEDS_PORTB_LEDS); + PORTD &= ~((LEDMask & LEDS_PORTD_LEDS) << LEDS_PORTD_MASK_SHIFT); + PORTE &= ~(LEDMask & LEDS_PORTE_LEDS); + } + + static inline void LEDs_SetAllLEDs(const uint8_t LEDMask) + { + PORTB = ((PORTB & ~LEDS_PORTB_LEDS) | (LEDMask & LEDS_PORTB_LEDS)); + PORTD = ((PORTD & ~(LEDS_PORTD_LEDS << LEDS_PORTD_MASK_SHIFT)) | + ((LEDMask & LEDS_PORTD_LEDS) << LEDS_PORTD_MASK_SHIFT)); + PORTE = ((PORTE & ~LEDS_PORTE_LEDS) | (LEDMask & LEDS_PORTE_LEDS)); + } + + static inline void LEDs_ChangeLEDs(const uint8_t LEDMask, + const uint8_t ActiveMask) + { + PORTB = ((PORTB & ~(LEDMask & LEDS_PORTB_LEDS)) | (ActiveMask & LEDS_PORTB_LEDS)); + PORTD = ((PORTD & ~((LEDMask & LEDS_PORTD_LEDS) << LEDS_PORTD_MASK_SHIFT)) | + ((ActiveMask & LEDS_PORTD_LEDS) << LEDS_PORTD_MASK_SHIFT)); + PORTE = ((PORTE & ~(LEDMask & LEDS_PORTE_LEDS)) | (ActiveMask & LEDS_PORTE_LEDS)); + } + + static inline void LEDs_ToggleLEDs(const uint8_t LEDMask) + { + PINB = (LEDMask & LEDS_PORTB_LEDS); + PIND = ((LEDMask & LEDS_PORTD_LEDS) << LEDS_PORTD_MASK_SHIFT); + PINE = (LEDMask & LEDS_PORTE_LEDS); + } + + static inline uint8_t LEDs_GetLEDs(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t LEDs_GetLEDs(void) + { + return ((PORTB & LEDS_PORTB_LEDS) | + ((PORTD & (LEDS_PORTD_LEDS << LEDS_PORTD_MASK_SHIFT)) >> LEDS_PORTD_MASK_SHIFT) | + (PORTE & LEDS_PORTE_LEDS)); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/OLIMEXISPMK2/Buttons.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/OLIMEXISPMK2/Buttons.h new file mode 100644 index 00000000..70b2467b --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/OLIMEXISPMK2/Buttons.h @@ -0,0 +1,103 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific Buttons driver header for the Olimex AVR-ISP-MK2 Development Board. + * \copydetails Group_Buttons_OLIMEXISPMK2 + * + * \note This file should not be included directly. It is automatically included as needed by the Buttons driver + * dispatch header located in LUFA/Drivers/Board/Buttons.h. + */ + +/** \ingroup Group_Buttons + * \defgroup Group_Buttons_OLIMEXISPMK2 OLIMEXISPMK2 + * \brief Board specific Buttons driver header for the Olimex AVR-ISP-MK2. + * + * Board specific Buttons driver header for the Olimex AVR-ISP-MK2 Development Board (https://www.olimex.com/dev/avr-isp-mk2.html). + * + * + * + * + *
NameInfoActive LevelPort Pin
BUTTONS_BUTTON1HWB ButtonLowPORTD.7
+ * + * @{ + */ + +#ifndef __BUTTONS_OLIMEXISPMK2_H__ +#define __BUTTONS_OLIMEXISPMK2_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_BUTTONS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/Buttons.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Button mask for the first button on the board. */ + #define BUTTONS_BUTTON1 (1 << 7) + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void Buttons_Init(void) + { + DDRD &= ~BUTTONS_BUTTON1; + PORTD |= BUTTONS_BUTTON1; + } + + static inline void Buttons_Disable(void) + { + DDRD &= ~BUTTONS_BUTTON1; + PORTD &= ~BUTTONS_BUTTON1; + } + + static inline uint8_t Buttons_GetStatus(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t Buttons_GetStatus(void) + { + return ((PIND & BUTTONS_BUTTON1) ^ BUTTONS_BUTTON1); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/OLIMEXISPMK2/LEDs.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/OLIMEXISPMK2/LEDs.h new file mode 100644 index 00000000..a1b8825d --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/OLIMEXISPMK2/LEDs.h @@ -0,0 +1,143 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific LED driver header for the Olimex AVR-ISP-MK2 Development Board. + * \copydetails Group_LEDs_OLIMEXISPMK2 + * + * \note This file should not be included directly. It is automatically included as needed by the LEDs driver + * dispatch header located in LUFA/Drivers/Board/LEDs.h. + */ + +/** \ingroup Group_LEDs + * \defgroup Group_LEDs_OLIMEXISPMK2 OLIMEXISPMK2 + * \brief Board specific LED driver header for the Olimex AVR-ISP-MK2. + * + * Board specific LED driver header for the Olimex AVR-ISP-MK2 Development Board (https://www.olimex.com/dev/avr-isp-mk2.html). + * + * + * + * + * + * + *
NameColorInfoActive LevelPort Pin
LEDS_LED1YellowTarget PowerHighPORTB.5
LEDS_LED2RedActivityHighPORTB.6
LEDS_LED3GreenReadyHighPORTB.7
+ * + * @{ + */ + +#ifndef __LEDS_OLIMEXISPMK2_H__ +#define __LEDS_OLIMEXISPMK2_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_LEDS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/LEDS.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** LED mask for the first LED on the board. */ + #define LEDS_LED1 (1 << 5) + + /** LED mask for the second LED on the board. */ + #define LEDS_LED2 (1 << 6) + + /** LED mask for the third LED on the board. */ + #define LEDS_LED3 (1 << 7) + + /** LED mask for all the LEDs on the board. */ + #define LEDS_ALL_LEDS (LEDS_LED1 | LEDS_LED2 | LEDS_LED3) + + /** LED mask for none of the board LEDs. */ + #define LEDS_NO_LEDS 0 + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void LEDs_Init(void) + { + DDRB |= LEDS_ALL_LEDS; + PORTB &= ~LEDS_ALL_LEDS; + } + + static inline void LEDs_Disable(void) + { + DDRB &= ~LEDS_ALL_LEDS; + PORTB &= ~LEDS_ALL_LEDS; + } + + static inline void LEDs_TurnOnLEDs(const uint8_t LEDMask) + { + PORTB |= LEDMask; + } + + static inline void LEDs_TurnOffLEDs(const uint8_t LEDMask) + { + PORTB &= ~LEDMask; + } + + static inline void LEDs_SetAllLEDs(const uint8_t LEDMask) + { + PORTB = ((PORTB & ~LEDS_ALL_LEDS) | LEDMask); + } + + static inline void LEDs_ChangeLEDs(const uint8_t LEDMask, + const uint8_t ActiveMask) + { + PORTB = ((PORTB & ~LEDMask) | ActiveMask); + } + + static inline void LEDs_ToggleLEDs(const uint8_t LEDMask) + { + PINB = LEDMask; + } + + static inline uint8_t LEDs_GetLEDs(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t LEDs_GetLEDs(void) + { + return (PORTB & LEDS_ALL_LEDS); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/OLIMEXT32U4/Buttons.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/OLIMEXT32U4/Buttons.h new file mode 100644 index 00000000..c779c557 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/OLIMEXT32U4/Buttons.h @@ -0,0 +1,103 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific Buttons driver header for the Olimex AVR-USB-T32U4 Development Board. + * \copydetails Group_Buttons_OLIMEXT32U4 + * + * \note This file should not be included directly. It is automatically included as needed by the Buttons driver + * dispatch header located in LUFA/Drivers/Board/Buttons.h. + */ + +/** \ingroup Group_Buttons + * \defgroup Group_Buttons_OLIMEXT32U4 OLIMEXT32U4 + * \brief Board specific Buttons driver header for the Olimex AVR-USB-32U4 Development Board. + * + * Board specific Buttons driver header for the Olimex AVR-USB-T32U4 Development Board (http://www.olimex.com/dev/avr-t32u4.html). + * + * + * + * + *
NameInfoActive LevelPort Pin
BUTTONS_BUTTON1HWB ButtonLowPORTE.2
+ * + * @{ + */ + +#ifndef __BUTTONS_OLIMEXT32U4_H__ +#define __BUTTONS_OLIMEXT32U4_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_BUTTONS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/Buttons.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Button mask for the first button on the board. */ + #define BUTTONS_BUTTON1 (1 << 2) + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void Buttons_Init(void) + { + DDRE &= ~BUTTONS_BUTTON1; + PORTE |= BUTTONS_BUTTON1; + } + + static inline void Buttons_Disable(void) + { + DDRE &= ~BUTTONS_BUTTON1; + PORTE &= ~BUTTONS_BUTTON1; + } + + static inline uint8_t Buttons_GetStatus(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t Buttons_GetStatus(void) + { + return ((PINE & BUTTONS_BUTTON1) ^ BUTTONS_BUTTON1); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/OLIMEXT32U4/LEDs.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/OLIMEXT32U4/LEDs.h new file mode 100644 index 00000000..b3e4c701 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/OLIMEXT32U4/LEDs.h @@ -0,0 +1,169 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific LED driver header for the Olimex AVR-USB-T32U4. + * \copydetails Group_LEDs_OLIMEXT32U4 + * + * \note This file should not be included directly. It is automatically included as needed by the LEDs driver + * dispatch header located in LUFA/Drivers/Board/LEDs.h. + */ + +/** \ingroup Group_LEDs + * \defgroup Group_LEDs_OLIMEXT32U4 OLIMEXT32U4 + * \brief Board specific LED driver header for the Olimex AVR-USB-T32U4. + * + * Board specific LED driver header for the Olimex AVR-USB-T32U4 (http://www.olimex.com/dev/avr-t32u4.html). + * + * + * + * + * + * + *
NameColorInfoActive LevelPort Pin
LEDS_LED1GreenTXHighPORTD.5
LEDS_LED2YellowRXHighPORTB.0
LEDS_LED3N/AGeneral Indicator (Not Mounted)HighPORTE.6
+ * + * @{ + */ + +#ifndef __LEDS_OLIMEXT32U4_H__ +#define __LEDS_OLIMEXT32U4_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_LEDS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/LEDS.h instead. + #endif + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Macros: */ + #define LEDS_PORTB_LEDS (LEDS_LED2) + #define LEDS_PORTD_LEDS (LEDS_LED1) + #define LEDS_PORTE_LEDS (LEDS_LED3) + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** LED mask for the first LED on the board. */ + #define LEDS_LED1 (1 << 5) + + /** LED mask for the second LED on the board. */ + #define LEDS_LED2 (1 << 0) + + /** LED mask for the third LED on the board. */ + #define LEDS_LED3 (1 << 6) + + /** LED mask for all the LEDs on the board. */ + #define LEDS_ALL_LEDS (LEDS_LED1 | LEDS_LED2 | LEDS_LED3) + + /** LED mask for none of the board LEDs. */ + #define LEDS_NO_LEDS 0 + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void LEDs_Init(void) + { + DDRB |= LEDS_PORTB_LEDS; + PORTB &= ~LEDS_PORTB_LEDS; + DDRD |= LEDS_PORTD_LEDS; + PORTD &= ~LEDS_PORTD_LEDS; + DDRE |= LEDS_PORTE_LEDS; + PORTE &= ~LEDS_PORTE_LEDS; + } + + static inline void LEDs_Disable(void) + { + DDRB &= ~LEDS_PORTB_LEDS; + PORTB &= ~LEDS_PORTB_LEDS; + DDRD &= ~LEDS_PORTD_LEDS; + PORTD &= ~LEDS_PORTD_LEDS; + DDRE &= ~LEDS_PORTE_LEDS; + PORTE &= ~LEDS_PORTE_LEDS; + } + + static inline void LEDs_TurnOnLEDs(const uint8_t LEDMask) + { + PORTB |= (LEDMask & LEDS_PORTB_LEDS); + PORTD |= (LEDMask & LEDS_PORTD_LEDS); + PORTE |= (LEDMask & LEDS_PORTE_LEDS); + } + + static inline void LEDs_TurnOffLEDs(const uint8_t LEDMask) + { + PORTB &= ~(LEDMask & LEDS_PORTB_LEDS); + PORTD &= ~(LEDMask & LEDS_PORTD_LEDS); + PORTE &= ~(LEDMask & LEDS_PORTE_LEDS); + } + + static inline void LEDs_SetAllLEDs(const uint8_t LEDMask) + { + PORTB = ((PORTB & ~LEDS_PORTB_LEDS) | (LEDMask & LEDS_PORTB_LEDS)); + PORTD = ((PORTD & ~LEDS_PORTD_LEDS) | (LEDMask & LEDS_PORTD_LEDS)); + PORTE = ((PORTE & ~LEDS_PORTE_LEDS) | (LEDMask & LEDS_PORTE_LEDS)); + } + + static inline void LEDs_ChangeLEDs(const uint8_t LEDMask, + const uint8_t ActiveMask) + { + PORTB = ((PORTB & ~(LEDMask & LEDS_PORTB_LEDS)) | (ActiveMask & LEDS_PORTB_LEDS)); + PORTD = ((PORTD & ~(LEDMask & LEDS_PORTD_LEDS)) | (ActiveMask & LEDS_PORTD_LEDS)); + PORTE = ((PORTE & ~(LEDMask & LEDS_PORTE_LEDS)) | (ActiveMask & LEDS_PORTE_LEDS)); + } + + static inline void LEDs_ToggleLEDs(const uint8_t LEDMask) + { + PINB = (LEDMask & LEDS_PORTB_LEDS); + PIND = (LEDMask & LEDS_PORTD_LEDS); + PINE = (LEDMask & LEDS_PORTE_LEDS); + } + + static inline uint8_t LEDs_GetLEDs(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t LEDs_GetLEDs(void) + { + return ((PORTB & LEDS_PORTB_LEDS) | (PORTD & LEDS_PORTD_LEDS) | (PORTE & LEDS_PORTE_LEDS)); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/RZUSBSTICK/LEDs.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/RZUSBSTICK/LEDs.h new file mode 100644 index 00000000..a440b6f0 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/RZUSBSTICK/LEDs.h @@ -0,0 +1,175 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific LED driver header for the Atmel RZUSBSTICK. + * \copydetails Group_LEDs_RZUSBSTICK + * + * \note This file should not be included directly. It is automatically included as needed by the LEDs driver + * dispatch header located in LUFA/Drivers/Board/LEDs.h. + */ + +/** \ingroup Group_LEDs + * \defgroup Group_LEDs_RZUSBSTICK RZUSBSTICK + * \brief Board specific LED driver header for the Atmel RZUSBSTICK. + * + * Board specific LED driver header for the Atmel RZUSBSTICK. + * + * + * + * + * + * + * + *
NameColorInfoActive LevelPort Pin
LEDS_LED1BlueGeneral IndicatorHighPORTD.7
LEDS_LED1RedGeneral IndicatorLowPORTD.5
LEDS_LED1GreenGeneral IndicatorLowPORTE.6
LEDS_LED1YellowGeneral IndicatorLowPORTE.7
+ * + * @{ + */ + +#ifndef __LEDS_RZUSBSTICK_H__ +#define __LEDS_RZUSBSTICK_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_LEDS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/LEDS.h instead. + #endif + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Macros: */ + #define LEDS_PORTD_LEDS (LEDS_LED1 | LEDS_LED2) + #define LEDS_PORTE_LEDS (LEDS_LED3 | LEDS_LED4) + + #define LEDS_PORTE_MASK_SHIFT 4 + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** LED mask for the first LED on the board. */ + #define LEDS_LED1 (1 << 7) + + /** LED mask for the second LED on the board. */ + #define LEDS_LED2 (1 << 5) + + /** LED mask for the third LED on the board. */ + #define LEDS_LED3 ((1 << 6) >> LEDS_PORTE_MASK_SHIFT) + + /** LED mask for the fourth LED on the board. */ + #define LEDS_LED4 ((1 << 7) >> LEDS_PORTE_MASK_SHIFT) + + /** LED mask for all the LEDs on the board. */ + #define LEDS_ALL_LEDS (LEDS_LED1 | LEDS_LED2 | LEDS_LED3 | LEDS_LED4) + + /** LED mask for none of the board LEDs. */ + #define LEDS_NO_LEDS 0 + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void LEDs_Init(void) + { + DDRD |= LEDS_PORTD_LEDS; + PORTD &= ~LEDS_LED1; + PORTD |= LEDS_LED2; + + DDRE |= (LEDS_PORTE_LEDS << LEDS_PORTE_MASK_SHIFT); + PORTE |= (LEDS_PORTE_LEDS << LEDS_PORTE_MASK_SHIFT); + } + + static inline void LEDs_Disable(void) + { + DDRD &= ~LEDS_PORTD_LEDS; + PORTD &= ~LEDS_PORTD_LEDS; + + DDRE &= ~(LEDS_PORTE_LEDS << LEDS_PORTE_MASK_SHIFT); + PORTE &= ~(LEDS_PORTE_LEDS << LEDS_PORTE_MASK_SHIFT); + } + + static inline void LEDs_TurnOnLEDs(const uint8_t LEDMask) + { + PORTD |= (LEDMask & LEDS_LED1); + PORTD &= ~(LEDMask & LEDS_LED2); + PORTE &= ~((LEDMask & LEDS_PORTE_LEDS) << LEDS_PORTE_MASK_SHIFT); + } + + static inline void LEDs_TurnOffLEDs(const uint8_t LEDMask) + { + PORTD &= ~(LEDMask & LEDS_LED1); + PORTD |= (LEDMask & LEDS_LED2); + PORTE |= ((LEDMask & LEDS_PORTE_LEDS) << LEDS_PORTE_MASK_SHIFT); + } + + static inline void LEDs_SetAllLEDs(const uint8_t LEDMask) + { + PORTD = (((PORTD & ~LEDS_LED1) | (LEDMask & LEDS_LED1)) | + ((PORTD | LEDS_LED2) & ~(LEDMask & LEDS_LED2))); + PORTE = ((PORTE | (LEDS_PORTE_LEDS << LEDS_PORTE_MASK_SHIFT)) & + ~((LEDMask & LEDS_PORTE_LEDS) << LEDS_PORTE_MASK_SHIFT)); + } + + static inline void LEDs_ChangeLEDs(const uint8_t LEDMask, + const uint8_t ActiveMask) + { + PORTD = (((PORTD & ~(LEDMask & LEDS_LED1)) | (ActiveMask & LEDS_LED1)) | + ((PORTD | (LEDMask & LEDS_LED2)) & ~(ActiveMask & LEDS_LED2))); + PORTE = ((PORTE | ((LEDMask & LEDS_PORTE_LEDS) << LEDS_PORTE_MASK_SHIFT)) & + ~((ActiveMask & LEDS_PORTE_LEDS) << LEDS_PORTE_MASK_SHIFT)); + } + + static inline void LEDs_ToggleLEDs(const uint8_t LEDMask) + { + PIND = (LEDMask & LEDS_PORTD_LEDS); + PINE = ((LEDMask & LEDS_PORTE_LEDS) << LEDS_PORTE_MASK_SHIFT); + } + + static inline uint8_t LEDs_GetLEDs(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t LEDs_GetLEDs(void) + { + return (((PORTD & LEDS_LED1) | (~PORTD & LEDS_LED2)) | + ((~PORTE & (LEDS_PORTE_LEDS << LEDS_PORTE_MASK_SHIFT)) >> LEDS_PORTE_MASK_SHIFT)); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/SPARKFUN8U2/LEDs.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/SPARKFUN8U2/LEDs.h new file mode 100644 index 00000000..39267055 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/SPARKFUN8U2/LEDs.h @@ -0,0 +1,135 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific LED driver header for the Sparkfun ATMEGA8U2 breakout board. + * \copydetails Group_LEDs_SPARKFUN8U2 + * + * \note This file should not be included directly. It is automatically included as needed by the LEDs driver + * dispatch header located in LUFA/Drivers/Board/LEDs.h. + */ + +/** \ingroup Group_LEDs + * \defgroup Group_LEDs_SPARKFUN8U2 SPARKFUN8U2 + * \brief Board specific LED driver header for the Sparkfun ATMEGA8U2 breakout board. + * + * Board specific LED driver header for the Sparkfun ATMEGA8U2 breakout board (http://www.sparkfun.com/products/10277). + * + * + * + * + *
NameColorInfoActive LevelPort Pin
LEDS_LED1GreenGeneral IndicatorLowPORTB.4
+ * + * @{ + */ + +#ifndef __LEDS_SPARKFUN8U2_H__ +#define __LEDS_SPARKFUN8U2_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_LEDS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/LEDS.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** LED mask for the first LED on the board. */ + #define LEDS_LED1 (1 << 4) + + /** LED mask for all the LEDs on the board. */ + #define LEDS_ALL_LEDS LEDS_LED1 + + /** LED mask for none of the board LEDs. */ + #define LEDS_NO_LEDS 0 + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void LEDs_Init(void) + { + DDRB |= LEDS_ALL_LEDS; + PORTB |= LEDS_ALL_LEDS; + } + + static inline void LEDs_Disable(void) + { + DDRB &= ~LEDS_ALL_LEDS; + PORTB &= ~LEDS_ALL_LEDS; + } + + static inline void LEDs_TurnOnLEDs(const uint8_t LEDMask) + { + PORTB &= ~LEDMask; + } + + static inline void LEDs_TurnOffLEDs(const uint8_t LEDMask) + { + PORTB |= LEDMask; + } + + static inline void LEDs_SetAllLEDs(const uint8_t LEDMask) + { + PORTB = ((PORTB | LEDS_ALL_LEDS) & ~LEDMask); + } + + static inline void LEDs_ChangeLEDs(const uint8_t LEDMask, + const uint8_t ActiveMask) + { + PORTB = ((PORTB | LEDMask) & ~ActiveMask); + } + + static inline void LEDs_ToggleLEDs(const uint8_t LEDMask) + { + PINB = LEDMask; + } + + static inline uint8_t LEDs_GetLEDs(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t LEDs_GetLEDs(void) + { + return (~PORTB & LEDS_ALL_LEDS); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/STK525/Buttons.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/STK525/Buttons.h new file mode 100644 index 00000000..dcca4d02 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/STK525/Buttons.h @@ -0,0 +1,103 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific Buttons driver header for the Atmel STK525. + * \copydetails Group_Buttons_STK525 + * + * \note This file should not be included directly. It is automatically included as needed by the Buttons driver + * dispatch header located in LUFA/Drivers/Board/Buttons.h. + */ + +/** \ingroup Group_Buttons + * \defgroup Group_Buttons_STK525 STK525 + * \brief Board specific Buttons driver header for the Atmel STK525. + * + * Board specific Buttons driver header for the Atmel STK525. + * + * + * + * + *
NameInfoActive LevelPort Pin
BUTTONS_BUTTON1HWB ButtonLowPORTE.2
+ * + * @{ + */ + +#ifndef __BUTTONS_STK525_H__ +#define __BUTTONS_STK525_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_BUTTONS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/Buttons.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Button mask for the first button on the board. */ + #define BUTTONS_BUTTON1 (1 << 2) + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void Buttons_Init(void) + { + DDRE &= ~BUTTONS_BUTTON1; + PORTE |= BUTTONS_BUTTON1; + } + + static inline void Buttons_Disable(void) + { + DDRE &= ~BUTTONS_BUTTON1; + PORTE &= ~BUTTONS_BUTTON1; + } + + static inline uint8_t Buttons_GetStatus(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t Buttons_GetStatus(void) + { + return ((PINE & BUTTONS_BUTTON1) ^ BUTTONS_BUTTON1); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/STK525/Dataflash.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/STK525/Dataflash.h new file mode 100644 index 00000000..1e24c526 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/STK525/Dataflash.h @@ -0,0 +1,220 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific Dataflash driver header for the Atmel STK525. + * \copydetails Group_Dataflash_STK525 + * + * \note This file should not be included directly. It is automatically included as needed by the dataflash driver + * dispatch header located in LUFA/Drivers/Board/Dataflash.h. + */ + +/** \ingroup Group_Dataflash + * \defgroup Group_Dataflash_STK525 STK525 + * \brief Board specific Dataflash driver header for the Atmel STK525. + * + * Board specific Dataflash driver header for the Atmel STK525. + * + * + * + * + *
NameInfoSelect PinSPI Port
DATAFLASH_CHIP1AT45DB321C (4MB)PORTB.4SPI0
+ * + * @{ + */ + +#ifndef __DATAFLASH_STK525_H__ +#define __DATAFLASH_STK525_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + #include "../../../Misc/AT45DB321C.h" + #include "../../../Peripheral/SPI.h" + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_DATAFLASH_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/Dataflash.h instead. + #endif + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Macros: */ + #define DATAFLASH_CHIPCS_MASK (1 << 4) + #define DATAFLASH_CHIPCS_DDR DDRB + #define DATAFLASH_CHIPCS_PORT PORTB + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Constant indicating the total number of dataflash ICs mounted on the selected board. */ + #define DATAFLASH_TOTALCHIPS 1 + + /** Mask for no dataflash chip selected. */ + #define DATAFLASH_NO_CHIP DATAFLASH_CHIPCS_MASK + + /** Mask for the first dataflash chip selected. */ + #define DATAFLASH_CHIP1 0 + + /** Internal main memory page size for the board's dataflash IC. */ + #define DATAFLASH_PAGE_SIZE 512 + + /** Total number of pages inside the board's dataflash IC. */ + #define DATAFLASH_PAGES 8192 + + /* Inline Functions: */ + /** Initializes the dataflash driver so that commands and data may be sent to an attached dataflash IC. + * The microcontroller's SPI driver MUST be initialized before any of the dataflash commands are used. + */ + static inline void Dataflash_Init(void) + { + DATAFLASH_CHIPCS_DDR |= DATAFLASH_CHIPCS_MASK; + DATAFLASH_CHIPCS_PORT |= DATAFLASH_CHIPCS_MASK; + } + + /** Sends a byte to the currently selected dataflash IC, and returns a byte from the dataflash. + * + * \param[in] Byte Byte of data to send to the dataflash + * + * \return Last response byte from the dataflash + */ + static inline uint8_t Dataflash_TransferByte(const uint8_t Byte) ATTR_ALWAYS_INLINE; + static inline uint8_t Dataflash_TransferByte(const uint8_t Byte) + { + return SPI_TransferByte(Byte); + } + + /** Sends a byte to the currently selected dataflash IC, and ignores the next byte from the dataflash. + * + * \param[in] Byte Byte of data to send to the dataflash + */ + static inline void Dataflash_SendByte(const uint8_t Byte) ATTR_ALWAYS_INLINE; + static inline void Dataflash_SendByte(const uint8_t Byte) + { + SPI_SendByte(Byte); + } + + /** Sends a dummy byte to the currently selected dataflash IC, and returns the next byte from the dataflash. + * + * \return Last response byte from the dataflash + */ + static inline uint8_t Dataflash_ReceiveByte(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT; + static inline uint8_t Dataflash_ReceiveByte(void) + { + return SPI_ReceiveByte(); + } + + /** Determines the currently selected dataflash chip. + * + * \return Mask of the currently selected Dataflash chip, either \ref DATAFLASH_NO_CHIP if no chip is selected + * or a DATAFLASH_CHIPn mask (where n is the chip number). + */ + static inline uint8_t Dataflash_GetSelectedChip(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT; + static inline uint8_t Dataflash_GetSelectedChip(void) + { + return (DATAFLASH_CHIPCS_PORT & DATAFLASH_CHIPCS_MASK); + } + + /** Selects the given dataflash chip. + * + * \param[in] ChipMask Mask of the Dataflash IC to select, in the form of DATAFLASH_CHIPn mask (where n is + * the chip number). + */ + static inline void Dataflash_SelectChip(const uint8_t ChipMask) ATTR_ALWAYS_INLINE; + static inline void Dataflash_SelectChip(const uint8_t ChipMask) + { + DATAFLASH_CHIPCS_PORT = ((DATAFLASH_CHIPCS_PORT & ~DATAFLASH_CHIPCS_MASK) | ChipMask); + } + + /** Deselects the current dataflash chip, so that no dataflash is selected. */ + static inline void Dataflash_DeselectChip(void) ATTR_ALWAYS_INLINE; + static inline void Dataflash_DeselectChip(void) + { + Dataflash_SelectChip(DATAFLASH_NO_CHIP); + } + + /** Selects a dataflash IC from the given page number, which should range from 0 to + * ((DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS) - 1). For boards containing only one + * dataflash IC, this will select DATAFLASH_CHIP1. If the given page number is outside + * the total number of pages contained in the boards dataflash ICs, all dataflash ICs + * are deselected. + * + * \param[in] PageAddress Address of the page to manipulate, ranging from + * 0 to ((DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS) - 1). + */ + static inline void Dataflash_SelectChipFromPage(const uint16_t PageAddress) + { + Dataflash_DeselectChip(); + + if (PageAddress >= DATAFLASH_PAGES) + return; + + Dataflash_SelectChip(DATAFLASH_CHIP1); + } + + /** Toggles the select line of the currently selected dataflash IC, so that it is ready to receive + * a new command. + */ + static inline void Dataflash_ToggleSelectedChipCS(void) + { + uint8_t SelectedChipMask = Dataflash_GetSelectedChip(); + + Dataflash_DeselectChip(); + Dataflash_SelectChip(SelectedChipMask); + } + + /** Spin-loops while the currently selected dataflash is busy executing a command, such as a main + * memory page program or main memory to buffer transfer. + */ + static inline void Dataflash_WaitWhileBusy(void) + { + Dataflash_ToggleSelectedChipCS(); + Dataflash_SendByte(DF_CMD_GETSTATUS); + while (!(Dataflash_ReceiveByte() & DF_STATUS_READY)); + Dataflash_ToggleSelectedChipCS(); + } + + /** Sends a set of page and buffer address bytes to the currently selected dataflash IC, for use with + * dataflash commands which require a complete 24-bit address. + * + * \param[in] PageAddress Page address within the selected dataflash IC + * \param[in] BufferByte Address within the dataflash's buffer + */ + static inline void Dataflash_SendAddressBytes(uint16_t PageAddress, + const uint16_t BufferByte) + { + Dataflash_SendByte(PageAddress >> 6); + Dataflash_SendByte((PageAddress << 2) | (BufferByte >> 8)); + Dataflash_SendByte(BufferByte); + } + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/STK525/Joystick.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/STK525/Joystick.h new file mode 100644 index 00000000..dfa86aca --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/STK525/Joystick.h @@ -0,0 +1,130 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific joystick driver header for the Atmel STK525. + * \copydetails Group_Joystick_STK525 + * + * \note This file should not be included directly. It is automatically included as needed by the joystick driver + * dispatch header located in LUFA/Drivers/Board/Joystick.h. + */ + +/** \ingroup Group_Joystick + * \defgroup Group_Joystick_STK525 STK525 + * \brief Board specific joystick driver header for the Atmel STK525. + * + * Board specific joystick driver header for the Atmel STK525. + * + * + * + * + *
Left Port PinUp Port PinRight Port PinDown Port PinPress Port Pin
PORTB.6PORTB.7PORTE.4PORTE.5PORTB.5
+ * + * @{ + */ + +#ifndef __JOYSTICK_STK525_H__ +#define __JOYSTICK_STK525_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_JOYSTICK_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/Joystick.h instead. + #endif + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Macros: */ + #define JOY_BMASK ((1 << 5) | (1 << 6) | (1 << 7)) + #define JOY_EMASK ((1 << 4) | (1 << 5)) + + #define JOY_PORTE_MASK_SHIFT 1 + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Mask for the joystick being pushed in the left direction. */ + #define JOY_LEFT (1 << 6) + + /** Mask for the joystick being pushed in the right direction. */ + #define JOY_RIGHT ((1 << 4) >> JOY_PORTE_MASK_SHIFT) + + /** Mask for the joystick being pushed in the upward direction. */ + #define JOY_UP (1 << 7) + + /** Mask for the joystick being pushed in the downward direction. */ + #define JOY_DOWN ((1 << 5) >> JOY_PORTE_MASK_SHIFT) + + /** Mask for the joystick being pushed inward. */ + #define JOY_PRESS (1 << 5) + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void Joystick_Init(void) + { + DDRB &= ~JOY_BMASK; + DDRE &= ~JOY_EMASK; + + PORTB |= JOY_BMASK; + PORTE |= JOY_EMASK; + } + + static inline void Joystick_Disable(void) + { + DDRB &= ~JOY_BMASK; + DDRE &= ~JOY_EMASK; + + PORTB &= ~JOY_BMASK; + PORTE &= ~JOY_EMASK; + } + + static inline uint8_t Joystick_GetStatus(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t Joystick_GetStatus(void) + { + return (((uint8_t)~PINB & JOY_BMASK) | (((uint8_t)~PINE & JOY_EMASK) >> JOY_PORTE_MASK_SHIFT)); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/STK525/LEDs.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/STK525/LEDs.h new file mode 100644 index 00000000..48ac4860 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/STK525/LEDs.h @@ -0,0 +1,147 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific LED driver header for the Atmel STK525. + * \copydetails Group_LEDs_STK525 + * + * \note This file should not be included directly. It is automatically included as needed by the LEDs driver + * dispatch header located in LUFA/Drivers/Board/LEDs.h. + */ + +/** \ingroup Group_LEDs + * \defgroup Group_LEDs_STK525 STK525 + * \brief Board specific LED driver header for the Atmel STK525. + * + * Board specific LED driver header for the Atmel STK525. + * + * + * + * + * + * + * + *
NameColorInfoActive LevelPort Pin
LEDS_LED1GreenGeneral IndicatorHighPORTD.4
LEDS_LED2GreenGeneral IndicatorHighPORTD.5
LEDS_LED3GreenGeneral IndicatorHighPORTD.6
LEDS_LED4GreenGeneral IndicatorHighPORTD.7
+ * + * @{ + */ + +#ifndef __LEDS_STK525_H__ +#define __LEDS_STK525_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_LEDS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/LEDS.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** LED mask for the first LED on the board. */ + #define LEDS_LED1 (1 << 4) + + /** LED mask for the second LED on the board. */ + #define LEDS_LED2 (1 << 5) + + /** LED mask for the third LED on the board. */ + #define LEDS_LED3 (1 << 7) + + /** LED mask for the fourth LED on the board. */ + #define LEDS_LED4 (1 << 6) + + /** LED mask for all the LEDs on the board. */ + #define LEDS_ALL_LEDS (LEDS_LED1 | LEDS_LED2 | LEDS_LED3 | LEDS_LED4) + + /** LED mask for none of the board LEDs. */ + #define LEDS_NO_LEDS 0 + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void LEDs_Init(void) + { + DDRD |= LEDS_ALL_LEDS; + PORTD &= ~LEDS_ALL_LEDS; + } + + static inline void LEDs_Disable(void) + { + DDRD &= ~LEDS_ALL_LEDS; + PORTD &= ~LEDS_ALL_LEDS; + } + + static inline void LEDs_TurnOnLEDs(const uint8_t LEDMask) + { + PORTD |= LEDMask; + } + + static inline void LEDs_TurnOffLEDs(const uint8_t LEDMask) + { + PORTD &= ~LEDMask; + } + + static inline void LEDs_SetAllLEDs(const uint8_t LEDMask) + { + PORTD = ((PORTD & ~LEDS_ALL_LEDS) | LEDMask); + } + + static inline void LEDs_ChangeLEDs(const uint8_t LEDMask, + const uint8_t ActiveMask) + { + PORTD = ((PORTD & ~LEDMask) | ActiveMask); + } + + static inline void LEDs_ToggleLEDs(const uint8_t LEDMask) + { + PIND = LEDMask; + } + + static inline uint8_t LEDs_GetLEDs(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t LEDs_GetLEDs(void) + { + return (PORTD & LEDS_ALL_LEDS); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/STK526/Buttons.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/STK526/Buttons.h new file mode 100644 index 00000000..ec5a7e0e --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/STK526/Buttons.h @@ -0,0 +1,103 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific Buttons driver header for the Atmel STK526. + * \copydetails Group_Buttons_STK526 + * + * \note This file should not be included directly. It is automatically included as needed by the Buttons driver + * dispatch header located in LUFA/Drivers/Board/Buttons.h. + */ + +/** \ingroup Group_Buttons + * \defgroup Group_Buttons_STK526 STK526 + * \brief Board specific Buttons driver header for the Atmel STK526. + * + * Board specific Buttons driver header for the Atmel STK526. + * + * + * + * + *
NameInfoActive LevelPort Pin
BUTTONS_BUTTON1HWB ButtonLowPORTD.7
+ * + * @{ + */ + +#ifndef __BUTTONS_STK526_H__ +#define __BUTTONS_STK526_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_BUTTONS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/Buttons.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Button mask for the first button on the board. */ + #define BUTTONS_BUTTON1 (1 << 7) + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void Buttons_Init(void) + { + DDRD &= ~BUTTONS_BUTTON1; + PORTD |= BUTTONS_BUTTON1; + } + + static inline void Buttons_Disable(void) + { + DDRD &= ~BUTTONS_BUTTON1; + PORTD &= ~BUTTONS_BUTTON1; + } + + static inline uint8_t Buttons_GetStatus(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t Buttons_GetStatus(void) + { + return ((PIND & BUTTONS_BUTTON1) ^ BUTTONS_BUTTON1); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/STK526/Dataflash.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/STK526/Dataflash.h new file mode 100644 index 00000000..07d44b14 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/STK526/Dataflash.h @@ -0,0 +1,220 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific Dataflash driver header for the Atmel STK525. + * \copydetails Group_Dataflash_STK526 + * + * \note This file should not be included directly. It is automatically included as needed by the dataflash driver + * dispatch header located in LUFA/Drivers/Board/Dataflash.h. + */ + +/** \ingroup Group_Dataflash + * \defgroup Group_Dataflash_STK526 STK526 + * \brief Board specific Dataflash driver header for the Atmel STK525. + * + * Board specific Dataflash driver header for the Atmel STK525. + * + * + * + * + *
NameInfoSelect PinSPI Port
DATAFLASH_CHIP1AT45DB642D (8MB)PORTC.2SPI0
+ * + * @{ + */ + +#ifndef __DATAFLASH_STK526_H__ +#define __DATAFLASH_STK526_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + #include "../../../Misc/AT45DB642D.h" + #include "../../../Peripheral/SPI.h" + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_DATAFLASH_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/Dataflash.h instead. + #endif + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Macros: */ + #define DATAFLASH_CHIPCS_MASK (1 << 2) + #define DATAFLASH_CHIPCS_DDR DDRC + #define DATAFLASH_CHIPCS_PORT PORTC + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Constant indicating the total number of dataflash ICs mounted on the selected board. */ + #define DATAFLASH_TOTALCHIPS 1 + + /** Mask for no dataflash chip selected. */ + #define DATAFLASH_NO_CHIP DATAFLASH_CHIPCS_MASK + + /** Mask for the first dataflash chip selected. */ + #define DATAFLASH_CHIP1 0 + + /** Internal main memory page size for the board's dataflash IC. */ + #define DATAFLASH_PAGE_SIZE 1024 + + /** Total number of pages inside the board's dataflash IC. */ + #define DATAFLASH_PAGES 8192 + + /* Inline Functions: */ + /** Initializes the dataflash driver so that commands and data may be sent to an attached dataflash IC. + * The microcontroller's SPI driver MUST be initialized before any of the dataflash commands are used. + */ + static inline void Dataflash_Init(void) + { + DATAFLASH_CHIPCS_DDR |= DATAFLASH_CHIPCS_MASK; + DATAFLASH_CHIPCS_PORT |= DATAFLASH_CHIPCS_MASK; + } + + /** Sends a byte to the currently selected dataflash IC, and returns a byte from the dataflash. + * + * \param[in] Byte Byte of data to send to the dataflash + * + * \return Last response byte from the dataflash + */ + static inline uint8_t Dataflash_TransferByte(const uint8_t Byte) ATTR_ALWAYS_INLINE; + static inline uint8_t Dataflash_TransferByte(const uint8_t Byte) + { + return SPI_TransferByte(Byte); + } + + /** Sends a byte to the currently selected dataflash IC, and ignores the next byte from the dataflash. + * + * \param[in] Byte Byte of data to send to the dataflash + */ + static inline void Dataflash_SendByte(const uint8_t Byte) ATTR_ALWAYS_INLINE; + static inline void Dataflash_SendByte(const uint8_t Byte) + { + SPI_SendByte(Byte); + } + + /** Sends a dummy byte to the currently selected dataflash IC, and returns the next byte from the dataflash. + * + * \return Last response byte from the dataflash + */ + static inline uint8_t Dataflash_ReceiveByte(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT; + static inline uint8_t Dataflash_ReceiveByte(void) + { + return SPI_ReceiveByte(); + } + + /** Determines the currently selected dataflash chip. + * + * \return Mask of the currently selected Dataflash chip, either \ref DATAFLASH_NO_CHIP if no chip is selected + * or a DATAFLASH_CHIPn mask (where n is the chip number). + */ + static inline uint8_t Dataflash_GetSelectedChip(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT; + static inline uint8_t Dataflash_GetSelectedChip(void) + { + return (DATAFLASH_CHIPCS_PORT & DATAFLASH_CHIPCS_MASK); + } + + /** Selects the given dataflash chip. + * + * \param[in] ChipMask Mask of the Dataflash IC to select, in the form of DATAFLASH_CHIPn mask (where n is + * the chip number). + */ + static inline void Dataflash_SelectChip(const uint8_t ChipMask) ATTR_ALWAYS_INLINE; + static inline void Dataflash_SelectChip(const uint8_t ChipMask) + { + DATAFLASH_CHIPCS_PORT = ((DATAFLASH_CHIPCS_PORT & ~DATAFLASH_CHIPCS_MASK) | ChipMask); + } + + /** Deselects the current dataflash chip, so that no dataflash is selected. */ + static inline void Dataflash_DeselectChip(void) ATTR_ALWAYS_INLINE; + static inline void Dataflash_DeselectChip(void) + { + Dataflash_SelectChip(DATAFLASH_NO_CHIP); + } + + /** Selects a dataflash IC from the given page number, which should range from 0 to + * ((DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS) - 1). For boards containing only one + * dataflash IC, this will select DATAFLASH_CHIP1. If the given page number is outside + * the total number of pages contained in the boards dataflash ICs, all dataflash ICs + * are deselected. + * + * \param[in] PageAddress Address of the page to manipulate, ranging from + * 0 to ((DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS) - 1). + */ + static inline void Dataflash_SelectChipFromPage(const uint16_t PageAddress) + { + Dataflash_DeselectChip(); + + if (PageAddress >= DATAFLASH_PAGES) + return; + + Dataflash_SelectChip(DATAFLASH_CHIP1); + } + + /** Toggles the select line of the currently selected dataflash IC, so that it is ready to receive + * a new command. + */ + static inline void Dataflash_ToggleSelectedChipCS(void) + { + uint8_t SelectedChipMask = Dataflash_GetSelectedChip(); + + Dataflash_DeselectChip(); + Dataflash_SelectChip(SelectedChipMask); + } + + /** Spin-loops while the currently selected dataflash is busy executing a command, such as a main + * memory page program or main memory to buffer transfer. + */ + static inline void Dataflash_WaitWhileBusy(void) + { + Dataflash_ToggleSelectedChipCS(); + Dataflash_SendByte(DF_CMD_GETSTATUS); + while (!(Dataflash_ReceiveByte() & DF_STATUS_READY)); + Dataflash_ToggleSelectedChipCS(); + } + + /** Sends a set of page and buffer address bytes to the currently selected dataflash IC, for use with + * dataflash commands which require a complete 24-bit address. + * + * \param[in] PageAddress Page address within the selected dataflash IC + * \param[in] BufferByte Address within the dataflash's buffer + */ + static inline void Dataflash_SendAddressBytes(uint16_t PageAddress, + const uint16_t BufferByte) + { + Dataflash_SendByte(PageAddress >> 5); + Dataflash_SendByte((PageAddress << 3) | (BufferByte >> 8)); + Dataflash_SendByte(BufferByte); + } + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/STK526/Joystick.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/STK526/Joystick.h new file mode 100644 index 00000000..bc5f489e --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/STK526/Joystick.h @@ -0,0 +1,123 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific joystick driver header for the Atmel STK526. + * \copydetails Group_Joystick_STK526 + * + * \note This file should not be included directly. It is automatically included as needed by the joystick driver + * dispatch header located in LUFA/Drivers/Board/Joystick.h. + */ + +/** \ingroup Group_Joystick + * \defgroup Group_Joystick_STK526 STK526 + * \brief Board specific joystick driver header for the Atmel STK526. + * + * Board specific joystick driver header for the Atmel STK526. + * + * + * + * + *
Left Port PinUp Port PinRight Port PinDown Port PinPress Port Pin
PORTB.4PORTB.5PORTB.6PORTB.7PORTB.0
+ * + * @{ + */ + +#ifndef __JOYSTICK_STK526_H__ +#define __JOYSTICK_STK526_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_JOYSTICK_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/Joystick.h instead. + #endif + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Macros: */ + #define JOY_BMASK ((1 << 0) | (1 << 4) | (1 << 5) | (1 << 6) | (1 << 7)) + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Mask for the joystick being pushed in the left direction. */ + #define JOY_LEFT (1 << 4) + + /** Mask for the joystick being pushed in the right direction. */ + #define JOY_RIGHT (1 << 6) + + /** Mask for the joystick being pushed in the upward direction. */ + #define JOY_UP (1 << 5) + + /** Mask for the joystick being pushed in the downward direction. */ + #define JOY_DOWN (1 << 7) + + /** Mask for the joystick being pushed inward. */ + #define JOY_PRESS (1 << 0) + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void Joystick_Init(void) + { + DDRB &= ~JOY_BMASK; + + PORTB |= JOY_BMASK; + } + + static inline void Joystick_Disable(void) + { + DDRB &= ~JOY_BMASK; + + PORTB &= ~JOY_BMASK; + } + + static inline uint8_t Joystick_GetStatus(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t Joystick_GetStatus(void) + { + return ((uint8_t)~PINB & JOY_BMASK); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/STK526/LEDs.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/STK526/LEDs.h new file mode 100644 index 00000000..d9bb3b99 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/STK526/LEDs.h @@ -0,0 +1,147 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific LED driver header for the Atmel STK526. + * \copydetails Group_LEDs_STK526 + * + * \note This file should not be included directly. It is automatically included as needed by the LEDs driver + * dispatch header located in LUFA/Drivers/Board/LEDs.h. + */ + +/** \ingroup Group_LEDs + * \defgroup Group_LEDs_STK526 STK526 + * \brief Board specific LED driver header for the Atmel STK526. + * + * Board specific LED driver header for the Atmel STK526. + * + * + * + * + * + * + * + *
NameColorInfoActive LevelPort Pin
LEDS_LED1GreenGeneral IndicatorHighPORTD.1
LEDS_LED2GreenGeneral IndicatorHighPORTD.0
LEDS_LED3GreenGeneral IndicatorHighPORTD.5
LEDS_LED4GreenGeneral IndicatorHighPORTD.4
+ * + * @{ + */ + +#ifndef __LEDS_STK526_H__ +#define __LEDS_STK526_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_LEDS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/LEDS.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** LED mask for the first LED on the board. */ + #define LEDS_LED1 (1 << 1) + + /** LED mask for the second LED on the board. */ + #define LEDS_LED2 (1 << 0) + + /** LED mask for the third LED on the board. */ + #define LEDS_LED3 (1 << 5) + + /** LED mask for the fourth LED on the board. */ + #define LEDS_LED4 (1 << 4) + + /** LED mask for all the LEDs on the board. */ + #define LEDS_ALL_LEDS (LEDS_LED1 | LEDS_LED2 | LEDS_LED3 | LEDS_LED4) + + /** LED mask for none of the board LEDs. */ + #define LEDS_NO_LEDS 0 + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void LEDs_Init(void) + { + DDRD |= LEDS_ALL_LEDS; + PORTD &= ~LEDS_ALL_LEDS; + } + + static inline void LEDs_Disable(void) + { + DDRD &= ~LEDS_ALL_LEDS; + PORTD &= ~LEDS_ALL_LEDS; + } + + static inline void LEDs_TurnOnLEDs(const uint8_t LEDMask) + { + PORTD |= LEDMask; + } + + static inline void LEDs_TurnOffLEDs(const uint8_t LEDMask) + { + PORTD &= ~LEDMask; + } + + static inline void LEDs_SetAllLEDs(const uint8_t LEDMask) + { + PORTD = ((PORTD & ~LEDS_ALL_LEDS) | LEDMask); + } + + static inline void LEDs_ChangeLEDs(const uint8_t LEDMask, + const uint8_t ActiveMask) + { + PORTD = ((PORTD & ~LEDMask) | ActiveMask); + } + + static inline void LEDs_ToggleLEDs(const uint8_t LEDMask) + { + PIND = LEDMask; + } + + static inline uint8_t LEDs_GetLEDs(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t LEDs_GetLEDs(void) + { + return (PORTD & LEDS_ALL_LEDS); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/TEENSY/LEDs.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/TEENSY/LEDs.h new file mode 100644 index 00000000..8f0cfafb --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/TEENSY/LEDs.h @@ -0,0 +1,176 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific LED driver header for the PJRC Teensy 1.x/2.x boards. + * \copydetails Group_LEDs_TEENSY + * + * \note This file should not be included directly. It is automatically included as needed by the LEDs driver + * dispatch header located in LUFA/Drivers/Board/LEDs.h. + */ + +/** \ingroup Group_LEDs + * \defgroup Group_LEDs_TEENSY2 TEENSY2 + * \brief Board specific LED driver header for the PJRC Teensy 2 boards. + * + * See \ref Group_LEDs_TEENSY for more details. + */ + +/** \ingroup Group_LEDs + * \defgroup Group_LEDs_TEENSY TEENSY + * \brief Board specific LED driver header for the PJRC Teensy 1.x/2.x boards. + * + * \note For version 2 Teensy boards, compile with BOARD = TEENSY2. + * + * Board specific LED driver header for the PJRC Teensy boards (http://www.pjrc.com/teensy/index.html). + * + * TEENSY: + * + * + * + *
NameColorInfoActive LevelPort Pin
LEDS_LED1GreenGeneral IndicatorHighPORTD.6
+ * + * TEENSY2: + * + * + * + *
NameColorInfoActive LevelPort Pin
LEDS_LED1GreenGeneral IndicatorLowPORTD.6
+ * + * @{ + */ + +#ifndef __LEDS_TEENSY_H__ +#define __LEDS_TEENSY_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_LEDS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/LEDS.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** LED mask for the first LED on the board. */ + #define LEDS_LED1 (1 << 6) + + /** LED mask for all the LEDs on the board. */ + #define LEDS_ALL_LEDS LEDS_LED1 + + /** LED mask for none of the board LEDs. */ + #define LEDS_NO_LEDS 0 + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void LEDs_Init(void) + { + DDRD |= LEDS_ALL_LEDS; + + #if (BOARD == BOARD_TEENSY2) + PORTD &= ~LEDS_ALL_LEDS; + #else + PORTD |= LEDS_ALL_LEDS; + #endif + } + + static inline void LEDs_Disable(void) + { + DDRD &= ~LEDS_ALL_LEDS; + PORTD &= ~LEDS_ALL_LEDS; + } + + static inline void LEDs_TurnOnLEDs(const uint8_t LEDMask) + { + #if (BOARD == BOARD_TEENSY2) + PORTD |= LEDMask; + #else + PORTD &= ~LEDMask; + #endif + } + + static inline void LEDs_TurnOffLEDs(const uint8_t LEDMask) + { + #if (BOARD == BOARD_TEENSY2) + PORTD &= ~LEDMask; + #else + PORTD |= LEDMask; + #endif + } + + static inline void LEDs_SetAllLEDs(const uint8_t LEDMask) + { + #if (BOARD == BOARD_TEENSY2) + PORTD = ((PORTD & ~LEDS_ALL_LEDS) | LEDMask); + #else + PORTD = ((PORTD | LEDS_ALL_LEDS) & ~LEDMask); + #endif + } + + static inline void LEDs_ChangeLEDs(const uint8_t LEDMask, + const uint8_t ActiveMask) + { + #if (BOARD == BOARD_TEENSY2) + PORTD = ((PORTD & ~LEDMask) | ActiveMask); + #else + PORTD = ((PORTD | LEDMask) & ~ActiveMask); + #endif + } + + static inline void LEDs_ToggleLEDs(const uint8_t LEDMask) + { + PIND = LEDMask; + } + + static inline uint8_t LEDs_GetLEDs(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t LEDs_GetLEDs(void) + { + #if (BOARD == BOARD_TEENSY2) + return (PORTD & LEDS_ALL_LEDS); + #else + return (~PORTD & LEDS_ALL_LEDS); + #endif + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/TUL/Buttons.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/TUL/Buttons.h new file mode 100644 index 00000000..a8e10412 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/TUL/Buttons.h @@ -0,0 +1,103 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific Buttons driver header for the TUL. + * \copydetails Group_Buttons_TUL + * + * \note This file should not be included directly. It is automatically included as needed by the Buttons driver + * dispatch header located in LUFA/Drivers/Board/Buttons.h. + */ + +/** \ingroup Group_Buttons + * \defgroup Group_Buttons_TUL TUL + * \brief Board specific Buttons driver header for the TUL. + * + * Board specific Buttons driver header for the Busware TUL (http://www.busware.de/tiki-index.php?page=TUL). + * + * + * + * + *
NameInfoActive LevelPort Pin
BUTTONS_BUTTON1HWB ButtonLowPORTE.2
+ * + * @{ + */ + +#ifndef __BUTTONS_TUL_H__ +#define __BUTTONS_TUL_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_BUTTONS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/Buttons.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Button mask for the first button on the board. */ + #define BUTTONS_BUTTON1 (1 << 2) + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void Buttons_Init(void) + { + DDRE &= ~BUTTONS_BUTTON1; + PORTE |= BUTTONS_BUTTON1; + } + + static inline void Buttons_Disable(void) + { + DDRE &= ~BUTTONS_BUTTON1; + PORTE &= ~BUTTONS_BUTTON1; + } + + static inline uint8_t Buttons_GetStatus(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t Buttons_GetStatus(void) + { + return ((PINE & BUTTONS_BUTTON1) ^ BUTTONS_BUTTON1); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/TUL/LEDs.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/TUL/LEDs.h new file mode 100644 index 00000000..494396bf --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/TUL/LEDs.h @@ -0,0 +1,135 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific LED driver header for the Busware TUL. + * \copydetails Group_LEDs_TUL + * + * \note This file should not be included directly. It is automatically included as needed by the LEDs driver + * dispatch header located in LUFA/Drivers/Board/LEDs.h. + */ + +/** \ingroup Group_LEDs + * \defgroup Group_LEDs_TUL TUL + * \brief Board specific LED driver header for the Busware TUL. + * + * Board specific LED driver header for the Busware TUL (http://www.busware.de/tiki-index.php?page=TUL). + * + * + * + * + *
NameColorInfoActive LevelPort Pin
LEDS_LED1GreenGeneral IndicatorHighPORTF.0
+ * + * @{ + */ + +#ifndef __LEDS_TUL_H__ +#define __LEDS_TUL_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_LEDS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/LEDS.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** LED mask for the first LED on the board. */ + #define LEDS_LED1 (1 << 0) + + /** LED mask for all the LEDs on the board. */ + #define LEDS_ALL_LEDS LEDS_LED1 + + /** LED mask for the none of the board LEDs. */ + #define LEDS_NO_LEDS 0 + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void LEDs_Init(void) + { + DDRF |= LEDS_ALL_LEDS; + PORTF &= ~LEDS_ALL_LEDS; + } + + static inline void LEDs_Disable(void) + { + DDRF &= ~LEDS_ALL_LEDS; + PORTF &= ~LEDS_ALL_LEDS; + } + + static inline void LEDs_TurnOnLEDs(const uint8_t LEDMask) + { + PORTF |= LEDMask; + } + + static inline void LEDs_TurnOffLEDs(const uint8_t LEDMask) + { + PORTF &= ~LEDMask; + } + + static inline void LEDs_SetAllLEDs(const uint8_t LEDMask) + { + PORTF = ((PORTF & ~LEDS_ALL_LEDS) | LEDMask); + } + + static inline void LEDs_ChangeLEDs(const uint8_t LEDMask, + const uint8_t ActiveMask) + { + PORTF = ((PORTF & ~LEDMask) | ActiveMask); + } + + static inline void LEDs_ToggleLEDs(const uint8_t LEDMask) + { + PINF = LEDMask; + } + + static inline uint8_t LEDs_GetLEDs(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t LEDs_GetLEDs(void) + { + return (PORTF & LEDS_ALL_LEDS); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/UDIP/Buttons.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/UDIP/Buttons.h new file mode 100644 index 00000000..3e0bede0 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/UDIP/Buttons.h @@ -0,0 +1,103 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific Buttons driver header for the UDIP. + * \copydetails Group_Buttons_UDIP + * + * \note This file should not be included directly. It is automatically included as needed by the Buttons driver + * dispatch header located in LUFA/Drivers/Board/Buttons.h. + */ + +/** \ingroup Group_Buttons + * \defgroup Group_Buttons_UDIP UDIP + * \brief Board specific Buttons driver header for the UDIP. + * + * Board specific Buttons driver header for the Linnix UDIP (http://linnix.com/udip/). + * + * + * + * + *
NameInfoActive LevelPort Pin
BUTTONS_BUTTON1HWB ButtonLowPORTD.7
+ * + * @{ + */ + +#ifndef __BUTTONS_UDIP_H__ +#define __BUTTONS_UDIP_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_BUTTONS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/Buttons.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Button mask for the first button on the board. */ + #define BUTTONS_BUTTON1 (1 << 7) + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void Buttons_Init(void) + { + DDRD &= ~BUTTONS_BUTTON1; + PORTD |= BUTTONS_BUTTON1; + } + + static inline void Buttons_Disable(void) + { + DDRD &= ~BUTTONS_BUTTON1; + PORTD &= ~BUTTONS_BUTTON1; + } + + static inline uint8_t Buttons_GetStatus(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t Buttons_GetStatus(void) + { + return ((PIND & BUTTONS_BUTTON1) ^ BUTTONS_BUTTON1); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/UDIP/LEDs.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/UDIP/LEDs.h new file mode 100644 index 00000000..1cff6fc6 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/UDIP/LEDs.h @@ -0,0 +1,163 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific LED driver header for the Linnix UDIP. + * \copydetails Group_LEDs_UDIP + * + * \note This file should not be included directly. It is automatically included as needed by the LEDs driver + * dispatch header located in LUFA/Drivers/Board/LEDs.h. + */ + +/** \ingroup Group_LEDs + * \defgroup Group_LEDs_UDIP UDIP + * \brief Board specific LED driver header for the Linnix UDIP. + * + * Board specific LED driver header for the Linnix UDIP (http://linnix.com/udip/). + * + * + * + * + * + * + * + *
NameColorInfoActive LevelPort Pin
LEDS_LED1GreenBicolor Indicator 1HighPORTB.6
LEDS_LED2RedBicolor Indicator 1HighPORTB.5
LEDS_LED3GreenBicolor Indicator 2HighPORTD.5
LEDS_LED4RedBicolor Indicator 2HighPORTD.4
+ * + * @{ + */ + +#ifndef __LEDS_UDIP_H__ +#define __LEDS_UDIP_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_LEDS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/LEDS.h instead. + #endif + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Macros: */ + #define LEDS_PORTB_LEDS (LEDS_LED1 | LEDS_LED2) + #define LEDS_PORTD_LEDS (LEDS_LED3 | LEDS_LED4) + + #define LEDS_PORTD_MASK_SHIFT 1 + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** LED mask for the first LED on the board. */ + #define LEDS_LED1 (1 << 6) + + /** LED mask for the second LED on the board. */ + #define LEDS_LED2 (1 << 5) + + /** LED mask for the third LED on the board. */ + #define LEDS_LED3 ((1 << 5) >> LEDS_PORTD_MASK_SHIFT) + + /** LED mask for the fourth LED on the board. */ + #define LEDS_LED4 ((1 << 4) >> LEDS_PORTD_MASK_SHIFT) + + /** LED mask for all the LEDs on the board. */ + #define LEDS_ALL_LEDS (LEDS_LED1 | LEDS_LED2 | LEDS_LED3 | LEDS_LED4) + + /** LED mask for none of the board LEDs. */ + #define LEDS_NO_LEDS 0 + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void LEDs_Init(void) + { + DDRB |= LEDS_PORTB_LEDS; + DDRD |= (LEDS_PORTD_LEDS << LEDS_PORTD_MASK_SHIFT); + } + + static inline void LEDs_Disable(void) + { + DDRB &= ~LEDS_PORTB_LEDS; + DDRD &= ~(LEDS_PORTD_LEDS << LEDS_PORTD_MASK_SHIFT); + } + + static inline void LEDs_TurnOnLEDs(const uint8_t LEDMask) + { + PORTB |= (LEDMask & LEDS_PORTB_LEDS); + PORTD |= ((LEDMask & LEDS_PORTD_LEDS) << LEDS_PORTD_MASK_SHIFT); + } + + static inline void LEDs_TurnOffLEDs(const uint8_t LEDMask) + { + PORTB &= ~(LEDMask & LEDS_PORTB_LEDS); + PORTD &= ~((LEDMask & LEDS_PORTD_LEDS) << LEDS_PORTD_MASK_SHIFT); + } + + static inline void LEDs_SetAllLEDs(const uint8_t LEDMask) + { + PORTB = (PORTB & ~LEDS_PORTB_LEDS) | (LEDMask & LEDS_PORTB_LEDS); + PORTD = (PORTD & ~(LEDS_PORTD_LEDS << LEDS_PORTD_MASK_SHIFT)) | + ((LEDMask & LEDS_PORTD_LEDS) << LEDS_PORTD_MASK_SHIFT); + } + + static inline void LEDs_ChangeLEDs(const uint8_t LEDMask, + const uint8_t ActiveMask) + { + PORTB = (PORTB & ~(LEDMask & LEDS_PORTB_LEDS)) | (ActiveMask & LEDS_PORTB_LEDS); + PORTD = (PORTD & ~((LEDMask & LEDS_PORTD_LEDS) << LEDS_PORTD_MASK_SHIFT)) | + ((ActiveMask & LEDS_PORTD_LEDS) << LEDS_PORTD_MASK_SHIFT); + } + + static inline void LEDs_ToggleLEDs(const uint8_t LEDMask) + { + PINB = (LEDMask & LEDS_PORTB_LEDS); + PIND = ((LEDMask & LEDS_PORTD_LEDS) << LEDS_PORTD_MASK_SHIFT); + } + + static inline uint8_t LEDs_GetLEDs(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t LEDs_GetLEDs(void) + { + return ((PORTB & LEDS_PORTB_LEDS) | ((PORTD & LEDS_PORTD_LEDS) >> LEDS_PORTD_MASK_SHIFT)); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/UNO/LEDs.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/UNO/LEDs.h new file mode 100644 index 00000000..c7e09d4c --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/UNO/LEDs.h @@ -0,0 +1,139 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific LED driver header for the Arduino Uno. + * \copydetails Group_LEDs_UNO + * + * \note This file should not be included directly. It is automatically included as needed by the LEDs driver + * dispatch header located in LUFA/Drivers/Board/LEDs.h. + */ + +/** \ingroup Group_LEDs + * \defgroup Group_LEDs_UNO UNO + * \brief Board specific LED driver header for the Arduino Uno. + * + * Board specific LED driver header for the Arduino Uno (http://arduino.cc/en/Main/ArduinoBoardUno). + * + * + * + * + * + *
NameColorInfoActive LevelPort Pin
LEDS_LED1YellowRXLowPORTD.4
LEDS_LED2YellowTXLowPORTD.5
+ * + * @{ + */ + +#ifndef __LEDS_UNO_H__ +#define __LEDS_UNO_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_LEDS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/LEDS.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** LED mask for the first LED on the board. */ + #define LEDS_LED1 (1 << 4) + + /** LED mask for the second LED on the board. */ + #define LEDS_LED2 (1 << 5) + + /** LED mask for all the LEDs on the board. */ + #define LEDS_ALL_LEDS (LEDS_LED1 | LEDS_LED2) + + /** LED mask for none of the board LEDs. */ + #define LEDS_NO_LEDS 0 + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void LEDs_Init(void) + { + DDRD |= LEDS_ALL_LEDS; + PORTD |= LEDS_ALL_LEDS; + } + + static inline void LEDs_Disable(void) + { + DDRD &= ~LEDS_ALL_LEDS; + PORTD &= ~LEDS_ALL_LEDS; + } + + static inline void LEDs_TurnOnLEDs(const uint8_t LEDMask) + { + PORTD &= ~LEDMask; + } + + static inline void LEDs_TurnOffLEDs(const uint8_t LEDMask) + { + PORTD |= LEDMask; + } + + static inline void LEDs_SetAllLEDs(const uint8_t LEDMask) + { + PORTD = ((PORTD | LEDS_ALL_LEDS) & ~LEDMask); + } + + static inline void LEDs_ChangeLEDs(const uint8_t LEDMask, + const uint8_t ActiveMask) + { + PORTD = ((PORTD | LEDMask) & ~ActiveMask); + } + + static inline void LEDs_ToggleLEDs(const uint8_t LEDMask) + { + PIND = LEDMask; + } + + static inline uint8_t LEDs_GetLEDs(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t LEDs_GetLEDs(void) + { + return (PORTD & LEDS_ALL_LEDS); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/USB2AX/Buttons.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/USB2AX/Buttons.h new file mode 100644 index 00000000..3775e5c8 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/USB2AX/Buttons.h @@ -0,0 +1,113 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific Buttons driver header for the Paranoid Studio USB2AX. + * \copydetails Group_Buttons_USB2AX + * + * \note This file should not be included directly. It is automatically included as needed by the Buttons driver + * dispatch header located in LUFA/Drivers/Board/Buttons.h. + */ + +/** \ingroup Group_Buttons + * \defgroup Group_Buttons_USB2AX_V3 USB2AX_V3 + * \brief Board specific Button driver header for the Paranoid Studio USB2AX revision 3. + * + * See \ref Group_Buttons_USB2AX for more details. + */ + +/** \ingroup Group_Buttons + * \defgroup Group_Buttons_USB2AX USB2AX + * \brief Board specific Buttons driver header for the Paranoid Studio USB2AX. + * + * \note For version 3 USB2AX boards, compile with BOARD = USB2AX_V3. + * + * Board specific Buttons driver header for the Paranoid Studio USB2AX (http://paranoidstudio.assembla.com/wiki/show/paranoidstudio/USB2AX). + * + * + * + * + *
NameInfoActive LevelPort Pin
BUTTONS_BUTTON1HWB ButtonLowPORTD.7
+ * + * @{ + */ + +#ifndef __BUTTONS_USB2AX_H__ +#define __BUTTONS_USB2AX_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_BUTTONS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/Buttons.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Button mask for the first button on the board. */ + #define BUTTONS_BUTTON1 (1 << 7) + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void Buttons_Init(void) + { + DDRD &= ~BUTTONS_BUTTON1; + PORTD |= BUTTONS_BUTTON1; + } + + static inline void Buttons_Disable(void) + { + DDRD &= ~BUTTONS_BUTTON1; + PORTD &= ~BUTTONS_BUTTON1; + } + + static inline uint8_t Buttons_GetStatus(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t Buttons_GetStatus(void) + { + return ((PIND & BUTTONS_BUTTON1) ^ BUTTONS_BUTTON1); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/USB2AX/LEDs.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/USB2AX/LEDs.h new file mode 100644 index 00000000..b8d2db01 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/USB2AX/LEDs.h @@ -0,0 +1,196 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific LED driver header for the Paranoid Studio USB2AX. + * \copydetails Group_LEDs_USB2AX + * + * \note This file should not be included directly. It is automatically included as needed by the LEDs driver + * dispatch header located in LUFA/Drivers/Board/LEDs.h. + */ + +/** \ingroup Group_LEDs + * \defgroup Group_LEDs_USB2AX_V3 USB2AX_V3 + * \brief Board specific LED driver header for the Paranoid Studio USB2AX revision 3. + * + * See \ref Group_LEDs_USB2AX for more details. + */ + +/** \ingroup Group_LEDs + * \defgroup Group_LEDs_USB2AX USB2AX + * \brief Board specific LED driver header for the Paranoid Studio USB2AX. + * + * \note For version 3 USB2AX boards, compile with BOARD = USB2AX_V3. + * + * Board specific LED driver header for the Paranoid Studio USB2AX (http://paranoidstudio.assembla.com/wiki/show/paranoidstudio/USB2AX). + * + * USB2AX: + * + * + * + *
NameColorInfoActive LevelPort Pin
LEDS_LED1GreenGeneral IndicatorHighPORTC.6
+ * + * USB2AX_V3: + * + * + * + *
NameColorInfoActive LevelPort Pin
LEDS_LED1GreenGeneral IndicatorHighPORTD.1
+ * + * @{ + */ + +#ifndef __LEDS_USB2AX_H__ +#define __LEDS_USB2AX_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_LEDS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/LEDS.h instead. + #endif + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Macros: */ + #if (BOARD == BOARD_USB2AX) + #define USB2AX_LEDS_LED1 (1 << 6) + #else + #define USB2AX_LEDS_LED1 (1 << 1) + #endif + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** LED mask for the first LED on the board. */ + #define LEDS_LED1 USB2AX_LEDS_LED1 + + /** LED mask for all the LEDs on the board. */ + #define LEDS_ALL_LEDS LEDS_LED1 + + /** LED mask for none of the board LEDs. */ + #define LEDS_NO_LEDS 0 + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void LEDs_Init(void) + { + #if (BOARD == BOARD_USB2AX) + DDRC |= LEDS_ALL_LEDS; + PORTC &= ~LEDS_ALL_LEDS; + #else + DDRD |= LEDS_ALL_LEDS; + PORTD &= ~LEDS_ALL_LEDS; + #endif + } + + static inline void LEDs_Disable(void) + { + #if (BOARD == BOARD_USB2AX) + DDRC &= ~LEDS_ALL_LEDS; + PORTC &= ~LEDS_ALL_LEDS; + #else + DDRD &= ~LEDS_ALL_LEDS; + PORTD &= ~LEDS_ALL_LEDS; + #endif + } + + static inline void LEDs_TurnOnLEDs(const uint8_t LEDMask) + { + #if (BOARD == BOARD_USB2AX) + PORTC |= LEDMask; + #else + PORTD |= LEDMask; + #endif + } + + static inline void LEDs_TurnOffLEDs(const uint8_t LEDMask) + { + #if (BOARD == BOARD_USB2AX) + PORTC &= ~LEDMask; + #else + PORTD &= ~LEDMask; + #endif + } + + static inline void LEDs_SetAllLEDs(const uint8_t LEDMask) + { + #if (BOARD == BOARD_USB2AX) + PORTC = ((PORTC & ~LEDS_ALL_LEDS) | LEDMask); + #else + PORTD = ((PORTD & ~LEDS_ALL_LEDS) | LEDMask); + #endif + } + + static inline void LEDs_ChangeLEDs(const uint8_t LEDMask, + const uint8_t ActiveMask) + { + #if (BOARD == BOARD_USB2AX) + PORTC = ((PORTC & ~LEDMask) | ActiveMask); + #else + PORTD = ((PORTD & ~LEDMask) | ActiveMask); + #endif + } + + static inline void LEDs_ToggleLEDs(const uint8_t LEDMask) + { + #if (BOARD == BOARD_USB2AX) + PINC = LEDMask; + #else + PIND = LEDMask; + #endif + } + + static inline uint8_t LEDs_GetLEDs(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t LEDs_GetLEDs(void) + { + #if (BOARD == BOARD_USB2AX) + return (PORTC & LEDS_ALL_LEDS); + #else + return (PORTD & LEDS_ALL_LEDS); + #endif + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/USBFOO/Buttons.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/USBFOO/Buttons.h new file mode 100644 index 00000000..876939cb --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/USBFOO/Buttons.h @@ -0,0 +1,103 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific Buttons driver header for the Kernel Concepts USBFOO. + * \copydetails Group_Buttons_USBFOO + * + * \note This file should not be included directly. It is automatically included as needed by the Buttons driver + * dispatch header located in LUFA/Drivers/Board/Buttons.h. + */ + +/** \ingroup Group_Buttons + * \defgroup Group_Buttons_USBFOO USBFOO + * \brief Board specific Buttons driver header for the Kernel Concepts USBFOO. + * + * Board specific Buttons driver header for the Kernel Concepts USBFOO (http://shop.kernelconcepts.de/product_info.php?products_id=102). + * + * + * + * + *
NameInfoActive LevelPort Pin
BUTTONS_BUTTON1HWB ButtonLowPORTD.7
+ * + * @{ + */ + +#ifndef __BUTTONS_USBFOO_H__ +#define __BUTTONS_USBFOO_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_BUTTONS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/Buttons.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Button mask for the first button on the board. */ + #define BUTTONS_BUTTON1 (1 << 7) + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void Buttons_Init(void) + { + DDRD &= ~BUTTONS_BUTTON1; + PORTD |= BUTTONS_BUTTON1; + } + + static inline void Buttons_Disable(void) + { + DDRD &= ~BUTTONS_BUTTON1; + PORTD &= ~BUTTONS_BUTTON1; + } + + static inline uint8_t Buttons_GetStatus(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t Buttons_GetStatus(void) + { + return ((PIND & BUTTONS_BUTTON1) ^ BUTTONS_BUTTON1); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/USBFOO/LEDs.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/USBFOO/LEDs.h new file mode 100644 index 00000000..7d093df1 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/USBFOO/LEDs.h @@ -0,0 +1,135 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific LED driver header for the Kernel Concepts USBFOO. + * \copydetails Group_LEDs_USBFOO + * + * \note This file should not be included directly. It is automatically included as needed by the LEDs driver + * dispatch header located in LUFA/Drivers/Board/LEDs.h. + */ + +/** \ingroup Group_LEDs + * \defgroup Group_LEDs_USBFOO USBFOO + * \brief Board specific LED driver header for the Kernel Concepts USBFOO. + * + * Board specific LED driver header for the Kernel Concepts USBFOO (http://shop.kernelconcepts.de/product_info.php?products_id=102). + * + * + * + * + *
NameColorInfoActive LevelPort Pin
LEDS_LED1GreenGeneral IndicatorLowPORTD.4
+ * + * @{ + */ + +#ifndef __LEDS_USBFOO_H__ +#define __LEDS_USBFOO_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_LEDS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/LEDS.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** LED mask for the first LED on the board. */ + #define LEDS_LED1 (1 << 4) + + /** LED mask for all the LEDs on the board. */ + #define LEDS_ALL_LEDS LEDS_LED1 + + /** LED mask for none of the board LEDs. */ + #define LEDS_NO_LEDS 0 + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void LEDs_Init(void) + { + DDRD |= LEDS_ALL_LEDS; + PORTD |= LEDS_ALL_LEDS; + } + + static inline void LEDs_Disable(void) + { + DDRD &= ~LEDS_ALL_LEDS; + PORTD &= ~LEDS_ALL_LEDS; + } + + static inline void LEDs_TurnOnLEDs(const uint8_t LEDMask) + { + PORTD &= ~LEDMask; + } + + static inline void LEDs_TurnOffLEDs(const uint8_t LEDMask) + { + PORTD |= LEDMask; + } + + static inline void LEDs_SetAllLEDs(const uint8_t LEDMask) + { + PORTD = ((PORTD | LEDS_ALL_LEDS) & ~LEDMask); + } + + static inline void LEDs_ChangeLEDs(const uint8_t LEDMask, + const uint8_t ActiveMask) + { + PORTD = ((PORTD | LEDMask) & ~ActiveMask); + } + + static inline void LEDs_ToggleLEDs(const uint8_t LEDMask) + { + PIND = LEDMask; + } + + static inline uint8_t LEDs_GetLEDs(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t LEDs_GetLEDs(void) + { + return (~PORTD & LEDS_ALL_LEDS); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/USBKEY/Buttons.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/USBKEY/Buttons.h new file mode 100644 index 00000000..63a3ae27 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/USBKEY/Buttons.h @@ -0,0 +1,103 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific Buttons driver header for the Atmel USBKEY. + * \copydetails Group_Buttons_USBKEY + * + * \note This file should not be included directly. It is automatically included as needed by the Buttons driver + * dispatch header located in LUFA/Drivers/Board/Buttons.h. + */ + +/** \ingroup Group_Buttons + * \defgroup Group_Buttons_USBKEY USBKEY + * \brief Board specific Buttons driver header for the Atmel USBKEY. + * + * Board specific Buttons driver header for the Atmel USBKEY. + * + * + * + * + *
NameInfoActive LevelPort Pin
BUTTONS_BUTTON1HWB ButtonLowPORTE.2
+ * + * @{ + */ + +#ifndef __BUTTONS_USBKEY_H__ +#define __BUTTONS_USBKEY_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_BUTTONS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/Buttons.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Button mask for the first button on the board. */ + #define BUTTONS_BUTTON1 (1 << 2) + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void Buttons_Init(void) + { + DDRE &= ~BUTTONS_BUTTON1; + PORTE |= BUTTONS_BUTTON1; + } + + static inline void Buttons_Disable(void) + { + DDRE &= ~BUTTONS_BUTTON1; + PORTE &= ~BUTTONS_BUTTON1; + } + + static inline uint8_t Buttons_GetStatus(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t Buttons_GetStatus(void) + { + return ((PINE & BUTTONS_BUTTON1) ^ BUTTONS_BUTTON1); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/USBKEY/Dataflash.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/USBKEY/Dataflash.h new file mode 100644 index 00000000..c47cfa9c --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/USBKEY/Dataflash.h @@ -0,0 +1,229 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific Dataflash driver header for the Atmel USBKEY. + * \copydetails Group_Dataflash_USBKEY + * + * \note This file should not be included directly. It is automatically included as needed by the dataflash driver + * dispatch header located in LUFA/Drivers/Board/Dataflash.h. + */ + +/** \ingroup Group_Dataflash + * \defgroup Group_Dataflash_USBKEY USBKEY + * \brief Board specific Dataflash driver header for the Atmel USBKEY. + * + * Board specific Dataflash driver header for the Atmel USBKEY board. + * + * + * + * + * + *
NameInfoSelect PinSPI Port
DATAFLASH_CHIP1AT45DB642D (8MB)PORTE.0SPI0
DATAFLASH_CHIP2AT45DB642D (8MB)PORTE.1SPI0
+ * + * @{ + */ + +#ifndef __DATAFLASH_USBKEY_H__ +#define __DATAFLASH_USBKEY_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + #include "../../../Misc/AT45DB642D.h" + #include "../../../Peripheral/SPI.h" + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_DATAFLASH_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/Dataflash.h instead. + #endif + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Macros: */ + #define DATAFLASH_CHIPCS_MASK ((1 << 1) | (1 << 0)) + #define DATAFLASH_CHIPCS_DDR DDRE + #define DATAFLASH_CHIPCS_PORT PORTE + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Constant indicating the total number of dataflash ICs mounted on the selected board. */ + #define DATAFLASH_TOTALCHIPS 2 + + /** Mask for no dataflash chip selected. */ + #define DATAFLASH_NO_CHIP DATAFLASH_CHIPCS_MASK + + /** Mask for the first dataflash chip selected. */ + #define DATAFLASH_CHIP1 (1 << 1) + + /** Mask for the second dataflash chip selected. */ + #define DATAFLASH_CHIP2 (1 << 0) + + /** Internal main memory page size for the board's dataflash ICs. */ + #define DATAFLASH_PAGE_SIZE 1024 + + /** Total number of pages inside each of the board's dataflash ICs. */ + #define DATAFLASH_PAGES 8192 + + /* Inline Functions: */ + /** Initializes the dataflash driver so that commands and data may be sent to an attached dataflash IC. + * The microcontroller's SPI driver MUST be initialized before any of the dataflash commands are used. + */ + static inline void Dataflash_Init(void) + { + DATAFLASH_CHIPCS_DDR |= DATAFLASH_CHIPCS_MASK; + DATAFLASH_CHIPCS_PORT |= DATAFLASH_CHIPCS_MASK; + } + + /** Sends a byte to the currently selected dataflash IC, and returns a byte from the dataflash. + * + * \param[in] Byte Byte of data to send to the dataflash + * + * \return Last response byte from the dataflash + */ + static inline uint8_t Dataflash_TransferByte(const uint8_t Byte) ATTR_ALWAYS_INLINE; + static inline uint8_t Dataflash_TransferByte(const uint8_t Byte) + { + return SPI_TransferByte(Byte); + } + + /** Sends a byte to the currently selected dataflash IC, and ignores the next byte from the dataflash. + * + * \param[in] Byte Byte of data to send to the dataflash + */ + static inline void Dataflash_SendByte(const uint8_t Byte) ATTR_ALWAYS_INLINE; + static inline void Dataflash_SendByte(const uint8_t Byte) + { + SPI_SendByte(Byte); + } + + /** Sends a dummy byte to the currently selected dataflash IC, and returns the next byte from the dataflash. + * + * \return Last response byte from the dataflash + */ + static inline uint8_t Dataflash_ReceiveByte(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT; + static inline uint8_t Dataflash_ReceiveByte(void) + { + return SPI_ReceiveByte(); + } + + /** Determines the currently selected dataflash chip. + * + * \return Mask of the currently selected Dataflash chip, either \ref DATAFLASH_NO_CHIP if no chip is selected + * or a DATAFLASH_CHIPn mask (where n is the chip number). + */ + static inline uint8_t Dataflash_GetSelectedChip(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT; + static inline uint8_t Dataflash_GetSelectedChip(void) + { + return (DATAFLASH_CHIPCS_PORT & DATAFLASH_CHIPCS_MASK); + } + + /** Selects the given dataflash chip. + * + * \param[in] ChipMask Mask of the Dataflash IC to select, in the form of DATAFLASH_CHIPn mask (where n is + * the chip number). + */ + static inline void Dataflash_SelectChip(const uint8_t ChipMask) ATTR_ALWAYS_INLINE; + static inline void Dataflash_SelectChip(const uint8_t ChipMask) + { + DATAFLASH_CHIPCS_PORT = ((DATAFLASH_CHIPCS_PORT & ~DATAFLASH_CHIPCS_MASK) | ChipMask); + } + + /** Deselects the current dataflash chip, so that no dataflash is selected. */ + static inline void Dataflash_DeselectChip(void) ATTR_ALWAYS_INLINE; + static inline void Dataflash_DeselectChip(void) + { + Dataflash_SelectChip(DATAFLASH_NO_CHIP); + } + + /** Selects a dataflash IC from the given page number, which should range from 0 to + * ((DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS) - 1). For boards containing only one + * dataflash IC, this will select DATAFLASH_CHIP1. If the given page number is outside + * the total number of pages contained in the boards dataflash ICs, all dataflash ICs + * are deselected. + * + * \param[in] PageAddress Address of the page to manipulate, ranging from + * 0 to ((DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS) - 1). + */ + static inline void Dataflash_SelectChipFromPage(const uint16_t PageAddress) + { + Dataflash_DeselectChip(); + + if (PageAddress >= (DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS)) + return; + + if (PageAddress & 0x01) + Dataflash_SelectChip(DATAFLASH_CHIP2); + else + Dataflash_SelectChip(DATAFLASH_CHIP1); + } + + /** Toggles the select line of the currently selected dataflash IC, so that it is ready to receive + * a new command. + */ + static inline void Dataflash_ToggleSelectedChipCS(void) + { + uint8_t SelectedChipMask = Dataflash_GetSelectedChip(); + + Dataflash_DeselectChip(); + Dataflash_SelectChip(SelectedChipMask); + } + + /** Spin-loops while the currently selected dataflash is busy executing a command, such as a main + * memory page program or main memory to buffer transfer. + */ + static inline void Dataflash_WaitWhileBusy(void) + { + Dataflash_ToggleSelectedChipCS(); + Dataflash_SendByte(DF_CMD_GETSTATUS); + while (!(Dataflash_ReceiveByte() & DF_STATUS_READY)); + Dataflash_ToggleSelectedChipCS(); + } + + /** Sends a set of page and buffer address bytes to the currently selected dataflash IC, for use with + * dataflash commands which require a complete 24-bit address. + * + * \param[in] PageAddress Page address within the selected dataflash IC + * \param[in] BufferByte Address within the dataflash's buffer + */ + static inline void Dataflash_SendAddressBytes(uint16_t PageAddress, + const uint16_t BufferByte) + { + PageAddress >>= 1; + + Dataflash_SendByte(PageAddress >> 5); + Dataflash_SendByte((PageAddress << 3) | (BufferByte >> 8)); + Dataflash_SendByte(BufferByte); + } + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/USBKEY/Joystick.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/USBKEY/Joystick.h new file mode 100644 index 00000000..9e9320ea --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/USBKEY/Joystick.h @@ -0,0 +1,130 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific joystick driver header for the Atmel USBKEY. + * \copydetails Group_Joystick_USBKEY + * + * \note This file should not be included directly. It is automatically included as needed by the joystick driver + * dispatch header located in LUFA/Drivers/Board/Joystick.h. + */ + +/** \ingroup Group_Joystick + * \defgroup Group_Joystick_USBKEY USBKEY + * \brief Board specific joystick driver header for the Atmel USBKEY. + * + * Board specific joystick driver header for the Atmel USBKEY. + * + * + * + * + *
Left Port PinUp Port PinRight Port PinDown Port PinPress Port Pin
PORTB.6PORTB.7PORTE.4PORTE.5PORTB.5
+ * + * @{ + */ + +#ifndef __JOYSTICK_USBKEY_H__ +#define __JOYSTICK_USBKEY_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_JOYSTICK_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/Joystick.h instead. + #endif + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Macros: */ + #define JOY_BMASK ((1 << 5) | (1 << 6) | (1 << 7)) + #define JOY_EMASK ((1 << 4) | (1 << 5)) + + #define JOY_PORTE_MASK_SHIFT 1 + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Mask for the joystick being pushed in the left direction. */ + #define JOY_LEFT (1 << 6) + + /** Mask for the joystick being pushed in the right direction. */ + #define JOY_RIGHT ((1 << 4) >> JOY_PORTE_MASK_SHIFT) + + /** Mask for the joystick being pushed in the upward direction. */ + #define JOY_UP (1 << 7) + + /** Mask for the joystick being pushed in the downward direction. */ + #define JOY_DOWN ((1 << 5) >> JOY_PORTE_MASK_SHIFT) + + /** Mask for the joystick being pushed inward. */ + #define JOY_PRESS (1 << 5) + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void Joystick_Init(void) + { + DDRB &= ~JOY_BMASK; + DDRE &= ~JOY_EMASK; + + PORTB |= JOY_BMASK; + PORTE |= JOY_EMASK; + } + + static inline void Joystick_Disable(void) + { + DDRB &= ~JOY_BMASK; + DDRE &= ~JOY_EMASK; + + PORTB &= ~JOY_BMASK; + PORTE &= ~JOY_EMASK; + } + + static inline uint8_t Joystick_GetStatus(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t Joystick_GetStatus(void) + { + return (((uint8_t)~PINB & JOY_BMASK) | (((uint8_t)~PINE & JOY_EMASK) >> JOY_PORTE_MASK_SHIFT)); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/USBKEY/LEDs.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/USBKEY/LEDs.h new file mode 100644 index 00000000..77cab1ec --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/USBKEY/LEDs.h @@ -0,0 +1,147 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific LED driver header for the Atmel USBKEY. + * \copydetails Group_LEDs_USBKEY + * + * \note This file should not be included directly. It is automatically included as needed by the LEDs driver + * dispatch header located in LUFA/Drivers/Board/LEDs.h. + */ + +/** \ingroup Group_LEDs + * \defgroup Group_LEDs_USBKEY USBKEY + * \brief Board specific LED driver header for the Atmel USBKEY. + * + * Board specific LED driver header for the Atmel USBKEY. + * + * + * + * + * + * + * + *
NameColorInfoActive LevelPort Pin
LEDS_LED1RedBicolor Indicator 1LowPORTD.4
LEDS_LED2GreenBicolor Indicator 1LowPORTD.5
LEDS_LED3RedBicolor Indicator 2LowPORTD.6
LEDS_LED4GreenBicolor Indicator 2LowPORTD.7
+ * + * @{ + */ + +#ifndef __LEDS_USBKEY_H__ +#define __LEDS_USBKEY_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_LEDS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/LEDS.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** LED mask for the first LED on the board. */ + #define LEDS_LED1 (1 << 4) + + /** LED mask for the second LED on the board. */ + #define LEDS_LED2 (1 << 5) + + /** LED mask for the third LED on the board. */ + #define LEDS_LED3 (1 << 7) + + /** LED mask for the fourth LED on the board. */ + #define LEDS_LED4 (1 << 6) + + /** LED mask for all the LEDs on the board. */ + #define LEDS_ALL_LEDS (LEDS_LED1 | LEDS_LED2 | LEDS_LED3 | LEDS_LED4) + + /** LED mask for none of the board LEDs. */ + #define LEDS_NO_LEDS 0 + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void LEDs_Init(void) + { + DDRD |= LEDS_ALL_LEDS; + PORTD &= ~LEDS_ALL_LEDS; + } + + static inline void LEDs_Disable(void) + { + DDRD &= ~LEDS_ALL_LEDS; + PORTD &= ~LEDS_ALL_LEDS; + } + + static inline void LEDs_TurnOnLEDs(const uint8_t LEDMask) + { + PORTD |= LEDMask; + } + + static inline void LEDs_TurnOffLEDs(const uint8_t LEDMask) + { + PORTD &= ~LEDMask; + } + + static inline void LEDs_SetAllLEDs(const uint8_t LEDMask) + { + PORTD = ((PORTD & ~LEDS_ALL_LEDS) | LEDMask); + } + + static inline void LEDs_ChangeLEDs(const uint8_t LEDMask, + const uint8_t ActiveMask) + { + PORTD = ((PORTD & ~LEDMask) | ActiveMask); + } + + static inline void LEDs_ToggleLEDs(const uint8_t LEDMask) + { + PIND = LEDMask; + } + + static inline uint8_t LEDs_GetLEDs(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t LEDs_GetLEDs(void) + { + return (PORTD & LEDS_ALL_LEDS); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/USBTINYMKII/Buttons.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/USBTINYMKII/Buttons.h new file mode 100644 index 00000000..29e73b7b --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/USBTINYMKII/Buttons.h @@ -0,0 +1,103 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific Buttons driver header for Tom's USBTINY MKII. + * \copydetails Group_Buttons_USBTINYMKII + * + * \note This file should not be included directly. It is automatically included as needed by the Buttons driver + * dispatch header located in LUFA/Drivers/Board/Buttons.h. + */ + +/** \ingroup Group_Buttons + * \defgroup Group_Buttons_USBTINYMKII USBTINYMKII + * \brief Board specific Buttons driver header for Tom's USBTINY MKII. + * + * Board specific Buttons driver header for Tom's USBTINY MKII (http://tom-itx.dyndns.org:81/~webpage/). + * + * + * + * + *
NameInfoActive LevelPort Pin
BUTTONS_BUTTON1HWB ButtonLowPORTD.7
+ * + * @{ + */ + +#ifndef __BUTTONS_USBTINYMKII_H__ +#define __BUTTONS_USBTINYMKII_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_BUTTONS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/Buttons.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Button mask for the first button on the board. */ + #define BUTTONS_BUTTON1 (1 << 7) + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void Buttons_Init(void) + { + DDRD &= ~BUTTONS_BUTTON1; + PORTD |= BUTTONS_BUTTON1; + } + + static inline void Buttons_Disable(void) + { + DDRD &= ~BUTTONS_BUTTON1; + PORTD &= ~BUTTONS_BUTTON1; + } + + static inline uint8_t Buttons_GetStatus(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t Buttons_GetStatus(void) + { + return ((PIND & BUTTONS_BUTTON1) ^ BUTTONS_BUTTON1); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/USBTINYMKII/LEDs.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/USBTINYMKII/LEDs.h new file mode 100644 index 00000000..0e6192ee --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/USBTINYMKII/LEDs.h @@ -0,0 +1,143 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific LED driver header for Tom's USBTINY MKII. + * \copydetails Group_LEDs_USBTINYMKII + * + * \note This file should not be included directly. It is automatically included as needed by the LEDs driver + * dispatch header located in LUFA/Drivers/Board/LEDs.h. + */ + +/** \ingroup Group_LEDs + * \defgroup Group_LEDs_USBTINYMKII USBTINYMKII + * \brief Board specific LED driver header for Tom's USBTINY MKII. + * + * Board specific LED driver header for Tom's USBTINY MKII (http://tom-itx.dyndns.org:81/~webpage/). + * + * + * + * + * + * + *
NameColorInfoActive LevelPort Pin
LEDS_LED1RedBicolor Indicator 1HighPORTB.6
LEDS_LED2GreenBicolor Indicator 1HighPORTB.7
LEDS_LED3RedTarget PowerHighPORTB.5
+ * + * @{ + */ + +#ifndef __LEDS_USBTINYMKII_H__ +#define __LEDS_USBTINYMKII_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_LEDS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/LEDS.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** LED mask for the first LED on the board. */ + #define LEDS_LED1 (1 << 6) + + /** LED mask for the second LED on the board. */ + #define LEDS_LED2 (1 << 7) + + /** LED mask for the third LED on the board. */ + #define LEDS_LED3 (1 << 5) + + /** LED mask for all the LEDs on the board. */ + #define LEDS_ALL_LEDS (LEDS_LED1 | LEDS_LED2 | LEDS_LED3) + + /** LED mask for none of the board LEDs. */ + #define LEDS_NO_LEDS 0 + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void LEDs_Init(void) + { + DDRB |= LEDS_ALL_LEDS; + PORTB &= ~LEDS_ALL_LEDS; + } + + static inline void LEDs_Disable(void) + { + DDRB &= ~LEDS_ALL_LEDS; + PORTB &= ~LEDS_ALL_LEDS; + } + + static inline void LEDs_TurnOnLEDs(const uint8_t LedMask) + { + PORTB |= LedMask; + } + + static inline void LEDs_TurnOffLEDs(const uint8_t LedMask) + { + PORTB &= ~LedMask; + } + + static inline void LEDs_SetAllLEDs(const uint8_t LedMask) + { + PORTB = ((PORTB & ~LEDS_ALL_LEDS) | LedMask); + } + + static inline void LEDs_ChangeLEDs(const uint8_t LedMask, + const uint8_t ActiveMask) + { + PORTB = ((PORTB & ~LedMask) | ActiveMask); + } + + static inline void LEDs_ToggleLEDs(const uint8_t LEDMask) + { + PINB = LEDMask; + } + + static inline uint8_t LEDs_GetLEDs(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t LEDs_GetLEDs(void) + { + return (PORTB & LEDS_ALL_LEDS); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/XPLAIN/Dataflash.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/XPLAIN/Dataflash.h new file mode 100644 index 00000000..ef428b0d --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/XPLAIN/Dataflash.h @@ -0,0 +1,243 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific Dataflash driver header for the original Atmel XPLAIN. + * \copydetails Group_Dataflash_XPLAIN + * + * \note This file should not be included directly. It is automatically included as needed by the dataflash driver + * dispatch header located in LUFA/Drivers/Board/Dataflash.h. + */ + +/** \ingroup Group_Dataflash + * \defgroup Group_Dataflash_XPLAIN_REV1 XPLAIN_REV1 + * \brief Board specific Dataflash driver header for the original Atmel XPLAIN, revision 1. + * + * See \ref Group_Dataflash_XPLAIN for more details. + */ + +/** \ingroup Group_Dataflash + * \defgroup Group_Dataflash_XPLAIN XPLAIN + * \brief Board specific Dataflash driver header for the original Atmel XPLAIN. + * + * \note For the first revision XPLAIN board, compile with BOARD = BOARD_XPLAIN_REV1. + * + * Board specific Dataflash driver header for the Atmel XPLAIN. + * + * Revision 1 Boards: + * + * + * + *
NameInfoSelect PinSPI Port
DATAFLASH_CHIP1AT45DB041D (512KB)PORTB.5SPI0
+ * + * Other Board Revisions: + * + * + * + *
NameInfoSelect PinSPI Port
DATAFLASH_CHIP1AT45DB642D (8MB)PORTB.5SPI0
+ * + * @{ + */ + +#ifndef __DATAFLASH_XPLAIN_H__ +#define __DATAFLASH_XPLAIN_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + #include "../../../Misc/AT45DB642D.h" + #include "../../../Peripheral/SPI.h" + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_DATAFLASH_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/Dataflash.h instead. + #endif + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Macros: */ + #define DATAFLASH_CHIPCS_MASK (1 << 5) + #define DATAFLASH_CHIPCS_DDR DDRB + #define DATAFLASH_CHIPCS_PORT PORTB + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Constant indicating the total number of dataflash ICs mounted on the selected board. */ + #define DATAFLASH_TOTALCHIPS 1 + + /** Mask for no dataflash chip selected. */ + #define DATAFLASH_NO_CHIP DATAFLASH_CHIPCS_MASK + + /** Mask for the first dataflash chip selected. */ + #define DATAFLASH_CHIP1 0 + + #if ((BOARD != BOARD_XPLAIN_REV1) || defined(__DOXYGEN__)) + /** Internal main memory page size for the board's dataflash ICs. */ + #define DATAFLASH_PAGE_SIZE 1024 + + /** Total number of pages inside each of the board's dataflash ICs. */ + #define DATAFLASH_PAGES 8192 + #else + #define DATAFLASH_PAGE_SIZE 256 + + #define DATAFLASH_PAGES 2048 + #endif + + /* Inline Functions: */ + /** Initializes the dataflash driver so that commands and data may be sent to an attached dataflash IC. + * The microcontroller's SPI driver MUST be initialized before any of the dataflash commands are used. + */ + static inline void Dataflash_Init(void) + { + DATAFLASH_CHIPCS_DDR |= DATAFLASH_CHIPCS_MASK; + DATAFLASH_CHIPCS_PORT |= DATAFLASH_CHIPCS_MASK; + } + + /** Sends a byte to the currently selected dataflash IC, and returns a byte from the dataflash. + * + * \param[in] Byte Byte of data to send to the dataflash + * + * \return Last response byte from the dataflash + */ + static inline uint8_t Dataflash_TransferByte(const uint8_t Byte) ATTR_ALWAYS_INLINE; + static inline uint8_t Dataflash_TransferByte(const uint8_t Byte) + { + return SPI_TransferByte(Byte); + } + + /** Sends a byte to the currently selected dataflash IC, and ignores the next byte from the dataflash. + * + * \param[in] Byte Byte of data to send to the dataflash + */ + static inline void Dataflash_SendByte(const uint8_t Byte) ATTR_ALWAYS_INLINE; + static inline void Dataflash_SendByte(const uint8_t Byte) + { + SPI_SendByte(Byte); + } + + /** Sends a dummy byte to the currently selected dataflash IC, and returns the next byte from the dataflash. + * + * \return Last response byte from the dataflash + */ + static inline uint8_t Dataflash_ReceiveByte(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT; + static inline uint8_t Dataflash_ReceiveByte(void) + { + return SPI_ReceiveByte(); + } + + /** Determines the currently selected dataflash chip. + * + * \return Mask of the currently selected Dataflash chip, either \ref DATAFLASH_NO_CHIP if no chip is selected + * or a DATAFLASH_CHIPn mask (where n is the chip number). + */ + static inline uint8_t Dataflash_GetSelectedChip(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT; + static inline uint8_t Dataflash_GetSelectedChip(void) + { + return (DATAFLASH_CHIPCS_PORT & DATAFLASH_CHIPCS_MASK); + } + + /** Selects the given dataflash chip. + * + * \param[in] ChipMask Mask of the Dataflash IC to select, in the form of DATAFLASH_CHIPn mask (where n is + * the chip number). + */ + static inline void Dataflash_SelectChip(const uint8_t ChipMask) ATTR_ALWAYS_INLINE; + static inline void Dataflash_SelectChip(const uint8_t ChipMask) + { + DATAFLASH_CHIPCS_PORT = ((DATAFLASH_CHIPCS_PORT & ~DATAFLASH_CHIPCS_MASK) | ChipMask); + } + + /** Deselects the current dataflash chip, so that no dataflash is selected. */ + static inline void Dataflash_DeselectChip(void) ATTR_ALWAYS_INLINE; + static inline void Dataflash_DeselectChip(void) + { + Dataflash_SelectChip(DATAFLASH_NO_CHIP); + } + + /** Selects a dataflash IC from the given page number, which should range from 0 to + * ((DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS) - 1). For boards containing only one + * dataflash IC, this will select DATAFLASH_CHIP1. If the given page number is outside + * the total number of pages contained in the boards dataflash ICs, all dataflash ICs + * are deselected. + * + * \param[in] PageAddress Address of the page to manipulate, ranging from + * 0 to ((DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS) - 1). + */ + static inline void Dataflash_SelectChipFromPage(const uint16_t PageAddress) + { + Dataflash_DeselectChip(); + + if (PageAddress >= DATAFLASH_PAGES) + return; + + Dataflash_SelectChip(DATAFLASH_CHIP1); + } + + /** Toggles the select line of the currently selected dataflash IC, so that it is ready to receive + * a new command. + */ + static inline void Dataflash_ToggleSelectedChipCS(void) + { + uint8_t SelectedChipMask = Dataflash_GetSelectedChip(); + + Dataflash_DeselectChip(); + Dataflash_SelectChip(SelectedChipMask); + } + + /** Spin-loops while the currently selected dataflash is busy executing a command, such as a main + * memory page program or main memory to buffer transfer. + */ + static inline void Dataflash_WaitWhileBusy(void) + { + Dataflash_ToggleSelectedChipCS(); + Dataflash_SendByte(DF_CMD_GETSTATUS); + while (!(Dataflash_ReceiveByte() & DF_STATUS_READY)); + Dataflash_ToggleSelectedChipCS(); + } + + /** Sends a set of page and buffer address bytes to the currently selected dataflash IC, for use with + * dataflash commands which require a complete 24-bit address. + * + * \param[in] PageAddress Page address within the selected dataflash IC + * \param[in] BufferByte Address within the dataflash's buffer + */ + static inline void Dataflash_SendAddressBytes(uint16_t PageAddress, + const uint16_t BufferByte) + { + Dataflash_SendByte(PageAddress >> 5); + Dataflash_SendByte((PageAddress << 3) | (BufferByte >> 8)); + Dataflash_SendByte(BufferByte); + } + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/XPLAIN/LEDs.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/XPLAIN/LEDs.h new file mode 100644 index 00000000..c7d74591 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/AVR8/XPLAIN/LEDs.h @@ -0,0 +1,142 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific LED driver header for the original Atmel XPLAIN. + * \copydetails Group_LEDs_XPLAIN + * + * \note This file should not be included directly. It is automatically included as needed by the LEDs driver + * dispatch header located in LUFA/Drivers/Board/LEDs.h. + */ + +/** \ingroup Group_LEDs + * \defgroup Group_LEDs_XPLAIN_REV1 XPLAIN_REV1 + * \brief Board specific LED driver header for the original Atmel XPLAIN, revision 1. + * + * See \ref Group_LEDs_XPLAIN for more details. + */ + +/** \ingroup Group_LEDs + * \defgroup Group_LEDs_XPLAIN XPLAIN + * \brief Board specific LED driver header for the original Atmel XPLAIN. + * + * Board specific LED driver header for the Atmel XPLAIN. + * + * + * + * + *
NameColorInfoActive LevelPort Pin
LEDS_LED1GreenGeneral IndicatorLowPORTB.6
+ * + * @{ + */ + +#ifndef __LEDS_XPLAIN_H__ +#define __LEDS_XPLAIN_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_LEDS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/LEDS.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** LED mask for the first LED on the board. */ + #define LEDS_LED1 (1 << 6) + + /** LED mask for all the LEDs on the board. */ + #define LEDS_ALL_LEDS LEDS_LED1 + + /** LED mask for none of the board LEDs. */ + #define LEDS_NO_LEDS 0 + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void LEDs_Init(void) + { + DDRB |= LEDS_ALL_LEDS; + PORTB |= LEDS_ALL_LEDS; + } + + static inline void LEDs_Disable(void) + { + DDRB &= ~LEDS_ALL_LEDS; + PORTB &= ~LEDS_ALL_LEDS; + } + + static inline void LEDs_TurnOnLEDs(const uint8_t LEDMask) + { + PORTB &= ~LEDMask; + } + + static inline void LEDs_TurnOffLEDs(const uint8_t LEDMask) + { + PORTB |= LEDMask; + } + + static inline void LEDs_SetAllLEDs(const uint8_t LEDMask) + { + PORTB = ((PORTB | LEDS_ALL_LEDS) & ~LEDMask); + } + + static inline void LEDs_ChangeLEDs(const uint8_t LEDMask, + const uint8_t ActiveMask) + { + PORTB = ((PORTB | LEDMask) & ~ActiveMask); + } + + static inline void LEDs_ToggleLEDs(const uint8_t LEDMask) + { + PINB = LEDMask; + } + + static inline uint8_t LEDs_GetLEDs(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t LEDs_GetLEDs(void) + { + return (~PORTB & LEDS_ALL_LEDS); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/Buttons.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/Buttons.h new file mode 100644 index 00000000..c5c09bed --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/Buttons.h @@ -0,0 +1,178 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Digital button board hardware driver. + * + * This file is the master dispatch header file for the board-specific Buttons driver, for boards containing + * physical pushbuttons connected to the microcontroller's GPIO pins. + * + * User code should include this file, which will in turn include the correct Button driver header file for the + * currently selected board. + * + * If the \c BOARD value is set to \c BOARD_USER, this will include the \c /Board/Buttons.h file in the user project + * directory. + * + * For possible \c BOARD makefile values, see \ref Group_BoardTypes. + */ + +/** \ingroup Group_BoardDrivers + * \defgroup Group_Buttons Buttons Driver - LUFA/Drivers/Board/Buttons.h + * \brief Digital button board hardware driver. + * + * \section Sec_Dependencies Module Source Dependencies + * The following files must be built with any user project that uses this module: + * - None + * + * \section Sec_ModDescription Module Description + * Hardware buttons driver. This provides an easy to use driver for the hardware buttons present on many boards. + * It provides a way to easily configure and check the status of all the buttons on the board so that appropriate + * actions can be taken. + * + * If the \c BOARD value is set to \c BOARD_USER, this will include the \c /Board/Buttons.h file in the user project + * directory. Otherwise, it will include the appropriate built in board driver header file. + * + * For possible \c BOARD makefile values, see \ref Group_BoardTypes. + * + * \section Sec_ExampleUsage Example Usage + * The following snippet is an example of how this module may be used within a typical + * application. + * + * \code + * // Initialize the button driver before first use + * Buttons_Init(); + * + * printf("Waiting for button press...\r\n"); + * + * // Loop until a board button has been pressed + * uint8_t ButtonPress; + * while (!(ButtonPress = Buttons_GetStatus())) {}; + * + * // Display which button was pressed (assuming two board buttons) + * printf("Button pressed: %s\r\n", (ButtonPress == BUTTONS_BUTTON1) ? "Button 1" : "Button 2"); + * \endcode + * + * @{ + */ + +#ifndef __BUTTONS_H__ +#define __BUTTONS_H__ + + /* Macros: */ + #define __INCLUDE_FROM_BUTTONS_H + + /* Includes: */ + #include "../../Common/Common.h" + + #if (BOARD == BOARD_NONE) + #error The Board Buttons driver cannot be used if the makefile BOARD option is not set. + #elif (BOARD == BOARD_USBKEY) + #include "AVR8/USBKEY/Buttons.h" + #elif (BOARD == BOARD_STK525) + #include "AVR8/STK525/Buttons.h" + #elif (BOARD == BOARD_STK526) + #include "AVR8/STK526/Buttons.h" + #elif (BOARD == BOARD_ATAVRUSBRF01) + #include "AVR8/ATAVRUSBRF01/Buttons.h" + #elif (BOARD == BOARD_BUMBLEB) + #include "AVR8/BUMBLEB/Buttons.h" + #elif (BOARD == BOARD_EVK527) + #include "AVR8/EVK527/Buttons.h" + #elif (BOARD == BOARD_USBTINYMKII) + #include "AVR8/USBTINYMKII/Buttons.h" + #elif (BOARD == BOARD_BENITO) + #include "AVR8/BENITO/Buttons.h" + #elif (BOARD == BOARD_JMDBU2) + #include "AVR8/JMDBU2/Buttons.h" + #elif (BOARD == BOARD_OLIMEX162) + #include "AVR8/OLIMEX162/Buttons.h" + #elif (BOARD == BOARD_USBFOO) + #include "AVR8/USBFOO/Buttons.h" + #elif (BOARD == BOARD_UDIP) + #include "AVR8/UDIP/Buttons.h" + #elif (BOARD == BOARD_CULV3) + #include "AVR8/CULV3/Buttons.h" + #elif (BOARD == BOARD_MINIMUS) + #include "AVR8/MINIMUS/Buttons.h" + #elif (BOARD == BOARD_MICROSIN162) + #include "AVR8/MICROSIN162/Buttons.h" + #elif (BOARD == BOARD_EVK1101) + #include "UC3/EVK1101/Buttons.h" + #elif (BOARD == BOARD_TUL) + #include "AVR8/TUL/Buttons.h" + #elif (BOARD == BOARD_EVK1100) + #include "UC3/EVK1100/Buttons.h" + #elif (BOARD == BOARD_EVK1104) + #include "UC3/EVK1104/Buttons.h" + #elif (BOARD == BOARD_A3BU_XPLAINED) + #include "XMEGA/A3BU_XPLAINED/Buttons.h" + #elif ((BOARD == BOARD_USB2AX) || (BOARD == BOARD_USB2AX_V3)) + #include "AVR8/USB2AX/Buttons.h" + #elif ((BOARD == BOARD_MICROPENDOUS_32U2) || (BOARD == BOARD_MICROPENDOUS_A) || \ + (BOARD == BOARD_MICROPENDOUS_1) || (BOARD == BOARD_MICROPENDOUS_2) || \ + (BOARD == BOARD_MICROPENDOUS_3) || (BOARD == BOARD_MICROPENDOUS_4) || \ + (BOARD == BOARD_MICROPENDOUS_REV1) || (BOARD == BOARD_MICROPENDOUS_REV2) || \ + (BOARD == BOARD_MICROPENDOUS_DIP)) + #include "AVR8/MICROPENDOUS/Buttons.h" + #elif (BOARD == BOARD_B1_XPLAINED) + #include "XMEGA/B1_XPLAINED/Buttons.h" + #elif (BOARD == BOARD_OLIMEX32U4) + #include "AVR8/OLIMEX32U4/Buttons.h" + #elif (BOARD == BOARD_OLIMEXT32U4) + #include "AVR8/OLIMEXT32U4/Buttons.h" + #elif (BOARD == BOARD_OLIMEXISPMK2) + #include "AVR8/OLIMEXISPMK2/Buttons.h" + #else + #include "Board/Buttons.h" + #endif + + /* Pseudo-Functions for Doxygen: */ + #if defined(__DOXYGEN__) + /** Initializes the buttons driver, so that the current button position can be read. This sets the appropriate + * I/O pins to an inputs with pull-ups enabled. + * + * This must be called before any Button driver functions are used. + */ + static inline void Buttons_Init(void); + + /** Disables the buttons driver, releasing the I/O pins back to their default high-impedance input mode. */ + static inline void Buttons_Disable(void); + + /** Returns a mask indicating which board buttons are currently pressed. + * + * \return Mask indicating which board buttons are currently pressed. + */ + static inline uint_reg_t Buttons_GetStatus(void) ATTR_WARN_UNUSED_RESULT; + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/Dataflash.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/Dataflash.h new file mode 100644 index 00000000..944ea5ff --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/Dataflash.h @@ -0,0 +1,252 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Master include file for the board dataflash IC driver. + * \brief Atmel Dataflash storage IC board hardware driver. + * + * This file is the master dispatch header file for the board-specific Atmel dataflash driver, for boards containing + * Atmel Dataflash ICs for external non-volatile storage. + * + * User code should include this file, which will in turn include the correct dataflash driver header file for + * the currently selected board. + * + * If the \c BOARD value is set to \c BOARD_USER, this will include the \c /Board/Dataflash.h file in the user project + * directory. + * + * For possible \c BOARD makefile values, see \ref Group_BoardTypes. + */ + +/** \ingroup Group_BoardDrivers + * \defgroup Group_Dataflash Dataflash Driver - LUFA/Drivers/Board/Dataflash.h + * \brief Atmel Dataflash storage IC board hardware driver. + * + * \section Sec_Dependencies Module Source Dependencies + * The following files must be built with any user project that uses this module: + * - None + * + * \section Sec_ModDescription Module Description + * Dataflash driver. This module provides an easy to use interface for the Dataflash ICs located on many boards, + * for the storage of large amounts of data into the Dataflash's non-volatile memory. + * + * If the \c BOARD value is set to \c BOARD_USER, this will include the \c /Board/Dataflash.h file in the user project + * directory. Otherwise, it will include the appropriate built in board driver header file. + * + * For possible \c BOARD makefile values, see \ref Group_BoardTypes. + * + * \section Sec_ExampleUsage Example Usage + * The following snippet is an example of how this module may be used within a typical + * application. + * + * \code + * // Initialize the SPI and board Dataflash drivers before first use + * SPI_Init(SPI_SPEED_FCPU_DIV_2 | SPI_ORDER_MSB_FIRST | SPI_SCK_LEAD_FALLING | + * SPI_SAMPLE_TRAILING | SPI_MODE_MASTER); + * Dataflash_Init(); + * + * uint8_t WriteBuffer[DATAFLASH_PAGE_SIZE]; + * uint8_t ReadBuffer[DATAFLASH_PAGE_SIZE]; + * + * // Fill page write buffer with a repeating pattern + * for (uint16_t i = 0; i < DATAFLASH_PAGE_SIZE; i++) + * WriteBuffer[i] = (i & 0xFF); + * + * // Must select the chip of interest first before operating on it + * Dataflash_SelectChip(DATAFLASH_CHIP1); + * + * // Write to the Dataflash's first internal memory buffer + * printf("Writing data to first dataflash buffer:\r\n"); + * Dataflash_SendByte(DF_CMD_BUFF1WRITE); + * Dataflash_SendAddressBytes(0, 0); + * + * for (uint16_t i = 0; i < DATAFLASH_PAGE_SIZE; i++) + * Dataflash_SendByte(WriteBuffer[i]); + * + * // Commit the Dataflash's first memory buffer to the non-volatile FLASH memory + * printf("Committing page to non-volatile memory page index 5:\r\n"); + * Dataflash_SendByte(DF_CMD_BUFF1TOMAINMEMWITHERASE); + * Dataflash_SendAddressBytes(5, 0); + * Dataflash_WaitWhileBusy(); + * + * // Read the page from non-volatile FLASH memory into the Dataflash's second memory buffer + * printf("Reading data into second dataflash buffer:\r\n"); + * Dataflash_SendByte(DF_CMD_MAINMEMTOBUFF2); + * Dataflash_SendAddressBytes(5, 0); + * Dataflash_WaitWhileBusy(); + * + * // Read the Dataflash's second internal memory buffer + * Dataflash_SendByte(DF_CMD_BUFF2READ); + * Dataflash_SendAddressBytes(0, 0); + * + * for (uint16_t i = 0; i < DATAFLASH_PAGE_SIZE; i++) + * ReadBuffer[i] = Dataflash_ReceiveByte(); + * + * // Deselect the chip after use + * Dataflash_DeselectChip(); + * \endcode + * + * @{ + */ + +#ifndef __DATAFLASH_H__ +#define __DATAFLASH_H__ + + /* Macros: */ + #define __INCLUDE_FROM_DATAFLASH_H + + /* Includes: */ + #include "../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + #if !defined(__DOXYGEN__) + #define __GET_DATAFLASH_MASK2(x, y) x ## y + #define __GET_DATAFLASH_MASK(x) __GET_DATAFLASH_MASK2(DATAFLASH_CHIP,x) + #endif + + /** Retrieves the Dataflash chip select mask for the given Dataflash chip index. + * + * \param[in] index Index of the dataflash chip mask to retrieve + * + * \return Mask for the given Dataflash chip's /CS pin + */ + #define DATAFLASH_CHIP_MASK(index) __GET_DATAFLASH_MASK(index) + + /* Inline Functions: */ + /** Initializes the dataflash driver so that commands and data may be sent to an attached dataflash IC. + * + * \note The microcontroller's physical interface driver connected to the Dataflash IC must be initialized before + * any of the dataflash commands are used. This is usually a SPI hardware port, but on some devices/boards may + * be a USART operating in SPI Master mode. + */ + static inline void Dataflash_Init(void); + + /** Determines the currently selected dataflash chip. + * + * \return Mask of the currently selected Dataflash chip, either \ref DATAFLASH_NO_CHIP if no chip is selected + * or a \c DATAFLASH_CHIPn mask (where n is the chip number). + */ + static inline uint8_t Dataflash_GetSelectedChip(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT; + + /** Selects the given dataflash chip. + * + * \param[in] ChipMask Mask of the Dataflash IC to select, in the form of \c DATAFLASH_CHIPn mask (where n is + * the chip number). + */ + static inline void Dataflash_SelectChip(const uint8_t ChipMask) ATTR_ALWAYS_INLINE; + + /** Deselects the current dataflash chip, so that no dataflash is selected. */ + static inline void Dataflash_DeselectChip(void) ATTR_ALWAYS_INLINE; + + /** Selects a dataflash IC from the given page number, which should range from 0 to + * ((DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS) - 1). For boards containing only one + * dataflash IC, this will select \ref DATAFLASH_CHIP1. If the given page number is outside + * the total number of pages contained in the boards dataflash ICs, all dataflash ICs + * are deselected. + * + * \param[in] PageAddress Address of the page to manipulate, ranging from + * 0 to ((DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS) - 1). + */ + static inline void Dataflash_SelectChipFromPage(const uint16_t PageAddress); + + /** Toggles the select line of the currently selected dataflash IC, so that it is ready to receive + * a new command. + */ + static inline void Dataflash_ToggleSelectedChipCS(void); + + /** Spin-loops while the currently selected dataflash is busy executing a command, such as a main + * memory page program or main memory to buffer transfer. + */ + static inline void Dataflash_WaitWhileBusy(void); + + /** Sends a set of page and buffer address bytes to the currently selected dataflash IC, for use with + * dataflash commands which require a complete 24-bit address. + * + * \param[in] PageAddress Page address within the selected dataflash IC + * \param[in] BufferByte Address within the dataflash's buffer + */ + static inline void Dataflash_SendAddressBytes(uint16_t PageAddress, + const uint16_t BufferByte); + + /** Sends a byte to the currently selected dataflash IC, and returns a byte from the dataflash. + * + * \param[in] Byte Byte of data to send to the dataflash + * + * \return Last response byte from the dataflash + */ + static inline uint8_t Dataflash_TransferByte(const uint8_t Byte) ATTR_ALWAYS_INLINE; + + /** Sends a byte to the currently selected dataflash IC, and ignores the next byte from the dataflash. + * + * \param[in] Byte Byte of data to send to the dataflash + */ + static inline void Dataflash_SendByte(const uint8_t Byte) ATTR_ALWAYS_INLINE; + + /** Sends a dummy byte to the currently selected dataflash IC, and returns the next byte from the dataflash. + * + * \return Last response byte from the dataflash + */ + static inline uint8_t Dataflash_ReceiveByte(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT; + + /* Includes: */ + #if (BOARD == BOARD_NONE) + #error The Board Dataflash driver cannot be used if the makefile BOARD option is not set. + #elif (BOARD == BOARD_USBKEY) + #include "AVR8/USBKEY/Dataflash.h" + #elif (BOARD == BOARD_STK525) + #include "AVR8/STK525/Dataflash.h" + #elif (BOARD == BOARD_STK526) + #include "AVR8/STK526/Dataflash.h" + #elif ((BOARD == BOARD_XPLAIN) || (BOARD == BOARD_XPLAIN_REV1)) + #include "AVR8/XPLAIN/Dataflash.h" + #elif (BOARD == BOARD_EVK527) + #include "AVR8/EVK527/Dataflash.h" + #elif (BOARD == BOARD_A3BU_XPLAINED) + #include "XMEGA/A3BU_XPLAINED/Dataflash.h" + #elif (BOARD == BOARD_B1_XPLAINED) + #include "XMEGA/B1_XPLAINED/Dataflash.h" + #else + #include "Board/Dataflash.h" + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/Joystick.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/Joystick.h new file mode 100644 index 00000000..640939a9 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/Joystick.h @@ -0,0 +1,144 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Digital joystick board hardware driver. + * + * This file is the master dispatch header file for the board-specific Joystick driver, for boards containing a + * digital joystick. + * + * User code should include this file, which will in turn include the correct joystick driver header file for the + * currently selected board. + * + * If the \c BOARD value is set to \c BOARD_USER, this will include the \c /Board/Joystick.h file in the user project + * directory. + * + * For possible \c BOARD makefile values, see \ref Group_BoardTypes. + */ + +/** \ingroup Group_BoardDrivers + * \defgroup Group_Joystick Joystick Driver - LUFA/Drivers/Board/Joystick.h + * \brief Digital joystick board hardware driver. + * + * \section Sec_Dependencies Module Source Dependencies + * The following files must be built with any user project that uses this module: + * - None + * + * \section Sec_ModDescription Module Description + * Hardware Joystick driver. This module provides an easy to use interface to control the hardware digital Joystick + * located on many boards. + * + * If the \c BOARD value is set to \c BOARD_USER, this will include the \c /Board/Joystick.h file in the user project + * directory. Otherwise, it will include the appropriate built in board driver header file. + * + * For possible \c BOARD makefile values, see \ref Group_BoardTypes. + * + * \section Sec_ExampleUsage Example Usage + * The following snippet is an example of how this module may be used within a typical + * application. + * + * \code + * // Initialize the board Joystick driver before first use + * Joystick_Init(); + * + * printf("Waiting for joystick movement...\r\n"); + * + * // Loop until a the joystick has been moved + * uint8_t JoystickMovement; + * while (!(JoystickMovement = Joystick_GetStatus())) {}; + * + * // Display which direction the joystick was moved in + * printf("Joystick moved:\r\n"); + * + * if (JoystickMovement & (JOY_UP | JOY_DOWN)) + * printf("%s ", (JoystickMovement & JOY_UP) ? "Up" : "Down"); + * + * if (JoystickMovement & (JOY_LEFT | JOY_RIGHT)) + * printf("%s ", (JoystickMovement & JOY_LEFT) ? "Left" : "Right"); + * + * if (JoystickMovement & JOY_PRESS) + * printf("Pressed"); + * \endcode + * + * @{ + */ + +#ifndef __JOYSTICK_H__ +#define __JOYSTICK_H__ + + /* Macros: */ + #define __INCLUDE_FROM_JOYSTICK_H + + /* Includes: */ + #include "../../Common/Common.h" + + #if (BOARD == BOARD_NONE) + #error The Board Joystick driver cannot be used if the makefile BOARD option is not set. + #elif (BOARD == BOARD_USBKEY) + #include "AVR8/USBKEY/Joystick.h" + #elif (BOARD == BOARD_STK525) + #include "AVR8/STK525/Joystick.h" + #elif (BOARD == BOARD_STK526) + #include "AVR8/STK526/Joystick.h" + #elif (BOARD == BOARD_BUMBLEB) + #include "AVR8/BUMBLEB/Joystick.h" + #elif (BOARD == BOARD_EVK527) + #include "AVR8/EVK527/Joystick.h" + #elif (BOARD == BOARD_EVK1101) + #include "UC3/EVK1101/Joystick.h" + #elif (BOARD == BOARD_EVK1100) + #include "UC3/EVK1100/Joystick.h" + #else + #include "Board/Joystick.h" + #endif + + /* Pseudo-Functions for Doxygen: */ + #if defined(__DOXYGEN__) + /** Initializes the joystick driver so that the joystick position can be read. This sets the appropriate + * I/O pins to inputs with their pull-ups enabled. + */ + static inline void Joystick_Init(void); + + /** Disables the joystick driver, releasing the I/O pins back to their default high-impedance input mode. */ + static inline void Joystick_Disable(void); + + /** Returns the current status of the joystick, as a mask indicating the direction the joystick is + * currently facing in (multiple bits can be set). + * + * \return Mask indicating the joystick direction - see corresponding board specific Joystick.h file + * for direction masks. + */ + static inline uint_reg_t Joystick_GetStatus(void) ATTR_WARN_UNUSED_RESULT; + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/LEDs.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/LEDs.h new file mode 100644 index 00000000..96438d0d --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/LEDs.h @@ -0,0 +1,274 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief LED board hardware driver. + * + * This file is the master dispatch header file for the board-specific LED driver, for boards containing user + * controllable LEDs. + * + * User code should include this file, which will in turn include the correct LED driver header file for the + * currently selected board. + * + * If the \c BOARD value is set to \c BOARD_USER, this will include the \c /Board/LEDs.h file in the user project + * directory. + * + * For possible \c BOARD makefile values, see \ref Group_BoardTypes. + */ + +/** \ingroup Group_BoardDrivers + * \defgroup Group_LEDs LEDs Driver - LUFA/Drivers/Board/LEDs.h + * \brief LED board hardware driver. + * + * \section Sec_Dependencies Module Source Dependencies + * The following files must be built with any user project that uses this module: + * - None + * + * \section Sec_ModDescription Module Description + * Hardware LEDs driver. This provides an easy to use driver for the hardware LEDs present on many boards. It + * provides an interface to configure, test and change the status of all the board LEDs. + * + * If the \c BOARD value is set to \c BOARD_USER, this will include the \c /Board/LEDs.h file in the user project + * directory. Otherwise, it will include the appropriate built in board driver header file. If the BOARD value + * is set to \c BOARD_NONE, this driver is silently disabled. + * + * For possible \c BOARD makefile values, see \ref Group_BoardTypes. + * + * \note To make code as compatible as possible, it is assumed that all boards carry a minimum of four LEDs. If + * a board contains less than four LEDs, the remaining LED masks are defined to 0 so as to have no effect. + * If other behavior is desired, either alias the remaining LED masks to existing LED masks via the -D + * switch in the project makefile, or alias them to nothing in the makefile to cause compilation errors when + * a non-existing LED is referenced in application code. Note that this means that it is possible to make + * compatible code for a board with no LEDs by making a board LED driver (see \ref Page_WritingBoardDrivers) + * which contains only stub functions and defines no LEDs. + * + * \section Sec_ExampleUsage Example Usage + * The following snippet is an example of how this module may be used within a typical + * application. + * + * \code + * // Initialize the board LED driver before first use + * LEDs_Init(); + * + * // Turn on each of the four LEDs in turn + * LEDs_SetAllLEDs(LEDS_LED1); + * Delay_MS(500); + * LEDs_SetAllLEDs(LEDS_LED2); + * Delay_MS(500); + * LEDs_SetAllLEDs(LEDS_LED3); + * Delay_MS(500); + * LEDs_SetAllLEDs(LEDS_LED4); + * Delay_MS(500); + * + * // Turn on all LEDs + * LEDs_SetAllLEDs(LEDS_ALL_LEDS); + * Delay_MS(1000); + * + * // Turn on LED 1, turn off LED 2, leaving LEDs 3 and 4 in their current state + * LEDs_ChangeLEDs((LEDS_LED1 | LEDS_LED2), LEDS_LED1); + * \endcode + * + * @{ + */ + +#ifndef __LEDS_H__ +#define __LEDS_H__ + + /* Macros: */ + #define __INCLUDE_FROM_LEDS_H + + /* Includes: */ + #include "../../Common/Common.h" + + #if (BOARD == BOARD_NONE) + static inline void LEDs_Init(void) {}; + static inline void LEDs_Disable(void) {}; + static inline void LEDs_TurnOnLEDs(const uint_reg_t LEDMask) {}; + static inline void LEDs_TurnOffLEDs(const uint_reg_t LEDMask) {}; + static inline void LEDs_SetAllLEDs(const uint_reg_t LEDMask) {}; + static inline void LEDs_ChangeLEDs(const uint_reg_t LEDMask, const uint_reg_t ActiveMask) {}; + static inline void LEDs_ToggleLEDs(const uint_reg_t LEDMask) {}; + static inline uint_reg_t LEDs_GetLEDs(void) { return 0; } + #elif (BOARD == BOARD_USBKEY) + #include "AVR8/USBKEY/LEDs.h" + #elif (BOARD == BOARD_STK525) + #include "AVR8/STK525/LEDs.h" + #elif (BOARD == BOARD_STK526) + #include "AVR8/STK526/LEDs.h" + #elif (BOARD == BOARD_RZUSBSTICK) + #include "AVR8/RZUSBSTICK/LEDs.h" + #elif (BOARD == BOARD_ATAVRUSBRF01) + #include "AVR8/ATAVRUSBRF01/LEDs.h" + #elif ((BOARD == BOARD_XPLAIN) || (BOARD == BOARD_XPLAIN_REV1)) + #include "AVR8/XPLAIN/LEDs.h" + #elif (BOARD == BOARD_BUMBLEB) + #include "AVR8/BUMBLEB/LEDs.h" + #elif (BOARD == BOARD_EVK527) + #include "AVR8/EVK527/LEDs.h" + #elif ((BOARD == BOARD_TEENSY) || (BOARD == BOARD_TEENSY2)) + #include "AVR8/TEENSY/LEDs.h" + #elif (BOARD == BOARD_USBTINYMKII) + #include "AVR8/USBTINYMKII/LEDs.h" + #elif (BOARD == BOARD_BENITO) + #include "AVR8/BENITO/LEDs.h" + #elif (BOARD == BOARD_JMDBU2) + #include "AVR8/JMDBU2/LEDs.h" + #elif (BOARD == BOARD_OLIMEX162) + #include "AVR8/OLIMEX162/LEDs.h" + #elif (BOARD == BOARD_USBFOO) + #include "AVR8/USBFOO/LEDs.h" + #elif (BOARD == BOARD_UDIP) + #include "AVR8/UDIP/LEDs.h" + #elif (BOARD == BOARD_BUI) + #include "AVR8/BUI/LEDs.h" + #elif (BOARD == BOARD_UNO) + #include "AVR8/UNO/LEDs.h" + #elif (BOARD == BOARD_CULV3) + #include "AVR8/CULV3/LEDs.h" + #elif (BOARD == BOARD_BLACKCAT) + #include "AVR8/BLACKCAT/LEDs.h" + #elif (BOARD == BOARD_MAXIMUS) + #include "AVR8/MAXIMUS/LEDs.h" + #elif (BOARD == BOARD_MINIMUS) + #include "AVR8/MINIMUS/LEDs.h" + #elif (BOARD == BOARD_ADAFRUITU4) + #include "AVR8/ADAFRUITU4/LEDs.h" + #elif (BOARD == BOARD_MICROSIN162) + #include "AVR8/MICROSIN162/LEDs.h" + #elif (BOARD == BOARD_SPARKFUN8U2) + #include "AVR8/SPARKFUN8U2/LEDs.h" + #elif (BOARD == BOARD_EVK1101) + #include "UC3/EVK1101/LEDs.h" + #elif (BOARD == BOARD_TUL) + #include "AVR8/TUL/LEDs.h" + #elif (BOARD == BOARD_EVK1100) + #include "UC3/EVK1100/LEDs.h" + #elif (BOARD == BOARD_EVK1104) + #include "UC3/EVK1104/LEDs.h" + #elif (BOARD == BOARD_A3BU_XPLAINED) + #include "XMEGA/A3BU_XPLAINED/LEDs.h" + #elif ((BOARD == BOARD_USB2AX) || (BOARD == BOARD_USB2AX_V3)) + #include "AVR8/USB2AX/LEDs.h" + #elif ((BOARD == BOARD_MICROPENDOUS_REV1) || (BOARD == BOARD_MICROPENDOUS_REV2) || \ + (BOARD == BOARD_MICROPENDOUS_32U2)) + #include "AVR8/MICROPENDOUS/LEDs.h" + #elif (BOARD == BOARD_B1_XPLAINED) + #include "XMEGA/B1_XPLAINED/LEDs.h" + #elif (BOARD == BOARD_MULTIO) + #include "AVR8/MULTIO/LEDs.h" + #elif (BOARD == BOARD_BIGMULTIO) + #include "AVR8/BIGMULTIO/LEDs.h" + #elif (BOARD == BOARD_DUCE) + #include "AVR8/DUCE/LEDs.h" + #elif (BOARD == BOARD_OLIMEX32U4) + #include "AVR8/OLIMEX32U4/LEDs.h" + #elif (BOARD == BOARD_OLIMEXT32U4) + #include "AVR8/OLIMEXT32U4/LEDs.h" + #elif (BOARD == BOARD_OLIMEXISPMK2) + #include "AVR8/OLIMEXISPMK2/LEDs.h" + #else + #include "Board/LEDs.h" + #endif + + /* Preprocessor Checks: */ + #if !defined(__DOXYGEN__) + #if !defined(LEDS_LED1) + #define LEDS_LED1 0 + #endif + + #if !defined(LEDS_LED2) + #define LEDS_LED2 0 + #endif + + #if !defined(LEDS_LED3) + #define LEDS_LED3 0 + #endif + + #if !defined(LEDS_LED4) + #define LEDS_LED4 0 + #endif + #endif + + /* Pseudo-Functions for Doxygen: */ + #if defined(__DOXYGEN__) + /** Initializes the board LED driver so that the LEDs can be controlled. This sets the appropriate port + * I/O pins as outputs, and sets the LEDs to default to off. + */ + static inline void LEDs_Init(void); + + /** Disables the board LED driver, releasing the I/O pins back to their default high-impedance input mode. */ + static inline void LEDs_Disable(void); + + /** Turns on the LEDs specified in the given LED mask. + * + * \param[in] LEDMask Mask of the board LEDs to manipulate (see board-specific LEDs.h driver file). + */ + static inline void LEDs_TurnOnLEDs(const uint_reg_t LEDMask); + + /** Turns off the LEDs specified in the given LED mask. + * + * \param[in] LEDMask Mask of the board LEDs to manipulate (see board-specific LEDs.h driver file). + */ + static inline void LEDs_TurnOffLEDs(const uint_reg_t LEDMask); + + /** Turns off all LEDs not specified in the given LED mask, and turns on all the LEDs in the given LED + * mask. + * + * \param[in] LEDMask Mask of the board LEDs to manipulate (see board-specific LEDs.h driver file). + */ + static inline void LEDs_SetAllLEDs(const uint_reg_t LEDMask); + + /** Turns off all LEDs in the LED mask that are not set in the active mask, and turns on all the LEDs + * specified in both the LED and active masks. + * + * \param[in] LEDMask Mask of the board LEDs to manipulate (see board-specific LEDs.h driver file). + * \param[in] ActiveMask Mask of whether the LEDs in the LED mask should be turned on or off. + */ + static inline void LEDs_ChangeLEDs(const uint_reg_t LEDMask, + const uint_reg_t ActiveMask); + + /** Toggles all LEDs in the LED mask, leaving all others in their current states. + * + * \param[in] LEDMask Mask of the board LEDs to manipulate (see board-specific LEDs.h driver file). + */ + static inline void LEDs_ToggleLEDs(const uint_reg_t LEDMask); + + /** Returns the status of all the board LEDs; set LED masks in the return value indicate that the + * corresponding LED is on. + * + * \return Mask of the board LEDs which are currently turned on. + */ + static inline uint_reg_t LEDs_GetLEDs(void) ATTR_WARN_UNUSED_RESULT; + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/Temperature.c b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/Temperature.c new file mode 100644 index 00000000..94843115 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/Temperature.c @@ -0,0 +1,66 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#define __INCLUDE_FROM_TEMPERATURE_C +#include "Temperature.h" + +#if defined(TEMPERATURE_SENSOR_DRIVER_COMPATIBLE) + +static const uint16_t PROGMEM Temperature_Lookup[TEMP_TABLE_SIZE] = +{ + 0x3B4, 0x3B0, 0x3AB, 0x3A6, 0x3A0, 0x39A, 0x394, 0x38E, 0x388, 0x381, 0x37A, 0x373, + 0x36B, 0x363, 0x35B, 0x353, 0x34A, 0x341, 0x338, 0x32F, 0x325, 0x31B, 0x311, 0x307, + 0x2FC, 0x2F1, 0x2E6, 0x2DB, 0x2D0, 0x2C4, 0x2B8, 0x2AC, 0x2A0, 0x294, 0x288, 0x27C, + 0x26F, 0x263, 0x256, 0x24A, 0x23D, 0x231, 0x225, 0x218, 0x20C, 0x200, 0x1F3, 0x1E7, + 0x1DB, 0x1CF, 0x1C4, 0x1B8, 0x1AC, 0x1A1, 0x196, 0x18B, 0x180, 0x176, 0x16B, 0x161, + 0x157, 0x14D, 0x144, 0x13A, 0x131, 0x128, 0x11F, 0x117, 0x10F, 0x106, 0x0FE, 0x0F7, + 0x0EF, 0x0E8, 0x0E1, 0x0DA, 0x0D3, 0x0CD, 0x0C7, 0x0C0, 0x0BA, 0x0B5, 0x0AF, 0x0AA, + 0x0A4, 0x09F, 0x09A, 0x096, 0x091, 0x08C, 0x088, 0x084, 0x080, 0x07C, 0x078, 0x074, + 0x071, 0x06D, 0x06A, 0x067, 0x064, 0x061, 0x05E, 0x05B, 0x058, 0x055, 0x053, 0x050, + 0x04E, 0x04C, 0x049, 0x047, 0x045, 0x043, 0x041, 0x03F, 0x03D, 0x03C, 0x03A, 0x038 +}; + +int8_t Temperature_GetTemperature(void) +{ + uint16_t Temp_ADC = ADC_GetChannelReading(ADC_REFERENCE_AVCC | ADC_RIGHT_ADJUSTED | TEMP_ADC_CHANNEL_MASK); + + if (Temp_ADC > pgm_read_word(&Temperature_Lookup[0])) + return TEMP_MIN_TEMP; + + for (uint16_t Index = 0; Index < TEMP_TABLE_SIZE; Index++) + { + if (Temp_ADC > pgm_read_word(&Temperature_Lookup[Index])) + return (Index + TEMP_TABLE_OFFSET_DEGREES); + } + + return TEMP_MAX_TEMP; +} + +#endif diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/Temperature.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/Temperature.h new file mode 100644 index 00000000..ed3aa7bd --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/Temperature.h @@ -0,0 +1,147 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief NTC Temperature Sensor board hardware driver. + * + * Master include file for the board temperature sensor driver, for the USB boards which contain a temperature sensor. + */ + +/** \ingroup Group_BoardDrivers + * \defgroup Group_Temperature Temperature Sensor Driver - LUFA/Drivers/Board/Temperature.h + * \brief NTC Temperature Sensor board hardware driver. + * + * \section Sec_Dependencies Module Source Dependencies + * The following files must be built with any user project that uses this module: + * - LUFA/Drivers/Board/Temperature.c (Makefile source module name: LUFA_SRC_TEMPERATURE) + * + * \section Sec_ModDescription Module Description + * Temperature sensor driver. This provides an easy to use interface for the hardware temperature sensor located + * on many boards. It provides an interface to configure the sensor and appropriate ADC channel, plus read out the + * current temperature in degrees C. It is designed for and will only work with the temperature sensor located on the + * official Atmel USB AVR boards, as each sensor has different characteristics. + * + * \section Sec_ExampleUsage Example Usage + * The following snippet is an example of how this module may be used within a typical + * application. + * + * \code + * // Initialize the ADC and board temperature sensor drivers before first use + * ADC_Init(ADC_FREE_RUNNING | ADC_PRESCALE_128); + * Temperature_Init(); + * + * // Display converted temperature in degrees Celsius + * printf("Current Temperature: %d Degrees\r\n", Temperature_GetTemperature()); + * \endcode + * + * @{ + */ + +#ifndef __TEMPERATURE_H__ +#define __TEMPERATURE_H__ + + /* Includes: */ + #include "../../Common/Common.h" + + /* Preprocessor Checks: */ + #if ((BOARD == BOARD_USBKEY) || (BOARD == BOARD_STK525) || \ + (BOARD == BOARD_STK526) || (BOARD == BOARD_EVK527)) + #define TEMPERATURE_SENSOR_DRIVER_COMPATIBLE + #endif + + #if !defined(__INCLUDE_FROM_TEMPERATURE_C) && !defined(TEMPERATURE_SENSOR_DRIVER_COMPATIBLE) + #error The selected board does not contain a compatible temperature sensor. + #endif + + #if defined(TEMPERATURE_SENSOR_DRIVER_COMPATIBLE) + + /* Includes: */ + #include "../Peripheral/ADC.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** ADC channel number for the temperature sensor. */ + #define TEMP_ADC_CHANNEL 0 + + /** ADC channel MUX mask for the temperature sensor. */ + #define TEMP_ADC_CHANNEL_MASK ADC_CHANNEL0 + + /** Size of the temperature sensor lookup table, in lookup values */ + #define TEMP_TABLE_SIZE 120 + + /** Minimum returnable temperature from the \ref Temperature_GetTemperature() function. */ + #define TEMP_MIN_TEMP TEMP_TABLE_OFFSET_DEGREES + + /** Maximum returnable temperature from the \ref Temperature_GetTemperature() function. */ + #define TEMP_MAX_TEMP ((TEMP_TABLE_SIZE - 1) + TEMP_TABLE_OFFSET_DEGREES) + + /* Inline Functions: */ + /** Initializes the temperature sensor driver, including setting up the appropriate ADC channel. + * This must be called before any other temperature sensor routines. + * + * \pre The ADC itself (not the ADC channel) must be configured separately before calling the + * temperature sensor functions. + */ + static inline void Temperature_Init(void) ATTR_ALWAYS_INLINE; + static inline void Temperature_Init(void) + { + ADC_SetupChannel(TEMP_ADC_CHANNEL); + } + + /* Function Prototypes: */ + /** Performs a complete ADC on the temperature sensor channel, and converts the result into a + * valid temperature between \ref TEMP_MIN_TEMP and \ref TEMP_MAX_TEMP in degrees Celsius. + * + * \return Signed temperature value in degrees Celsius. + */ + int8_t Temperature_GetTemperature(void) ATTR_WARN_UNUSED_RESULT; + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Macros: */ + #define TEMP_TABLE_OFFSET_DEGREES -21 + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/UC3/EVK1100/Buttons.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/UC3/EVK1100/Buttons.h new file mode 100644 index 00000000..f0f596e8 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/UC3/EVK1100/Buttons.h @@ -0,0 +1,117 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific Buttons driver header for the Atmel EVK1100. + * \copydetails Group_Buttons_EVK1100 + * + * \note This file should not be included directly. It is automatically included as needed by the Buttons driver + * dispatch header located in LUFA/Drivers/Board/Buttons.h. + */ + +/** \ingroup Group_Buttons + * \defgroup Group_Buttons_EVK1100 EVK1100 + * \brief Board specific Buttons driver header for the Atmel EVK1100. + * + * Board specific Buttons driver header for the Atmel EVK1100. + * + * + * + * + * + * + *
NameInfoActive LevelPort Pin
BUTTONS_BUTTON1SW0 ButtonLowGPIO88
BUTTONS_BUTTON2SW1 ButtonLowGPIO85
BUTTONS_BUTTON3SW2 ButtonLowGPIO82
+ * + * @{ + */ + +#ifndef __BUTTONS_EVK1100_H__ +#define __BUTTONS_EVK1100_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_BUTTONS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/Buttons.h instead. + #endif + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Macros: */ + #define BUTTONS_PORT 2 + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Mask of the first button on the board */ + #define BUTTONS_BUTTON1 (1UL << 24) + + /** Mask of the second button on the board */ + #define BUTTONS_BUTTON2 (1UL << 21) + + /** Mask of the third button on the board */ + #define BUTTONS_BUTTON3 (1UL << 18) + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void Buttons_Init(void) + { + AVR32_GPIO.port[BUTTONS_PORT].gpers = (BUTTONS_BUTTON1 | BUTTONS_BUTTON2); + AVR32_GPIO.port[BUTTONS_PORT].puers = (BUTTONS_BUTTON1 | BUTTONS_BUTTON2); + } + + static inline void Buttons_Disable(void) + { + AVR32_GPIO.port[BUTTONS_PORT].gperc = (BUTTONS_BUTTON1 | BUTTONS_BUTTON2); + AVR32_GPIO.port[BUTTONS_PORT].puerc = (BUTTONS_BUTTON1 | BUTTONS_BUTTON2); + } + + static inline uint32_t Buttons_GetStatus(void) ATTR_WARN_UNUSED_RESULT; + static inline uint32_t Buttons_GetStatus(void) + { + return (~(AVR32_GPIO.port[JOY_MOVE_PORT].pvr & (BUTTONS_BUTTON1 | BUTTONS_BUTTON2))); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/UC3/EVK1100/Joystick.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/UC3/EVK1100/Joystick.h new file mode 100644 index 00000000..adc6aea6 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/UC3/EVK1100/Joystick.h @@ -0,0 +1,122 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific joystick driver header for the Atmel EVK1100. + * \copydetails Group_Joystick_EVK1100 + * + * \note This file should not be included directly. It is automatically included as needed by the joystick driver + * dispatch header located in LUFA/Drivers/Board/Joystick.h. + */ + +/** \ingroup Group_Joystick + * \defgroup Group_Joystick_EVK1100 EVK1100 + * \brief Board specific joystick driver header for the Atmel EVK1100. + * + * Board specific joystick driver header for the Atmel EVK1100. + * + * + * + * + *
Left Port PinUp Port PinRight Port PinDown Port PinPress Port Pin
GPIO25GPIO26GPIO28GPIO27GPIO20
+ * + * @{ + */ + +#ifndef __JOYSTICK_EVK1100_H__ +#define __JOYSTICK_EVK1100_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_JOYSTICK_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/Joystick.h instead. + #endif + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Macros: */ + #define JOY_PORT 0 + #define JOY_MASK ((1UL << 28) | (1UL << 27) | (1UL << 26) | (1UL << 25) | (1UL << 20)) + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Mask for the joystick being pushed in the left direction. */ + #define JOY_LEFT (1UL << 25) + + /** Mask for the joystick being pushed in the upward direction. */ + #define JOY_UP (1UL << 26) + + /** Mask for the joystick being pushed in the right direction. */ + #define JOY_RIGHT (1UL << 28) + + /** Mask for the joystick being pushed in the downward direction. */ + #define JOY_DOWN (1UL << 27) + + /** Mask for the joystick being pushed inward. */ + #define JOY_PRESS (1UL << 20) + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void Joystick_Init(void) + { + AVR32_GPIO.port[JOY_PORT].gpers = JOY_MASK; + AVR32_GPIO.port[JOY_PORT].gpers = JOY_MASK; + }; + + static inline void Joystick_Disable(void) + { + AVR32_GPIO.port[JOY_PORT].gperc = JOY_MASK; + AVR32_GPIO.port[JOY_PORT].gperc = JOY_MASK; + }; + + static inline uint32_t Joystick_GetStatus(void) ATTR_WARN_UNUSED_RESULT; + static inline uint32_t Joystick_GetStatus(void) + { + return (uint32_t)(~(AVR32_GPIO.port[JOY_PORT].pvr & JOY_MASK)); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/UC3/EVK1100/LEDs.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/UC3/EVK1100/LEDs.h new file mode 100644 index 00000000..3e5ab851 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/UC3/EVK1100/LEDs.h @@ -0,0 +1,173 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific LED driver header for the Atmel EVK1100. + * \copydetails Group_LEDs_EVK1100 + * + * \note This file should not be included directly. It is automatically included as needed by the LEDs driver + * dispatch header located in LUFA/Drivers/Board/LEDs.h. + */ + +/** \ingroup Group_LEDs + * \defgroup Group_LEDs_EVK1100 EVK1100 + * \brief Board specific LED driver header for the Atmel EVK1100. + * + * Board specific LED driver header for the Atmel EVK1100. + * + * + * + * + * + * + * + * + * + * + * + *
NameColorInfoActive LevelPort Pin
LEDS_LED1GreenLED0 LEDLowGPIO51
LEDS_LED2GreenLED1 LEDLowGPIO52
LEDS_LED3GreenLED2 LEDLowGPIO53
LEDS_LED4GreenLED3 LEDLowGPIO54
LEDS_LED5GreenLED4 LEDLowGPIO59
LEDS_LED6GreenLED5 LEDLowGPIO60
LEDS_LED7GreenLED6 LEDLowGPIO61
LEDS_LED8GreenLED7 LEDLowGPIO62
+ * + * @{ + */ + +#ifndef __LEDS_EVK1100_H__ +#define __LEDS_EVK1100_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_LEDS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/LEDS.h instead. + #endif + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Macros: */ + #define LEDS_PORT 1 + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** LED mask for the first LED on the board. */ + #define LEDS_LED1 (1UL << 19) + + /** LED mask for the second LED on the board. */ + #define LEDS_LED2 (1UL << 20) + + /** LED mask for the third LED on the board. */ + #define LEDS_LED3 (1UL << 21) + + /** LED mask for the fourth LED on the board. */ + #define LEDS_LED4 (1UL << 22) + + /** LED mask for the fifth LED on the board. */ + #define LEDS_LED5 (1UL << 27) + + /** LED mask for the sixth LED on the board. */ + #define LEDS_LED6 (1UL << 28) + + /** LED mask for the seventh LED on the board. */ + #define LEDS_LED7 (1UL << 29) + + /** LED mask for the eighth LED on the board. */ + #define LEDS_LED8 (1UL << 30) + + /** LED mask for all the LEDs on the board. */ + #define LEDS_ALL_LEDS (LEDS_LED1 | LEDS_LED2 | LEDS_LED3 | LEDS_LED4 \ + LEDS_LED5 | LEDS_LED6 | LEDS_LED7 | LEDS_LED8) + + /** LED mask for the none of the board LEDs */ + #define LEDS_NO_LEDS 0 + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void LEDs_Init(void) + { + AVR32_GPIO.port[LEDS_PORT].gpers = LEDS_ALL_LEDS; + AVR32_GPIO.port[LEDS_PORT].oders = LEDS_ALL_LEDS; + AVR32_GPIO.port[LEDS_PORT].ovrs = LEDS_ALL_LEDS; + } + + static inline void LEDs_Disable(void) + { + AVR32_GPIO.port[LEDS_PORT].gperc = LEDS_ALL_LEDS; + AVR32_GPIO.port[LEDS_PORT].oderc = LEDS_ALL_LEDS; + AVR32_GPIO.port[LEDS_PORT].ovrc = LEDS_ALL_LEDS; + } + + static inline void LEDs_TurnOnLEDs(const uint32_t LEDMask) + { + AVR32_GPIO.port[LEDS_PORT].ovrc = LEDMask; + } + + static inline void LEDs_TurnOffLEDs(const uint32_t LEDMask) + { + AVR32_GPIO.port[LEDS_PORT].ovrs = LEDMask; + } + + static inline void LEDs_SetAllLEDs(const uint32_t LEDMask) + { + AVR32_GPIO.port[LEDS_PORT].ovrs = LEDS_ALL_LEDS; + AVR32_GPIO.port[LEDS_PORT].ovrc = LEDMask; + } + + static inline void LEDs_ChangeLEDs(const uint32_t LEDMask, const uint32_t ActiveMask) + { + AVR32_GPIO.port[LEDS_PORT].ovrs = LEDMask; + AVR32_GPIO.port[LEDS_PORT].ovrc = ActiveMask; + } + + static inline void LEDs_ToggleLEDs(const uint32_t LEDMask) + { + AVR32_GPIO.port[LEDS_PORT].ovrt = LEDMask; + } + + static inline uint32_t LEDs_GetLEDs(void) ATTR_WARN_UNUSED_RESULT; + static inline uint32_t LEDs_GetLEDs(void) + { + return (~AVR32_GPIO.port[LEDS_PORT].ovr & LEDS_ALL_LEDS); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/UC3/EVK1101/Buttons.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/UC3/EVK1101/Buttons.h new file mode 100644 index 00000000..40f8aecf --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/UC3/EVK1101/Buttons.h @@ -0,0 +1,113 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific Buttons driver header for the Atmel EVK1101. + * \copydetails Group_Buttons_EVK1101 + * + * \note This file should not be included directly. It is automatically included as needed by the Buttons driver + * dispatch header located in LUFA/Drivers/Board/Buttons.h. + */ + +/** \ingroup Group_Buttons + * \defgroup Group_Buttons_EVK1101 EVK1101 + * \brief Board specific Buttons driver header for the Atmel EVK1101. + * + * Board specific Buttons driver header for the Atmel EVK1101. + * + * + * + * + * + *
NameInfoActive LevelPort Pin
BUTTONS_BUTTON1SW0 ButtonLowGPIO34
BUTTONS_BUTTON2SW1 ButtonLowGPIO35
+ * + * @{ + */ + +#ifndef __BUTTONS_EVK1101_H__ +#define __BUTTONS_EVK1101_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_BUTTONS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/Buttons.h instead. + #endif + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Macros: */ + #define BUTTONS_PORT 1 + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Mask of the first button on the board */ + #define BUTTONS_BUTTON1 (1UL << 2) + + /** Mask of the second button on the board */ + #define BUTTONS_BUTTON2 (1UL << 3) + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void Buttons_Init(void) + { + AVR32_GPIO.port[BUTTONS_PORT].gpers = (BUTTONS_BUTTON1 | BUTTONS_BUTTON2); + AVR32_GPIO.port[BUTTONS_PORT].puers = (BUTTONS_BUTTON1 | BUTTONS_BUTTON2); + } + + static inline void Buttons_Disable(void) + { + AVR32_GPIO.port[BUTTONS_PORT].gperc = (BUTTONS_BUTTON1 | BUTTONS_BUTTON2); + AVR32_GPIO.port[BUTTONS_PORT].puerc = (BUTTONS_BUTTON1 | BUTTONS_BUTTON2); + } + + static inline uint32_t Buttons_GetStatus(void) ATTR_WARN_UNUSED_RESULT; + static inline uint32_t Buttons_GetStatus(void) + { + return (~(AVR32_GPIO.port[BUTTONS_PORT].pvr & (BUTTONS_BUTTON1 | BUTTONS_BUTTON2))); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/UC3/EVK1101/Joystick.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/UC3/EVK1101/Joystick.h new file mode 100644 index 00000000..d61c52e3 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/UC3/EVK1101/Joystick.h @@ -0,0 +1,131 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific joystick driver header for the Atmel EVK1101. + * \copydetails Group_Joystick_EVK1101 + * + * \note This file should not be included directly. It is automatically included as needed by the joystick driver + * dispatch header located in LUFA/Drivers/Board/Joystick.h. + */ + +/** \ingroup Group_Joystick + * \defgroup Group_Joystick_EVK1101 EVK1101 + * \brief Board specific joystick driver header for the Atmel EVK1101. + * + * Board specific joystick driver header for the Atmel EVK1101. + * + * + * + * + *
Left Port PinUp Port PinRight Port PinDown Port PinPress Port Pin
GPIO38GPIO39GPIO41GPIO40GPIO13
+ * + * @{ + */ + +#ifndef __JOYSTICK_EVK1101_H__ +#define __JOYSTICK_EVK1101_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_JOYSTICK_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/Joystick.h instead. + #endif + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Macros: */ + #define JOY_MOVE_PORT 1 + #define JOY_MOVE_MASK ((1UL << 6) | (1UL << 7) | (1UL << 8) | (1UL << 9)) + #define JOY_PRESS_PORT 0 + #define JOY_PRESS_MASK (1UL << 13) + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Mask for the joystick being pushed in the left direction. */ + #define JOY_LEFT (1UL << 6) + + /** Mask for the joystick being pushed in the upward direction. */ + #define JOY_UP (1UL << 7) + + /** Mask for the joystick being pushed in the right direction. */ + #define JOY_RIGHT (1UL << 9) + + /** Mask for the joystick being pushed in the downward direction. */ + #define JOY_DOWN (1UL << 8) + + /** Mask for the joystick being pushed inward. */ + #define JOY_PRESS (1UL << 13) + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void Joystick_Init(void) + { + AVR32_GPIO.port[JOY_MOVE_PORT].gpers = JOY_MOVE_MASK; + AVR32_GPIO.port[JOY_PRESS_PORT].gpers = JOY_PRESS_MASK; + + AVR32_GPIO.port[JOY_MOVE_PORT].puers = JOY_MOVE_MASK; + AVR32_GPIO.port[JOY_PRESS_PORT].puers = JOY_PRESS_MASK; + }; + + static inline void Joystick_Disable(void) + { + AVR32_GPIO.port[JOY_MOVE_PORT].gperc = JOY_MOVE_MASK; + AVR32_GPIO.port[JOY_PRESS_PORT].gperc = JOY_PRESS_MASK; + + AVR32_GPIO.port[JOY_MOVE_PORT].puerc = JOY_MOVE_MASK; + AVR32_GPIO.port[JOY_PRESS_PORT].puerc = JOY_PRESS_MASK; + }; + + static inline uint32_t Joystick_GetStatus(void) ATTR_WARN_UNUSED_RESULT; + static inline uint32_t Joystick_GetStatus(void) + { + return (uint32_t)(~((AVR32_GPIO.port[JOY_MOVE_PORT].pvr & JOY_MOVE_MASK) | + (AVR32_GPIO.port[JOY_PRESS_PORT].pvr & JOY_PRESS_MASK))); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/UC3/EVK1101/LEDs.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/UC3/EVK1101/LEDs.h new file mode 100644 index 00000000..1f1960d1 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/UC3/EVK1101/LEDs.h @@ -0,0 +1,156 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific LED driver header for the Atmel EVK1101. + * \copydetails Group_LEDs_EVK1101 + * + * \note This file should not be included directly. It is automatically included as needed by the LEDs driver + * dispatch header located in LUFA/Drivers/Board/LEDs.h. + */ + +/** \ingroup Group_LEDs + * \defgroup Group_LEDs_EVK1101 EVK1101 + * \brief Board specific LED driver header for the Atmel EVK1101. + * + * Board specific LED driver header for the Atmel EVK1101. + * + * + * + * + * + * + * + *
NameColorInfoActive LevelPort Pin
LEDS_LED1GreenLED0 LEDLowGPIO7
LEDS_LED2GreenLED1 LEDLowGPIO8
LEDS_LED3GreenLED2 LEDLowGPIO21
LEDS_LED4GreenLED3 LEDLowGPIO22
+ * + * @{ + */ + +#ifndef __LEDS_EVK1101_H__ +#define __LEDS_EVK1101_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_LEDS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/LEDS.h instead. + #endif + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Macros: */ + #define LEDS_PORT 0 + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** LED mask for the first LED on the board. */ + #define LEDS_LED1 (1UL << 7) + + /** LED mask for the second LED on the board. */ + #define LEDS_LED2 (1UL << 8) + + /** LED mask for the third LED on the board. */ + #define LEDS_LED3 (1UL << 21) + + /** LED mask for the fourth LED on the board. */ + #define LEDS_LED4 (1UL << 22) + + /** LED mask for all the LEDs on the board. */ + #define LEDS_ALL_LEDS (LEDS_LED1 | LEDS_LED2 | LEDS_LED3 | LEDS_LED4) + + /** LED mask for the none of the board LEDs */ + #define LEDS_NO_LEDS 0 + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void LEDs_Init(void) + { + AVR32_GPIO.port[LEDS_PORT].gpers = LEDS_ALL_LEDS; + AVR32_GPIO.port[LEDS_PORT].oders = LEDS_ALL_LEDS; + AVR32_GPIO.port[LEDS_PORT].ovrs = LEDS_ALL_LEDS; + } + + static inline void LEDs_Disable(void) + { + AVR32_GPIO.port[LEDS_PORT].gperc = LEDS_ALL_LEDS; + AVR32_GPIO.port[LEDS_PORT].oderc = LEDS_ALL_LEDS; + AVR32_GPIO.port[LEDS_PORT].ovrc = LEDS_ALL_LEDS; + } + + static inline void LEDs_TurnOnLEDs(const uint32_t LEDMask) + { + AVR32_GPIO.port[LEDS_PORT].ovrc = LEDMask; + } + + static inline void LEDs_TurnOffLEDs(const uint32_t LEDMask) + { + AVR32_GPIO.port[LEDS_PORT].ovrs = LEDMask; + } + + static inline void LEDs_SetAllLEDs(const uint32_t LEDMask) + { + AVR32_GPIO.port[LEDS_PORT].ovrs = LEDS_ALL_LEDS; + AVR32_GPIO.port[LEDS_PORT].ovrc = LEDMask; + } + + static inline void LEDs_ChangeLEDs(const uint32_t LEDMask, const uint32_t ActiveMask) + { + AVR32_GPIO.port[LEDS_PORT].ovrs = LEDMask; + AVR32_GPIO.port[LEDS_PORT].ovrc = ActiveMask; + } + + static inline void LEDs_ToggleLEDs(const uint32_t LEDMask) + { + AVR32_GPIO.port[LEDS_PORT].ovrt = LEDMask; + } + + static inline uint32_t LEDs_GetLEDs(void) ATTR_WARN_UNUSED_RESULT; + static inline uint32_t LEDs_GetLEDs(void) + { + return (~AVR32_GPIO.port[LEDS_PORT].ovr & LEDS_ALL_LEDS); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/UC3/EVK1104/Buttons.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/UC3/EVK1104/Buttons.h new file mode 100644 index 00000000..1c6bdd0d --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/UC3/EVK1104/Buttons.h @@ -0,0 +1,109 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific Buttons driver header for the Atmel EVK1104. + * \copydetails Group_Buttons_EVK1104 + * + * \note This file should not be included directly. It is automatically included as needed by the Buttons driver + * dispatch header located in LUFA/Drivers/Board/Buttons.h. + */ + +/** \ingroup Group_Buttons + * \defgroup Group_Buttons_EVK1104 EVK1104 + * \brief Board specific Buttons driver header for the Atmel EVK1104. + * + * Board specific Buttons driver header for the Atmel EVK1104. + * + * + * + * + *
NameInfoActive LevelPort Pin
BUTTONS_BUTTON1SW0 ButtonLowGPIO42
+ * + * @{ + */ + +#ifndef __BUTTONS_EVK1104_H__ +#define __BUTTONS_EVK1104_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_BUTTONS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/Buttons.h instead. + #endif + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Macros: */ + #define BUTTONS_PORT 1 + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Mask of the first button on the board */ + #define BUTTONS_BUTTON1 (1UL << 10) + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void Buttons_Init(void) + { + AVR32_GPIO.port[BUTTONS_PORT].gpers = (BUTTONS_BUTTON1 | BUTTONS_BUTTON2); + AVR32_GPIO.port[BUTTONS_PORT].puers = (BUTTONS_BUTTON1 | BUTTONS_BUTTON2); + } + + static inline void Buttons_Disable(void) + { + AVR32_GPIO.port[BUTTONS_PORT].gperc = (BUTTONS_BUTTON1 | BUTTONS_BUTTON2); + AVR32_GPIO.port[BUTTONS_PORT].puerc = (BUTTONS_BUTTON1 | BUTTONS_BUTTON2); + } + + static inline uint32_t Buttons_GetStatus(void) ATTR_WARN_UNUSED_RESULT; + static inline uint32_t Buttons_GetStatus(void) + { + return (~(AVR32_GPIO.port[JOY_MOVE_PORT].pvr & (BUTTONS_BUTTON1 | BUTTONS_BUTTON2))); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/UC3/EVK1104/LEDs.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/UC3/EVK1104/LEDs.h new file mode 100644 index 00000000..14595517 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/UC3/EVK1104/LEDs.h @@ -0,0 +1,174 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific LED driver header for the Atmel EVK1104. + * \copydetails Group_LEDs_EVK1104 + * + * \note This file should not be included directly. It is automatically included as needed by the LEDs driver + * dispatch header located in LUFA/Drivers/Board/LEDs.h. + */ + +/** \ingroup Group_LEDs + * \defgroup Group_LEDs_EVK1104 EVK1104 + * \brief Board specific LED driver header for the Atmel EVK1104. + * + * Board specific LED driver header for the Atmel EVK1104. + * + * + * + * + * + * + * + *
NameColorInfoActive LevelPort Pin
LEDS_LED1GreenLED0 LEDLowGPIO67
LEDS_LED2GreenLED1 LEDLowGPIO101
LEDS_LED3GreenLED2 LEDLowGPIO102
LEDS_LED4GreenLED3 LEDLowGPIO105
+ * + * @{ + */ + +#ifndef __LEDS_EVK1104_H__ +#define __LEDS_EVK1104_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_LEDS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/LEDS.h instead. + #endif + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Macros: */ + #define LEDS_LEDMASK2 (1UL << 3) + #define LEDS_LEDMASK3 ((1UL << 9) | (1UL << 6) | (1UL << 5)) + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** LED mask for the first LED on the board. */ + #define LEDS_LED1 (1UL << 3) + + /** LED mask for the second LED on the board. */ + #define LEDS_LED2 (1UL << 5) + + /** LED mask for the third LED on the board. */ + #define LEDS_LED3 (1UL << 9) + + /** LED mask for the fourth LED on the board. */ + #define LEDS_LED4 (1UL << 6) + + /** LED mask for all the LEDs on the board. */ + #define LEDS_ALL_LEDS (LEDS_LED1 | LEDS_LED2 | LEDS_LED3 | LEDS_LED4) + + /** LED mask for the none of the board LEDs */ + #define LEDS_NO_LEDS 0 + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void LEDs_Init(void) + { + AVR32_GPIO.port[2].gpers = LEDS_LEDMASK2; + AVR32_GPIO.port[2].oders = LEDS_LEDMASK2; + AVR32_GPIO.port[2].ovrs = LEDS_LEDMASK2; + + AVR32_GPIO.port[3].gpers = LEDS_LEDMASK3; + AVR32_GPIO.port[3].oders = LEDS_LEDMASK3; + AVR32_GPIO.port[3].ovrs = LEDS_LEDMASK3; + } + + static inline void LEDs_Disable(void) + { + AVR32_GPIO.port[2].gperc = LEDS_LEDMASK2; + AVR32_GPIO.port[2].oderc = LEDS_LEDMASK2; + AVR32_GPIO.port[2].ovrc = LEDS_LEDMASK2; + + AVR32_GPIO.port[3].gperc = LEDS_LEDMASK3; + AVR32_GPIO.port[3].oderc = LEDS_LEDMASK3; + AVR32_GPIO.port[3].ovrc = LEDS_LEDMASK3; + } + + static inline void LEDs_TurnOnLEDs(const uint32_t LEDMask) + { + AVR32_GPIO.port[2].ovrc = (LEDMask & LEDS_LEDMASK2); + AVR32_GPIO.port[3].ovrc = (LEDMask & LEDS_LEDMASK3); + } + + static inline void LEDs_TurnOffLEDs(const uint32_t LEDMask) + { + AVR32_GPIO.port[2].ovrs = (LEDMask & LEDS_LEDMASK2); + AVR32_GPIO.port[3].ovrs = (LEDMask & LEDS_LEDMASK3); + } + + static inline void LEDs_SetAllLEDs(const uint32_t LEDMask) + { + AVR32_GPIO.port[2].ovrs = LEDS_LEDMASK2; + AVR32_GPIO.port[2].ovrc = (LEDMask & LEDS_LEDMASK2); + + AVR32_GPIO.port[3].ovrs = LEDS_LEDMASK3; + AVR32_GPIO.port[3].ovrc = (LEDMask & LEDS_LEDMASK3); + } + + static inline void LEDs_ChangeLEDs(const uint32_t LEDMask, const uint32_t ActiveMask) + { + AVR32_GPIO.port[2].ovrs = (LEDMask & LEDS_LEDMASK2); + AVR32_GPIO.port[2].ovrc = (ActiveMask & LEDS_LEDMASK2); + + AVR32_GPIO.port[3].ovrs = (LEDMask & LEDS_LEDMASK3); + AVR32_GPIO.port[3].ovrc = (ActiveMask & LEDS_LEDMASK3); + } + + static inline void LEDs_ToggleLEDs(const uint32_t LEDMask) + { + AVR32_GPIO.port[2].ovrt = (LEDMask & LEDS_LEDMASK2); + AVR32_GPIO.port[3].ovrt = (LEDMask & LEDS_LEDMASK3); + } + + static inline uint32_t LEDs_GetLEDs(void) ATTR_WARN_UNUSED_RESULT; + static inline uint32_t LEDs_GetLEDs(void) + { + return ((~AVR32_GPIO.port[2].ovr & LEDS_LEDMASK2) | (~AVR32_GPIO.port[3].ovr & LEDS_LEDMASK3)); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/XMEGA/A3BU_XPLAINED/Buttons.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/XMEGA/A3BU_XPLAINED/Buttons.h new file mode 100644 index 00000000..ebe24a74 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/XMEGA/A3BU_XPLAINED/Buttons.h @@ -0,0 +1,119 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific Buttons driver header for the Atmel XMEGA A3BU Xplained. + * \copydetails Group_Buttons_A3BU_XPLAINED + * + * \note This file should not be included directly. It is automatically included as needed by the Buttons driver + * dispatch header located in LUFA/Drivers/Board/Buttons.h. + */ + +/** \ingroup Group_Buttons + * \defgroup Group_Buttons_A3BU_XPLAINED A3BU_XPLAINED + * \brief Board specific Buttons driver header for the Atmel XMEGA A3BU Xplained. + * + * Board specific Buttons driver header for the Atmel XMEGA A3BU Xplained. + * + * + * + * + * + * + *
NameInfoActive LevelPort Pin
BUTTONS_BUTTON1SW0 ButtonLowPORTE.5
BUTTONS_BUTTON2SW1 ButtonLowPORTF.1
BUTTONS_BUTTON3SW2 ButtonLowPORTF.2
+ * + * @{ + */ + +#ifndef __BUTTONS_A3BU_XPLAINED_H__ +#define __BUTTONS_A3BU_XPLAINED_H__ + + /* Includes: */ + #include + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_BUTTONS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/Buttons.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Button mask for the first button on the board. */ + #define BUTTONS_BUTTON1 (1 << 5) + + /** Button mask for the second button on the board. */ + #define BUTTONS_BUTTON2 (1 << 1) + + /** Button mask for the third button on the board. */ + #define BUTTONS_BUTTON3 (1 << 2) + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void Buttons_Init(void) + { + PORTE.OUTCLR = BUTTONS_BUTTON1; + PORTE.PIN5CTRL = (PORT_OPC_PULLUP_gc | PORT_INVEN_bm); + + PORTF.OUTCLR = (BUTTONS_BUTTON2 | BUTTONS_BUTTON3); + PORTF.PIN1CTRL = (PORT_OPC_PULLUP_gc | PORT_INVEN_bm); + PORTF.PIN2CTRL = (PORT_OPC_PULLUP_gc | PORT_INVEN_bm); + } + + static inline void Buttons_Disable(void) + { + PORTE.OUTCLR = BUTTONS_BUTTON1; + PORTE.PIN5CTRL = 0; + + PORTF.OUTCLR = (BUTTONS_BUTTON2 | BUTTONS_BUTTON3); + PORTF.PIN1CTRL = 0; + PORTF.PIN2CTRL = 0; + } + + static inline uint8_t Buttons_GetStatus(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t Buttons_GetStatus(void) + { + return ((PORTE_IN & BUTTONS_BUTTON1) | (PORTF_IN & (BUTTONS_BUTTON2 | BUTTONS_BUTTON3))); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/XMEGA/A3BU_XPLAINED/Dataflash.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/XMEGA/A3BU_XPLAINED/Dataflash.h new file mode 100644 index 00000000..34f8ce12 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/XMEGA/A3BU_XPLAINED/Dataflash.h @@ -0,0 +1,222 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific Dataflash driver header for the Atmel XMEGA B1 Xplained. + * \copydetails Group_Dataflash_B1_XPLAINED + * + * \note This file should not be included directly. It is automatically included as needed by the dataflash driver + * dispatch header located in LUFA/Drivers/Board/Dataflash.h. + */ + +/** \ingroup Group_Dataflash + * \defgroup Group_Dataflash_B1_XPLAINED B1_XPLAINED + * \brief Board specific Dataflash driver header for the Atmel XMEGA B1 Xplained. + * + * Board specific Dataflash driver header for the Atmel XMEGA B1 Xplained board. + * + * + * + * + *
NameInfoSelect PinSPI Port
DATAFLASH_CHIP1AT45DB642D (8MB)PORTF.4USARTD0 (In SPI Mode)
+ * + * @{ + */ + +#ifndef __DATAFLASH_B1_XPLAINED_H__ +#define __DATAFLASH_B1_XPLAINED_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + #include "../../../Misc/AT45DB642D.h" + #include "../../../Peripheral/SerialSPI.h" + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_DATAFLASH_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/Dataflash.h instead. + #endif + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Macros: */ + #define DATAFLASH_CHIPCS_MASK (1 << 4) + #define DATAFLASH_CHIPCS_PORT PORTF + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Constant indicating the total number of dataflash ICs mounted on the selected board. */ + #define DATAFLASH_TOTALCHIPS 1 + + /** Mask for no dataflash chip selected. */ + #define DATAFLASH_NO_CHIP 0 + + /** Mask for the first dataflash chip selected. */ + #define DATAFLASH_CHIP1 (1 << 4) + + /** Internal main memory page size for the board's dataflash ICs. */ + #define DATAFLASH_PAGE_SIZE 1024 + + /** Total number of pages inside each of the board's dataflash ICs. */ + #define DATAFLASH_PAGES 8192 + + /* Inline Functions: */ + /** Initializes the dataflash driver so that commands and data may be sent to an attached dataflash IC. + * The microcontroller's SPI driver MUST be initialized before any of the dataflash commands are used. + */ + static inline void Dataflash_Init(void) + { + DATAFLASH_CHIPCS_PORT.DIRSET = DATAFLASH_CHIPCS_MASK; + + PORTCFG.MPCMASK = DATAFLASH_CHIPCS_MASK; + DATAFLASH_CHIPCS_PORT.PIN0CTRL = PORT_INVEN_bm; + } + + /** Sends a byte to the currently selected dataflash IC, and returns a byte from the dataflash. + * + * \param[in] Byte Byte of data to send to the dataflash + * + * \return Last response byte from the dataflash + */ + static inline uint8_t Dataflash_TransferByte(const uint8_t Byte) ATTR_ALWAYS_INLINE; + static inline uint8_t Dataflash_TransferByte(const uint8_t Byte) + { + return SerialSPI_TransferByte(&USARTD0, Byte); + } + + /** Sends a byte to the currently selected dataflash IC, and ignores the next byte from the dataflash. + * + * \param[in] Byte Byte of data to send to the dataflash + */ + static inline void Dataflash_SendByte(const uint8_t Byte) ATTR_ALWAYS_INLINE; + static inline void Dataflash_SendByte(const uint8_t Byte) + { + SerialSPI_SendByte(&USARTD0, Byte); + } + + /** Sends a dummy byte to the currently selected dataflash IC, and returns the next byte from the dataflash. + * + * \return Last response byte from the dataflash + */ + static inline uint8_t Dataflash_ReceiveByte(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT; + static inline uint8_t Dataflash_ReceiveByte(void) + { + return SerialSPI_ReceiveByte(&USARTD0); + } + + /** Determines the currently selected dataflash chip. + * + * \return Mask of the currently selected Dataflash chip, either \ref DATAFLASH_NO_CHIP if no chip is selected + * or a DATAFLASH_CHIPn mask (where n is the chip number). + */ + static inline uint8_t Dataflash_GetSelectedChip(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT; + static inline uint8_t Dataflash_GetSelectedChip(void) + { + return (DATAFLASH_CHIPCS_PORT.OUT & DATAFLASH_CHIPCS_MASK); + } + + /** Selects the given dataflash chip. + * + * \param[in] ChipMask Mask of the Dataflash IC to select, in the form of DATAFLASH_CHIPn mask (where n is + * the chip number). + */ + static inline void Dataflash_SelectChip(const uint8_t ChipMask) ATTR_ALWAYS_INLINE; + static inline void Dataflash_SelectChip(const uint8_t ChipMask) + { + DATAFLASH_CHIPCS_PORT.OUTCLR = DATAFLASH_CHIPCS_MASK; + DATAFLASH_CHIPCS_PORT.OUTSET = ChipMask; + } + + /** Deselects the current dataflash chip, so that no dataflash is selected. */ + static inline void Dataflash_DeselectChip(void) ATTR_ALWAYS_INLINE; + static inline void Dataflash_DeselectChip(void) + { + Dataflash_SelectChip(DATAFLASH_NO_CHIP); + } + + /** Selects a dataflash IC from the given page number, which should range from 0 to + * ((DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS) - 1). For boards containing only one + * dataflash IC, this will select DATAFLASH_CHIP1. If the given page number is outside + * the total number of pages contained in the boards dataflash ICs, all dataflash ICs + * are deselected. + * + * \param[in] PageAddress Address of the page to manipulate, ranging from + * 0 to ((DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS) - 1). + */ + static inline void Dataflash_SelectChipFromPage(const uint16_t PageAddress) + { + Dataflash_DeselectChip(); + + if (PageAddress >= (DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS)) + return; + + Dataflash_SelectChip(DATAFLASH_CHIP1); + } + + /** Toggles the select line of the currently selected dataflash IC, so that it is ready to receive + * a new command. + */ + static inline void Dataflash_ToggleSelectedChipCS(void) + { + uint8_t SelectedChipMask = Dataflash_GetSelectedChip(); + + Dataflash_DeselectChip(); + Dataflash_SelectChip(SelectedChipMask); + } + + /** Spin-loops while the currently selected dataflash is busy executing a command, such as a main + * memory page program or main memory to buffer transfer. + */ + static inline void Dataflash_WaitWhileBusy(void) + { + Dataflash_ToggleSelectedChipCS(); + Dataflash_SendByte(DF_CMD_GETSTATUS); + while (!(Dataflash_ReceiveByte() & DF_STATUS_READY)); + Dataflash_ToggleSelectedChipCS(); + } + + /** Sends a set of page and buffer address bytes to the currently selected dataflash IC, for use with + * dataflash commands which require a complete 24-bit address. + * + * \param[in] PageAddress Page address within the selected dataflash IC + * \param[in] BufferByte Address within the dataflash's buffer + */ + static inline void Dataflash_SendAddressBytes(uint16_t PageAddress, + const uint16_t BufferByte) + { + Dataflash_SendByte(PageAddress >> 5); + Dataflash_SendByte((PageAddress << 3) | (BufferByte >> 8)); + Dataflash_SendByte(BufferByte); + } + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/XMEGA/A3BU_XPLAINED/LEDs.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/XMEGA/A3BU_XPLAINED/LEDs.h new file mode 100644 index 00000000..f930844c --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/XMEGA/A3BU_XPLAINED/LEDs.h @@ -0,0 +1,144 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific LED driver header for the Atmel XMEGA A3BU Xplained. + * \copydetails Group_LEDs_A3BU_XPLAINED + * + * \note This file should not be included directly. It is automatically included as needed by the LEDs driver + * dispatch header located in LUFA/Drivers/Board/LEDs.h. + */ + +/** \ingroup Group_LEDs + * \defgroup Group_LEDs_A3BU_XPLAINED A3BU_XPLAINED + * \brief Board specific LED driver header for the Atmel XMEGA A3BU Xplained. + * + * Board specific LED driver header for the Atmel XMEGA A3BU Xplained. + * + * + * + * + * + *
NameColorInfoActive LevelPort Pin
LEDS_LED1YellowLED0 LEDLowPORTR.0
LEDS_LED2YellowLED1 LEDLowPORTR.1
+ * + * @{ + */ + +#ifndef __LEDS_A3BU_XPLAINED_H__ +#define __LEDS_A3BU_XPLAINED_H__ + + /* Includes: */ + #include + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_LEDS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/LEDS.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** LED mask for the first LED on the board. */ + #define LEDS_LED1 (1 << 0) + + /** LED mask for the second LED on the board. */ + #define LEDS_LED2 (1 << 1) + + /** LED mask for all the LEDs on the board. */ + #define LEDS_ALL_LEDS (LEDS_LED1 | LEDS_LED2) + + /** LED mask for none of the board LEDs. */ + #define LEDS_NO_LEDS 0 + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void LEDs_Init(void) + { + PORTR.DIRSET = LEDS_ALL_LEDS; + PORTR.OUTCLR = LEDS_ALL_LEDS; + + PORTCFG.MPCMASK = LEDS_ALL_LEDS; + PORTR.PIN0CTRL = PORT_INVEN_bm; + } + + static inline void LEDs_Disable(void) + { + PORTR.DIRCLR = LEDS_ALL_LEDS; + PORTR.OUTCLR = LEDS_ALL_LEDS; + + PORTCFG.MPCMASK = 0; + PORTR.PIN0CTRL = LEDS_ALL_LEDS; + } + + static inline void LEDs_TurnOnLEDs(const uint8_t LEDMask) + { + PORTR_OUTSET = LEDMask; + } + + static inline void LEDs_TurnOffLEDs(const uint8_t LEDMask) + { + PORTR_OUTCLR = LEDMask; + } + + static inline void LEDs_SetAllLEDs(const uint8_t LEDMask) + { + PORTR_OUT = (PORTR.OUT & ~LEDS_ALL_LEDS) | LEDMask; + } + + static inline void LEDs_ChangeLEDs(const uint8_t LEDMask, const uint8_t ActiveMask) + { + PORTR_OUT = (PORTR.OUT & ~LEDMask) | ActiveMask; + } + + static inline void LEDs_ToggleLEDs(const uint8_t LEDMask) + { + PORTR_OUTTGL = LEDMask; + } + + static inline uint8_t LEDs_GetLEDs(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t LEDs_GetLEDs(void) + { + return (PORTR_OUT & LEDS_ALL_LEDS); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/XMEGA/B1_XPLAINED/Buttons.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/XMEGA/B1_XPLAINED/Buttons.h new file mode 100644 index 00000000..ae5445a1 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/XMEGA/B1_XPLAINED/Buttons.h @@ -0,0 +1,119 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific Buttons driver header for the Atmel XMEGA B1 Xplained. + * \copydetails Group_Buttons_B1_XPLAINED + * + * \note This file should not be included directly. It is automatically included as needed by the Buttons driver + * dispatch header located in LUFA/Drivers/Board/Buttons.h. + */ + +/** \ingroup Group_Buttons + * \defgroup Group_Buttons_B1_XPLAINED B1_XPLAINED + * \brief Board specific Buttons driver header for the Atmel XMEGA B1 Xplained. + * + * Board specific Buttons driver header for the Atmel XMEGA B1 Xplained. + * + * + * + * + * + * + * + *
NameInfoActive LevelPort Pin
BUTTONS_BUTTON1Touch CS0 ButtonLowPORTE.0
BUTTONS_BUTTON2Touch CS1 ButtonLowPORTE.1
BUTTONS_BUTTON3Touch CS2 ButtonLowPORTE.2
BUTTONS_BUTTON4Touch CS3 ButtonLowPORTE.3
+ * + * @{ + */ + +#ifndef __BUTTONS_B1_XPLAINED_H__ +#define __BUTTONS_B1_XPLAINED_H__ + + /* Includes: */ + #include + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_BUTTONS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/Buttons.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Button mask for the first button on the board. */ + #define BUTTONS_BUTTON1 (1 << 0) + + /** Button mask for the second button on the board. */ + #define BUTTONS_BUTTON2 (1 << 1) + + /** Button mask for the third button on the board. */ + #define BUTTONS_BUTTON3 (1 << 2) + + /** Button mask for the fourth button on the board. */ + #define BUTTONS_BUTTON4 (1 << 3) + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void Buttons_Init(void) + { + PORTE.OUTSET = (BUTTONS_BUTTON1 | BUTTONS_BUTTON2 | BUTTONS_BUTTON3 | BUTTONS_BUTTON4); + + PORTCFG.MPCMASK = (BUTTONS_BUTTON1 | BUTTONS_BUTTON2 | BUTTONS_BUTTON3 | BUTTONS_BUTTON4); + PORTE.PIN0CTRL = (PORT_INVEN_bm | PORT_OPC_PULLUP_gc); + } + + static inline void Buttons_Disable(void) + { + PORTE.OUTCLR = (BUTTONS_BUTTON1 | BUTTONS_BUTTON2 | BUTTONS_BUTTON3 | BUTTONS_BUTTON4); + + PORTCFG.MPCMASK = (BUTTONS_BUTTON1 | BUTTONS_BUTTON2 | BUTTONS_BUTTON3 | BUTTONS_BUTTON4); + PORTE.PIN0CTRL = 0; + } + + static inline uint8_t Buttons_GetStatus(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t Buttons_GetStatus(void) + { + return (PORTE_IN & (BUTTONS_BUTTON1 | BUTTONS_BUTTON2 | BUTTONS_BUTTON3 | BUTTONS_BUTTON4)); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/XMEGA/B1_XPLAINED/Dataflash.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/XMEGA/B1_XPLAINED/Dataflash.h new file mode 100644 index 00000000..2f58c484 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/XMEGA/B1_XPLAINED/Dataflash.h @@ -0,0 +1,224 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific Dataflash driver header for the Atmel XMEGA A3BU Xplained. + * \copydetails Group_Dataflash_A3BU_XPLAINED + * + * \note This file should not be included directly. It is automatically included as needed by the dataflash driver + * dispatch header located in LUFA/Drivers/Board/Dataflash.h. + */ + +/** \ingroup Group_Dataflash + * \defgroup Group_Dataflash_A3BU_XPLAINED A3BU_XPLAINED + * \brief Board specific Dataflash driver header for the Atmel XMEGA A3BU Xplained. + * + * Board specific Dataflash driver header for the Atmel XMEGA A3BU Xplained board. + * + * + * + * + *
NameInfoSelect PinSPI Port
DATAFLASH_CHIP1AT45DB642D (8MB)PORTD.2USARTC0 (In SPI Mode, Remapped)
+ * + * @{ + */ + +#ifndef __DATAFLASH_A3BU_XPLAINED_H__ +#define __DATAFLASH_A3BU_XPLAINED_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + #include "../../../Misc/AT45DB642D.h" + #include "../../../Peripheral/SerialSPI.h" + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_DATAFLASH_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/Dataflash.h instead. + #endif + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Macros: */ + #define DATAFLASH_CHIPCS_MASK (1 << 2) + #define DATAFLASH_CHIPCS_PORT PORTD + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Constant indicating the total number of dataflash ICs mounted on the selected board. */ + #define DATAFLASH_TOTALCHIPS 1 + + /** Mask for no dataflash chip selected. */ + #define DATAFLASH_NO_CHIP 0 + + /** Mask for the first dataflash chip selected. */ + #define DATAFLASH_CHIP1 (1 << 2) + + /** Internal main memory page size for the board's dataflash ICs. */ + #define DATAFLASH_PAGE_SIZE 1024 + + /** Total number of pages inside each of the board's dataflash ICs. */ + #define DATAFLASH_PAGES 8192 + + /* Inline Functions: */ + /** Initializes the dataflash driver so that commands and data may be sent to an attached dataflash IC. + * The microcontroller's SPI driver MUST be initialized before any of the dataflash commands are used. + */ + static inline void Dataflash_Init(void) + { + DATAFLASH_CHIPCS_PORT.DIRSET = DATAFLASH_CHIPCS_MASK; + + PORTCFG.MPCMASK = DATAFLASH_CHIPCS_MASK; + DATAFLASH_CHIPCS_PORT.PIN0CTRL = PORT_INVEN_bm; + + PORTC.REMAP |= PORT_USART0_bm; + } + + /** Sends a byte to the currently selected dataflash IC, and returns a byte from the dataflash. + * + * \param[in] Byte Byte of data to send to the dataflash + * + * \return Last response byte from the dataflash + */ + static inline uint8_t Dataflash_TransferByte(const uint8_t Byte) ATTR_ALWAYS_INLINE; + static inline uint8_t Dataflash_TransferByte(const uint8_t Byte) + { + return SerialSPI_TransferByte(&USARTC0, Byte); + } + + /** Sends a byte to the currently selected dataflash IC, and ignores the next byte from the dataflash. + * + * \param[in] Byte Byte of data to send to the dataflash + */ + static inline void Dataflash_SendByte(const uint8_t Byte) ATTR_ALWAYS_INLINE; + static inline void Dataflash_SendByte(const uint8_t Byte) + { + SerialSPI_SendByte(&USARTC0, Byte); + } + + /** Sends a dummy byte to the currently selected dataflash IC, and returns the next byte from the dataflash. + * + * \return Last response byte from the dataflash + */ + static inline uint8_t Dataflash_ReceiveByte(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT; + static inline uint8_t Dataflash_ReceiveByte(void) + { + return SerialSPI_ReceiveByte(&USARTC0); + } + + /** Determines the currently selected dataflash chip. + * + * \return Mask of the currently selected Dataflash chip, either \ref DATAFLASH_NO_CHIP if no chip is selected + * or a DATAFLASH_CHIPn mask (where n is the chip number). + */ + static inline uint8_t Dataflash_GetSelectedChip(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT; + static inline uint8_t Dataflash_GetSelectedChip(void) + { + return (DATAFLASH_CHIPCS_PORT.OUT & DATAFLASH_CHIPCS_MASK); + } + + /** Selects the given dataflash chip. + * + * \param[in] ChipMask Mask of the Dataflash IC to select, in the form of DATAFLASH_CHIPn mask (where n is + * the chip number). + */ + static inline void Dataflash_SelectChip(const uint8_t ChipMask) ATTR_ALWAYS_INLINE; + static inline void Dataflash_SelectChip(const uint8_t ChipMask) + { + DATAFLASH_CHIPCS_PORT.OUTCLR = DATAFLASH_CHIPCS_MASK; + DATAFLASH_CHIPCS_PORT.OUTSET = (ChipMask & DATAFLASH_CHIPCS_MASK); + } + + /** Deselects the current dataflash chip, so that no dataflash is selected. */ + static inline void Dataflash_DeselectChip(void) ATTR_ALWAYS_INLINE; + static inline void Dataflash_DeselectChip(void) + { + Dataflash_SelectChip(DATAFLASH_NO_CHIP); + } + + /** Selects a dataflash IC from the given page number, which should range from 0 to + * ((DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS) - 1). For boards containing only one + * dataflash IC, this will select DATAFLASH_CHIP1. If the given page number is outside + * the total number of pages contained in the boards dataflash ICs, all dataflash ICs + * are deselected. + * + * \param[in] PageAddress Address of the page to manipulate, ranging from + * 0 to ((DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS) - 1). + */ + static inline void Dataflash_SelectChipFromPage(const uint16_t PageAddress) + { + Dataflash_DeselectChip(); + + if (PageAddress >= (DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS)) + return; + + Dataflash_SelectChip(DATAFLASH_CHIP1); + } + + /** Toggles the select line of the currently selected dataflash IC, so that it is ready to receive + * a new command. + */ + static inline void Dataflash_ToggleSelectedChipCS(void) + { + uint8_t SelectedChipMask = Dataflash_GetSelectedChip(); + + Dataflash_DeselectChip(); + Dataflash_SelectChip(SelectedChipMask); + } + + /** Spin-loops while the currently selected dataflash is busy executing a command, such as a main + * memory page program or main memory to buffer transfer. + */ + static inline void Dataflash_WaitWhileBusy(void) + { + Dataflash_ToggleSelectedChipCS(); + Dataflash_SendByte(DF_CMD_GETSTATUS); + while (!(Dataflash_ReceiveByte() & DF_STATUS_READY)); + Dataflash_ToggleSelectedChipCS(); + } + + /** Sends a set of page and buffer address bytes to the currently selected dataflash IC, for use with + * dataflash commands which require a complete 24-bit address. + * + * \param[in] PageAddress Page address within the selected dataflash IC + * \param[in] BufferByte Address within the dataflash's buffer + */ + static inline void Dataflash_SendAddressBytes(uint16_t PageAddress, + const uint16_t BufferByte) + { + Dataflash_SendByte(PageAddress >> 5); + Dataflash_SendByte((PageAddress << 3) | (BufferByte >> 8)); + Dataflash_SendByte(BufferByte); + } + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/XMEGA/B1_XPLAINED/LEDs.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/XMEGA/B1_XPLAINED/LEDs.h new file mode 100644 index 00000000..b4b74321 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Board/XMEGA/B1_XPLAINED/LEDs.h @@ -0,0 +1,182 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Board specific LED driver header for the Atmel XMEGA B1 Xplained. + * \copydetails Group_LEDs_B1_XPLAINED + * + * \note This file should not be included directly. It is automatically included as needed by the LEDs driver + * dispatch header located in LUFA/Drivers/Board/LEDs.h. + */ + +/** \ingroup Group_LEDs + * \defgroup Group_LEDs_B1_XPLAINED B1_XPLAINED + * \brief Board specific LED driver header for the Atmel XMEGA B1 Xplained. + * + * Board specific LED driver header for the Atmel XMEGA B1 Xplained. + * + * + * + * + * + * + * + * + *
NameColorInfoActive LevelPort Pin
LEDS_LED1YellowLED0 LEDHighPORTB.4
LEDS_LED2YellowLED1 LEDHighPORTB.5
LEDS_LED3YellowLED2 LEDHighPORTB.6
LEDS_LED4YellowLED3 LEDHighPORTB.7
LEDS_LED5GreenUSB LEDLowPORTE.4
+ * + * @{ + */ + +#ifndef __LEDS_B1_XPLAINED_H__ +#define __LEDS_B1_XPLAINED_H__ + + /* Includes: */ + #include + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_LEDS_H) + #error Do not include this file directly. Include LUFA/Drivers/Board/LEDS.h instead. + #endif + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Macros: */ + #define LEDS_PORTB_LEDS (LEDS_LED1 | LEDS_LED2 | LEDS_LED3 | LEDS_LED4) + #define LEDS_PORTE_LEDS LEDS_LED5 + + #define LEDS_PORTE_MASK_SHIFT 1 + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** LED mask for the first LED on the board. */ + #define LEDS_LED1 (1 << 4) + + /** LED mask for the second LED on the board. */ + #define LEDS_LED2 (1 << 5) + + /** LED mask for the third LED on the board. */ + #define LEDS_LED3 (1 << 6) + + /** LED mask for the fourth LED on the board. */ + #define LEDS_LED4 (1 << 7) + + /** LED mask for the fifth LED on the board. */ + #define LEDS_LED5 ((1 << 4) >> LEDS_PORTE_MASK_SHIFT) + + /** LED mask for all the LEDs on the board. */ + #define LEDS_ALL_LEDS (LEDS_LED1 | LEDS_LED2 | LEDS_LED3 | LEDS_LED4 | LEDS_LED5) + + /** LED mask for none of the board LEDs. */ + #define LEDS_NO_LEDS 0 + + /* Inline Functions: */ + #if !defined(__DOXYGEN__) + static inline void LEDs_Init(void) + { + PORTB.DIRSET = LEDS_PORTB_LEDS; + PORTB.OUTCLR = LEDS_PORTB_LEDS; + + PORTCFG.MPCMASK = LEDS_PORTB_LEDS; + PORTB.PIN0CTRL = PORT_INVEN_bm; + + PORTE.DIRSET = (LEDS_PORTE_LEDS << LEDS_PORTE_MASK_SHIFT); + PORTE.OUTCLR = (LEDS_PORTE_LEDS << LEDS_PORTE_MASK_SHIFT); + } + + static inline void LEDs_Disable(void) + { + PORTB.DIRCLR = LEDS_PORTB_LEDS; + PORTB.OUTCLR = LEDS_PORTB_LEDS; + + PORTCFG.MPCMASK = 0; + PORTB.PIN0CTRL = LEDS_PORTB_LEDS; + + PORTE.DIRCLR = (LEDS_PORTE_LEDS << LEDS_PORTE_MASK_SHIFT); + PORTE.OUTCLR = (LEDS_PORTE_LEDS << LEDS_PORTE_MASK_SHIFT); + } + + static inline void LEDs_TurnOnLEDs(const uint8_t LEDMask) + { + PORTB_OUTSET = (LEDMask & LEDS_PORTB_LEDS); + PORTE_OUTSET = ((LEDMask & LEDS_PORTE_LEDS) << LEDS_PORTE_MASK_SHIFT); + } + + static inline void LEDs_TurnOffLEDs(const uint8_t LEDMask) + { + PORTB_OUTCLR = (LEDMask & LEDS_PORTB_LEDS); + PORTE_OUTCLR = ((LEDMask & LEDS_PORTE_LEDS) << LEDS_PORTE_MASK_SHIFT); + } + + static inline void LEDs_SetAllLEDs(const uint8_t LEDMask) + { + PORTB_OUTCLR = LEDS_PORTB_LEDS; + PORTE_OUTCLR = (LEDS_PORTE_LEDS << LEDS_PORTE_MASK_SHIFT); + + PORTB_OUTSET = (LEDMask & LEDS_PORTB_LEDS); + PORTE_OUTSET = ((LEDMask & LEDS_PORTE_LEDS) << LEDS_PORTE_MASK_SHIFT); + } + + static inline void LEDs_ChangeLEDs(const uint8_t LEDMask, const uint8_t ActiveMask) + { + PORTB_OUTCLR = (LEDMask & LEDS_PORTB_LEDS); + PORTE_OUTCLR = ((LEDMask & LEDS_PORTE_LEDS) << LEDS_PORTE_MASK_SHIFT); + + PORTB_OUTSET = (ActiveMask & LEDS_PORTB_LEDS); + PORTE_OUTSET = ((ActiveMask & LEDS_PORTE_LEDS) << LEDS_PORTE_MASK_SHIFT); + } + + static inline void LEDs_ToggleLEDs(const uint8_t LEDMask) + { + PORTB_OUTTGL = (LEDMask & LEDS_PORTB_LEDS); + PORTE_OUTTGL = ((LEDMask & LEDS_PORTE_LEDS) << LEDS_PORTE_MASK_SHIFT); + } + + static inline uint8_t LEDs_GetLEDs(void) ATTR_WARN_UNUSED_RESULT; + static inline uint8_t LEDs_GetLEDs(void) + { + return ((PORTB_OUT & LEDS_PORTB_LEDS) | (PORTE_OUT & (LEDS_PORTE_LEDS << LEDS_PORTE_MASK_SHIFT))); + } + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Misc/AT45DB321C.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Misc/AT45DB321C.h new file mode 100644 index 00000000..5c6780f3 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Misc/AT45DB321C.h @@ -0,0 +1,100 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Command constants for the Atmel AT45DB321C Dataflash. + * \copydetails Group_AT45DB321C + */ + +/** \ingroup Group_MiscDrivers + * \defgroup Group_AT45DB321C Atmel AT45DB321C Dataflash Commands + * \brief Command constants for the Atmel AT45DB321C Dataflash. + * + * Dataflash command constants for the Atmel AT45DB321C Dataflash IC. + * + * @{ + */ + +#ifndef __AT45DB321C_CMDS_H__ +#define __AT45DB321C_CMDS_H__ + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** \name Dataflash Status Values */ + //@{ + #define DF_STATUS_READY (1 << 7) + #define DF_STATUS_COMPMISMATCH (1 << 6) + #define DF_STATUS_SECTORPROTECTION_ON (1 << 1) + //@} + + /** \name Dataflash Commands */ + //@{ + #define DF_CMD_GETSTATUS 0xD7 + + #define DF_CMD_MAINMEMTOBUFF1 0x53 + #define DF_CMD_MAINMEMTOBUFF2 0x55 + #define DF_CMD_MAINMEMTOBUFF1COMP 0x60 + #define DF_CMD_MAINMEMTOBUFF2COMP 0x61 + #define DF_CMD_AUTOREWRITEBUFF1 0x58 + #define DF_CMD_AUTOREWRITEBUFF2 0x59 + + #define DF_CMD_MAINMEMPAGEREAD 0xD2 + #define DF_CMD_CONTARRAYREAD_LF 0xE8 + #define DF_CMD_BUFF1READ_LF 0xD4 + #define DF_CMD_BUFF2READ_LF 0xD6 + + #define DF_CMD_BUFF1WRITE 0x84 + #define DF_CMD_BUFF2WRITE 0x87 + #define DF_CMD_BUFF1TOMAINMEMWITHERASE 0x83 + #define DF_CMD_BUFF2TOMAINMEMWITHERASE 0x86 + #define DF_CMD_BUFF1TOMAINMEM 0x88 + #define DF_CMD_BUFF2TOMAINMEM 0x89 + #define DF_CMD_MAINMEMPAGETHROUGHBUFF1 0x82 + #define DF_CMD_MAINMEMPAGETHROUGHBUFF2 0x85 + + #define DF_CMD_PAGEERASE 0x81 + #define DF_CMD_BLOCKERASE 0x50 + + #define DF_CMD_SECTORPROTECTIONOFF ((char[]){0x3D, 0x2A, 0x7F, 0xCF}) + #define DF_CMD_SECTORPROTECTIONOFF_BYTE1 0x3D + #define DF_CMD_SECTORPROTECTIONOFF_BYTE2 0x2A + #define DF_CMD_SECTORPROTECTIONOFF_BYTE3 0x7F + #define DF_CMD_SECTORPROTECTIONOFF_BYTE4 0xCF + + #define DF_CMD_READMANUFACTURERDEVICEINFO 0x9F + //@} + + /** Manufacturer code for Atmel Corporation, returned by Atmel Dataflash ICs in response to the \c DF_CMD_READMANUFACTURERDEVICEINFO command. */ + #define DF_MANUFACTURER_ATMEL 0x1F + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Misc/AT45DB642D.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Misc/AT45DB642D.h new file mode 100644 index 00000000..cbd15d63 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Misc/AT45DB642D.h @@ -0,0 +1,116 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Command constants for the Atmel AT45DB642D Dataflash. + * \copydetails Group_AT45DB642D + */ + +/** \ingroup Group_MiscDrivers + * \defgroup Group_AT45DB642D Atmel AT45DB642D Dataflash Commands + * \brief Command constants for the Atmel AT45DB642D Dataflash. + * + * Dataflash command constants for the Atmel AT45DB642D Dataflash IC. + * + * @{ + */ + +#ifndef __AT45DB642D_CMDS_H__ +#define __AT45DB642D_CMDS_H__ + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** \name Dataflash Status Values */ + //@{ + #define DF_STATUS_READY (1 << 7) + #define DF_STATUS_COMPMISMATCH (1 << 6) + #define DF_STATUS_SECTORPROTECTION_ON (1 << 1) + #define DF_STATUS_BINARYPAGESIZE_ON (1 << 0) + //@} + + /** \name Dataflash Commands */ + //@{ + #define DF_CMD_GETSTATUS 0xD7 + #define DF_CMD_POWERDOWN 0xB9 + #define DF_CMD_WAKEUP 0xAB + + #define DF_CMD_MAINMEMTOBUFF1 0x53 + #define DF_CMD_MAINMEMTOBUFF2 0x55 + #define DF_CMD_MAINMEMTOBUFF1COMP 0x60 + #define DF_CMD_MAINMEMTOBUFF2COMP 0x61 + #define DF_CMD_AUTOREWRITEBUFF1 0x58 + #define DF_CMD_AUTOREWRITEBUFF2 0x59 + + #define DF_CMD_MAINMEMPAGEREAD 0xD2 + #define DF_CMD_CONTARRAYREAD_LF 0x03 + #define DF_CMD_BUFF1READ_LF 0xD1 + #define DF_CMD_BUFF2READ_LF 0xD3 + + #define DF_CMD_BUFF1WRITE 0x84 + #define DF_CMD_BUFF2WRITE 0x87 + #define DF_CMD_BUFF1TOMAINMEMWITHERASE 0x83 + #define DF_CMD_BUFF2TOMAINMEMWITHERASE 0x86 + #define DF_CMD_BUFF1TOMAINMEM 0x88 + #define DF_CMD_BUFF2TOMAINMEM 0x89 + #define DF_CMD_MAINMEMPAGETHROUGHBUFF1 0x82 + #define DF_CMD_MAINMEMPAGETHROUGHBUFF2 0x85 + + #define DF_CMD_PAGEERASE 0x81 + #define DF_CMD_BLOCKERASE 0x50 + #define DF_CMD_SECTORERASE 0x7C + + #define DF_CMD_CHIPERASE ((char[]){0xC7, 0x94, 0x80, 0x9A}) + #define DF_CMD_CHIPERASE_BYTE1 0xC7 + #define DF_CMD_CHIPERASE_BYTE2 0x94 + #define DF_CMD_CHIPERASE_BYTE3 0x80 + #define DF_CMD_CHIPERASE_BYTE4 0x9A + + #define DF_CMD_SECTORPROTECTIONOFF ((char[]){0x3D, 0x2A, 0x7F, 0x9A}) + #define DF_CMD_SECTORPROTECTIONOFF_BYTE1 0x3D + #define DF_CMD_SECTORPROTECTIONOFF_BYTE2 0x2A + #define DF_CMD_SECTORPROTECTIONOFF_BYTE3 0x7F + #define DF_CMD_SECTORPROTECTIONOFF_BYTE4 0x9A + + #define DF_CMD_BINARYPAGESIZEMODEON ((char[]){0x3D, 0x2A, 0x80, 0xA6}) + #define DF_CMD_BINARYPAGESIZEMODEON_BYTE1 0x3D + #define DF_CMD_BINARYPAGESIZEMODEON_BYTE2 0x2A + #define DF_CMD_BINARYPAGESIZEMODEON_BYTE3 0x80 + #define DF_CMD_BINARYPAGESIZEMODEON_BYTE4 0xA6 + + #define DF_CMD_READMANUFACTURERDEVICEINFO 0x9F + //@} + + /** Manufacturer code for Atmel Corporation, returned by Atmel Dataflash ICs in response to the \c DF_CMD_READMANUFACTURERDEVICEINFO command. */ + #define DF_MANUFACTURER_ATMEL 0x1F + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Misc/RingBuffer.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Misc/RingBuffer.h new file mode 100644 index 00000000..6d0f60ff --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Misc/RingBuffer.h @@ -0,0 +1,303 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Lightweight ring (circular) buffer, for fast insertion/deletion of bytes. + * + * Lightweight ring buffer, for fast insertion/deletion. Multiple buffers can be created of + * different sizes to suit different needs. + * + * Note that for each buffer, insertion and removal operations may occur at the same time (via + * a multi-threaded ISR based system) however the same kind of operation (two or more insertions + * or deletions) must not overlap. If there is possibility of two or more of the same kind of + * operating occurring at the same point in time, atomic (mutex) locking should be used. + */ + +/** \ingroup Group_MiscDrivers + * \defgroup Group_RingBuff Generic Byte Ring Buffer - LUFA/Drivers/Misc/RingBuffer.h + * \brief Lightweight ring buffer, for fast insertion/deletion of bytes. + * + * \section Sec_Dependencies Module Source Dependencies + * The following files must be built with any user project that uses this module: + * - None + * + * \section Sec_ModDescription Module Description + * Lightweight ring buffer, for fast insertion/deletion. Multiple buffers can be created of + * different sizes to suit different needs. + * + * Note that for each buffer, insertion and removal operations may occur at the same time (via + * a multi-threaded ISR based system) however the same kind of operation (two or more insertions + * or deletions) must not overlap. If there is possibility of two or more of the same kind of + * operating occurring at the same point in time, atomic (mutex) locking should be used. + * + * \section Sec_ExampleUsage Example Usage + * The following snippet is an example of how this module may be used within a typical + * application. + * + * \code + * // Create the buffer structure and its underlying storage array + * RingBuffer_t Buffer; + * uint8_t BufferData[128]; + * + * // Initialize the buffer with the created storage array + * RingBuffer_InitBuffer(&Buffer, BufferData, sizeof(BufferData)); + * + * // Insert some data into the buffer + * RingBuffer_Insert(Buffer, 'H'); + * RingBuffer_Insert(Buffer, 'E'); + * RingBuffer_Insert(Buffer, 'L'); + * RingBuffer_Insert(Buffer, 'L'); + * RingBuffer_Insert(Buffer, 'O'); + * + * // Cache the number of stored bytes in the buffer + * uint16_t BufferCount = RingBuffer_GetCount(&Buffer); + * + * // Printer stored data length + * printf("Buffer Length: %d, Buffer Data: \r\n", BufferCount); + * + * // Print contents of the buffer one character at a time + * while (BufferCount--) + * putc(RingBuffer_Remove(&Buffer)); + * \endcode + * + * @{ + */ + +#ifndef __RING_BUFFER_H__ +#define __RING_BUFFER_H__ + + /* Includes: */ + #include "../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Type Defines: */ + /** \brief Ring Buffer Management Structure. + * + * Type define for a new ring buffer object. Buffers should be initialized via a call to + * \ref RingBuffer_InitBuffer() before use. + */ + typedef struct + { + uint8_t* In; /**< Current storage location in the circular buffer. */ + uint8_t* Out; /**< Current retrieval location in the circular buffer. */ + uint8_t* Start; /**< Pointer to the start of the buffer's underlying storage array. */ + uint8_t* End; /**< Pointer to the end of the buffer's underlying storage array. */ + uint16_t Size; /**< Size of the buffer's underlying storage array. */ + uint16_t Count; /**< Number of bytes currently stored in the buffer. */ + } RingBuffer_t; + + /* Inline Functions: */ + /** Initializes a ring buffer ready for use. Buffers must be initialized via this function + * before any operations are called upon them. Already initialized buffers may be reset + * by re-initializing them using this function. + * + * \param[out] Buffer Pointer to a ring buffer structure to initialize. + * \param[out] DataPtr Pointer to a global array that will hold the data stored into the ring buffer. + * \param[out] Size Maximum number of bytes that can be stored in the underlying data array. + */ + static inline void RingBuffer_InitBuffer(RingBuffer_t* Buffer, uint8_t* const DataPtr, const uint16_t Size) + ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); + static inline void RingBuffer_InitBuffer(RingBuffer_t* Buffer, uint8_t* const DataPtr, const uint16_t Size) + { + GCC_FORCE_POINTER_ACCESS(Buffer); + + uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask(); + GlobalInterruptDisable(); + + Buffer->In = DataPtr; + Buffer->Out = DataPtr; + Buffer->Start = &DataPtr[0]; + Buffer->End = &DataPtr[Size]; + Buffer->Size = Size; + Buffer->Count = 0; + + SetGlobalInterruptMask(CurrentGlobalInt); + } + + /** Retrieves the current number of bytes stored in a particular buffer. This value is computed + * by entering an atomic lock on the buffer, so that the buffer cannot be modified while the + * computation takes place. This value should be cached when reading out the contents of the buffer, + * so that as small a time as possible is spent in an atomic lock. + * + * \note The value returned by this function is guaranteed to only be the minimum number of bytes + * stored in the given buffer; this value may change as other threads write new data, thus + * the returned number should be used only to determine how many successive reads may safely + * be performed on the buffer. + * + * \param[in] Buffer Pointer to a ring buffer structure whose count is to be computed. + * + * \return Number of bytes currently stored in the buffer. + */ + static inline uint16_t RingBuffer_GetCount(RingBuffer_t* const Buffer) ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1); + static inline uint16_t RingBuffer_GetCount(RingBuffer_t* const Buffer) + { + uint16_t Count; + + uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask(); + GlobalInterruptDisable(); + + Count = Buffer->Count; + + SetGlobalInterruptMask(CurrentGlobalInt); + return Count; + } + + /** Retrieves the free space in a particular buffer. This value is computed by entering an atomic lock + * on the buffer, so that the buffer cannot be modified while the computation takes place. + * + * \note The value returned by this function is guaranteed to only be the maximum number of bytes + * free in the given buffer; this value may change as other threads write new data, thus + * the returned number should be used only to determine how many successive writes may safely + * be performed on the buffer when there is a single writer thread. + * + * \param[in] Buffer Pointer to a ring buffer structure whose free count is to be computed. + * + * \return Number of free bytes in the buffer. + */ + static inline uint16_t RingBuffer_GetFreeCount(RingBuffer_t* const Buffer) ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1); + static inline uint16_t RingBuffer_GetFreeCount(RingBuffer_t* const Buffer) + { + return (Buffer->Size - RingBuffer_GetCount(Buffer)); + } + + /** Atomically determines if the specified ring buffer contains any data. This should + * be tested before removing data from the buffer, to ensure that the buffer does not + * underflow. + * + * If the data is to be removed in a loop, store the total number of bytes stored in the + * buffer (via a call to the \ref RingBuffer_GetCount() function) in a temporary variable + * to reduce the time spent in atomicity locks. + * + * \param[in,out] Buffer Pointer to a ring buffer structure to insert into. + * + * \return Boolean \c true if the buffer contains no free space, false otherwise. + */ + static inline bool RingBuffer_IsEmpty(RingBuffer_t* const Buffer) ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1); + static inline bool RingBuffer_IsEmpty(RingBuffer_t* const Buffer) + { + return (RingBuffer_GetCount(Buffer) == 0); + } + + /** Atomically determines if the specified ring buffer contains any free space. This should + * be tested before storing data to the buffer, to ensure that no data is lost due to a + * buffer overrun. + * + * \param[in,out] Buffer Pointer to a ring buffer structure to insert into. + * + * \return Boolean \c true if the buffer contains no free space, false otherwise. + */ + static inline bool RingBuffer_IsFull(RingBuffer_t* const Buffer) ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1); + static inline bool RingBuffer_IsFull(RingBuffer_t* const Buffer) + { + return (RingBuffer_GetCount(Buffer) == Buffer->Size); + } + + /** Inserts an element into the ring buffer. + * + * \warning Only one execution thread (main program thread or an ISR) may insert into a single buffer + * otherwise data corruption may occur. Insertion and removal may occur from different execution + * threads. + * + * \param[in,out] Buffer Pointer to a ring buffer structure to insert into. + * \param[in] Data Data element to insert into the buffer. + */ + static inline void RingBuffer_Insert(RingBuffer_t* Buffer, const uint8_t Data) ATTR_NON_NULL_PTR_ARG(1); + static inline void RingBuffer_Insert(RingBuffer_t* Buffer, const uint8_t Data) + { + GCC_FORCE_POINTER_ACCESS(Buffer); + + *Buffer->In = Data; + + if (++Buffer->In == Buffer->End) + Buffer->In = Buffer->Start; + + uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask(); + GlobalInterruptDisable(); + + Buffer->Count++; + + SetGlobalInterruptMask(CurrentGlobalInt); + } + + /** Removes an element from the ring buffer. + * + * \warning Only one execution thread (main program thread or an ISR) may remove from a single buffer + * otherwise data corruption may occur. Insertion and removal may occur from different execution + * threads. + * + * \param[in,out] Buffer Pointer to a ring buffer structure to retrieve from. + * + * \return Next data element stored in the buffer. + */ + static inline uint8_t RingBuffer_Remove(RingBuffer_t* Buffer) ATTR_NON_NULL_PTR_ARG(1); + static inline uint8_t RingBuffer_Remove(RingBuffer_t* Buffer) + { + GCC_FORCE_POINTER_ACCESS(Buffer); + + uint8_t Data = *Buffer->Out; + + if (++Buffer->Out == Buffer->End) + Buffer->Out = Buffer->Start; + + uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask(); + GlobalInterruptDisable(); + + Buffer->Count--; + + SetGlobalInterruptMask(CurrentGlobalInt); + + return Data; + } + + /** Returns the next element stored in the ring buffer, without removing it. + * + * \param[in,out] Buffer Pointer to a ring buffer structure to retrieve from. + * + * \return Next data element stored in the buffer. + */ + static inline uint8_t RingBuffer_Peek(RingBuffer_t* const Buffer) ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1); + static inline uint8_t RingBuffer_Peek(RingBuffer_t* const Buffer) + { + return *Buffer->Out; + } + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Misc/TerminalCodes.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Misc/TerminalCodes.h new file mode 100644 index 00000000..2f71a84b --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Misc/TerminalCodes.h @@ -0,0 +1,231 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief ANSI terminal special escape code macros. + * + * ANSI terminal compatible escape sequences. These escape sequences are designed to be concatenated with existing + * strings to modify their display on a compatible terminal application. + */ + +/** \ingroup Group_MiscDrivers + * \defgroup Group_Terminal ANSI Terminal Escape Codes - LUFA/Drivers/Misc/TerminalCodes.h + * \brief ANSI terminal special escape code macros. + * + * \section Sec_Dependencies Module Source Dependencies + * The following files must be built with any user project that uses this module: + * - None + * + * \section Sec_ModDescription Module Description + * Escape code macros for ANSI compliant text terminals. + * + * \note If desired, the macro \c DISABLE_TERMINAL_CODES can be defined in the project makefile and passed to the GCC + * compiler via the -D switch to disable the terminal codes without modifying the source, for use with non + * compatible terminals (any terminal codes then equate to empty strings). + * + * \section Sec_ExampleUsage Example Usage + * The following snippet is an example of how this module may be used within a typical + * application. + * + * \code + * printf("Normal String, " + * ESC_BOLD_ON "Bold String, " + * ESC_UNDERLINE_ON "Bold and Underlined String" + * ESC_RESET ESC_FG_BLUE ESC_BG_YELLOW "Normal Blue-on-Yellow String"); + * \endcode + * + * @{ + */ + +#ifndef __TERMINALCODES_H__ +#define __TERMINALCODES_H__ + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + #if !defined(DISABLE_TERMINAL_CODES) + /** Creates an ANSI escape sequence with the specified payload. + * + * \param[in] EscapeSeq Payload to encode as an ANSI escape sequence, a \c ESC_* mask. + */ + #define ANSI_ESCAPE_SEQUENCE(EscapeSeq) "\33[" EscapeSeq + #else + #define ANSI_ESCAPE_SEQUENCE(EscapeSeq) + #endif + + /** \name Text Display Modifier Control Sequences */ + //@{ + /** Turns on bold so that any following text is printed to the terminal in bold. */ + #define ESC_BOLD_ON ANSI_ESCAPE_SEQUENCE("1m") + + /** Turns on italics so that any following text is printed to the terminal in italics. */ + #define ESC_ITALICS_ON ANSI_ESCAPE_SEQUENCE("3m") + + /** Turns on underline so that any following text is printed to the terminal underlined. */ + #define ESC_UNDERLINE_ON ANSI_ESCAPE_SEQUENCE("4m") + + /** Turns on inverse so that any following text is printed to the terminal in inverted colours. */ + #define ESC_INVERSE_ON ANSI_ESCAPE_SEQUENCE("7m") + + /** Turns on strikethrough so that any following text is printed to the terminal with a line through the + * center. + */ + #define ESC_STRIKETHROUGH_ON ANSI_ESCAPE_SEQUENCE("9m") + + /** Turns off bold so that any following text is printed to the terminal in non bold. */ + #define ESC_BOLD_OFF ANSI_ESCAPE_SEQUENCE("22m") + + /** Turns off italics so that any following text is printed to the terminal in non italics. */ + #define ESC_ITALICS_OFF ANSI_ESCAPE_SEQUENCE("23m") + + /** Turns off underline so that any following text is printed to the terminal non underlined. */ + #define ESC_UNDERLINE_OFF ANSI_ESCAPE_SEQUENCE("24m") + + /** Turns off inverse so that any following text is printed to the terminal in non inverted colours. */ + #define ESC_INVERSE_OFF ANSI_ESCAPE_SEQUENCE("27m") + + /** Turns off strikethrough so that any following text is printed to the terminal without a line through + * the center. + */ + #define ESC_STRIKETHROUGH_OFF ANSI_ESCAPE_SEQUENCE("29m") + //@} + + /** \name Text Colour Control Sequences */ + //@{ + /** Sets the foreground (text) colour to black. */ + #define ESC_FG_BLACK ANSI_ESCAPE_SEQUENCE("30m") + + /** Sets the foreground (text) colour to red. */ + #define ESC_FG_RED ANSI_ESCAPE_SEQUENCE("31m") + + /** Sets the foreground (text) colour to green. */ + #define ESC_FG_GREEN ANSI_ESCAPE_SEQUENCE("32m") + + /** Sets the foreground (text) colour to yellow. */ + #define ESC_FG_YELLOW ANSI_ESCAPE_SEQUENCE("33m") + + /** Sets the foreground (text) colour to blue. */ + #define ESC_FG_BLUE ANSI_ESCAPE_SEQUENCE("34m") + + /** Sets the foreground (text) colour to magenta. */ + #define ESC_FG_MAGENTA ANSI_ESCAPE_SEQUENCE("35m") + + /** Sets the foreground (text) colour to cyan. */ + #define ESC_FG_CYAN ANSI_ESCAPE_SEQUENCE("36m") + + /** Sets the foreground (text) colour to white. */ + #define ESC_FG_WHITE ANSI_ESCAPE_SEQUENCE("37m") + + /** Sets the foreground (text) colour to the terminal's default. */ + #define ESC_FG_DEFAULT ANSI_ESCAPE_SEQUENCE("39m") + + /** Sets the text background colour to black. */ + #define ESC_BG_BLACK ANSI_ESCAPE_SEQUENCE("40m") + + /** Sets the text background colour to red. */ + #define ESC_BG_RED ANSI_ESCAPE_SEQUENCE("41m") + + /** Sets the text background colour to green. */ + #define ESC_BG_GREEN ANSI_ESCAPE_SEQUENCE("42m") + + /** Sets the text background colour to yellow. */ + #define ESC_BG_YELLOW ANSI_ESCAPE_SEQUENCE("43m") + + /** Sets the text background colour to blue. */ + #define ESC_BG_BLUE ANSI_ESCAPE_SEQUENCE("44m") + + /** Sets the text background colour to magenta. */ + #define ESC_BG_MAGENTA ANSI_ESCAPE_SEQUENCE("45m") + + /** Sets the text background colour to cyan. */ + #define ESC_BG_CYAN ANSI_ESCAPE_SEQUENCE("46m") + + /** Sets the text background colour to white. */ + #define ESC_BG_WHITE ANSI_ESCAPE_SEQUENCE("47m") + + /** Sets the text background colour to the terminal's default. */ + #define ESC_BG_DEFAULT ANSI_ESCAPE_SEQUENCE("49m") + //@} + + /** \name Cursor Positioning Control Sequences */ + //@{ + /** Saves the current cursor position so that it may be restored with \ref ESC_CURSOR_POS_RESTORE. */ + #define ESC_CURSOR_POS_SAVE ANSI_ESCAPE_SEQUENCE("s") + + /** Restores the cursor position to the last position saved with \ref ESC_CURSOR_POS_SAVE. */ + #define ESC_CURSOR_POS_RESTORE ANSI_ESCAPE_SEQUENCE("u") + + /** Sets the cursor position to the given line and column. + * + * \param[in] Line Line number to position the cursor at. + * \param[in] Column Column number to position the cursor at. + */ + #define ESC_CURSOR_POS(Line, Column) ANSI_ESCAPE_SEQUENCE(#Line ";" #Column "H") + + /** Moves the cursor up the given number of lines. + * + * \param[in] Lines Number of lines to move the cursor position + */ + #define ESC_CURSOR_UP(Lines) ANSI_ESCAPE_SEQUENCE(#Lines "A") + + /** Moves the cursor down the given number of lines. + * + * \param[in] Lines Number of lines to move the cursor position + */ + #define ESC_CURSOR_DOWN(Lines) ANSI_ESCAPE_SEQUENCE(#Lines "B") + + /** Moves the cursor to the right the given number of columns. + * + * \param[in] Columns Number of columns to move the cursor position + */ + #define ESC_CURSOR_FORWARD(Columns) ANSI_ESCAPE_SEQUENCE(#Columns "C") + + /** Moves the cursor to the left the given number of columns. + * + * \param[in] Columns Number of columns to move the cursor position + */ + #define ESC_CURSOR_BACKWARD(Columns) ANSI_ESCAPE_SEQUENCE(#Columns "D") + //@} + + /** \name Miscellaneous Control Sequences */ + //@{ + /** Resets any escape sequence modifiers back to their defaults. */ + #define ESC_RESET ANSI_ESCAPE_SEQUENCE("0m") + + /** Erases the entire display, returning the cursor to the top left. */ + #define ESC_ERASE_DISPLAY ANSI_ESCAPE_SEQUENCE("2J") + + /** Erases the current line, returning the cursor to the far left. */ + #define ESC_ERASE_LINE ANSI_ESCAPE_SEQUENCE("K") + //@} + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/ADC.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/ADC.h new file mode 100644 index 00000000..ebce11b3 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/ADC.h @@ -0,0 +1,75 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Hardware Analogue-to-Digital converter driver. + * + * This file is the master dispatch header file for the device-specific ADC driver, for microcontrollers + * containing an ADC. + * + * User code should include this file, which will in turn include the correct ADC driver header file for the + * currently selected architecture and microcontroller model. + */ + +/** \ingroup Group_PeripheralDrivers + * \defgroup Group_ADC ADC Driver - LUFA/Drivers/Peripheral/ADC.h + * \brief Hardware Analogue-to-Digital converter driver. + * + * \section Sec_Dependencies Module Source Dependencies + * The following files must be built with any user project that uses this module: + * - None + * + * \section Sec_ModDescription Module Description + * Hardware ADC driver. This module provides an easy to use driver for the hardware ADC + * present on many microcontrollers, for the conversion of analogue signals into the + * digital domain. + * + * \note The exact API for this driver may vary depending on the target used - see + * individual target module documentation for the API specific to your target processor. + */ + +#ifndef __ADC_H__ +#define __ADC_H__ + + /* Macros: */ + #define __INCLUDE_FROM_ADC_H + + /* Includes: */ + #include "../../Common/Common.h" + + /* Includes: */ + #if (ARCH == ARCH_AVR8) + #include "AVR8/ADC_AVR8.h" + #else + #error The ADC peripheral driver is not currently available for your selected architecture. + #endif + +#endif + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/AVR8/ADC_AVR8.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/AVR8/ADC_AVR8.h new file mode 100644 index 00000000..c002f79f --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/AVR8/ADC_AVR8.h @@ -0,0 +1,456 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief ADC Peripheral Driver (AVR8) + * + * On-chip Analogue-to-Digital converter (ADC) driver for supported U4, U6 and U7 model AVRs that contain an ADC + * peripheral internally. + * + * \note This file should not be included directly. It is automatically included as needed by the ADC driver + * dispatch header located in LUFA/Drivers/Peripheral/ADC.h. + */ + +/** \ingroup Group_ADC + * \defgroup Group_ADC_AVR8 ADC Peripheral Driver (AVR8) + * + * \section Sec_ModDescription Module Description + * On-chip Analogue-to-Digital converter (ADC) driver for supported U4, U6 and U7 model AVRs that contain an ADC + * peripheral internally. + * + * \note This file should not be included directly. It is automatically included as needed by the ADC driver + * dispatch header located in LUFA/Drivers/Peripheral/ADC.h. + * + * \section Sec_ExampleUsage Example Usage + * The following snippet is an example of how this module may be used within a typical + * application. + * + * \code + * // Initialize the ADC driver before first use + * ADC_Init(ADC_FREE_RUNNING | ADC_PRESCALE_32); + * + * // Must setup the ADC channel to read beforehand + * ADC_SetupChannel(1); + * + * // Perform a single conversion of the ADC channel 1 + * ADC_GetChannelReading(ADC_REFERENCE_AVCC | ADC_RIGHT_ADJUSTED | ADC_CHANNEL1); + * printf("Conversion Result: %d\r\n", ADC_GetResult()); + * + * // Start reading ADC channel 1 in free running (continuous conversion) mode + * ADC_StartReading(ADC_REFERENCE_AVCC | ADC_RIGHT_ADJUSTED | ADC_CHANNEL1); + * for (;;) + * { + * while (!(ADC_IsReadingComplete())) {}; + * printf("Conversion Result: %d\r\n", ADC_GetResult()); + * } + * \endcode + * + * @{ + */ + +#ifndef __ADC_AVR8_H__ +#define __ADC_AVR8_H__ + + /* Includes: */ + #include "../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_ADC_H) + #error Do not include this file directly. Include LUFA/Drivers/Peripheral/ADC.h instead. + #endif + + #if !(defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB646__) || \ + defined(__AVR_AT90USB1287__) || defined(__AVR_AT90USB647__) || \ + defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__) || \ + defined(__AVR_ATmega32U6__)) + #error The ADC peripheral driver is not currently available for your selected microcontroller model. + #endif + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Macros: */ + #define _ADC_GET_MUX_MASK2(y) ADC_CHANNEL ## y + #define _ADC_GET_MUX_MASK(y) _ADC_GET_MUX_MASK2(y) + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** \name ADC Reference Configuration Masks */ + //@{ + /** Reference mask, for using the voltage present at the AVR's AREF pin for the ADC reference. */ + #define ADC_REFERENCE_AREF 0 + + /** Reference mask, for using the voltage present at the AVR's AVCC pin for the ADC reference. */ + #define ADC_REFERENCE_AVCC (1 << REFS0) + + /** Reference mask, for using the internally generated 2.56V reference voltage as the ADC reference. */ + #define ADC_REFERENCE_INT2560MV ((1 << REFS1) | (1 << REFS0)) + //@} + + /** \name ADC Result Adjustment Configuration Masks */ + //@{ + /** Left-adjusts the 10-bit ADC result, so that the upper 8 bits of the value returned by the + * \ref ADC_GetResult() macro contain the 8 most significant bits of the result. + */ + #define ADC_LEFT_ADJUSTED (1 << ADLAR) + + /** Right-adjusts the 10-bit ADC result, so that the lower 8 bits of the value returned by the + * \ref ADC_GetResult() macro contain the 8 least significant bits of the result. + */ + #define ADC_RIGHT_ADJUSTED (0 << ADLAR) + //@} + + /** \name ADC Mode Configuration Masks */ + //@{ + /** Sets the ADC mode to free running, so that conversions take place continuously as fast as the ADC + * is capable of at the given input clock speed. + */ + #define ADC_FREE_RUNNING (1 << ADATE) + + /** Sets the ADC mode to single conversion, so that only a single conversion will take place before + * the ADC returns to idle. + */ + #define ADC_SINGLE_CONVERSION (0 << ADATE) + //@} + + /** \name ADC Prescaler Configuration Masks */ + //@{ + /** Sets the ADC input clock to prescale by a factor of 2 the AVR's system clock. */ + #define ADC_PRESCALE_2 (1 << ADPS0) + + /** Sets the ADC input clock to prescale by a factor of 4 the AVR's system clock. */ + #define ADC_PRESCALE_4 (1 << ADPS1) + + /** Sets the ADC input clock to prescale by a factor of 8 the AVR's system clock. */ + #define ADC_PRESCALE_8 ((1 << ADPS0) | (1 << ADPS1)) + + /** Sets the ADC input clock to prescale by a factor of 16 the AVR's system clock. */ + #define ADC_PRESCALE_16 (1 << ADPS2) + + /** Sets the ADC input clock to prescale by a factor of 32 the AVR's system clock. */ + #define ADC_PRESCALE_32 ((1 << ADPS2) | (1 << ADPS0)) + + /** Sets the ADC input clock to prescale by a factor of 64 the AVR's system clock. */ + #define ADC_PRESCALE_64 ((1 << ADPS2) | (1 << ADPS1)) + + /** Sets the ADC input clock to prescale by a factor of 128 the AVR's system clock. */ + #define ADC_PRESCALE_128 ((1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0)) + //@} + + /** \name ADC MUX Masks */ + //@{ + /** MUX mask define for the ADC0 channel of the ADC. See \ref ADC_StartReading() and \ref ADC_GetChannelReading(). */ + #define ADC_CHANNEL0 (0x00 << MUX0) + + /** MUX mask define for the ADC1 channel of the ADC. See \ref ADC_StartReading() and \ref ADC_GetChannelReading(). */ + #define ADC_CHANNEL1 (0x01 << MUX0) + + #if (!(defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__)) || defined(__DOXYGEN__)) + /** MUX mask define for the ADC2 channel of the ADC. See \ref ADC_StartReading() and \ref ADC_GetChannelReading(). + * + * \note Not available on all AVR models. + */ + #define ADC_CHANNEL2 (0x02 << MUX0) + + /** MUX mask define for the ADC3 channel of the ADC. See \ref ADC_StartReading() and \ref ADC_GetChannelReading(). + * + * \note Not available on all AVR models. + */ + #define ADC_CHANNEL3 (0x03 << MUX0) + #endif + + /** MUX mask define for the ADC4 channel of the ADC. See \ref ADC_StartReading() and \ref ADC_GetChannelReading(). */ + #define ADC_CHANNEL4 (0x04 << MUX0) + + /** MUX mask define for the ADC5 channel of the ADC. See \ref ADC_StartReading() and \ref ADC_GetChannelReading(). */ + #define ADC_CHANNEL5 (0x05 << MUX0) + + /** MUX mask define for the ADC6 channel of the ADC. See \ref ADC_StartReading() and \ref ADC_GetChannelReading(). */ + #define ADC_CHANNEL6 (0x06 << MUX0) + + /** MUX mask define for the ADC7 channel of the ADC. See \ref ADC_StartReading and \ref ADC_GetChannelReading. */ + #define ADC_CHANNEL7 (0x07 << MUX0) + + #if (defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__) || defined(__DOXYGEN__)) + /** MUX mask define for the ADC8 channel of the ADC. See \ref ADC_StartReading() and \ref ADC_GetChannelReading(). + * + * \note Not available on all AVR models. + */ + #define ADC_CHANNEL8 ((1 << 8) | (0x00 << MUX0)) + + /** MUX mask define for the ADC9 channel of the ADC. See \ref ADC_StartReading() and \ref ADC_GetChannelReading(). + * + * \note Not available on all AVR models. + */ + #define ADC_CHANNEL9 ((1 << 8) | (0x01 << MUX0)) + + /** MUX mask define for the ADC10 channel of the ADC. See \ref ADC_StartReading() and \ref ADC_GetChannelReading(). + * + * \note Not available on all AVR models. + */ + #define ADC_CHANNEL10 ((1 << 8) | (0x02 << MUX0)) + + /** MUX mask define for the ADC11 channel of the ADC. See \ref ADC_StartReading() and \ref ADC_GetChannelReading(). + * + * \note Not available on all AVR models. + */ + #define ADC_CHANNEL11 ((1 << 8) | (0x03 << MUX0)) + + /** MUX mask define for the ADC12 channel of the ADC. See \ref ADC_StartReading() and \ref ADC_GetChannelReading(). + * + * \note Not available on all AVR models. + */ + #define ADC_CHANNEL12 ((1 << 8) | (0x04 << MUX0)) + + /** MUX mask define for the ADC13 channel of the ADC. See \ref ADC_StartReading() and \ref ADC_GetChannelReading(). + * + * \note Not available on all AVR models. + */ + #define ADC_CHANNEL13 ((1 << 8) | (0x05 << MUX0)) + + /** MUX mask define for the internal temperature sensor channel of the ADC. See \ref ADC_StartReading() and + * \ref ADC_GetChannelReading(). + * + * \note Not available on all AVR models. + */ + #define ADC_INT_TEMP_SENS ((1 << 8) | (0x07 << MUX0)) + #endif + + /** MUX mask define for the internal 1.1V band-gap channel of the ADC. See \ref ADC_StartReading() and \ref ADC_GetChannelReading(). */ + #define ADC_1100MV_BANDGAP (0x1E << MUX0) + + /** Retrieves the ADC MUX mask for the given ADC channel number. + * + * \attention This macro will only work correctly on channel numbers that are compile-time + * constants defined by the preprocessor. + * + * \param[in] Channel Index of the ADC channel whose MUX mask is to be retrieved. + */ + #define ADC_GET_CHANNEL_MASK(Channel) _ADC_GET_MUX_MASK(Channel) + //@} + + /* Inline Functions: */ + /** Configures the given ADC channel, ready for ADC conversions. This function sets the + * associated port pin as an input and disables the digital portion of the I/O to reduce + * power consumption. + * + * \note This must only be called for ADC channels with are connected to a physical port + * pin of the AVR, denoted by its special alternative function ADCx. + * + * \warning The channel number must be specified as an integer, and not a \c ADC_CHANNEL* mask. + * + * \param[in] ChannelIndex ADC channel number to set up for conversions. + */ + static inline void ADC_SetupChannel(const uint8_t ChannelIndex) + { + #if (defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB646__) || \ + defined(__AVR_AT90USB1287__) || defined(__AVR_AT90USB647__) || \ + defined(__AVR_ATmega32U6__)) + DDRF &= ~(1 << ChannelIndex); + DIDR0 |= (1 << ChannelIndex); + #elif (defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__)) + if (ChannelIndex < 8) + { + DDRF &= ~(1 << ChannelIndex); + DIDR0 |= (1 << ChannelIndex); + } + else if (ChannelIndex == 8) + { + DDRD &= ~(1 << 4); + DIDR2 |= (1 << 0); + } + else if (ChannelIndex < 11) + { + DDRD &= ~(1 << (ChannelIndex - 3)); + DIDR2 |= (1 << (ChannelIndex - 8)); + } + else + { + DDRB &= ~(1 << (ChannelIndex - 7)); + DIDR2 |= (1 << (ChannelIndex - 8)); + } + #endif + } + + /** De-configures the given ADC channel, re-enabling digital I/O mode instead of analog. This + * function sets the associated port pin as an input and re-enabled the digital portion of + * the I/O. + * + * \note This must only be called for ADC channels with are connected to a physical port + * pin of the AVR, denoted by its special alternative function ADCx. + * + * \warning The channel number must be specified as an integer, and not a \c ADC_CHANNEL* mask. + * + * \param[in] ChannelIndex ADC channel number to set up for conversions. + */ + static inline void ADC_DisableChannel(const uint8_t ChannelIndex) + { + #if (defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB646__) || \ + defined(__AVR_AT90USB1287__) || defined(__AVR_AT90USB647__) || \ + defined(__AVR_ATmega32U6__)) + DDRF &= ~(1 << ChannelIndex); + DIDR0 &= ~(1 << ChannelIndex); + #elif (defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__)) + if (ChannelIndex < 8) + { + DDRF &= ~(1 << ChannelIndex); + DIDR0 &= ~(1 << ChannelIndex); + } + else if (ChannelIndex == 8) + { + DDRD &= ~(1 << 4); + DIDR2 &= ~(1 << 0); + } + else if (ChannelIndex < 11) + { + DDRD &= ~(1 << (ChannelIndex - 3)); + DIDR2 &= ~(1 << (ChannelIndex - 8)); + } + else + { + DDRB &= ~(1 << (ChannelIndex - 7)); + DIDR2 &= ~(1 << (ChannelIndex - 8)); + } + #endif + } + + /** Starts the reading of the given channel, but does not wait until the conversion has completed. + * Once executed, the conversion status can be determined via the \ref ADC_IsReadingComplete() macro and + * the result read via the \ref ADC_GetResult() macro. + * + * If the ADC has been initialized in free running mode, calling this function once will begin the repeated + * conversions. If the ADC is in single conversion mode (or the channel to convert from is to be changed), + * this function must be called each time a conversion is to take place. + * + * \param[in] MUXMask ADC channel mask, reference mask and adjustment mask. + */ + static inline void ADC_StartReading(const uint16_t MUXMask) + { + ADMUX = MUXMask; + + #if (defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__) || defined(__DOXYGEN__)) + if (MUXMask & (1 << 8)) + ADCSRB |= (1 << MUX5); + else + ADCSRB &= ~(1 << MUX5); + #endif + + ADCSRA |= (1 << ADSC); + } + + /** Indicates if the current ADC conversion is completed, or still in progress. + * + * \return Boolean false if the reading is still taking place, or true if the conversion is + * complete and ready to be read out with \ref ADC_GetResult(). + */ + static inline bool ADC_IsReadingComplete(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool ADC_IsReadingComplete(void) + { + return ((ADCSRA & (1 << ADIF)) ? true : false); + } + + /** Retrieves the conversion value of the last completed ADC conversion and clears the reading + * completion flag. + * + * \return The result of the last ADC conversion as an unsigned value. + */ + static inline uint16_t ADC_GetResult(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint16_t ADC_GetResult(void) + { + ADCSRA |= (1 << ADIF); + return ADC; + } + + /** Performs a complete single reading from channel, including a polling spin-loop to wait for the + * conversion to complete, and the returning of the converted value. + * + * \note For free running mode, the automated conversions should be initialized with a single call + * to \ref ADC_StartReading() to select the channel and begin the automated conversions, and + * the results read directly from the \ref ADC_GetResult() instead to reduce overhead. + * + * \param[in] MUXMask Mask comprising of an ADC channel mask, reference mask and adjustment mask. + * + * \return Converted ADC result for the given ADC channel. + */ + static inline uint16_t ADC_GetChannelReading(const uint16_t MUXMask) ATTR_WARN_UNUSED_RESULT; + static inline uint16_t ADC_GetChannelReading(const uint16_t MUXMask) + { + ADC_StartReading(MUXMask); + + while (!(ADC_IsReadingComplete())); + + return ADC_GetResult(); + } + + /** Initializes the ADC, ready for conversions. This must be called before any other ADC operations. + * The "mode" parameter should be a mask comprised of a conversion mode (free running or single) and + * prescaler masks. + * + * \param[in] Mode Mask of ADC prescale and mode settings. + */ + static inline void ADC_Init(const uint8_t Mode) ATTR_ALWAYS_INLINE; + static inline void ADC_Init(const uint8_t Mode) + { + ADCSRA = ((1 << ADEN) | Mode); + } + + /** Turns off the ADC. If this is called, any further ADC operations will require a call to + * \ref ADC_Init() before the ADC can be used again. + */ + static inline void ADC_Disable(void) ATTR_ALWAYS_INLINE; + static inline void ADC_Disable(void) + { + ADCSRA = 0; + } + + /** Indicates if the ADC is currently enabled. + * + * \return Boolean \c true if the ADC subsystem is currently enabled, \c false otherwise. + */ + static inline bool ADC_GetStatus(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool ADC_GetStatus(void) + { + return ((ADCSRA & (1 << ADEN)) ? true : false); + } + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/AVR8/SPI_AVR8.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/AVR8/SPI_AVR8.h new file mode 100644 index 00000000..dde3ec5a --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/AVR8/SPI_AVR8.h @@ -0,0 +1,256 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief SPI Peripheral Driver (AVR8) + * + * On-chip SPI driver for the 8-bit AVR microcontrollers. + * + * \note This file should not be included directly. It is automatically included as needed by the SPI driver + * dispatch header located in LUFA/Drivers/Peripheral/SPI.h. + */ + +/** \ingroup Group_SPI + * \defgroup Group_SPI_AVR8 SPI Peripheral Driver (AVR8) + * + * \section Sec_ModDescription Module Description + * Driver for the hardware SPI port available on most 8-bit AVR microcontroller models. This + * module provides an easy to use driver for the setup and transfer of data over the + * AVR's SPI port. + * + * \note This file should not be included directly. It is automatically included as needed by the SPI driver + * dispatch header located in LUFA/Drivers/Peripheral/SPI.h. + * + * \section Sec_ExampleUsage Example Usage + * The following snippet is an example of how this module may be used within a typical + * application. + * + * \code + * // Initialize the SPI driver before first use + * SPI_Init(SPI_SPEED_FCPU_DIV_2 | SPI_ORDER_MSB_FIRST | SPI_SCK_LEAD_FALLING | + * SPI_SAMPLE_TRAILING | SPI_MODE_MASTER); + * + * // Send several bytes, ignoring the returned data + * SPI_SendByte(0x01); + * SPI_SendByte(0x02); + * SPI_SendByte(0x03); + * + * // Receive several bytes, sending a dummy 0x00 byte each time + * uint8_t Byte1 = SPI_ReceiveByte(); + * uint8_t Byte2 = SPI_ReceiveByte(); + * uint8_t Byte3 = SPI_ReceiveByte(); + * + * // Send a byte, and store the received byte from the same transaction + * uint8_t ResponseByte = SPI_TransferByte(0xDC); + * \endcode + * + * @{ + */ + +#ifndef __SPI_AVR8_H__ +#define __SPI_AVR8_H__ + + /* Includes: */ + #include "../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_SPI_H) + #error Do not include this file directly. Include LUFA/Drivers/Peripheral/SPI.h instead. + #endif + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Macros: */ + #define SPI_USE_DOUBLESPEED (1 << SPE) + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** \name SPI Prescaler Configuration Masks */ + //@{ + /** SPI prescaler mask for \ref SPI_Init(). Divides the system clock by a factor of 2. */ + #define SPI_SPEED_FCPU_DIV_2 SPI_USE_DOUBLESPEED + + /** SPI prescaler mask for \ref SPI_Init(). Divides the system clock by a factor of 4. */ + #define SPI_SPEED_FCPU_DIV_4 0 + + /** SPI prescaler mask for \ref SPI_Init(). Divides the system clock by a factor of 8. */ + #define SPI_SPEED_FCPU_DIV_8 (SPI_USE_DOUBLESPEED | (1 << SPR0)) + + /** SPI prescaler mask for \ref SPI_Init(). Divides the system clock by a factor of 16. */ + #define SPI_SPEED_FCPU_DIV_16 (1 << SPR0) + + /** SPI prescaler mask for \ref SPI_Init(). Divides the system clock by a factor of 32. */ + #define SPI_SPEED_FCPU_DIV_32 (SPI_USE_DOUBLESPEED | (1 << SPR1)) + + /** SPI prescaler mask for \ref SPI_Init(). Divides the system clock by a factor of 64. */ + #define SPI_SPEED_FCPU_DIV_64 (SPI_USE_DOUBLESPEED | (1 << SPR1) | (1 << SPR0)) + + /** SPI prescaler mask for \ref SPI_Init(). Divides the system clock by a factor of 128. */ + #define SPI_SPEED_FCPU_DIV_128 ((1 << SPR1) | (1 << SPR0)) + //@} + + /** \name SPI SCK Polarity Configuration Masks */ + //@{ + /** SPI clock polarity mask for \ref SPI_Init(). Indicates that the SCK should lead on the rising edge. */ + #define SPI_SCK_LEAD_RISING (0 << CPOL) + + /** SPI clock polarity mask for \ref SPI_Init(). Indicates that the SCK should lead on the falling edge. */ + #define SPI_SCK_LEAD_FALLING (1 << CPOL) + //@} + + /** \name SPI Sample Edge Configuration Masks */ + //@{ + /** SPI data sample mode mask for \ref SPI_Init(). Indicates that the data should sampled on the leading edge. */ + #define SPI_SAMPLE_LEADING (0 << CPHA) + + /** SPI data sample mode mask for \ref SPI_Init(). Indicates that the data should be sampled on the trailing edge. */ + #define SPI_SAMPLE_TRAILING (1 << CPHA) + //@} + + /** \name SPI Data Ordering Configuration Masks */ + //@{ + /** SPI data order mask for \ref SPI_Init(). Indicates that data should be shifted out MSB first. */ + #define SPI_ORDER_MSB_FIRST (0 << DORD) + + /** SPI data order mask for \ref SPI_Init(). Indicates that data should be shifted out LSB first. */ + #define SPI_ORDER_LSB_FIRST (1 << DORD) + //@} + + /** \name SPI Mode Configuration Masks */ + //@{ + /** SPI mode mask for \ref SPI_Init(). Indicates that the SPI interface should be initialized into slave mode. */ + #define SPI_MODE_SLAVE (0 << MSTR) + + /** SPI mode mask for \ref SPI_Init(). Indicates that the SPI interface should be initialized into master mode. */ + #define SPI_MODE_MASTER (1 << MSTR) + //@} + + /* Inline Functions: */ + /** Initializes the SPI subsystem, ready for transfers. Must be called before calling any other + * SPI routines. + * + * \param[in] SPIOptions SPI Options, a mask consisting of one of each of the \c SPI_SPEED_*, + * \c SPI_SCK_*, \c SPI_SAMPLE_*, \c SPI_ORDER_* and \c SPI_MODE_* masks. + */ + static inline void SPI_Init(const uint8_t SPIOptions) + { + /* Prevent high rise times on PB.0 (/SS) from forcing a change to SPI slave mode */ + DDRB |= (1 << 0); + PORTB |= (1 << 0); + + DDRB |= ((1 << 1) | (1 << 2)); + DDRB &= ~(1 << 3); + PORTB |= (1 << 3); + + if (SPIOptions & SPI_USE_DOUBLESPEED) + SPSR |= (1 << SPI2X); + else + SPSR &= ~(1 << SPI2X); + + /* Switch /SS to input mode after configuration to allow for forced mode changes */ + DDRB &= ~(1 << 0); + + SPCR = ((1 << SPE) | SPIOptions); + } + + /** Turns off the SPI driver, disabling and returning used hardware to their default configuration. */ + static inline void SPI_Disable(void) + { + DDRB &= ~((1 << 1) | (1 << 2)); + PORTB &= ~((1 << 0) | (1 << 3)); + + SPCR = 0; + SPSR = 0; + } + + /** Retrieves the currently selected SPI mode, once the SPI interface has been configured. + * + * \return \ref SPI_MODE_MASTER if the interface is currently in SPI Master mode, \ref SPI_MODE_SLAVE otherwise + */ + static inline uint8_t SPI_GetCurrentMode(void) ATTR_ALWAYS_INLINE; + static inline uint8_t SPI_GetCurrentMode(void) + { + return (SPCR & SPI_MODE_MASTER); + } + + /** Sends and receives a byte through the SPI interface, blocking until the transfer is complete. + * + * \param[in] Byte Byte to send through the SPI interface. + * + * \return Response byte from the attached SPI device. + */ + static inline uint8_t SPI_TransferByte(const uint8_t Byte) ATTR_ALWAYS_INLINE; + static inline uint8_t SPI_TransferByte(const uint8_t Byte) + { + SPDR = Byte; + while (!(SPSR & (1 << SPIF))); + return SPDR; + } + + /** Sends a byte through the SPI interface, blocking until the transfer is complete. The response + * byte sent to from the attached SPI device is ignored. + * + * \param[in] Byte Byte to send through the SPI interface. + */ + static inline void SPI_SendByte(const uint8_t Byte) ATTR_ALWAYS_INLINE; + static inline void SPI_SendByte(const uint8_t Byte) + { + SPDR = Byte; + while (!(SPSR & (1 << SPIF))); + } + + /** Sends a dummy byte through the SPI interface, blocking until the transfer is complete. The response + * byte from the attached SPI device is returned. + * + * \return The response byte from the attached SPI device. + */ + static inline uint8_t SPI_ReceiveByte(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT; + static inline uint8_t SPI_ReceiveByte(void) + { + SPDR = 0x00; + while (!(SPSR & (1 << SPIF))); + return SPDR; + } + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/AVR8/SerialSPI_AVR8.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/AVR8/SerialSPI_AVR8.h new file mode 100644 index 00000000..9a122f50 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/AVR8/SerialSPI_AVR8.h @@ -0,0 +1,200 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Master SPI Mode Serial USART Peripheral Driver (XMEGA) + * + * On-chip Master SPI mode USART driver for the XMEGA AVR microcontrollers. + * + * \note This file should not be included directly. It is automatically included as needed by the SPI Master + * Mode USART driver dispatch header located in LUFA/Drivers/Peripheral/Serial.h. + */ + +/** \ingroup Group_SerialSPI + * \defgroup Group_SerialSPI_AVR8 Master SPI Mode Serial USART Peripheral Driver (AVR8) + * + * \section Sec_ModDescription Module Description + * On-chip serial USART driver for the 8-bit AVR8 microcontrollers. + * + * \note This file should not be included directly. It is automatically included as needed by the SPI Master + * driver dispatch header located in LUFA/Drivers/Peripheral/SerialSPI.h. + * + * \section Sec_ExampleUsage Example Usage + * The following snippet is an example of how this module may be used within a typical + * application. + * + * \code + * // Initialize the Master SPI mode USART driver before first use, with 1Mbit baud + * SerialSPI_Init((USART_SPI_SCK_LEAD_RISING | SPI_SAMPLE_LEADING | SPI_ORDER_MSB_FIRST), 1000000); + * + * // Send several bytes, ignoring the returned data + * SerialSPI_SendByte(0x01); + * SerialSPI_SendByte(0x02); + * SerialSPI_SendByte(0x03); + * + * // Receive several bytes, sending a dummy 0x00 byte each time + * uint8_t Byte1 = SerialSPI_ReceiveByte(); + * uint8_t Byte2 = SerialSPI_ReceiveByte(); + * uint8_t Byte3 = SerialSPI_ReceiveByte(); + * + * // Send a byte, and store the received byte from the same transaction + * uint8_t ResponseByte = SerialSPI_TransferByte(0xDC); + * \endcode + * + * @{ + */ + +#ifndef __SERIAL_SPI_AVR8_H__ +#define __SERIAL_SPI_AVR8_H__ + + /* Includes: */ + #include "../../../Common/Common.h" + + #include + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_SERIAL_SPI_H) + #error Do not include this file directly. Include LUFA/Drivers/Peripheral/Serial.h instead. + #endif + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + #define SERIAL_SPI_UBBRVAL(Baud) ((Baud < (F_CPU / 2)) ? ((F_CPU / (2 * Baud)) - 1) : 0) + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** \name SPI SCK Polarity Configuration Masks */ + //@{ + /** SPI clock polarity mask for \ref SPI_Init(). Indicates that the SCK should lead on the rising edge. */ + #define USART_SPI_SCK_LEAD_RISING (0 << UCPOL) + + /** SPI clock polarity mask for \ref SPI_Init(). Indicates that the SCK should lead on the falling edge. */ + #define USART_SPI_SCK_LEAD_FALLING (1 << UCPOL) + //@} + + /** \name SPI Sample Edge Configuration Masks */ + //@{ + /** SPI data sample mode mask for \ref SerialSPI_Init(). Indicates that the data should sampled on the leading edge. */ + #define USART_SPI_SAMPLE_LEADING (0 << UPCHA) + + /** SPI data sample mode mask for \ref SerialSPI_Init(). Indicates that the data should be sampled on the trailing edge. */ + #define USART_SPI_SAMPLE_TRAILING (1 << UPCHA) + //@} + + /** \name SPI Data Ordering Configuration Masks */ + //@{ + /** SPI data order mask for \ref SerialSPI_Init(). Indicates that data should be shifted out MSB first. */ + #define USART_SPI_ORDER_MSB_FIRST (0 << UDORD) + + /** SPI data order mask for \ref SerialSPI_Init(). Indicates that data should be shifted out LSB first. */ + #define USART_SPI_ORDER_LSB_FIRST (1 << UDORD) + //@} + + /* Inline Functions: */ + /** Initialize the USART module in Master SPI mode. + * + * \param[in] SPIOptions USART SPI Options, a mask consisting of one of each of the \c USART_SPI_SCK_*, + * \c USART_SPI_SAMPLE_* and \c USART_SPI_ORDER_* masks. + * \param[in] BaudRate SPI baud rate, in bits per second. + */ + static inline void SerialSPI_Init(const uint8_t SPIOptions, + const uint32_t BaudRate) + { + UBRR1 = SERIAL_SPI_UBBRVAL(BaudRate); + + UCSR1C = ((1 << UMSEL11) | (1 << UMSEL10) | SPIOptions); + UCSR1B = ((1 << TXEN1) | (1 << RXEN1)); + + DDRD |= (1 << 3); + PORTD |= (1 << 2); + } + + /** Turns off the USART driver, disabling and returning used hardware to their default configuration. */ + static inline void SerialSPI_Disable(void) + { + UCSR1B = 0; + UCSR1A = 0; + UCSR1C = 0; + + UBRR1 = 0; + + DDRD &= ~(1 << 3); + PORTD &= ~(1 << 2); + } + + /** Sends and receives a byte through the USART SPI interface, blocking until the transfer is complete. + * + * \param[in] DataByte Byte to send through the USART SPI interface. + * + * \return Response byte from the attached SPI device. + */ + static inline uint8_t SerialSPI_TransferByte(const uint8_t DataByte) + { + UDR1 = DataByte; + while (!(UCSR1A & (1 << TXC1))); + UCSR1A = (1 << TXC1); + return UDR1; + } + + /** Sends a byte through the USART SPI interface, blocking until the transfer is complete. The response + * byte sent to from the attached SPI device is ignored. + * + * \param[in] DataByte Byte to send through the USART SPI interface. + */ + static inline void SerialSPI_SendByte(const uint8_t DataByte) + { + SerialSPI_TransferByte(DataByte); + } + + /** Sends a dummy byte through the USART SPI interface, blocking until the transfer is complete. The response + * byte from the attached SPI device is returned. + * + * \return The response byte from the attached SPI device. + */ + static inline uint8_t SerialSPI_ReceiveByte(void) + { + return SerialSPI_TransferByte(0); + } + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/AVR8/Serial_AVR8.c b/protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/AVR8/Serial_AVR8.c new file mode 100644 index 00000000..a1f64b02 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/AVR8/Serial_AVR8.c @@ -0,0 +1,119 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#include "../../../Common/Common.h" +#if (ARCH == ARCH_AVR8) + +#define __INCLUDE_FROM_SERIAL_C +#include "../Serial.h" + +FILE USARTSerialStream; + +int Serial_putchar(char DataByte, + FILE *Stream) +{ + (void)Stream; + + Serial_SendByte(DataByte); + return 0; +} + +int Serial_getchar(FILE *Stream) +{ + (void)Stream; + + if (!(Serial_IsCharReceived())) + return _FDEV_EOF; + + return Serial_ReceiveByte(); +} + +int Serial_getchar_Blocking(FILE *Stream) +{ + (void)Stream; + + while (!(Serial_IsCharReceived())); + return Serial_ReceiveByte(); +} + +void Serial_SendString_P(const char* FlashStringPtr) +{ + uint8_t CurrByte; + + while ((CurrByte = pgm_read_byte(FlashStringPtr)) != 0x00) + { + Serial_SendByte(CurrByte); + FlashStringPtr++; + } +} + +void Serial_SendString(const char* StringPtr) +{ + uint8_t CurrByte; + + while ((CurrByte = *StringPtr) != 0x00) + { + Serial_SendByte(CurrByte); + StringPtr++; + } +} + +void Serial_SendData(const uint8_t* Buffer, + uint16_t Length) +{ + while (Length--) + Serial_SendByte(*(Buffer++)); +} + +void Serial_CreateStream(FILE* Stream) +{ + if (!(Stream)) + { + Stream = &USARTSerialStream; + stdin = Stream; + stdout = Stream; + } + + *Stream = (FILE)FDEV_SETUP_STREAM(Serial_putchar, Serial_getchar, _FDEV_SETUP_RW); +} + +void Serial_CreateBlockingStream(FILE* Stream) +{ + if (!(Stream)) + { + Stream = &USARTSerialStream; + stdin = Stream; + stdout = Stream; + } + + *Stream = (FILE)FDEV_SETUP_STREAM(Serial_putchar, Serial_getchar_Blocking, _FDEV_SETUP_RW); +} + +#endif diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/AVR8/Serial_AVR8.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/AVR8/Serial_AVR8.h new file mode 100644 index 00000000..8416082f --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/AVR8/Serial_AVR8.h @@ -0,0 +1,239 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Serial USART Peripheral Driver (AVR8) + * + * On-chip serial USART driver for the 8-bit AVR microcontrollers. + * + * \note This file should not be included directly. It is automatically included as needed by the USART driver + * dispatch header located in LUFA/Drivers/Peripheral/Serial.h. + */ + +/** \ingroup Group_Serial + * \defgroup Group_Serial_AVR8 Serial USART Peripheral Driver (AVR8) + * + * \section Sec_ModDescription Module Description + * On-chip serial USART driver for the 8-bit AVR microcontrollers. + * + * \note This file should not be included directly. It is automatically included as needed by the USART driver + * dispatch header located in LUFA/Drivers/Peripheral/Serial.h. + * + * \section Sec_ExampleUsage Example Usage + * The following snippet is an example of how this module may be used within a typical + * application. + * + * \code + * // Initialize the serial USART driver before first use, with 9600 baud (and no double-speed mode) + * Serial_Init(9600, false); + * + * // Send a string through the USART + * Serial_TxString("Test String\r\n"); + * + * // Receive a byte through the USART + * uint8_t DataByte = Serial_RxByte(); + * \endcode + * + * @{ + */ + +#ifndef __SERIAL_AVR8_H__ +#define __SERIAL_AVR8_H__ + + /* Includes: */ + #include "../../../Common/Common.h" + #include "../../Misc/TerminalCodes.h" + + #include + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_SERIAL_H) && !defined(__INCLUDE_FROM_SERIAL_C) + #error Do not include this file directly. Include LUFA/Drivers/Peripheral/Serial.h instead. + #endif + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* External Variables: */ + extern FILE USARTSerialStream; + + /* Function Prototypes: */ + int Serial_putchar(char DataByte, + FILE *Stream); + int Serial_getchar(FILE *Stream); + int Serial_getchar_Blocking(FILE *Stream); + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Macro for calculating the baud value from a given baud rate when the \c U2X (double speed) bit is + * not set. + * + * \param[in] Baud Target serial UART baud rate. + * + * \return Closest UBRR register value for the given UART frequency. + */ + #define SERIAL_UBBRVAL(Baud) ((((F_CPU / 16) + (Baud / 2)) / (Baud)) - 1) + + /** Macro for calculating the baud value from a given baud rate when the \c U2X (double speed) bit is + * set. + * + * \param[in] Baud Target serial UART baud rate. + * + * \return Closest UBRR register value for the given UART frequency. + */ + #define SERIAL_2X_UBBRVAL(Baud) ((((F_CPU / 8) + (Baud / 2)) / (Baud)) - 1) + + /* Function Prototypes: */ + /** Transmits a given string located in program space (FLASH) through the USART. + * + * \param[in] FlashStringPtr Pointer to a string located in program space. + */ + void Serial_SendString_P(const char* FlashStringPtr) ATTR_NON_NULL_PTR_ARG(1); + + /** Transmits a given string located in SRAM memory through the USART. + * + * \param[in] StringPtr Pointer to a string located in SRAM space. + */ + void Serial_SendString(const char* StringPtr) ATTR_NON_NULL_PTR_ARG(1); + + /** Transmits a given buffer located in SRAM memory through the USART. + * + * \param[in] Buffer Pointer to a buffer containing the data to send. + * \param[in] Length Length of the data to send, in bytes. + */ + void Serial_SendData(const uint8_t* Buffer, uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); + + /** Creates a standard character stream from the USART so that it can be used with all the regular functions + * in the avr-libc \c library that accept a \c FILE stream as a destination (e.g. \c fprintf). The created + * stream is bidirectional and can be used for both input and output functions. + * + * Reading data from this stream is non-blocking, i.e. in most instances, complete strings cannot be read in by a single + * fetch, as the endpoint will not be ready at some point in the transmission, aborting the transfer. However, this may + * be used when the read data is processed byte-per-bye (via \c getc()) or when the user application will implement its own + * line buffering. + * + * \param[in,out] Stream Pointer to a FILE structure where the created stream should be placed, if \c NULL, \c stdout + * and \c stdin will be configured to use the USART. + * + * \pre The USART must first be configured via a call to \ref Serial_Init() before the stream is used. + */ + void Serial_CreateStream(FILE* Stream); + + /** Identical to \ref Serial_CreateStream(), except that reads are blocking until the calling stream function terminates + * the transfer. + * + * \param[in,out] Stream Pointer to a FILE structure where the created stream should be placed, if \c NULL, \c stdout + * and \c stdin will be configured to use the USART. + * + * \pre The USART must first be configured via a call to \ref Serial_Init() before the stream is used. + */ + void Serial_CreateBlockingStream(FILE* Stream); + + /* Inline Functions: */ + /** Initializes the USART, ready for serial data transmission and reception. This initializes the interface to + * standard 8-bit, no parity, 1 stop bit settings suitable for most applications. + * + * \param[in] BaudRate Serial baud rate, in bits per second. + * \param[in] DoubleSpeed Enables double speed mode when set, halving the sample time to double the baud rate. + */ + static inline void Serial_Init(const uint32_t BaudRate, + const bool DoubleSpeed) + { + UBRR1 = (DoubleSpeed ? SERIAL_2X_UBBRVAL(BaudRate) : SERIAL_UBBRVAL(BaudRate)); + + UCSR1C = ((1 << UCSZ11) | (1 << UCSZ10)); + UCSR1A = (DoubleSpeed ? (1 << U2X1) : 0); + UCSR1B = ((1 << TXEN1) | (1 << RXEN1)); + + DDRD |= (1 << 3); + PORTD |= (1 << 2); + } + + /** Turns off the USART driver, disabling and returning used hardware to their default configuration. */ + static inline void Serial_Disable(void) + { + UCSR1B = 0; + UCSR1A = 0; + UCSR1C = 0; + + UBRR1 = 0; + + DDRD &= ~(1 << 3); + PORTD &= ~(1 << 2); + } + + /** Indicates whether a character has been received through the USART. + * + * \return Boolean \c true if a character has been received, \c false otherwise. + */ + static inline bool Serial_IsCharReceived(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool Serial_IsCharReceived(void) + { + return ((UCSR1A & (1 << RXC1)) ? true : false); + } + + /** Transmits a given byte through the USART. + * + * \param[in] DataByte Byte to transmit through the USART. + */ + static inline void Serial_SendByte(const char DataByte) ATTR_ALWAYS_INLINE; + static inline void Serial_SendByte(const char DataByte) + { + while (!(UCSR1A & (1 << UDRE1))); + UDR1 = DataByte; + } + + /** Receives the next byte from the USART. + * + * \return Next byte received from the USART, or a negative value if no byte has been received. + */ + static inline int16_t Serial_ReceiveByte(void) ATTR_ALWAYS_INLINE; + static inline int16_t Serial_ReceiveByte(void) + { + if (!(Serial_IsCharReceived())) + return -1; + + return UDR1; + } + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/AVR8/TWI_AVR8.c b/protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/AVR8/TWI_AVR8.c new file mode 100644 index 00000000..3cc3f0b6 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/AVR8/TWI_AVR8.c @@ -0,0 +1,207 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#include "../../../Common/Common.h" +#if (ARCH == ARCH_AVR8) && defined(TWCR) + +#define __INCLUDE_FROM_TWI_C +#include "../TWI.h" + +uint8_t TWI_StartTransmission(const uint8_t SlaveAddress, + const uint8_t TimeoutMS) +{ + for (;;) + { + bool BusCaptured = false; + uint16_t TimeoutRemaining; + + TWCR = ((1 << TWINT) | (1 << TWSTA) | (1 << TWEN)); + + TimeoutRemaining = (TimeoutMS * 100); + while (TimeoutRemaining-- && !(BusCaptured)) + { + if (TWCR & (1 << TWINT)) + { + switch (TWSR & TW_STATUS_MASK) + { + case TW_START: + case TW_REP_START: + BusCaptured = true; + break; + case TW_MT_ARB_LOST: + TWCR = ((1 << TWINT) | (1 << TWSTA) | (1 << TWEN)); + continue; + default: + TWCR = (1 << TWEN); + return TWI_ERROR_BusFault; + } + } + + _delay_us(10); + } + + if (!(TimeoutRemaining)) + { + TWCR = (1 << TWEN); + return TWI_ERROR_BusCaptureTimeout; + } + + TWDR = SlaveAddress; + TWCR = ((1 << TWINT) | (1 << TWEN)); + + TimeoutRemaining = (TimeoutMS * 100); + while (TimeoutRemaining--) + { + if (TWCR & (1 << TWINT)) + break; + + _delay_us(10); + } + + if (!(TimeoutRemaining)) + return TWI_ERROR_SlaveResponseTimeout; + + switch (TWSR & TW_STATUS_MASK) + { + case TW_MT_SLA_ACK: + case TW_MR_SLA_ACK: + return TWI_ERROR_NoError; + default: + TWCR = ((1 << TWINT) | (1 << TWSTO) | (1 << TWEN)); + return TWI_ERROR_SlaveNotReady; + } + } +} + +bool TWI_SendByte(const uint8_t Byte) +{ + TWDR = Byte; + TWCR = ((1 << TWINT) | (1 << TWEN)); + while (!(TWCR & (1 << TWINT))); + + return ((TWSR & TW_STATUS_MASK) == TW_MT_DATA_ACK); +} + +bool TWI_ReceiveByte(uint8_t* const Byte, + const bool LastByte) +{ + uint8_t TWCRMask; + + if (LastByte) + TWCRMask = ((1 << TWINT) | (1 << TWEN)); + else + TWCRMask = ((1 << TWINT) | (1 << TWEN) | (1 << TWEA)); + + TWCR = TWCRMask; + while (!(TWCR & (1 << TWINT))); + *Byte = TWDR; + + uint8_t Status = (TWSR & TW_STATUS_MASK); + + return ((LastByte) ? (Status == TW_MR_DATA_NACK) : (Status == TW_MR_DATA_ACK)); +} + +uint8_t TWI_ReadPacket(const uint8_t SlaveAddress, + const uint8_t TimeoutMS, + const uint8_t* InternalAddress, + uint8_t InternalAddressLen, + uint8_t* Buffer, + uint8_t Length) +{ + uint8_t ErrorCode; + + if ((ErrorCode = TWI_StartTransmission((SlaveAddress & TWI_DEVICE_ADDRESS_MASK) | TWI_ADDRESS_WRITE, + TimeoutMS)) == TWI_ERROR_NoError) + { + while (InternalAddressLen--) + { + if (!(TWI_SendByte(*(InternalAddress++)))) + { + ErrorCode = TWI_ERROR_SlaveNAK; + break; + } + } + + if ((ErrorCode = TWI_StartTransmission((SlaveAddress & TWI_DEVICE_ADDRESS_MASK) | TWI_ADDRESS_READ, + TimeoutMS)) == TWI_ERROR_NoError) + { + while (Length--) + { + if (!(TWI_ReceiveByte(Buffer++, (Length == 0)))) + { + ErrorCode = TWI_ERROR_SlaveNAK; + break; + } + } + + TWI_StopTransmission(); + } + } + + return ErrorCode; +} + +uint8_t TWI_WritePacket(const uint8_t SlaveAddress, + const uint8_t TimeoutMS, + const uint8_t* InternalAddress, + uint8_t InternalAddressLen, + const uint8_t* Buffer, + uint8_t Length) +{ + uint8_t ErrorCode; + + if ((ErrorCode = TWI_StartTransmission((SlaveAddress & TWI_DEVICE_ADDRESS_MASK) | TWI_ADDRESS_WRITE, + TimeoutMS)) == TWI_ERROR_NoError) + { + while (InternalAddressLen--) + { + if (!(TWI_SendByte(*(InternalAddress++)))) + { + ErrorCode = TWI_ERROR_SlaveNAK; + break; + } + } + + while (Length--) + { + if (!(TWI_SendByte(*(Buffer++)))) + { + ErrorCode = TWI_ERROR_SlaveNAK; + break; + } + } + + TWI_StopTransmission(); + } + + return ErrorCode; +} + +#endif diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/AVR8/TWI_AVR8.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/AVR8/TWI_AVR8.h new file mode 100644 index 00000000..92c7389a --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/AVR8/TWI_AVR8.h @@ -0,0 +1,304 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief TWI Peripheral Driver (AVR8) + * + * On-chip TWI driver for the 8-bit AVR microcontrollers. + * + * \note This file should not be included directly. It is automatically included as needed by the TWI driver + * dispatch header located in LUFA/Drivers/Peripheral/TWI.h. + */ + +/** \ingroup Group_TWI + * \defgroup Group_TWI_AVR8 TWI Peripheral Driver (AVR8) + * + * \section Sec_ModDescription Module Description + * Master mode TWI driver for the 8-bit AVR microcontrollers which contain a hardware TWI module. + * + * \note This file should not be included directly. It is automatically included as needed by the TWI driver + * dispatch header located in LUFA/Drivers/Peripheral/TWI.h. + * + * \section Sec_ExampleUsage Example Usage + * The following snippet is an example of how this module may be used within a typical + * application. + * + * Low Level API Example: + * \code + * // Initialize the TWI driver before first use at 200KHz + * TWI_Init(TWI_BIT_PRESCALE_1, TWI_BITLENGTH_FROM_FREQ(1, 200000)); + * + * // Start a write session to device at device address 0xA0, internal address 0xDC with a 10ms timeout + * if (TWI_StartTransmission(0xA0 | TWI_ADDRESS_WRITE, 10) == TWI_ERROR_NoError) + * { + * TWI_SendByte(0xDC); + * + * TWI_SendByte(0x01); + * TWI_SendByte(0x02); + * TWI_SendByte(0x03); + * + * // Must stop transmission afterwards to release the bus + * TWI_StopTransmission(); + * } + * + * // Start a read session to device at address 0xA0, internal address 0xDC with a 10ms timeout + * if (TWI_StartTransmission(0xA0 | TWI_ADDRESS_WRITE, 10) == TWI_ERROR_NoError) + * { + * TWI_SendByte(0xDC); + * TWI_StopTransmission(); + * + * if (TWI_StartTransmission(0xA0 | TWI_ADDRESS_READ, 10) == TWI_ERROR_NoError) + * { + * uint8_t Byte1, Byte2, Byte3; + * + * // Read three bytes, acknowledge after the third byte is received + * TWI_ReceiveByte(&Byte1, false); + * TWI_ReceiveByte(&Byte2, false); + * TWI_ReceiveByte(&Byte3, true); + * + * // Must stop transmission afterwards to release the bus + * TWI_StopTransmission(); + * } + * } + * \endcode + * + * High Level API Example: + * \code + * // Initialize the TWI driver before first use at 200KHz + * TWI_Init(TWI_BIT_PRESCALE_1, TWI_BITLENGTH_FROM_FREQ(1, 200000)); + * + * // Start a write session to device at device address 0xA0, internal address 0xDC with a 10ms timeout + * uint8_t InternalWriteAddress = 0xDC; + * uint8_t WritePacket[3] = {0x01, 0x02, 0x03}; + * + * TWI_WritePacket(0xA0, 10, &InternalWriteAddress, sizeof(InternalWriteAddress), + * &WritePacket, sizeof(WritePacket); + * + * // Start a read session to device at address 0xA0, internal address 0xDC with a 10ms timeout + * uint8_t InternalReadAddress = 0xDC; + * uint8_t ReadPacket[3]; + * + * TWI_ReadPacket(0xA0, 10, &InternalReadAddress, sizeof(InternalReadAddress), + * &ReadPacket, sizeof(ReadPacket); + * \endcode + * + * @{ + */ + +#ifndef __TWI_AVR8_H__ +#define __TWI_AVR8_H__ + + /* Includes: */ + #include "../../../Common/Common.h" + + #include + #include + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_TWI_H) && !defined(__INCLUDE_FROM_TWI_C) + #error Do not include this file directly. Include LUFA/Drivers/Peripheral/TWI.h instead. + #endif + + #if !(defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB646__) || \ + defined(__AVR_AT90USB1287__) || defined(__AVR_AT90USB647__) || \ + defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__) || \ + defined(__AVR_ATmega32U6__)) + #error The TWI peripheral driver is not currently available for your selected microcontroller model. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** TWI slave device address mask for a read session. Mask with a slave device base address to obtain + * the correct TWI bus address for the slave device when reading data from it. + */ + #define TWI_ADDRESS_READ 0x01 + + /** TWI slave device address mask for a write session. Mask with a slave device base address to obtain + * the correct TWI bus address for the slave device when writing data to it. + */ + #define TWI_ADDRESS_WRITE 0x00 + + /** Mask to retrieve the base address for a TWI device, which can then be ORed with \ref TWI_ADDRESS_READ + * or \ref TWI_ADDRESS_WRITE to obtain the device's read and write address respectively. + */ + #define TWI_DEVICE_ADDRESS_MASK 0xFE + + /** Bit length prescaler for \ref TWI_Init(). This mask multiplies the TWI bit length prescaler by 1. */ + #define TWI_BIT_PRESCALE_1 ((0 << TWPS1) | (0 << TWPS0)) + + /** Bit length prescaler for \ref TWI_Init(). This mask multiplies the TWI bit length prescaler by 4. */ + #define TWI_BIT_PRESCALE_4 ((0 << TWPS1) | (1 << TWPS0)) + + /** Bit length prescaler for \ref TWI_Init(). This mask multiplies the TWI bit length prescaler by 16. */ + #define TWI_BIT_PRESCALE_16 ((1 << TWPS1) | (0 << TWPS0)) + + /** Bit length prescaler for \ref TWI_Init(). This mask multiplies the TWI bit length prescaler by 64. */ + #define TWI_BIT_PRESCALE_64 ((1 << TWPS1) | (1 << TWPS0)) + + /** Calculates the length of each bit on the TWI bus for a given target frequency. This may be used with + * the \ref TWI_Init() function to convert a bus frequency to a number of clocks for the \c BitLength + * parameter. + * + * \param[in] Prescale Prescaler set on the TWI bus. + * \param[in] Frequency Desired TWI bus frequency in Hz. + * + * \return Bit length in clocks for the given TWI bus frequency at the given prescaler value. + */ + #define TWI_BITLENGTH_FROM_FREQ(Prescale, Frequency) ((((F_CPU / (Prescale)) / (Frequency)) - 16) / 2) + + /* Enums: */ + /** Enum for the possible return codes of the TWI transfer start routine and other dependant TWI functions. */ + enum TWI_ErrorCodes_t + { + TWI_ERROR_NoError = 0, /**< Indicates that the command completed successfully. */ + TWI_ERROR_BusFault = 1, /**< A TWI bus fault occurred while attempting to capture the bus. */ + TWI_ERROR_BusCaptureTimeout = 2, /**< A timeout occurred whilst waiting for the bus to be ready. */ + TWI_ERROR_SlaveResponseTimeout = 3, /**< No ACK received at the nominated slave address within the timeout period. */ + TWI_ERROR_SlaveNotReady = 4, /**< Slave NAKed the TWI bus START condition. */ + TWI_ERROR_SlaveNAK = 5, /**< Slave NAKed whilst attempting to send data to the device. */ + }; + + /* Inline Functions: */ + /** Initializes the TWI hardware into master mode, ready for data transmission and reception. This must be + * before any other TWI operations. + * + * The generated SCL frequency will be according to the formula
F_CPU / (16 + 2 * BitLength + 4 ^ Prescale)
. + * + * \attention The value of the \c BitLength parameter should not be set below 10 or invalid bus conditions may + * occur, as indicated in the AVR8 microcontroller datasheet. + * + * \param[in] Prescale Prescaler to use when determining the bus frequency, a \c TWI_BIT_PRESCALE_* value. + * \param[in] BitLength Length of the bits sent on the bus. + */ + static inline void TWI_Init(const uint8_t Prescale, const uint8_t BitLength) ATTR_ALWAYS_INLINE; + static inline void TWI_Init(const uint8_t Prescale, const uint8_t BitLength) + { + TWCR |= (1 << TWEN); + TWSR = Prescale; + TWBR = BitLength; + } + + /** Turns off the TWI driver hardware. If this is called, any further TWI operations will require a call to + * \ref TWI_Init() before the TWI can be used again. + */ + static inline void TWI_Disable(void) ATTR_ALWAYS_INLINE; + static inline void TWI_Disable(void) + { + TWCR &= ~(1 << TWEN); + } + + /** Sends a TWI STOP onto the TWI bus, terminating communication with the currently addressed device. */ + static inline void TWI_StopTransmission(void) ATTR_ALWAYS_INLINE; + static inline void TWI_StopTransmission(void) + { + TWCR = ((1 << TWINT) | (1 << TWSTO) | (1 << TWEN)); + } + + /* Function Prototypes: */ + /** Begins a master mode TWI bus communication with the given slave device address. + * + * \param[in] SlaveAddress Address of the slave TWI device to communicate with. + * \param[in] TimeoutMS Timeout period within which the slave must respond, in milliseconds. + * + * \return A value from the \ref TWI_ErrorCodes_t enum. + */ + uint8_t TWI_StartTransmission(const uint8_t SlaveAddress, + const uint8_t TimeoutMS); + + /** Sends a byte to the currently addressed device on the TWI bus. + * + * \param[in] Byte Byte to send to the currently addressed device + * + * \return Boolean \c true if the recipient ACKed the byte, \c false otherwise + */ + bool TWI_SendByte(const uint8_t Byte); + + /** Receives a byte from the currently addressed device on the TWI bus. + * + * \param[in] Byte Location where the read byte is to be stored. + * \param[in] LastByte Indicates if the byte should be ACKed if false, NAKed if true. + * + * \return Boolean \c true if the byte reception successfully completed, \c false otherwise. + */ + bool TWI_ReceiveByte(uint8_t* const Byte, + const bool LastByte) ATTR_NON_NULL_PTR_ARG(1); + + /** High level function to perform a complete packet transfer over the TWI bus to the specified + * device. + * + * \param[in] SlaveAddress Base address of the TWI slave device to communicate with. + * \param[in] TimeoutMS Timeout for bus capture and slave START ACK, in milliseconds. + * \param[in] InternalAddress Pointer to a location where the internal slave read start address is stored. + * \param[in] InternalAddressLen Size of the internal device address, in bytes. + * \param[in] Buffer Pointer to a buffer where the read packet data is to be stored. + * \param[in] Length Size of the packet to read, in bytes. + * + * \return A value from the \ref TWI_ErrorCodes_t enum. + */ + uint8_t TWI_ReadPacket(const uint8_t SlaveAddress, + const uint8_t TimeoutMS, + const uint8_t* InternalAddress, + uint8_t InternalAddressLen, + uint8_t* Buffer, + uint8_t Length) ATTR_NON_NULL_PTR_ARG(3); + + /** High level function to perform a complete packet transfer over the TWI bus from the specified + * device. + * + * \param[in] SlaveAddress Base address of the TWI slave device to communicate with + * \param[in] TimeoutMS Timeout for bus capture and slave START ACK, in milliseconds + * \param[in] InternalAddress Pointer to a location where the internal slave write start address is stored + * \param[in] InternalAddressLen Size of the internal device address, in bytes + * \param[in] Buffer Pointer to a buffer where the packet data to send is stored + * \param[in] Length Size of the packet to send, in bytes + * + * \return A value from the \ref TWI_ErrorCodes_t enum. + */ + uint8_t TWI_WritePacket(const uint8_t SlaveAddress, + const uint8_t TimeoutMS, + const uint8_t* InternalAddress, + uint8_t InternalAddressLen, + const uint8_t* Buffer, + uint8_t Length) ATTR_NON_NULL_PTR_ARG(3); + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/SPI.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/SPI.h new file mode 100644 index 00000000..1fab22b6 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/SPI.h @@ -0,0 +1,76 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Hardware Serial Peripheral Interface driver. + * + * This file is the master dispatch header file for the device-specific SPI driver, for microcontrollers + * containing a hardware SPI. + * + * User code should include this file, which will in turn include the correct SPI driver header file for the + * currently selected architecture and microcontroller model. + */ + +/** \ingroup Group_PeripheralDrivers + * \defgroup Group_SPI SPI Driver - LUFA/Drivers/Peripheral/SPI.h + * \brief Hardware Serial Peripheral Interface driver. + * + * \section Sec_Dependencies Module Source Dependencies + * The following files must be built with any user project that uses this module: + * - None + * + * \section Sec_ModDescription Module Description + * Hardware SPI driver. This module provides an easy to use driver for the setup and transfer of data over + * the selected architecture and microcontroller model's SPI port. + * + * \note The exact API for this driver may vary depending on the target used - see + * individual target module documentation for the API specific to your target processor. + */ + +#ifndef __SPI_H__ +#define __SPI_H__ + + /* Macros: */ + #define __INCLUDE_FROM_SPI_H + + /* Includes: */ + #include "../../Common/Common.h" + + /* Includes: */ + #if (ARCH == ARCH_AVR8) + #include "AVR8/SPI_AVR8.h" + #elif (ARCH == ARCH_XMEGA) + #include "XMEGA/SPI_XMEGA.h" + #else + #error The SPI peripheral driver is not currently available for your selected architecture. + #endif + +#endif + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/Serial.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/Serial.h new file mode 100644 index 00000000..0db13ba4 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/Serial.h @@ -0,0 +1,76 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Hardware Serial USART driver. + * + * This file is the master dispatch header file for the device-specific USART driver, for microcontrollers + * containing a hardware USART. + * + * User code should include this file, which will in turn include the correct ADC driver header file for the + * currently selected architecture and microcontroller model. + */ + +/** \ingroup Group_PeripheralDrivers + * \defgroup Group_Serial Serial USART Driver - LUFA/Drivers/Peripheral/Serial.h + * \brief Hardware Serial USART driver. + * + * \section Sec_Dependencies Module Source Dependencies + * The following files must be built with any user project that uses this module: + * - LUFA/Drivers/Peripheral/ARCH/Serial_ARCH.c (Makefile source module name: LUFA_SRC_SERIAL) + * + * \section Sec_ModDescription Module Description + * Hardware serial USART driver. This module provides an easy to use driver for the setup and transfer + * of data over the selected architecture and microcontroller model's USART port. + * + * \note The exact API for this driver may vary depending on the target used - see + * individual target module documentation for the API specific to your target processor. + */ + +#ifndef __SERIAL_H__ +#define __SERIAL_H__ + + /* Macros: */ + #define __INCLUDE_FROM_SERIAL_H + + /* Includes: */ + #include "../../Common/Common.h" + + /* Includes: */ + #if (ARCH == ARCH_AVR8) + #include "AVR8/Serial_AVR8.h" + #elif (ARCH == ARCH_XMEGA) + #include "XMEGA/Serial_XMEGA.h" + #else + #error The Serial peripheral driver is not currently available for your selected architecture. + #endif + +#endif + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/SerialSPI.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/SerialSPI.h new file mode 100644 index 00000000..f5eede84 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/SerialSPI.h @@ -0,0 +1,76 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Hardware SPI Master Mode Serial USART driver. + * + * This file is the master dispatch header file for the device-specific SPI Master Mode USART driver, for + * microcontrollers containing a hardware USART capable of operating in a Master SPI mode. + * + * User code should include this file, which will in turn include the correct ADC driver header file for the + * currently selected architecture and microcontroller model. + */ + +/** \ingroup Group_PeripheralDrivers + * \defgroup Group_SerialSPI Master SPI Mode Serial USART Driver - LUFA/Drivers/Peripheral/SerialSPI.h + * \brief Hardware SPI Master Mode Serial USART driver. + * + * \section Sec_Dependencies Module Source Dependencies + * The following files must be built with any user project that uses this module: + * - None + * + * \section Sec_ModDescription Module Description + * Hardware SPI Master Mode serial USART driver. This module provides an easy to use driver for the setup and transfer + * of data over the selected architecture and microcontroller model's USART port, using a SPI framing format. + * + * \note The exact API for this driver may vary depending on the target used - see + * individual target module documentation for the API specific to your target processor. + */ + +#ifndef __SERIAL_SPI_H__ +#define __SERIAL_SPI_H__ + + /* Macros: */ + #define __INCLUDE_FROM_SERIAL_SPI_H + + /* Includes: */ + #include "../../Common/Common.h" + + /* Includes: */ + #if (ARCH == ARCH_AVR8) + #include "AVR8/SerialSPI_AVR8.h" + #elif (ARCH == ARCH_XMEGA) + #include "XMEGA/SerialSPI_XMEGA.h" + #else + #error The Serial SPI Master Mode peripheral driver is not currently available for your selected architecture. + #endif + +#endif + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/TWI.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/TWI.h new file mode 100644 index 00000000..34012fda --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/TWI.h @@ -0,0 +1,74 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Hardware Two Wire Interface (I2C) driver. + * + * This file is the master dispatch header file for the device-specific SPI driver, for microcontrollers + * containing a hardware TWI. + * + * User code should include this file, which will in turn include the correct TWI driver header file for the + * currently selected architecture and microcontroller model. + */ + +/** \ingroup Group_PeripheralDrivers + * \defgroup Group_TWI TWI Driver - LUFA/Drivers/Peripheral/TWI.h + * \brief Hardware Two Wire Interface (I2C) driver. + * + * \section Sec_Dependencies Module Source Dependencies + * The following files must be built with any user project that uses this module: + * - LUFA/Drivers/Peripheral/ARCH/TWI_ARCH.c (Makefile source module name: LUFA_SRC_TWI) + * + * \section Sec_ModDescription Module Description + * Hardware TWI driver. This module provides an easy to use driver for the setup and transfer of data over + * the selected architecture and microcontroller model's TWI bus port. + * + * \note The exact API for this driver may vary depending on the target used - see + * individual target module documentation for the API specific to your target processor. + */ + +#ifndef __TWI_H__ +#define __TWI_H__ + + /* Macros: */ + #define __INCLUDE_FROM_TWI_H + + /* Includes: */ + #include "../../Common/Common.h" + + /* Includes: */ + #if (ARCH == ARCH_AVR8) + #include "AVR8/TWI_AVR8.h" + #else + #error The TWI peripheral driver is not currently available for your selected architecture. + #endif + +#endif + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/XMEGA/SPI_XMEGA.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/XMEGA/SPI_XMEGA.h new file mode 100644 index 00000000..25fb73d1 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/XMEGA/SPI_XMEGA.h @@ -0,0 +1,248 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief SPI Peripheral Driver (XMEGA) + * + * On-chip SPI driver for the XMEGA microcontrollers. + * + * \note This file should not be included directly. It is automatically included as needed by the SPI driver + * dispatch header located in LUFA/Drivers/Peripheral/SPI.h. + */ + +/** \ingroup Group_SPI + * \defgroup Group_SPI_XMEGA SPI Peripheral Driver (XMEGA) + * + * \section Sec_ModDescription Module Description + * Driver for the hardware SPI port(s) available on XMEGA AVR microcontroller models. This + * module provides an easy to use driver for the setup and transfer of data over the AVR's + * SPI ports. + * + * \note This file should not be included directly. It is automatically included as needed by the SPI driver + * dispatch header located in LUFA/Drivers/Peripheral/SPI.h. + * + * \code + * // Initialize the SPI driver before first use + * SPI_Init(&SPIC, + * SPI_SPEED_FCPU_DIV_2 | SPI_ORDER_MSB_FIRST | SPI_SCK_LEAD_FALLING | + * SPI_SAMPLE_TRAILING | SPI_MODE_MASTER); + * + * // Send several bytes, ignoring the returned data + * SPI_SendByte(&SPIC, 0x01); + * SPI_SendByte(&SPIC, 0x02); + * SPI_SendByte(&SPIC, 0x03); + * + * // Receive several bytes, sending a dummy 0x00 byte each time + * uint8_t Byte1 = SPI_ReceiveByte(&SPIC); + * uint8_t Byte2 = SPI_ReceiveByte(&SPIC); + * uint8_t Byte3 = SPI_ReceiveByte(&SPIC); + * + * // Send a byte, and store the received byte from the same transaction + * uint8_t ResponseByte = SPI_TransferByte(&SPIC, 0xDC); + * \endcode + * + * @{ + */ + +#ifndef __SPI_XMEGA_H__ +#define __SPI_XMEGA_H__ + + /* Includes: */ + #include "../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_SPI_H) + #error Do not include this file directly. Include LUFA/Drivers/Peripheral/SPI.h instead. + #endif + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Macros: */ + #define SPI_USE_DOUBLESPEED SPI_CLK2X_bm + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** \name SPI Prescaler Configuration Masks */ + //@{ + /** SPI prescaler mask for \ref SPI_Init(). Divides the system clock by a factor of 2. */ + #define SPI_SPEED_FCPU_DIV_2 SPI_USE_DOUBLESPEED + + /** SPI prescaler mask for \ref SPI_Init(). Divides the system clock by a factor of 4. */ + #define SPI_SPEED_FCPU_DIV_4 0 + + /** SPI prescaler mask for \ref SPI_Init(). Divides the system clock by a factor of 8. */ + #define SPI_SPEED_FCPU_DIV_8 (SPI_USE_DOUBLESPEED | (1 << SPI_PRESCALER_gp)) + + /** SPI prescaler mask for \ref SPI_Init(). Divides the system clock by a factor of 16. */ + #define SPI_SPEED_FCPU_DIV_16 (1 << SPI_PRESCALER_gp) + + /** SPI prescaler mask for \ref SPI_Init(). Divides the system clock by a factor of 32. */ + #define SPI_SPEED_FCPU_DIV_32 (SPI_USE_DOUBLESPEED | (2 << SPI_PRESCALER_gp)) + + /** SPI prescaler mask for \ref SPI_Init(). Divides the system clock by a factor of 64. */ + #define SPI_SPEED_FCPU_DIV_64 (2 << SPI_PRESCALER_gp) + + /** SPI prescaler mask for \ref SPI_Init(). Divides the system clock by a factor of 128. */ + #define SPI_SPEED_FCPU_DIV_128 (3 << SPI_PRESCALER_gp) + //@} + + /** \name SPI SCK Polarity Configuration Masks */ + //@{ + /** SPI clock polarity mask for \ref SPI_Init(). Indicates that the SCK should lead on the rising edge. */ + #define SPI_SCK_LEAD_RISING 0 + + /** SPI clock polarity mask for \ref SPI_Init(). Indicates that the SCK should lead on the falling edge. */ + #define SPI_SCK_LEAD_FALLING SPI_MODE1_bm + //@} + + /** \name SPI Sample Edge Configuration Masks */ + //@{ + /** SPI data sample mode mask for \ref SPI_Init(). Indicates that the data should sampled on the leading edge. */ + #define SPI_SAMPLE_LEADING 0 + + /** SPI data sample mode mask for \ref SPI_Init(). Indicates that the data should be sampled on the trailing edge. */ + #define SPI_SAMPLE_TRAILING SPI_MODE0_bm + //@} + + /** \name SPI Data Ordering Configuration Masks */ + //@{ + /** SPI data order mask for \ref SPI_Init(). Indicates that data should be shifted out MSB first. */ + #define SPI_ORDER_MSB_FIRST 0 + + /** SPI data order mask for \ref SPI_Init(). Indicates that data should be shifted out LSB first. */ + #define SPI_ORDER_LSB_FIRST SPI_DORD_bm + //@} + + /** \name SPI Mode Configuration Masks */ + //@{ + /** SPI mode mask for \ref SPI_Init(). Indicates that the SPI interface should be initialized into slave mode. */ + #define SPI_MODE_SLAVE 0 + + /** SPI mode mask for \ref SPI_Init(). Indicates that the SPI interface should be initialized into master mode. */ + #define SPI_MODE_MASTER SPI_MASTER_bm + //@} + + /* Inline Functions: */ + /** Initializes the SPI subsystem, ready for transfers. Must be called before calling any other + * SPI routines. + * + * \param[in,out] SPI Pointer to the base of the SPI peripheral within the device. + * \param[in] SPIOptions SPI Options, a mask consisting of one of each of the \c SPI_SPEED_*, + * \c SPI_SCK_*, \c SPI_SAMPLE_*, \c SPI_ORDER_* and \c SPI_MODE_* masks. + */ + static inline void SPI_Init(SPI_t* const SPI, + const uint8_t SPIOptions) + { + SPI->CTRL = (SPIOptions | SPI_ENABLE_bm); + } + + /** Turns off the SPI driver, disabling and returning used hardware to their default configuration. + * + * \param[in,out] SPI Pointer to the base of the SPI peripheral within the device. + */ + static inline void SPI_Disable(SPI_t* const SPI) + { + SPI->CTRL &= ~SPI_ENABLE_bm; + } + + /** Retrieves the currently selected SPI mode, once the SPI interface has been configured. + * + * \param[in,out] SPI Pointer to the base of the SPI peripheral within the device. + * + * \return \ref SPI_MODE_MASTER if the interface is currently in SPI Master mode, \ref SPI_MODE_SLAVE otherwise + */ + static inline uint8_t SPI_GetCurrentMode(SPI_t* const SPI) ATTR_ALWAYS_INLINE; + static inline uint8_t SPI_GetCurrentMode(SPI_t* const SPI) + { + return (SPI->CTRL & SPI_MASTER_bm); + } + + /** Sends and receives a byte through the SPI interface, blocking until the transfer is complete. + * + * \param[in,out] SPI Pointer to the base of the SPI peripheral within the device. + * \param[in] Byte Byte to send through the SPI interface. + * + * \return Response byte from the attached SPI device. + */ + static inline uint8_t SPI_TransferByte(SPI_t* const SPI, + const uint8_t Byte) ATTR_ALWAYS_INLINE; + static inline uint8_t SPI_TransferByte(SPI_t* const SPI, + const uint8_t Byte) + { + SPI->DATA = Byte; + while (!(SPI->STATUS & SPI_IF_bm)); + return SPI->DATA; + } + + /** Sends a byte through the SPI interface, blocking until the transfer is complete. The response + * byte sent to from the attached SPI device is ignored. + * + * \param[in,out] SPI Pointer to the base of the SPI peripheral within the device. + * \param[in] Byte Byte to send through the SPI interface. + */ + static inline void SPI_SendByte(SPI_t* const SPI, + const uint8_t Byte) ATTR_ALWAYS_INLINE; + static inline void SPI_SendByte(SPI_t* const SPI, + const uint8_t Byte) + { + SPI->DATA = Byte; + while (!(SPI->STATUS & SPI_IF_bm)); + } + + /** Sends a dummy byte through the SPI interface, blocking until the transfer is complete. The response + * byte from the attached SPI device is returned. + * + * \param[in,out] SPI Pointer to the base of the SPI peripheral within the device. + * + * \return The response byte from the attached SPI device. + */ + static inline uint8_t SPI_ReceiveByte(SPI_t* const SPI) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT; + static inline uint8_t SPI_ReceiveByte(SPI_t* const SPI) + { + SPI->DATA = 0; + while (!(SPI->STATUS & SPI_IF_bm)); + return SPI->DATA; + } + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/XMEGA/SerialSPI_XMEGA.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/XMEGA/SerialSPI_XMEGA.h new file mode 100644 index 00000000..6d0ea111 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/XMEGA/SerialSPI_XMEGA.h @@ -0,0 +1,203 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Master SPI Mode Serial USART Peripheral Driver (XMEGA) + * + * On-chip Master SPI mode USART driver for the XMEGA AVR microcontrollers. + * + * \note This file should not be included directly. It is automatically included as needed by the SPI Master + * Mode USART driver dispatch header located in LUFA/Drivers/Peripheral/Serial.h. + */ + +/** \ingroup Group_SerialSPI + * \defgroup Group_SerialSPI_XMEGA Master SPI Mode Serial USART Peripheral Driver (XMEGA) + * + * \section Sec_ModDescription Module Description + * On-chip serial USART driver for the XMEGA AVR microcontrollers. + * + * \note This file should not be included directly. It is automatically included as needed by the ADC driver + * dispatch header located in LUFA/Drivers/Peripheral/SerialSPI.h. + * + * \section Sec_ExampleUsage Example Usage + * The following snippet is an example of how this module may be used within a typical + * application. + * + * \code + * // Initialize the Master SPI mode USART driver before first use, with 1Mbit baud + * SerialSPI_Init(&USARTD0, (USART_SPI_SCK_LEAD_RISING | USART_SPI_SAMPLE_LEADING | USART_SPI_ORDER_MSB_FIRST), 1000000); + * + * // Send several bytes, ignoring the returned data + * SerialSPI_SendByte(&USARTD0, 0x01); + * SerialSPI_SendByte(&USARTD0, 0x02); + * SerialSPI_SendByte(&USARTD0, 0x03); + * + * // Receive several bytes, sending a dummy 0x00 byte each time + * uint8_t Byte1 = SerialSPI_ReceiveByte(&USARTD); + * uint8_t Byte2 = SerialSPI_ReceiveByte(&USARTD); + * uint8_t Byte3 = SerialSPI_ReceiveByte(&USARTD); + * + * // Send a byte, and store the received byte from the same transaction + * uint8_t ResponseByte = SerialSPI_TransferByte(&USARTD0, 0xDC); + * \endcode + * + * @{ + */ + +#ifndef __SERIAL_SPI_XMEGA_H__ +#define __SERIAL_SPI_XMEGA_H__ + + /* Includes: */ + #include "../../../Common/Common.h" + + #include + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_SERIAL_SPI_H) + #error Do not include this file directly. Include LUFA/Drivers/Peripheral/Serial.h instead. + #endif + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + #define SERIAL_SPI_UBBRVAL(Baud) ((Baud < (F_CPU / 2)) ? ((F_CPU / (2 * Baud)) - 1) : 0) + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** \name SPI SCK Polarity Configuration Masks */ + //@{ + /** SPI clock polarity mask for \ref SerialSPI_Init(). Indicates that the SCK should lead on the rising edge. */ + #define USART_SPI_SCK_LEAD_RISING 0 + //@} + + /** \name SPI Sample Edge Configuration Masks */ + //@{ + /** SPI data sample mode mask for \ref SerialSPI_Init(). Indicates that the data should sampled on the leading edge. */ + #define USART_SPI_SAMPLE_LEADING 0 + + /** SPI data sample mode mask for \ref SerialSPI_Init(). Indicates that the data should be sampled on the trailing edge. */ + #define USART_SPI_SAMPLE_TRAILING USART_UPCHA_bm + //@} + + /** \name SPI Data Ordering Configuration Masks */ + //@{ + /** SPI data order mask for \ref SerialSPI_Init(). Indicates that data should be shifted out MSB first. */ + #define USART_SPI_ORDER_MSB_FIRST 0 + + /** SPI data order mask for \ref SerialSPI_Init(). Indicates that data should be shifted out LSB first. */ + #define USART_SPI_ORDER_LSB_FIRST USART_UDORD_bm + //@} + + /* Inline Functions: */ + /** Initialize the USART module in Master SPI mode. + * + * \param[in,out] USART Pointer to the base of the USART peripheral within the device. + * \param[in] SPIOptions USART SPI Options, a mask consisting of one of each of the \c USART_SPI_SCK_*, + * \c USART_SPI_SAMPLE_* and \c USART_SPI_ORDER_* masks. + * \param[in] BaudRate SPI baud rate, in bits per second. + */ + static inline void SerialSPI_Init(USART_t* const USART, + const uint8_t SPIOptions, + const uint32_t BaudRate) + { + uint16_t BaudValue = SERIAL_SPI_UBBRVAL(BaudRate); + + USART->BAUDCTRLB = (BaudValue >> 8); + USART->BAUDCTRLA = (BaudValue & 0xFF); + + USART->CTRLC = (USART_CMODE_MSPI_gc | SPIOptions); + USART->CTRLB = (USART_RXEN_bm | USART_TXEN_bm); + } + + /** Turns off the USART driver, disabling and returning used hardware to their default configuration. + * + * \param[in,out] USART Pointer to the base of the USART peripheral within the device. + */ + static inline void SerialSPI_Disable(USART_t* const USART) + { + USART->CTRLA = 0; + USART->CTRLB = 0; + USART->CTRLC = 0; + } + + /** Sends and receives a byte through the USART SPI interface, blocking until the transfer is complete. + * + * \param[in,out] USART Pointer to the base of the USART peripheral within the device. + * \param[in] DataByte Byte to send through the USART SPI interface. + * + * \return Response byte from the attached SPI device. + */ + static inline uint8_t SerialSPI_TransferByte(USART_t* const USART, + const uint8_t DataByte) + { + USART->DATA = DataByte; + while (!(USART->STATUS & USART_TXCIF_bm)); + USART->STATUS = USART_TXCIF_bm; + return USART->DATA; + } + + /** Sends a byte through the USART SPI interface, blocking until the transfer is complete. The response + * byte sent to from the attached SPI device is ignored. + * + * \param[in,out] USART Pointer to the base of the USART peripheral within the device. + * \param[in] DataByte Byte to send through the USART SPI interface. + */ + static inline void SerialSPI_SendByte(USART_t* const USART, + const uint8_t DataByte) + { + SerialSPI_TransferByte(USART, DataByte); + } + + /** Sends a dummy byte through the USART SPI interface, blocking until the transfer is complete. The response + * byte from the attached SPI device is returned. + * + * \param[in,out] USART Pointer to the base of the USART peripheral within the device. + * + * \return The response byte from the attached SPI device. + */ + static inline uint8_t SerialSPI_ReceiveByte(USART_t* const USART) + { + return SerialSPI_TransferByte(USART, 0); + } + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/XMEGA/Serial_XMEGA.c b/protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/XMEGA/Serial_XMEGA.c new file mode 100644 index 00000000..51a4d049 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/XMEGA/Serial_XMEGA.c @@ -0,0 +1,122 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#include "../../../Common/Common.h" +#if (ARCH == ARCH_XMEGA) + +#define __INCLUDE_FROM_SERIAL_C +#include "../Serial.h" + +FILE USARTSerialStream; + +int Serial_putchar(char DataByte, + FILE *Stream) +{ + USART_t* USART = fdev_get_udata(Stream); + + Serial_SendByte(USART, DataByte); + return 0; +} + +int Serial_getchar(FILE *Stream) +{ + USART_t* USART = fdev_get_udata(Stream); + + if (!(Serial_IsCharReceived(USART))) + return _FDEV_EOF; + + return Serial_ReceiveByte(USART); +} + +int Serial_getchar_Blocking(FILE *Stream) +{ + USART_t* USART = fdev_get_udata(Stream); + + while (!(Serial_IsCharReceived(USART))); + return Serial_ReceiveByte(USART); +} + +void Serial_SendString_P(USART_t* const USART, + const char* FlashStringPtr) +{ + uint8_t CurrByte; + + while ((CurrByte = pgm_read_byte(FlashStringPtr)) != 0x00) + { + Serial_SendByte(USART, CurrByte); + FlashStringPtr++; + } +} + +void Serial_SendString(USART_t* const USART, + const char* StringPtr) +{ + uint8_t CurrByte; + + while ((CurrByte = *StringPtr) != 0x00) + { + Serial_SendByte(USART, CurrByte); + StringPtr++; + } +} + +void Serial_SendData(USART_t* const USART, + const uint8_t* Buffer, + uint16_t Length) +{ + while (Length--) + Serial_SendByte(USART, *(Buffer++)); +} + +void Serial_CreateStream(FILE* Stream) +{ + if (!(Stream)) + { + Stream = &USARTSerialStream; + stdin = Stream; + stdout = Stream; + } + + *Stream = (FILE)FDEV_SETUP_STREAM(Serial_putchar, Serial_getchar, _FDEV_SETUP_RW); +} + +void Serial_CreateBlockingStream(FILE* Stream) +{ + if (!(Stream)) + { + Stream = &USARTSerialStream; + stdin = Stream; + stdout = Stream; + } + + *Stream = (FILE)FDEV_SETUP_STREAM(Serial_putchar, Serial_getchar_Blocking, _FDEV_SETUP_RW); +} + +#endif diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/XMEGA/Serial_XMEGA.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/XMEGA/Serial_XMEGA.h new file mode 100644 index 00000000..35b60d15 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/Peripheral/XMEGA/Serial_XMEGA.h @@ -0,0 +1,252 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Serial USART Peripheral Driver (XMEGA) + * + * On-chip serial USART driver for the XMEGA AVR microcontrollers. + * + * \note This file should not be included directly. It is automatically included as needed by the USART driver + * dispatch header located in LUFA/Drivers/Peripheral/Serial.h. + */ + +/** \ingroup Group_Serial + * \defgroup Group_Serial_XMEGA Serial USART Peripheral Driver (XMEGA) + * + * \section Sec_ModDescription Module Description + * On-chip serial USART driver for the XMEGA AVR microcontrollers. + * + * \note This file should not be included directly. It is automatically included as needed by the USART driver + * dispatch header located in LUFA/Drivers/Peripheral/Serial.h. + * + * \section Sec_ExampleUsage Example Usage + * The following snippet is an example of how this module may be used within a typical + * application. + * + * \code + * // Initialize the serial USART driver before first use, with 9600 baud (and no double-speed mode) + * Serial_Init(&USARTD0, 9600, false); + * + * // Send a string through the USART + * Serial_TxString(&USARTD0, "Test String\r\n"); + * + * // Receive a byte through the USART + * uint8_t DataByte = Serial_RxByte(&USARTD0); + * \endcode + * + * @{ + */ + +#ifndef __SERIAL_XMEGA_H__ +#define __SERIAL_XMEGA_H__ + + /* Includes: */ + #include "../../../Common/Common.h" + #include "../../Misc/TerminalCodes.h" + + #include + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_SERIAL_H) && !defined(__INCLUDE_FROM_SERIAL_C) + #error Do not include this file directly. Include LUFA/Drivers/Peripheral/Serial.h instead. + #endif + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* External Variables: */ + extern FILE USARTSerialStream; + + /* Function Prototypes: */ + int Serial_putchar(char DataByte, + FILE *Stream); + int Serial_getchar(FILE *Stream); + int Serial_getchar_Blocking(FILE *Stream); + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Macro for calculating the baud value from a given baud rate when the \c U2X (double speed) bit is + * not set. + * + * \param[in] Baud Target serial UART baud rate. + * + * \return Closest UBRR register value for the given UART frequency. + */ + #define SERIAL_UBBRVAL(Baud) ((((F_CPU / 16) + (Baud / 2)) / (Baud)) - 1) + + /** Macro for calculating the baud value from a given baud rate when the \c U2X (double speed) bit is + * set. + * + * \param[in] Baud Target serial UART baud rate. + * + * \return Closest UBRR register value for the given UART frequency. + */ + #define SERIAL_2X_UBBRVAL(Baud) ((((F_CPU / 8) + (Baud / 2)) / (Baud)) - 1) + + /* Function Prototypes: */ + /** Transmits a given string located in program space (FLASH) through the USART. + * + * \param[in,out] USART Pointer to the base of the USART peripheral within the device. + * \param[in] FlashStringPtr Pointer to a string located in program space. + */ + void Serial_SendString_P(USART_t* const USART, + const char* FlashStringPtr) ATTR_NON_NULL_PTR_ARG(1); + + /** Transmits a given string located in SRAM memory through the USART. + * + * \param[in,out] USART Pointer to the base of the USART peripheral within the device. + * \param[in] StringPtr Pointer to a string located in SRAM space. + */ + void Serial_SendString(USART_t* const USART, + const char* StringPtr) ATTR_NON_NULL_PTR_ARG(1); + + /** Transmits a given buffer located in SRAM memory through the USART. + * + * \param[in,out] USART Pointer to the base of the USART peripheral within the device. + * \param[in] Buffer Pointer to a buffer containing the data to send. + * \param[in] Length Length of the data to send, in bytes. + */ + void Serial_SendData(USART_t* const USART, + const uint8_t* Buffer, uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); + + /** Creates a standard character stream from the USART so that it can be used with all the regular functions + * in the avr-libc \c library that accept a \c FILE stream as a destination (e.g. \c fprintf). The created + * stream is bidirectional and can be used for both input and output functions. + * + * Reading data from this stream is non-blocking, i.e. in most instances, complete strings cannot be read in by a single + * fetch, as the endpoint will not be ready at some point in the transmission, aborting the transfer. However, this may + * be used when the read data is processed byte-per-bye (via \c getc()) or when the user application will implement its own + * line buffering. + * + * \param[in,out] Stream Pointer to a FILE structure where the created stream should be placed, if \c NULL, \c stdout + * and \c stdin will be configured to use the USART. + * + * \pre The USART must first be configured via a call to \ref Serial_Init() before the stream is used. + */ + void Serial_CreateStream(FILE* Stream); + + /** Identical to \ref Serial_CreateStream(), except that reads are blocking until the calling stream function terminates + * the transfer. + * + * \param[in,out] Stream Pointer to a FILE structure where the created stream should be placed, if \c NULL, \c stdout + * and \c stdin will be configured to use the USART. + * + * \pre The USART must first be configured via a call to \ref Serial_Init() before the stream is used. + */ + void Serial_CreateBlockingStream(FILE* Stream); + + /* Inline Functions: */ + /** Initializes the USART, ready for serial data transmission and reception. This initializes the interface to + * standard 8-bit, no parity, 1 stop bit settings suitable for most applications. + * + * \param[in,out] USART Pointer to the base of the USART peripheral within the device. + * \param[in] BaudRate Serial baud rate, in bits per second. + * \param[in] DoubleSpeed Enables double speed mode when set, halving the sample time to double the baud rate. + */ + static inline void Serial_Init(USART_t* const USART, + const uint32_t BaudRate, + const bool DoubleSpeed) + { + uint16_t BaudValue = (DoubleSpeed ? SERIAL_2X_UBBRVAL(BaudRate) : SERIAL_UBBRVAL(BaudRate)); + + USART->BAUDCTRLB = (BaudValue >> 8); + USART->BAUDCTRLA = (BaudValue & 0xFF); + + USART->CTRLC = (USART_CMODE_ASYNCHRONOUS_gc | USART_PMODE_DISABLED_gc | USART_CHSIZE_8BIT_gc); + USART->CTRLB = (USART_RXEN_bm | USART_TXEN_bm | (DoubleSpeed ? USART_CLK2X_bm : 0)); + } + + /** Turns off the USART driver, disabling and returning used hardware to their default configuration. + * + * \param[in,out] USART Pointer to the base of the USART peripheral within the device. + */ + static inline void Serial_Disable(USART_t* const USART) + { + USART->CTRLA = 0; + USART->CTRLB = 0; + USART->CTRLC = 0; + } + + /** Indicates whether a character has been received through the USART. + * + * \param[in,out] USART Pointer to the base of the USART peripheral within the device. + * + * \return Boolean \c true if a character has been received, \c false otherwise. + */ + static inline bool Serial_IsCharReceived(USART_t* const USART) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool Serial_IsCharReceived(USART_t* const USART) + { + return ((USART->STATUS & USART_RXCIF_bm) ? true : false); + } + + /** Transmits a given byte through the USART. + * + * \param[in,out] USART Pointer to the base of the USART peripheral within the device. + * \param[in] DataByte Byte to transmit through the USART. + */ + static inline void Serial_SendByte(USART_t* const USART, + const char DataByte) ATTR_ALWAYS_INLINE; + static inline void Serial_SendByte(USART_t* const USART, + const char DataByte) + { + while (!(USART->STATUS & USART_DREIF_bm)); + USART->DATA = DataByte; + } + + /** Receives the next byte from the USART. + * + * \param[in,out] USART Pointer to the base of the USART peripheral within the device. + * + * \return Next byte received from the USART, or a negative value if no byte has been received. + */ + static inline int16_t Serial_ReceiveByte(USART_t* const USART) ATTR_ALWAYS_INLINE; + static inline int16_t Serial_ReceiveByte(USART_t* const USART) + { + if (!(Serial_IsCharReceived(USART))) + return -1; + + USART->STATUS = USART_RXCIF_bm; + return USART->DATA; + } + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/AndroidAccessoryClass.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/AndroidAccessoryClass.h new file mode 100644 index 00000000..2f2fa5bc --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/AndroidAccessoryClass.h @@ -0,0 +1,76 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Master include file for the library USB Android Open Accessory Class driver. + * + * Master include file for the library USB Android Open Accessory Class driver, for both host and device modes, where available. + * + * This file should be included in all user projects making use of this optional class driver, instead of + * including any headers in the USB/ClassDriver/Device, USB/ClassDriver/Host or USB/ClassDriver/Common subdirectories. + */ + +/** \ingroup Group_USBClassDrivers + * \defgroup Group_USBClassAOA Android Open Accessory Class Driver + * + * \section Sec_Dependencies Module Source Dependencies + * The following files must be built with any user project that uses this module: + * - LUFA/Drivers/USB/Class/Host/AndroidAccessoryClassHost.c (Makefile source module name: LUFA_SRC_USBCLASS) + * + * \section Sec_ModDescription Module Description + * Android Open Accessory Class Driver module. This module contains an internal implementation of the USB Android Open Accessory + * Class, for Host USB mode. User applications can use this class driver instead of implementing the Android Open Accessory Class + * manually via the low-level LUFA APIs. + * + * This module is designed to simplify the user code by exposing only the required interface needed to interface with + * Host using the USB Android Open Accessory Class. + * + * @{ + */ + +#ifndef _AOA_CLASS_H_ +#define _AOA_CLASS_H_ + + /* Macros: */ + #define __INCLUDE_FROM_USB_DRIVER + #define __INCLUDE_FROM_AOA_DRIVER + + /* Includes: */ + #include "../Core/USBMode.h" + + #if defined(USB_CAN_BE_HOST) + #include "Host/AndroidAccessoryClassHost.h" + #endif + +#endif + +/** @} */ + + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/AudioClass.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/AudioClass.h new file mode 100644 index 00000000..91aa22f3 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/AudioClass.h @@ -0,0 +1,80 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Master include file for the library USB Audio 1.0 Class driver. + * + * Master include file for the library USB Audio 1.0 Class driver, for both host and device modes, where available. + * + * This file should be included in all user projects making use of this optional class driver, instead of + * including any headers in the USB/ClassDriver/Device, USB/ClassDriver/Host or USB/ClassDriver/Common subdirectories. + */ + +/** \ingroup Group_USBClassDrivers + * \defgroup Group_USBClassAudio Audio 1.0 Class Driver + * + * \section Sec_Dependencies Module Source Dependencies + * The following files must be built with any user project that uses this module: + * - LUFA/Drivers/USB/Class/Device/AudioClassDevice.c (Makefile source module name: LUFA_SRC_USBCLASS) + * - LUFA/Drivers/USB/Class/Host/AudioClassHost.c (Makefile source module name: LUFA_SRC_USBCLASS) + * + * \section Sec_ModDescription Module Description + * Audio 1.0 Class Driver module. This module contains an internal implementation of the USB Audio 1.0 Class, for both + * Device and Host USB modes. User applications can use this class driver instead of implementing the Audio 1.0 class + * manually via the low-level LUFA APIs. + * + * This module is designed to simplify the user code by exposing only the required interface needed to interface with + * Hosts or Devices using the USB Audio 1.0 Class. + * + * @{ + */ + +#ifndef _AUDIO_CLASS_H_ +#define _AUDIO_CLASS_H_ + + /* Macros: */ + #define __INCLUDE_FROM_USB_DRIVER + #define __INCLUDE_FROM_AUDIO_DRIVER + + /* Includes: */ + #include "../Core/USBMode.h" + + #if defined(USB_CAN_BE_DEVICE) + #include "Device/AudioClassDevice.h" + #endif + + #if defined(USB_CAN_BE_HOST) + #include "Host/AudioClassHost.h" + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/CDCClass.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/CDCClass.h new file mode 100644 index 00000000..6bfd3848 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/CDCClass.h @@ -0,0 +1,80 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Master include file for the library USB CDC-ACM Class driver. + * + * Master include file for the library USB CDC Class driver, for both host and device modes, where available. + * + * This file should be included in all user projects making use of this optional class driver, instead of + * including any headers in the USB/ClassDriver/Device, USB/ClassDriver/Host or USB/ClassDriver/Common subdirectories. + */ + +/** \ingroup Group_USBClassDrivers + * \defgroup Group_USBClassCDC CDC-ACM (Virtual Serial) Class Driver + * + * \section Sec_Dependencies Module Source Dependencies + * The following files must be built with any user project that uses this module: + * - LUFA/Drivers/USB/Class/Device/CDCClassDevice.c (Makefile source module name: LUFA_SRC_USBCLASS) + * - LUFA/Drivers/USB/Class/Host/CDCClassHost.c (Makefile source module name: LUFA_SRC_USBCLASS) + * + * \section Sec_ModDescription Module Description + * CDC Class Driver module. This module contains an internal implementation of the USB CDC-ACM class Virtual Serial + * Ports, for both Device and Host USB modes. User applications can use this class driver instead of implementing the + * CDC class manually via the low-level LUFA APIs. + * + * This module is designed to simplify the user code by exposing only the required interface needed to interface with + * Hosts or Devices using the USB CDC Class. + * + * @{ + */ + +#ifndef _CDC_CLASS_H_ +#define _CDC_CLASS_H_ + + /* Macros: */ + #define __INCLUDE_FROM_USB_DRIVER + #define __INCLUDE_FROM_CDC_DRIVER + + /* Includes: */ + #include "../Core/USBMode.h" + + #if defined(USB_CAN_BE_DEVICE) + #include "Device/CDCClassDevice.h" + #endif + + #if defined(USB_CAN_BE_HOST) + #include "Host/CDCClassHost.h" + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Common/AndroidAccessoryClassCommon.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Common/AndroidAccessoryClassCommon.h new file mode 100644 index 00000000..db97f488 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Common/AndroidAccessoryClassCommon.h @@ -0,0 +1,128 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Common definitions and declarations for the library USB Android Open Accessory Class driver. + * + * Common definitions and declarations for the library USB Android Open Accessory Class driver. + * + * \note This file should not be included directly. It is automatically included as needed by the USB module driver + * dispatch header located in LUFA/Drivers/USB.h. + */ + +/** \ingroup Group_USBClassAOA + * \defgroup Group_USBClassAOACommon Common Class Definitions + * + * \section Sec_ModDescription Module Description + * Constants, Types and Enum definitions that are common to both Device and Host modes for the USB + * Android Open Accessory Class. + * + * @{ + */ + +#ifndef _AOA_CLASS_COMMON_H_ +#define _AOA_CLASS_COMMON_H_ + + /* Includes: */ + #include "../../Core/StdDescriptors.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_AOA_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB.h instead. + #endif + + /* Macros: */ + /** Product ID value in a Device Descriptor to indicate an Android device in Open Accessory mode. */ + #define ANDROID_ACCESSORY_PRODUCT_ID 0x2D00 + + /** Product ID value in a Device Descriptor to indicate an Android device in Open Accessory and Android Debug mode. */ + #define ANDROID_ACCESSORY_ADB_PRODUCT_ID 0x2D01 + + /* Enums: */ + /** Enum for possible Class, Subclass and Protocol values of device and interface descriptors relating to the + * Android Open Accessory class. + */ + enum AOA_Descriptor_ClassSubclassProtocol_t + { + AOA_CSCP_AOADataClass = 0xFF, /**< Descriptor Class value indicating that the device or interface + * belongs to the AOA data class. + */ + AOA_CSCP_AOADataSubclass = 0xFF, /**< Descriptor Subclass value indicating that the device or interface + * belongs to AOA data subclass. + */ + AOA_CSCP_AOADataProtocol = 0x00, /**< Descriptor Protocol value indicating that the device or interface + * belongs to the AOA data class protocol. + */ + }; + + /** Enum for the Android Open Accessory class specific control requests that can be issued by the USB bus host. */ + enum AOA_ClassRequests_t + { + AOA_REQ_GetAccessoryProtocol = 0x33, /**< Android Open Accessory control request to retrieve the device's supported Accessory Protocol version. */ + AOA_REQ_SendString = 0x34, /**< Android Open Accessory control request to set an accessory property string in the device. */ + AOA_REQ_StartAccessoryMode = 0x35, /**< Android Open Accessory control request to switch the device into Accessory mode. */ + }; + + /** Enum for the possible Android Open Accessory property string indexes. */ + enum AOA_Strings_t + { + AOA_STRING_Manufacturer = 0, /**< Index of the Manufacturer property string. */ + AOA_STRING_Model = 1, /**< Index of the Model Name property string. */ + AOA_STRING_Description = 2, /**< Index of the Description property string. */ + AOA_STRING_Version = 3, /**< Index of the Version Number property string. */ + AOA_STRING_URI = 4, /**< Index of the URI Information property string. */ + AOA_STRING_Serial = 5, /**< Index of the Serial Number property string. */ + + #if !defined(__DOXYGEN__) + AOA_STRING_TOTAL_STRINGS + #endif + }; + + /** Enum for the possible Android Open Accessory protocol versions. */ + enum AOA_Protocols_t + { + AOA_PROTOCOL_AccessoryV1 = 0x0001, /**< Android Open Accessory version 1. */ + }; + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Common/AudioClassCommon.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Common/AudioClassCommon.h new file mode 100644 index 00000000..f33fef68 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Common/AudioClassCommon.h @@ -0,0 +1,774 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Common definitions and declarations for the library USB Audio 1.0 Class driver. + * + * Common definitions and declarations for the library USB Audio 1.0 Class driver. + * + * \note This file should not be included directly. It is automatically included as needed by the USB module driver + * dispatch header located in LUFA/Drivers/USB.h. + */ + +/** \ingroup Group_USBClassAudio + * \defgroup Group_USBClassAudioCommon Common Class Definitions + * + * \section Sec_ModDescription Module Description + * Constants, Types and Enum definitions that are common to both Device and Host modes for the USB + * Audio 1.0 Class. + * + * @{ + */ + +#ifndef _AUDIO_CLASS_COMMON_H_ +#define _AUDIO_CLASS_COMMON_H_ + + /* Includes: */ + #include "../../Core/StdDescriptors.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_AUDIO_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB.h instead. + #endif + + /* Macros: */ + /** \name Audio Channel Masks */ + //@{ + /** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */ + #define AUDIO_CHANNEL_LEFT_FRONT (1 << 0) + + /** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */ + #define AUDIO_CHANNEL_RIGHT_FRONT (1 << 1) + + /** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */ + #define AUDIO_CHANNEL_CENTER_FRONT (1 << 2) + + /** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */ + #define AUDIO_CHANNEL_LOW_FREQ_ENHANCE (1 << 3) + + /** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */ + #define AUDIO_CHANNEL_LEFT_SURROUND (1 << 4) + + /** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */ + #define AUDIO_CHANNEL_RIGHT_SURROUND (1 << 5) + + /** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */ + #define AUDIO_CHANNEL_LEFT_OF_CENTER (1 << 6) + + /** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */ + #define AUDIO_CHANNEL_RIGHT_OF_CENTER (1 << 7) + + /** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */ + #define AUDIO_CHANNEL_SURROUND (1 << 8) + + /** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */ + #define AUDIO_CHANNEL_SIDE_LEFT (1 << 9) + + /** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */ + #define AUDIO_CHANNEL_SIDE_RIGHT (1 << 10) + + /** Supported channel mask for an Audio class terminal descriptor. See the Audio class specification for more details. */ + #define AUDIO_CHANNEL_TOP (1 << 11) + //@} + + /** \name Audio Feature Masks */ + //@{ + /** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */ + #define AUDIO_FEATURE_MUTE (1 << 0) + + /** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */ + #define AUDIO_FEATURE_VOLUME (1 << 1) + + /** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */ + #define AUDIO_FEATURE_BASS (1 << 2) + + /** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */ + #define AUDIO_FEATURE_MID (1 << 3) + + /** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */ + #define AUDIO_FEATURE_TREBLE (1 << 4) + + /** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */ + #define AUDIO_FEATURE_GRAPHIC_EQUALIZER (1 << 5) + + /** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */ + #define AUDIO_FEATURE_AUTOMATIC_GAIN (1 << 6) + + /** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */ + #define AUDIO_FEATURE_DELAY (1 << 7) + + /** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */ + #define AUDIO_FEATURE_BASS_BOOST (1 << 8) + + /** Supported feature mask for an Audio class feature unit descriptor. See the Audio class specification for more details. */ + #define AUDIO_FEATURE_BASS_LOUDNESS (1 << 9) + //@} + + /** \name Audio Terminal Types */ + //@{ + /** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */ + #define AUDIO_TERMINAL_UNDEFINED 0x0100 + + /** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */ + #define AUDIO_TERMINAL_STREAMING 0x0101 + + /** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */ + #define AUDIO_TERMINAL_VENDOR 0x01FF + + /** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */ + #define AUDIO_TERMINAL_IN_UNDEFINED 0x0200 + + /** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */ + #define AUDIO_TERMINAL_IN_MIC 0x0201 + + /** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */ + #define AUDIO_TERMINAL_IN_DESKTOP_MIC 0x0202 + + /** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */ + #define AUDIO_TERMINAL_IN_PERSONAL_MIC 0x0203 + + /** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */ + #define AUDIO_TERMINAL_IN_OMNIDIR_MIC 0x0204 + + /** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */ + #define AUDIO_TERMINAL_IN_MIC_ARRAY 0x0205 + + /** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */ + #define AUDIO_TERMINAL_IN_PROCESSING_MIC 0x0206 + + /** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */ + #define AUDIO_TERMINAL_IN_OUT_UNDEFINED 0x0300 + + /** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */ + #define AUDIO_TERMINAL_OUT_SPEAKER 0x0301 + + /** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */ + #define AUDIO_TERMINAL_OUT_HEADPHONES 0x0302 + + /** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */ + #define AUDIO_TERMINAL_OUT_HEAD_MOUNTED 0x0303 + + /** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */ + #define AUDIO_TERMINAL_OUT_DESKTOP 0x0304 + + /** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */ + #define AUDIO_TERMINAL_OUT_ROOM 0x0305 + + /** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */ + #define AUDIO_TERMINAL_OUT_COMMUNICATION 0x0306 + + /** Terminal type constant for an Audio class terminal descriptor. See the Audio class specification for more details. */ + #define AUDIO_TERMINAL_OUT_LOWFREQ 0x0307 + //@} + + /** Convenience macro to fill a 24-bit \ref USB_Audio_SampleFreq_t structure with the given sample rate as a 24-bit number. + * + * \param[in] freq Required audio sampling frequency in HZ + */ + #define AUDIO_SAMPLE_FREQ(freq) {.Byte1 = ((uint32_t)freq & 0xFF), .Byte2 = (((uint32_t)freq >> 8) & 0xFF), .Byte3 = (((uint32_t)freq >> 16) & 0xFF)} + + /** Mask for the attributes parameter of an Audio class-specific Endpoint descriptor, indicating that the endpoint + * accepts only filled endpoint packets of audio samples. + */ + #define AUDIO_EP_FULL_PACKETS_ONLY (1 << 7) + + /** Mask for the attributes parameter of an Audio class-specific Endpoint descriptor, indicating that the endpoint + * will accept partially filled endpoint packets of audio samples. + */ + #define AUDIO_EP_ACCEPTS_SMALL_PACKETS (0 << 7) + + /** Mask for the attributes parameter of an Audio class-specific Endpoint descriptor, indicating that the endpoint + * allows for sampling frequency adjustments to be made via control requests directed at the endpoint. + */ + #define AUDIO_EP_SAMPLE_FREQ_CONTROL (1 << 0) + + /** Mask for the attributes parameter of an Audio class-specific Endpoint descriptor, indicating that the endpoint + * allows for pitch adjustments to be made via control requests directed at the endpoint. + */ + #define AUDIO_EP_PITCH_CONTROL (1 << 1) + + /* Enums: */ + /** Enum for possible Class, Subclass and Protocol values of device and interface descriptors relating to the Audio + * device class. + */ + enum Audio_Descriptor_ClassSubclassProtocol_t + { + AUDIO_CSCP_AudioClass = 0x01, /**< Descriptor Class value indicating that the device or + * interface belongs to the USB Audio 1.0 class. + */ + AUDIO_CSCP_ControlSubclass = 0x01, /**< Descriptor Subclass value indicating that the device or + * interface belongs to the Audio Control subclass. + */ + AUDIO_CSCP_ControlProtocol = 0x00, /**< Descriptor Protocol value indicating that the device or + * interface belongs to the Audio Control protocol. + */ + AUDIO_CSCP_AudioStreamingSubclass = 0x02, /**< Descriptor Subclass value indicating that the device or + * interface belongs to the MIDI Streaming subclass. + */ + AUDIO_CSCP_MIDIStreamingSubclass = 0x03, /**< Descriptor Subclass value indicating that the device or + * interface belongs to the Audio streaming subclass. + */ + AUDIO_CSCP_StreamingProtocol = 0x00, /**< Descriptor Protocol value indicating that the device or + * interface belongs to the Streaming Audio protocol. + */ + }; + + /** Audio class specific interface description subtypes, for the Audio Control interface. */ + enum Audio_CSInterface_AC_SubTypes_t + { + AUDIO_DSUBTYPE_CSInterface_Header = 0x01, /**< Audio class specific control interface header. */ + AUDIO_DSUBTYPE_CSInterface_InputTerminal = 0x02, /**< Audio class specific control interface Input Terminal. */ + AUDIO_DSUBTYPE_CSInterface_OutputTerminal = 0x03, /**< Audio class specific control interface Output Terminal. */ + AUDIO_DSUBTYPE_CSInterface_Mixer = 0x04, /**< Audio class specific control interface Mixer Unit. */ + AUDIO_DSUBTYPE_CSInterface_Selector = 0x05, /**< Audio class specific control interface Selector Unit. */ + AUDIO_DSUBTYPE_CSInterface_Feature = 0x06, /**< Audio class specific control interface Feature Unit. */ + AUDIO_DSUBTYPE_CSInterface_Processing = 0x07, /**< Audio class specific control interface Processing Unit. */ + AUDIO_DSUBTYPE_CSInterface_Extension = 0x08, /**< Audio class specific control interface Extension Unit. */ + }; + + /** Audio class specific interface description subtypes, for the Audio Streaming interface. */ + enum Audio_CSInterface_AS_SubTypes_t + { + AUDIO_DSUBTYPE_CSInterface_General = 0x01, /**< Audio class specific streaming interface general descriptor. */ + AUDIO_DSUBTYPE_CSInterface_FormatType = 0x02, /**< Audio class specific streaming interface format type descriptor. */ + AUDIO_DSUBTYPE_CSInterface_FormatSpecific = 0x03, /**< Audio class specific streaming interface format information descriptor. */ + }; + + /** Audio class specific endpoint description subtypes, for the Audio Streaming interface. */ + enum Audio_CSEndpoint_SubTypes_t + { + AUDIO_DSUBTYPE_CSEndpoint_General = 0x01, /**< Audio class specific endpoint general descriptor. */ + }; + + /** Enum for the Audio class specific control requests that can be issued by the USB bus host. */ + enum Audio_ClassRequests_t + { + AUDIO_REQ_SetCurrent = 0x01, /**< Audio class-specific request to set the current value of a parameter within the device. */ + AUDIO_REQ_SetMinimum = 0x02, /**< Audio class-specific request to set the minimum value of a parameter within the device. */ + AUDIO_REQ_SetMaximum = 0x03, /**< Audio class-specific request to set the maximum value of a parameter within the device. */ + AUDIO_REQ_SetResolution = 0x04, /**< Audio class-specific request to set the resolution value of a parameter within the device. */ + AUDIO_REQ_SetMemory = 0x05, /**< Audio class-specific request to set the memory value of a parameter within the device. */ + AUDIO_REQ_GetCurrent = 0x81, /**< Audio class-specific request to get the current value of a parameter within the device. */ + AUDIO_REQ_GetMinimum = 0x82, /**< Audio class-specific request to get the minimum value of a parameter within the device. */ + AUDIO_REQ_GetMaximum = 0x83, /**< Audio class-specific request to get the maximum value of a parameter within the device. */ + AUDIO_REQ_GetResolution = 0x84, /**< Audio class-specific request to get the resolution value of a parameter within the device. */ + AUDIO_REQ_GetMemory = 0x85, /**< Audio class-specific request to get the memory value of a parameter within the device. */ + AUDIO_REQ_GetStatus = 0xFF, /**< Audio class-specific request to get the device status. */ + }; + + /** Enum for Audio class specific Endpoint control modifiers which can be set and retrieved by a USB host, if the corresponding + * endpoint control is indicated to be supported in the Endpoint's Audio-class specific endpoint descriptor. + */ + enum Audio_EndpointControls_t + { + AUDIO_EPCONTROL_SamplingFreq = 0x01, /**< Sampling frequency adjustment of the endpoint. */ + AUDIO_EPCONTROL_Pitch = 0x02, /**< Pitch adjustment of the endpoint. */ + }; + + /* Type Defines: */ + /** \brief Audio class-specific Input Terminal Descriptor (LUFA naming conventions). + * + * Type define for an Audio class-specific input terminal descriptor. This indicates to the host that the device + * contains an input audio source, either from a physical terminal on the device, or a logical terminal (for example, + * a USB endpoint). See the USB Audio specification for more details. + * + * \see \ref USB_Audio_StdDescriptor_InputTerminal_t for the version of this type with standard element names. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length. */ + uint8_t Subtype; /**< Sub type value used to distinguish between audio class-specific descriptors, + * must be \ref AUDIO_DSUBTYPE_CSInterface_InputTerminal. + */ + + uint8_t TerminalID; /**< ID value of this terminal unit - must be a unique value within the device. */ + uint16_t TerminalType; /**< Type of terminal, a \c TERMINAL_* mask. */ + uint8_t AssociatedOutputTerminal; /**< ID of associated output terminal, for physically grouped terminals + * such as the speaker and microphone of a phone handset. + */ + uint8_t TotalChannels; /**< Total number of separate audio channels within this interface (right, left, etc.) */ + uint16_t ChannelConfig; /**< \c CHANNEL_* masks indicating what channel layout is supported by this terminal. */ + + uint8_t ChannelStrIndex; /**< Index of a string descriptor describing this channel within the device. */ + uint8_t TerminalStrIndex; /**< Index of a string descriptor describing this descriptor within the device. */ + } ATTR_PACKED USB_Audio_Descriptor_InputTerminal_t; + + /** \brief Audio class-specific Input Terminal Descriptor (USB-IF naming conventions). + * + * Type define for an Audio class-specific input terminal descriptor. This indicates to the host that the device + * contains an input audio source, either from a physical terminal on the device, or a logical terminal (for example, + * a USB endpoint). See the USB Audio specification for more details. + * + * \see \ref USB_Audio_Descriptor_InputTerminal_t for the version of this type with non-standard LUFA specific + * element names. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + uint8_t bLength; /**< Size of the descriptor, in bytes. */ + uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value + * given by the specific class. + */ + + uint8_t bDescriptorSubtype; /**< Sub type value used to distinguish between audio class-specific descriptors, + * must be \ref AUDIO_DSUBTYPE_CSInterface_InputTerminal. + */ + uint8_t bTerminalID; /**< ID value of this terminal unit - must be a unique value within the device. */ + uint16_t wTerminalType; /**< Type of terminal, a \c TERMINAL_* mask. */ + uint8_t bAssocTerminal; /**< ID of associated output terminal, for physically grouped terminals + * such as the speaker and microphone of a phone handset. + */ + uint8_t bNrChannels; /**< Total number of separate audio channels within this interface (right, left, etc.) */ + uint16_t wChannelConfig; /**< \c CHANNEL_* masks indicating what channel layout is supported by this terminal. */ + + uint8_t iChannelNames; /**< Index of a string descriptor describing this channel within the device. */ + uint8_t iTerminal; /**< Index of a string descriptor describing this descriptor within the device. */ + } ATTR_PACKED USB_Audio_StdDescriptor_InputTerminal_t; + + /** \brief Audio class-specific Output Terminal Descriptor (LUFA naming conventions). + * + * Type define for an Audio class-specific output terminal descriptor. This indicates to the host that the device + * contains an output audio sink, either to a physical terminal on the device, or a logical terminal (for example, + * a USB endpoint). See the USB Audio specification for more details. + * + * \see \ref USB_Audio_StdDescriptor_OutputTerminal_t for the version of this type with standard element names. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length. */ + uint8_t Subtype; /**< Sub type value used to distinguish between audio class-specific descriptors, + * must be \ref AUDIO_DSUBTYPE_CSInterface_OutputTerminal. + */ + + uint8_t TerminalID; /**< ID value of this terminal unit - must be a unique value within the device. */ + uint16_t TerminalType; /**< Type of terminal, a \c TERMINAL_* mask. */ + uint8_t AssociatedInputTerminal; /**< ID of associated input terminal, for physically grouped terminals + * such as the speaker and microphone of a phone handset. + */ + uint8_t SourceID; /**< ID value of the unit this terminal's audio is sourced from. */ + + uint8_t TerminalStrIndex; /**< Index of a string descriptor describing this descriptor within the device. */ + } ATTR_PACKED USB_Audio_Descriptor_OutputTerminal_t; + + /** \brief Audio class-specific Output Terminal Descriptor (USB-IF naming conventions). + * + * Type define for an Audio class-specific output terminal descriptor. This indicates to the host that the device + * contains an output audio sink, either to a physical terminal on the device, or a logical terminal (for example, + * a USB endpoint). See the USB Audio specification for more details. + * + * \see \ref USB_Audio_Descriptor_OutputTerminal_t for the version of this type with non-standard LUFA specific + * element names. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + uint8_t bLength; /**< Size of the descriptor, in bytes. */ + uint8_t bDescriptorType; /**< Sub type value used to distinguish between audio class-specific descriptors, + * must be \ref AUDIO_DSUBTYPE_CSInterface_OutputTerminal. + */ + + uint8_t bDescriptorSubtype; /**< Sub type value used to distinguish between audio class-specific descriptors, + * a value from the \ref Audio_CSInterface_AC_SubTypes_t enum. + */ + uint8_t bTerminalID; /**< ID value of this terminal unit - must be a unique value within the device. */ + uint16_t wTerminalType; /**< Type of terminal, a \c TERMINAL_* mask. */ + uint8_t bAssocTerminal; /**< ID of associated input terminal, for physically grouped terminals + * such as the speaker and microphone of a phone handset. + */ + uint8_t bSourceID; /**< ID value of the unit this terminal's audio is sourced from. */ + + uint8_t iTerminal; /**< Index of a string descriptor describing this descriptor within the device. */ + } ATTR_PACKED USB_Audio_StdDescriptor_OutputTerminal_t; + + /** \brief Audio class-specific Interface Descriptor (LUFA naming conventions). + * + * Type define for an Audio class-specific interface descriptor. This follows a regular interface descriptor to + * supply extra information about the audio device's layout to the host. See the USB Audio specification for more + * details. + * + * \see \ref USB_Audio_StdDescriptor_Interface_AC_t for the version of this type with standard element names. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length. */ + uint8_t Subtype; /**< Sub type value used to distinguish between audio class-specific descriptors, + * a value from the \ref Audio_CSInterface_AS_SubTypes_t enum. + */ + + uint16_t ACSpecification; /**< Binary coded decimal value, indicating the supported Audio Class specification version. */ + uint16_t TotalLength; /**< Total length of the Audio class-specific descriptors, including this descriptor. */ + + uint8_t InCollection; /**< Total number of Audio Streaming interfaces linked to this Audio Control interface (must be 1). */ + uint8_t InterfaceNumber; /**< Interface number of the associated Audio Streaming interface. */ + } ATTR_PACKED USB_Audio_Descriptor_Interface_AC_t; + + /** \brief Audio class-specific Interface Descriptor (USB-IF naming conventions). + * + * Type define for an Audio class-specific interface descriptor. This follows a regular interface descriptor to + * supply extra information about the audio device's layout to the host. See the USB Audio specification for more + * details. + * + * \see \ref USB_Audio_Descriptor_Interface_AC_t for the version of this type with non-standard LUFA specific + * element names. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + uint8_t bLength; /**< Size of the descriptor, in bytes. */ + uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value + * given by the specific class. + */ + + uint8_t bDescriptorSubtype;/**< Sub type value used to distinguish between audio class-specific descriptors, + * a value from the \ref Audio_CSInterface_AS_SubTypes_t enum. + */ + + uint16_t bcdADC; /**< Binary coded decimal value, indicating the supported Audio Class specification version. */ + uint16_t wTotalLength; /**< Total length of the Audio class-specific descriptors, including this descriptor. */ + + uint8_t bInCollection; /**< Total number of Audio Streaming interfaces linked to this Audio Control interface (must be 1). */ + uint8_t bInterfaceNumbers; /**< Interface number of the associated Audio Streaming interface. */ + } ATTR_PACKED USB_Audio_StdDescriptor_Interface_AC_t; + + /** \brief Audio class-specific Feature Unit Descriptor (LUFA naming conventions). + * + * Type define for an Audio class-specific Feature Unit descriptor. This indicates to the host what features + * are present in the device's audio stream for basic control, such as per-channel volume. See the USB Audio + * specification for more details. + * + * \see \ref USB_Audio_StdDescriptor_FeatureUnit_t for the version of this type with standard element names. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length. */ + uint8_t Subtype; /**< Sub type value used to distinguish between audio class-specific descriptors, + * must be \ref AUDIO_DSUBTYPE_CSInterface_Feature. + */ + + uint8_t UnitID; /**< ID value of this feature unit - must be a unique value within the device. */ + uint8_t SourceID; /**< Source ID value of the audio source input into this feature unit. */ + + uint8_t ControlSize; /**< Size of each element in the \c ChannelControls array. */ + uint8_t ChannelControls[3]; /**< Feature masks for the control channel, and each separate audio channel. */ + + uint8_t FeatureUnitStrIndex; /**< Index of a string descriptor describing this descriptor within the device. */ + } ATTR_PACKED USB_Audio_Descriptor_FeatureUnit_t; + + /** \brief Audio class-specific Feature Unit Descriptor (USB-IF naming conventions). + * + * Type define for an Audio class-specific Feature Unit descriptor. This indicates to the host what features + * are present in the device's audio stream for basic control, such as per-channel volume. See the USB Audio + * specification for more details. + * + * \see \ref USB_Audio_Descriptor_FeatureUnit_t for the version of this type with non-standard LUFA specific + * element names. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + uint8_t bLength; /**< Size of the descriptor, in bytes. */ + uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value + * given by the specific class. + */ + + uint8_t bDescriptorSubtype; /**< Sub type value used to distinguish between audio class-specific descriptors, + * must be \ref AUDIO_DSUBTYPE_CSInterface_Feature. + */ + + uint8_t bUnitID; /**< ID value of this feature unit - must be a unique value within the device. */ + uint8_t bSourceID; /**< Source ID value of the audio source input into this feature unit. */ + + uint8_t bControlSize; /**< Size of each element in the \c ChannelControls array. */ + uint8_t bmaControls[3]; /**< Feature masks for the control channel, and each separate audio channel. */ + + uint8_t iFeature; /**< Index of a string descriptor describing this descriptor within the device. */ + } ATTR_PACKED USB_Audio_StdDescriptor_FeatureUnit_t; + + /** \brief Audio class-specific Streaming Audio Interface Descriptor (LUFA naming conventions). + * + * Type define for an Audio class-specific streaming interface descriptor. This indicates to the host + * how audio streams within the device are formatted. See the USB Audio specification for more details. + * + * \see \ref USB_Audio_StdDescriptor_Interface_AS_t for the version of this type with standard element names. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length. */ + uint8_t Subtype; /**< Sub type value used to distinguish between audio class-specific descriptors, + * a value from the \ref Audio_CSInterface_AS_SubTypes_t enum. + */ + + uint8_t TerminalLink; /**< ID value of the output terminal this descriptor is describing. */ + + uint8_t FrameDelay; /**< Delay in frames resulting from the complete sample processing from input to output. */ + uint16_t AudioFormat; /**< Format of the audio stream, see Audio Device Formats specification. */ + } ATTR_PACKED USB_Audio_Descriptor_Interface_AS_t; + + /** \brief Audio class-specific Streaming Audio Interface Descriptor (USB-IF naming conventions). + * + * Type define for an Audio class-specific streaming interface descriptor. This indicates to the host + * how audio streams within the device are formatted. See the USB Audio specification for more details. + * + * \see \ref USB_Audio_Descriptor_Interface_AS_t for the version of this type with non-standard LUFA specific + * element names. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + uint8_t bLength; /**< Size of the descriptor, in bytes. */ + uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value + * given by the specific class. + */ + + uint8_t bDescriptorSubtype; /**< Sub type value used to distinguish between audio class-specific descriptors, + * a value from the \ref Audio_CSInterface_AS_SubTypes_t enum. + */ + + uint8_t bTerminalLink; /**< ID value of the output terminal this descriptor is describing. */ + + uint8_t bDelay; /**< Delay in frames resulting from the complete sample processing from input to output. */ + uint16_t wFormatTag; /**< Format of the audio stream, see Audio Device Formats specification. */ + } ATTR_PACKED USB_Audio_StdDescriptor_Interface_AS_t; + + /** \brief Audio class-specific Format Descriptor (LUFA naming conventions). + * + * Type define for an Audio class-specific audio format descriptor. This is used to give the host full details + * about the number of channels, the sample resolution, acceptable sample frequencies and encoding method used + * in the device's audio streams. See the USB Audio specification for more details. + * + * \attention This descriptor must be followed by one or more \ref USB_Audio_SampleFreq_t elements containing + * the continuous or discrete sample frequencies. + * + * \see \ref USB_Audio_StdDescriptor_Format_t for the version of this type with standard element names. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length. */ + uint8_t Subtype; /**< Sub type value used to distinguish between audio class-specific descriptors, + * must be \ref AUDIO_DSUBTYPE_CSInterface_FormatType. + */ + + uint8_t FormatType; /**< Format of the audio stream, see Audio Device Formats specification. */ + uint8_t Channels; /**< Total number of discrete channels in the stream. */ + + uint8_t SubFrameSize; /**< Size in bytes of each channel's sample data in the stream. */ + uint8_t BitResolution; /**< Bits of resolution of each channel's samples in the stream. */ + + uint8_t TotalDiscreteSampleRates; /**< Total number of discrete sample frequencies supported by the device. When + * zero, this must be followed by the lower and upper continuous sampling + * frequencies supported by the device; otherwise, this must be followed + * by the given number of discrete sampling frequencies supported. + */ + } ATTR_PACKED USB_Audio_Descriptor_Format_t; + + /** \brief 24-Bit Audio Frequency Structure. + * + * Type define for a 24bit audio sample frequency structure. As GCC does not contain a built in 24-bit datatype, + * this this structure is used to build up the value instead. Fill this structure with the \ref AUDIO_SAMPLE_FREQ() macro. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + uint8_t Byte1; /**< Lowest 8 bits of the 24-bit value. */ + uint8_t Byte2; /**< Middle 8 bits of the 24-bit value. */ + uint8_t Byte3; /**< Upper 8 bits of the 24-bit value. */ + } ATTR_PACKED USB_Audio_SampleFreq_t; + + /** \brief Audio class-specific Format Descriptor (USB-IF naming conventions). + * + * Type define for an Audio class-specific audio format descriptor. This is used to give the host full details + * about the number of channels, the sample resolution, acceptable sample frequencies and encoding method used + * in the device's audio streams. See the USB Audio specification for more details. + * + * \attention This descriptor must be followed by one or more 24-bit integer elements containing the continuous + * or discrete sample frequencies. + * + * \see \ref USB_Audio_Descriptor_Format_t for the version of this type with non-standard LUFA specific + * element names. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + uint8_t bLength; /**< Size of the descriptor, in bytes. */ + uint8_t bDescriptorType; /**< Sub type value used to distinguish between audio class-specific descriptors, + * must be \ref AUDIO_DSUBTYPE_CSInterface_FormatType. + */ + + uint8_t bDescriptorSubtype;/**< Sub type value used to distinguish between audio class-specific descriptors, + * a value from the \ref Audio_CSInterface_AS_SubTypes_t enum. + */ + + uint8_t bFormatType; /**< Format of the audio stream, see Audio Device Formats specification. */ + uint8_t bNrChannels; /**< Total number of discrete channels in the stream. */ + + uint8_t bSubFrameSize; /**< Size in bytes of each channel's sample data in the stream. */ + uint8_t bBitResolution; /**< Bits of resolution of each channel's samples in the stream. */ + + uint8_t bSampleFrequencyType; /**< Total number of sample frequencies supported by the device. When + * zero, this must be followed by the lower and upper continuous sampling + * frequencies supported by the device; otherwise, this must be followed + * by the given number of discrete sampling frequencies supported. + */ + } ATTR_PACKED USB_Audio_StdDescriptor_Format_t; + + /** \brief Audio class-specific Streaming Endpoint Descriptor (LUFA naming conventions). + * + * Type define for an Audio class-specific endpoint descriptor. This contains a regular endpoint + * descriptor with a few Audio-class-specific extensions. See the USB Audio specification for more details. + * + * \see \ref USB_Audio_StdDescriptor_StreamEndpoint_Std_t for the version of this type with standard element names. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + USB_Descriptor_Endpoint_t Endpoint; /**< Standard endpoint descriptor describing the audio endpoint. */ + + uint8_t Refresh; /**< Always set to zero for Audio class devices. */ + uint8_t SyncEndpointNumber; /**< Endpoint address to send synchronization information to, if needed (zero otherwise). */ + } ATTR_PACKED USB_Audio_Descriptor_StreamEndpoint_Std_t; + + /** \brief Audio class-specific Streaming Endpoint Descriptor (USB-IF naming conventions). + * + * Type define for an Audio class-specific endpoint descriptor. This contains a regular endpoint + * descriptor with a few Audio-class-specific extensions. See the USB Audio specification for more details. + * + * \see \ref USB_Audio_Descriptor_StreamEndpoint_Std_t for the version of this type with non-standard LUFA specific + * element names. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + uint8_t bLength; /**< Size of the descriptor, in bytes. */ + uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a + * value given by the specific class. + */ + uint8_t bEndpointAddress; /**< Logical address of the endpoint within the device for the current + * configuration, including direction mask. + */ + uint8_t bmAttributes; /**< Endpoint attributes, comprised of a mask of the endpoint type (\c EP_TYPE_*) + * and attributes (\c ENDPOINT_ATTR_*) masks. + */ + 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. + */ + + uint8_t bRefresh; /**< Always set to zero for Audio class devices. */ + uint8_t bSynchAddress; /**< Endpoint address to send synchronization information to, if needed (zero otherwise). */ + } ATTR_PACKED USB_Audio_StdDescriptor_StreamEndpoint_Std_t; + + /** \brief Audio class-specific Extended Endpoint Descriptor (LUFA naming conventions). + * + * Type define for an Audio class-specific extended endpoint descriptor. This contains extra information + * on the usage of endpoints used to stream audio in and out of the USB Audio device, and follows an Audio + * class-specific extended endpoint descriptor. See the USB Audio specification for more details. + * + * \see \ref USB_Audio_StdDescriptor_StreamEndpoint_Spc_t for the version of this type with standard element names. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length. */ + uint8_t Subtype; /**< Sub type value used to distinguish between audio class-specific descriptors, + * a value from the \ref Audio_CSEndpoint_SubTypes_t enum. + */ + + uint8_t Attributes; /**< Audio class-specific endpoint attributes, such as \ref AUDIO_EP_FULL_PACKETS_ONLY. */ + + uint8_t LockDelayUnits; /**< Units used for the LockDelay field, see Audio class specification. */ + uint16_t LockDelay; /**< Time required to internally lock endpoint's internal clock recovery circuitry. */ + } ATTR_PACKED USB_Audio_Descriptor_StreamEndpoint_Spc_t; + + /** \brief Audio class-specific Extended Endpoint Descriptor (USB-IF naming conventions). + * + * Type define for an Audio class-specific extended endpoint descriptor. This contains extra information + * on the usage of endpoints used to stream audio in and out of the USB Audio device, and follows an Audio + * class-specific extended endpoint descriptor. See the USB Audio specification for more details. + * + * \see \ref USB_Audio_Descriptor_StreamEndpoint_Spc_t for the version of this type with non-standard LUFA specific + * element names. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + uint8_t bLength; /**< Size of the descriptor, in bytes. */ + uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value + * given by the specific class. + */ + + uint8_t bDescriptorSubtype; /**< Sub type value used to distinguish between audio class-specific descriptors, + * a value from the \ref Audio_CSEndpoint_SubTypes_t enum. + */ + + uint8_t bmAttributes; /**< Audio class-specific endpoint attributes, such as \ref AUDIO_EP_FULL_PACKETS_ONLY. */ + + uint8_t bLockDelayUnits; /**< Units used for the LockDelay field, see Audio class specification. */ + uint16_t wLockDelay; /**< Time required to internally lock endpoint's internal clock recovery circuitry. */ + } ATTR_PACKED USB_Audio_StdDescriptor_StreamEndpoint_Spc_t; + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Common/CDCClassCommon.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Common/CDCClassCommon.h new file mode 100644 index 00000000..f14a766c --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Common/CDCClassCommon.h @@ -0,0 +1,386 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Common definitions and declarations for the library USB CDC Class driver. + * + * Common definitions and declarations for the library USB CDC Class driver. + * + * \note This file should not be included directly. It is automatically included as needed by the USB module driver + * dispatch header located in LUFA/Drivers/USB.h. + */ + +/** \ingroup Group_USBClassCDC + * \defgroup Group_USBClassCDCCommon Common Class Definitions + * + * \section Sec_ModDescription Module Description + * Constants, Types and Enum definitions that are common to both Device and Host modes for the USB + * CDC Class. + * + * @{ + */ + +#ifndef _CDC_CLASS_COMMON_H_ +#define _CDC_CLASS_COMMON_H_ + + /* Includes: */ + #include "../../Core/StdDescriptors.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_CDC_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB.h instead. + #endif + + /* Macros: */ + /** \name Virtual Control Line Masks */ + //@{ + /** Mask for the DTR handshake line for use with the \ref CDC_REQ_SetControlLineState class-specific request + * from the host, to indicate that the DTR line state should be high. + */ + #define CDC_CONTROL_LINE_OUT_DTR (1 << 0) + + /** Mask for the RTS handshake line for use with the \ref CDC_REQ_SetControlLineState class-specific request + * from the host, to indicate that the RTS line state should be high. + */ + #define CDC_CONTROL_LINE_OUT_RTS (1 << 1) + + /** Mask for the DCD handshake line for use with the \ref CDC_NOTIF_SerialState class-specific notification + * from the device to the host, to indicate that the DCD line state is currently high. + */ + #define CDC_CONTROL_LINE_IN_DCD (1 << 0) + + /** Mask for the DSR handshake line for use with the \ref CDC_NOTIF_SerialState class-specific notification + * from the device to the host, to indicate that the DSR line state is currently high. + */ + #define CDC_CONTROL_LINE_IN_DSR (1 << 1) + + /** Mask for the BREAK handshake line for use with the \ref CDC_NOTIF_SerialState class-specific notification + * from the device to the host, to indicate that the BREAK line state is currently high. + */ + #define CDC_CONTROL_LINE_IN_BREAK (1 << 2) + + /** Mask for the RING handshake line for use with the \ref CDC_NOTIF_SerialState class-specific notification + * from the device to the host, to indicate that the RING line state is currently high. + */ + #define CDC_CONTROL_LINE_IN_RING (1 << 3) + + /** Mask for use with the \ref CDC_NOTIF_SerialState class-specific notification from the device to the host, + * to indicate that a framing error has occurred on the virtual serial port. + */ + #define CDC_CONTROL_LINE_IN_FRAMEERROR (1 << 4) + + /** Mask for use with the \ref CDC_NOTIF_SerialState class-specific notification from the device to the host, + * to indicate that a parity error has occurred on the virtual serial port. + */ + #define CDC_CONTROL_LINE_IN_PARITYERROR (1 << 5) + + /** Mask for use with the \ref CDC_NOTIF_SerialState class-specific notification from the device to the host, + * to indicate that a data overrun error has occurred on the virtual serial port. + */ + #define CDC_CONTROL_LINE_IN_OVERRUNERROR (1 << 6) + //@} + + /** Macro to define a CDC class-specific functional descriptor. CDC functional descriptors have a + * uniform structure but variable sized data payloads, thus cannot be represented accurately by + * a single typedef struct. A macro is used instead so that functional descriptors can be created + * easily by specifying the size of the payload. This allows \c sizeof() to work correctly. + * + * \param[in] DataSize Size in bytes of the CDC functional descriptor's data payload. + */ + #define CDC_FUNCTIONAL_DESCRIPTOR(DataSize) \ + struct \ + { \ + USB_Descriptor_Header_t Header; \ + uint8_t SubType; \ + uint8_t Data[DataSize]; \ + } + + /* Enums: */ + /** Enum for possible Class, Subclass and Protocol values of device and interface descriptors relating to the CDC + * device class. + */ + enum CDC_Descriptor_ClassSubclassProtocol_t + { + CDC_CSCP_CDCClass = 0x02, /**< Descriptor Class value indicating that the device or interface + * belongs to the CDC class. + */ + CDC_CSCP_NoSpecificSubclass = 0x00, /**< Descriptor Subclass value indicating that the device or interface + * belongs to no specific subclass of the CDC class. + */ + CDC_CSCP_ACMSubclass = 0x02, /**< Descriptor Subclass value indicating that the device or interface + * belongs to the Abstract Control Model CDC subclass. + */ + CDC_CSCP_ATCommandProtocol = 0x01, /**< Descriptor Protocol value indicating that the device or interface + * belongs to the AT Command protocol of the CDC class. + */ + CDC_CSCP_NoSpecificProtocol = 0x00, /**< Descriptor Protocol value indicating that the device or interface + * belongs to no specific protocol of the CDC class. + */ + CDC_CSCP_VendorSpecificProtocol = 0xFF, /**< Descriptor Protocol value indicating that the device or interface + * belongs to a vendor-specific protocol of the CDC class. + */ + CDC_CSCP_CDCDataClass = 0x0A, /**< Descriptor Class value indicating that the device or interface + * belongs to the CDC Data class. + */ + CDC_CSCP_NoDataSubclass = 0x00, /**< Descriptor Subclass value indicating that the device or interface + * belongs to no specific subclass of the CDC data class. + */ + CDC_CSCP_NoDataProtocol = 0x00, /**< Descriptor Protocol value indicating that the device or interface + * belongs to no specific protocol of the CDC data class. + */ + }; + + /** Enum for the CDC class specific control requests that can be issued by the USB bus host. */ + enum CDC_ClassRequests_t + { + CDC_REQ_SendEncapsulatedCommand = 0x00, /**< CDC class-specific request to send an encapsulated command to the device. */ + CDC_REQ_GetEncapsulatedResponse = 0x01, /**< CDC class-specific request to retrieve an encapsulated command response from the device. */ + CDC_REQ_SetLineEncoding = 0x20, /**< CDC class-specific request to set the current virtual serial port configuration settings. */ + CDC_REQ_GetLineEncoding = 0x21, /**< CDC class-specific request to get the current virtual serial port configuration settings. */ + CDC_REQ_SetControlLineState = 0x22, /**< CDC class-specific request to set the current virtual serial port handshake line states. */ + CDC_REQ_SendBreak = 0x23, /**< CDC class-specific request to send a break to the receiver via the carrier channel. */ + }; + + /** Enum for the CDC class specific notification requests that can be issued by a CDC device to a host. */ + enum CDC_ClassNotifications_t + { + CDC_NOTIF_SerialState = 0x20, /**< Notification type constant for a change in the virtual serial port + * handshake line states, for use with a \ref USB_Request_Header_t + * notification structure when sent to the host via the CDC notification + * endpoint. + */ + }; + + /** Enum for the CDC class specific interface descriptor subtypes. */ + enum CDC_DescriptorSubtypes_t + { + CDC_DSUBTYPE_CSInterface_Header = 0x00, /**< CDC class-specific Header functional descriptor. */ + CDC_DSUBTYPE_CSInterface_CallManagement = 0x01, /**< CDC class-specific Call Management functional descriptor. */ + CDC_DSUBTYPE_CSInterface_ACM = 0x02, /**< CDC class-specific Abstract Control Model functional descriptor. */ + CDC_DSUBTYPE_CSInterface_DirectLine = 0x03, /**< CDC class-specific Direct Line functional descriptor. */ + CDC_DSUBTYPE_CSInterface_TelephoneRinger = 0x04, /**< CDC class-specific Telephone Ringer functional descriptor. */ + CDC_DSUBTYPE_CSInterface_TelephoneCall = 0x05, /**< CDC class-specific Telephone Call functional descriptor. */ + CDC_DSUBTYPE_CSInterface_Union = 0x06, /**< CDC class-specific Union functional descriptor. */ + CDC_DSUBTYPE_CSInterface_CountrySelection = 0x07, /**< CDC class-specific Country Selection functional descriptor. */ + CDC_DSUBTYPE_CSInterface_TelephoneOpModes = 0x08, /**< CDC class-specific Telephone Operation Modes functional descriptor. */ + CDC_DSUBTYPE_CSInterface_USBTerminal = 0x09, /**< CDC class-specific USB Terminal functional descriptor. */ + CDC_DSUBTYPE_CSInterface_NetworkChannel = 0x0A, /**< CDC class-specific Network Channel functional descriptor. */ + CDC_DSUBTYPE_CSInterface_ProtocolUnit = 0x0B, /**< CDC class-specific Protocol Unit functional descriptor. */ + CDC_DSUBTYPE_CSInterface_ExtensionUnit = 0x0C, /**< CDC class-specific Extension Unit functional descriptor. */ + CDC_DSUBTYPE_CSInterface_MultiChannel = 0x0D, /**< CDC class-specific Multi-Channel Management functional descriptor. */ + CDC_DSUBTYPE_CSInterface_CAPI = 0x0E, /**< CDC class-specific Common ISDN API functional descriptor. */ + CDC_DSUBTYPE_CSInterface_Ethernet = 0x0F, /**< CDC class-specific Ethernet functional descriptor. */ + CDC_DSUBTYPE_CSInterface_ATM = 0x10, /**< CDC class-specific Asynchronous Transfer Mode functional descriptor. */ + }; + + /** Enum for the possible line encoding formats of a virtual serial port. */ + enum CDC_LineEncodingFormats_t + { + CDC_LINEENCODING_OneStopBit = 0, /**< Each frame contains one stop bit. */ + CDC_LINEENCODING_OneAndAHalfStopBits = 1, /**< Each frame contains one and a half stop bits. */ + CDC_LINEENCODING_TwoStopBits = 2, /**< Each frame contains two stop bits. */ + }; + + /** Enum for the possible line encoding parity settings of a virtual serial port. */ + enum CDC_LineEncodingParity_t + { + CDC_PARITY_None = 0, /**< No parity bit mode on each frame. */ + CDC_PARITY_Odd = 1, /**< Odd parity bit mode on each frame. */ + CDC_PARITY_Even = 2, /**< Even parity bit mode on each frame. */ + CDC_PARITY_Mark = 3, /**< Mark parity bit mode on each frame. */ + CDC_PARITY_Space = 4, /**< Space parity bit mode on each frame. */ + }; + + /* Type Defines: */ + /** \brief CDC class-specific Functional Header Descriptor (LUFA naming conventions). + * + * Type define for a CDC class-specific functional header descriptor. This indicates to the host that the device + * contains one or more CDC functional data descriptors, which give the CDC interface's capabilities and configuration. + * See the CDC class specification for more details. + * + * \see \ref USB_CDC_StdDescriptor_FunctionalHeader_t for the version of this type with standard element names. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length. */ + uint8_t Subtype; /**< Sub type value used to distinguish between CDC class-specific descriptors, + * must be \ref CDC_DSUBTYPE_CSInterface_Header. + */ + uint16_t CDCSpecification; /**< Version number of the CDC specification implemented by the device, + * encoded in BCD format. + */ + } ATTR_PACKED USB_CDC_Descriptor_FunctionalHeader_t; + + /** \brief CDC class-specific Functional Header Descriptor (USB-IF naming conventions). + * + * Type define for a CDC class-specific functional header descriptor. This indicates to the host that the device + * contains one or more CDC functional data descriptors, which give the CDC interface's capabilities and configuration. + * See the CDC class specification for more details. + * + * \see \ref USB_CDC_Descriptor_FunctionalHeader_t for the version of this type with non-standard LUFA specific + * element names. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + uint8_t bFunctionLength; /**< Size of the descriptor, in bytes. */ + uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value + * given by the specific class. + */ + uint8_t bDescriptorSubType; /**< Sub type value used to distinguish between CDC class-specific descriptors, + * must be \ref CDC_DSUBTYPE_CSInterface_Header. + */ + uint16_t bcdCDC; /**< Version number of the CDC specification implemented by the device, encoded in BCD format. */ + } ATTR_PACKED USB_CDC_StdDescriptor_FunctionalHeader_t; + + /** \brief CDC class-specific Functional ACM Descriptor (LUFA naming conventions). + * + * Type define for a CDC class-specific functional ACM descriptor. This indicates to the host that the CDC interface + * supports the CDC ACM subclass of the CDC specification. See the CDC class specification for more details. + * + * \see \ref USB_CDC_StdDescriptor_FunctionalACM_t for the version of this type with standard element names. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length. */ + uint8_t Subtype; /**< Sub type value used to distinguish between CDC class-specific descriptors, + * must be \ref CDC_DSUBTYPE_CSInterface_ACM. + */ + uint8_t Capabilities; /**< Capabilities of the ACM interface, given as a bit mask. For most devices, + * this should be set to a fixed value of 0x06 - for other capabilities, refer + * to the CDC ACM specification. + */ + } ATTR_PACKED USB_CDC_Descriptor_FunctionalACM_t; + + /** \brief CDC class-specific Functional ACM Descriptor (USB-IF naming conventions). + * + * Type define for a CDC class-specific functional ACM descriptor. This indicates to the host that the CDC interface + * supports the CDC ACM subclass of the CDC specification. See the CDC class specification for more details. + * + * \see \ref USB_CDC_Descriptor_FunctionalACM_t for the version of this type with non-standard LUFA specific + * element names. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + uint8_t bFunctionLength; /**< Size of the descriptor, in bytes. */ + uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value + * given by the specific class. + */ + uint8_t bDescriptorSubType; /**< Sub type value used to distinguish between CDC class-specific descriptors, + * must be \ref CDC_DSUBTYPE_CSInterface_ACM. + */ + uint8_t bmCapabilities; /**< Capabilities of the ACM interface, given as a bit mask. For most devices, + * this should be set to a fixed value of 0x06 - for other capabilities, refer + * to the CDC ACM specification. + */ + } ATTR_PACKED USB_CDC_StdDescriptor_FunctionalACM_t; + + /** \brief CDC class-specific Functional Union Descriptor (LUFA naming conventions). + * + * Type define for a CDC class-specific functional Union descriptor. This indicates to the host that specific + * CDC control and data interfaces are related. See the CDC class specification for more details. + * + * \see \ref USB_CDC_StdDescriptor_FunctionalUnion_t for the version of this type with standard element names. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length. */ + uint8_t Subtype; /**< Sub type value used to distinguish between CDC class-specific descriptors, + * must be \ref CDC_DSUBTYPE_CSInterface_Union. + */ + uint8_t MasterInterfaceNumber; /**< Interface number of the CDC Control interface. */ + uint8_t SlaveInterfaceNumber; /**< Interface number of the CDC Data interface. */ + } ATTR_PACKED USB_CDC_Descriptor_FunctionalUnion_t; + + /** \brief CDC class-specific Functional Union Descriptor (USB-IF naming conventions). + * + * Type define for a CDC class-specific functional Union descriptor. This indicates to the host that specific + * CDC control and data interfaces are related. See the CDC class specification for more details. + * + * \see \ref USB_CDC_Descriptor_FunctionalUnion_t for the version of this type with non-standard LUFA specific + * element names. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + uint8_t bFunctionLength; /**< Size of the descriptor, in bytes. */ + uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value + * given by the specific class. + */ + uint8_t bDescriptorSubType; /**< Sub type value used to distinguish between CDC class-specific descriptors, + * must be \ref CDC_DSUBTYPE_CSInterface_Union. + */ + uint8_t bMasterInterface; /**< Interface number of the CDC Control interface. */ + uint8_t bSlaveInterface0; /**< Interface number of the CDC Data interface. */ + } ATTR_PACKED USB_CDC_StdDescriptor_FunctionalUnion_t; + + /** \brief CDC Virtual Serial Port Line Encoding Settings Structure. + * + * Type define for a CDC Line Encoding structure, used to hold the various encoding parameters for a virtual + * serial port. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + uint32_t BaudRateBPS; /**< Baud rate of the virtual serial port, in bits per second. */ + uint8_t CharFormat; /**< Character format of the virtual serial port, a value from the + * \ref CDC_LineEncodingFormats_t enum. + */ + uint8_t ParityType; /**< Parity setting of the virtual serial port, a value from the + * \ref CDC_LineEncodingParity_t enum. + */ + uint8_t DataBits; /**< Bits of data per character of the virtual serial port. */ + } ATTR_PACKED CDC_LineEncoding_t; + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Common/HIDClassCommon.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Common/HIDClassCommon.h new file mode 100644 index 00000000..bc5cb465 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Common/HIDClassCommon.h @@ -0,0 +1,655 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Common definitions and declarations for the library USB HID Class driver. + * + * Common definitions and declarations for the library USB HID Class driver. + * + * \note This file should not be included directly. It is automatically included as needed by the USB module driver + * dispatch header located in LUFA/Drivers/USB.h. + */ + +/** \ingroup Group_USBClassHID + * \defgroup Group_USBClassHIDCommon Common Class Definitions + * + * \section Sec_ModDescription Module Description + * Constants, Types and Enum definitions that are common to both Device and Host modes for the USB + * HID Class. + * + * @{ + */ + +#ifndef _HID_CLASS_COMMON_H_ +#define _HID_CLASS_COMMON_H_ + + /* Includes: */ + #include "../../Core/StdDescriptors.h" + #include "HIDParser.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_HID_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB.h instead. + #endif + + /* Macros: */ + /** \name Keyboard Standard Report Modifier Masks */ + //@{ + /** Constant for a keyboard report modifier byte, indicating that the keyboard's left control key is currently pressed. */ + #define HID_KEYBOARD_MODIFIER_LEFTCTRL (1 << 0) + + /** Constant for a keyboard report modifier byte, indicating that the keyboard's left shift key is currently pressed. */ + #define HID_KEYBOARD_MODIFIER_LEFTSHIFT (1 << 1) + + /** Constant for a keyboard report modifier byte, indicating that the keyboard's left alt key is currently pressed. */ + #define HID_KEYBOARD_MODIFIER_LEFTALT (1 << 2) + + /** Constant for a keyboard report modifier byte, indicating that the keyboard's left GUI key is currently pressed. */ + #define HID_KEYBOARD_MODIFIER_LEFTGUI (1 << 3) + + /** Constant for a keyboard report modifier byte, indicating that the keyboard's right control key is currently pressed. */ + #define HID_KEYBOARD_MODIFIER_RIGHTCTRL (1 << 4) + + /** Constant for a keyboard report modifier byte, indicating that the keyboard's right shift key is currently pressed. */ + #define HID_KEYBOARD_MODIFIER_RIGHTSHIFT (1 << 5) + + /** Constant for a keyboard report modifier byte, indicating that the keyboard's right alt key is currently pressed. */ + #define HID_KEYBOARD_MODIFIER_RIGHTALT (1 << 6) + + /** Constant for a keyboard report modifier byte, indicating that the keyboard's right GUI key is currently pressed. */ + #define HID_KEYBOARD_MODIFIER_RIGHTGUI (1 << 7) + //@} + + /** \name Keyboard Standard Report LED Masks */ + //@{ + /** Constant for a keyboard output report LED byte, indicating that the host's NUM LOCK mode is currently set. */ + #define HID_KEYBOARD_LED_NUMLOCK (1 << 0) + + /** Constant for a keyboard output report LED byte, indicating that the host's CAPS LOCK mode is currently set. */ + #define HID_KEYBOARD_LED_CAPSLOCK (1 << 1) + + /** Constant for a keyboard output report LED byte, indicating that the host's SCROLL LOCK mode is currently set. */ + #define HID_KEYBOARD_LED_SCROLLLOCK (1 << 2) + + /** Constant for a keyboard output report LED byte, indicating that the host's KATANA mode is currently set. */ + #define HID_KEYBOARD_LED_KATANA (1 << 3) + //@} + + /** \name Keyboard Standard Report Key Scan-codes */ + //@{ + #define HID_KEYBOARD_SC_ERROR_ROLLOVER 0x01 + #define HID_KEYBOARD_SC_POST_FAIL 0x02 + #define HID_KEYBOARD_SC_ERROR_UNDEFINED 0x03 + #define HID_KEYBOARD_SC_A 0x04 + #define HID_KEYBOARD_SC_B 0x05 + #define HID_KEYBOARD_SC_C 0x06 + #define HID_KEYBOARD_SC_D 0x07 + #define HID_KEYBOARD_SC_E 0x08 + #define HID_KEYBOARD_SC_F 0x09 + #define HID_KEYBOARD_SC_G 0x0A + #define HID_KEYBOARD_SC_H 0x0B + #define HID_KEYBOARD_SC_I 0x0C + #define HID_KEYBOARD_SC_J 0x0D + #define HID_KEYBOARD_SC_K 0x0E + #define HID_KEYBOARD_SC_L 0x0F + #define HID_KEYBOARD_SC_M 0x10 + #define HID_KEYBOARD_SC_N 0x11 + #define HID_KEYBOARD_SC_O 0x12 + #define HID_KEYBOARD_SC_P 0x13 + #define HID_KEYBOARD_SC_Q 0x14 + #define HID_KEYBOARD_SC_R 0x15 + #define HID_KEYBOARD_SC_S 0x16 + #define HID_KEYBOARD_SC_T 0x17 + #define HID_KEYBOARD_SC_U 0x18 + #define HID_KEYBOARD_SC_V 0x19 + #define HID_KEYBOARD_SC_W 0x1A + #define HID_KEYBOARD_SC_X 0x1B + #define HID_KEYBOARD_SC_Y 0x1C + #define HID_KEYBOARD_SC_Z 0x1D + #define HID_KEYBOARD_SC_1_AND_EXCLAMATION 0x1E + #define HID_KEYBOARD_SC_2_AND_AT 0x1F + #define HID_KEYBOARD_SC_3_AND_HASHMARK 0x20 + #define HID_KEYBOARD_SC_4_AND_DOLLAR 0x21 + #define HID_KEYBOARD_SC_5_AND_PERCENTAGE 0x22 + #define HID_KEYBOARD_SC_6_AND_CARET 0x23 + #define HID_KEYBOARD_SC_7_AND_AND_AMPERSAND 0x24 + #define HID_KEYBOARD_SC_8_AND_ASTERISK 0x25 + #define HID_KEYBOARD_SC_9_AND_OPENING_PARENTHESIS 0x26 + #define HID_KEYBOARD_SC_0_AND_CLOSING_PARENTHESIS 0x27 + #define HID_KEYBOARD_SC_ENTER 0x28 + #define HID_KEYBOARD_SC_ESCAPE 0x29 + #define HID_KEYBOARD_SC_BACKSPACE 0x2A + #define HID_KEYBOARD_SC_TAB 0x2B + #define HID_KEYBOARD_SC_SPACE 0x2C + #define HID_KEYBOARD_SC_MINUS_AND_UNDERSCORE 0x2D + #define HID_KEYBOARD_SC_EQUAL_AND_PLUS 0x2E + #define HID_KEYBOARD_SC_OPENING_BRACKET_AND_OPENING_BRACE 0x2F + #define HID_KEYBOARD_SC_CLOSING_BRACKET_AND_CLOSING_BRACE 0x30 + #define HID_KEYBOARD_SC_BACKSLASH_AND_PIPE 0x31 + #define HID_KEYBOARD_SC_NON_US_HASHMARK_AND_TILDE 0x32 + #define HID_KEYBOARD_SC_SEMICOLON_AND_COLON 0x33 + #define HID_KEYBOARD_SC_APOSTROPHE_AND_QUOTE 0x34 + #define HID_KEYBOARD_SC_GRAVE_ACCENT_AND_TILDE 0x35 + #define HID_KEYBOARD_SC_COMMA_AND_LESS_THAN_SIGN 0x36 + #define HID_KEYBOARD_SC_DOT_AND_GREATER_THAN_SIGN 0x37 + #define HID_KEYBOARD_SC_SLASH_AND_QUESTION_MARK 0x38 + #define HID_KEYBOARD_SC_CAPS_LOCK 0x39 + #define HID_KEYBOARD_SC_F1 0x3A + #define HID_KEYBOARD_SC_F2 0x3B + #define HID_KEYBOARD_SC_F3 0x3C + #define HID_KEYBOARD_SC_F4 0x3D + #define HID_KEYBOARD_SC_F5 0x3E + #define HID_KEYBOARD_SC_F6 0x3F + #define HID_KEYBOARD_SC_F7 0x40 + #define HID_KEYBOARD_SC_F8 0x41 + #define HID_KEYBOARD_SC_F9 0x42 + #define HID_KEYBOARD_SC_F10 0x43 + #define HID_KEYBOARD_SC_F11 0x44 + #define HID_KEYBOARD_SC_F12 0x45 + #define HID_KEYBOARD_SC_PRINT_SCREEN 0x46 + #define HID_KEYBOARD_SC_SCROLL_LOCK 0x47 + #define HID_KEYBOARD_SC_PAUSE 0x48 + #define HID_KEYBOARD_SC_INSERT 0x49 + #define HID_KEYBOARD_SC_HOME 0x4A + #define HID_KEYBOARD_SC_PAGE_UP 0x4B + #define HID_KEYBOARD_SC_DELETE 0x4C + #define HID_KEYBOARD_SC_END 0x4D + #define HID_KEYBOARD_SC_PAGE_DOWN 0x4E + #define HID_KEYBOARD_SC_RIGHT_ARROW 0x4F + #define HID_KEYBOARD_SC_LEFT_ARROW 0x50 + #define HID_KEYBOARD_SC_DOWN_ARROW 0x51 + #define HID_KEYBOARD_SC_UP_ARROW 0x52 + #define HID_KEYBOARD_SC_NUM_LOCK 0x53 + #define HID_KEYBOARD_SC_KEYPAD_SLASH 0x54 + #define HID_KEYBOARD_SC_KEYPAD_ASTERISK 0x55 + #define HID_KEYBOARD_SC_KEYPAD_MINUS 0x56 + #define HID_KEYBOARD_SC_KEYPAD_PLUS 0x57 + #define HID_KEYBOARD_SC_KEYPAD_ENTER 0x58 + #define HID_KEYBOARD_SC_KEYPAD_1_AND_END 0x59 + #define HID_KEYBOARD_SC_KEYPAD_2_AND_DOWN_ARROW 0x5A + #define HID_KEYBOARD_SC_KEYPAD_3_AND_PAGE_DOWN 0x5B + #define HID_KEYBOARD_SC_KEYPAD_4_AND_LEFT_ARROW 0x5C + #define HID_KEYBOARD_SC_KEYPAD_5 0x5D + #define HID_KEYBOARD_SC_KEYPAD_6_AND_RIGHT_ARROW 0x5E + #define HID_KEYBOARD_SC_KEYPAD_7_AND_HOME 0x5F + #define HID_KEYBOARD_SC_KEYPAD_8_AND_UP_ARROW 0x60 + #define HID_KEYBOARD_SC_KEYPAD_9_AND_PAGE_UP 0x61 + #define HID_KEYBOARD_SC_KEYPAD_0_AND_INSERT 0x62 + #define HID_KEYBOARD_SC_KEYPAD_DOT_AND_DELETE 0x63 + #define HID_KEYBOARD_SC_NON_US_BACKSLASH_AND_PIPE 0x64 + #define HID_KEYBOARD_SC_POWER 0x66 + #define HID_KEYBOARD_SC_EQUAL_SIGN 0x67 + #define HID_KEYBOARD_SC_F13 0x68 + #define HID_KEYBOARD_SC_F14 0x69 + #define HID_KEYBOARD_SC_F15 0x6A + #define HID_KEYBOARD_SC_F16 0x6B + #define HID_KEYBOARD_SC_F17 0x6C + #define HID_KEYBOARD_SC_F18 0x6D + #define HID_KEYBOARD_SC_F19 0x6E + #define HID_KEYBOARD_SC_F20 0x6F + #define HID_KEYBOARD_SC_F21 0x70 + #define HID_KEYBOARD_SC_F22 0x71 + #define HID_KEYBOARD_SC_F23 0x72 + #define HID_KEYBOARD_SC_F24 0x73 + #define HID_KEYBOARD_SC_EXECUTE 0x74 + #define HID_KEYBOARD_SC_HELP 0x75 + #define HID_KEYBOARD_SC_MANU 0x76 + #define HID_KEYBOARD_SC_SELECT 0x77 + #define HID_KEYBOARD_SC_STOP 0x78 + #define HID_KEYBOARD_SC_AGAIN 0x79 + #define HID_KEYBOARD_SC_UNDO 0x7A + #define HID_KEYBOARD_SC_CUT 0x7B + #define HID_KEYBOARD_SC_COPY 0x7C + #define HID_KEYBOARD_SC_PASTE 0x7D + #define HID_KEYBOARD_SC_FIND 0x7E + #define HID_KEYBOARD_SC_MUTE 0x7F + #define HID_KEYBOARD_SC_VOLUME_UP 0x80 + #define HID_KEYBOARD_SC_VOLUME_DOWN 0x81 + #define HID_KEYBOARD_SC_LOCKING_CAPS_LOCK 0x82 + #define HID_KEYBOARD_SC_LOCKING_NUM_LOCK 0x83 + #define HID_KEYBOARD_SC_LOCKING_SCROLL_LOCK 0x84 + #define HID_KEYBOARD_SC_KEYPAD_COMMA 0x85 + #define HID_KEYBOARD_SC_KEYPAD_EQUAL_SIGN 0x86 + #define HID_KEYBOARD_SC_INTERNATIONAL1 0x87 + #define HID_KEYBOARD_SC_INTERNATIONAL2 0x88 + #define HID_KEYBOARD_SC_INTERNATIONAL3 0x89 + #define HID_KEYBOARD_SC_INTERNATIONAL4 0x8A + #define HID_KEYBOARD_SC_INTERNATIONAL5 0x8B + #define HID_KEYBOARD_SC_INTERNATIONAL6 0x8C + #define HID_KEYBOARD_SC_INTERNATIONAL7 0x8D + #define HID_KEYBOARD_SC_INTERNATIONAL8 0x8E + #define HID_KEYBOARD_SC_INTERNATIONAL9 0x8F + #define HID_KEYBOARD_SC_LANG1 0x90 + #define HID_KEYBOARD_SC_LANG2 0x91 + #define HID_KEYBOARD_SC_LANG3 0x92 + #define HID_KEYBOARD_SC_LANG4 0x93 + #define HID_KEYBOARD_SC_LANG5 0x94 + #define HID_KEYBOARD_SC_LANG6 0x95 + #define HID_KEYBOARD_SC_LANG7 0x96 + #define HID_KEYBOARD_SC_LANG8 0x97 + #define HID_KEYBOARD_SC_LANG9 0x98 + #define HID_KEYBOARD_SC_ALTERNATE_ERASE 0x99 + #define HID_KEYBOARD_SC_SISREQ 0x9A + #define HID_KEYBOARD_SC_CANCEL 0x9B + #define HID_KEYBOARD_SC_CLEAR 0x9C + #define HID_KEYBOARD_SC_PRIOR 0x9D + #define HID_KEYBOARD_SC_RETURN 0x9E + #define HID_KEYBOARD_SC_SEPARATOR 0x9F + #define HID_KEYBOARD_SC_OUT 0xA0 + #define HID_KEYBOARD_SC_OPER 0xA1 + #define HID_KEYBOARD_SC_CLEAR_AND_AGAIN 0xA2 + #define HID_KEYBOARD_SC_CRSEL_ANDPROPS 0xA3 + #define HID_KEYBOARD_SC_EXSEL 0xA4 + #define HID_KEYBOARD_SC_KEYPAD_00 0xB0 + #define HID_KEYBOARD_SC_KEYPAD_000 0xB1 + #define HID_KEYBOARD_SC_THOUSANDS_SEPARATOR 0xB2 + #define HID_KEYBOARD_SC_DECIMAL_SEPARATOR 0xB3 + #define HID_KEYBOARD_SC_CURRENCY_UNIT 0xB4 + #define HID_KEYBOARD_SC_CURRENCY_SUB_UNIT 0xB5 + #define HID_KEYBOARD_SC_KEYPAD_OPENING_PARENTHESIS 0xB6 + #define HID_KEYBOARD_SC_KEYPAD_CLOSING_PARENTHESIS 0xB7 + #define HID_KEYBOARD_SC_KEYPAD_OPENING_BRACE 0xB8 + #define HID_KEYBOARD_SC_KEYPAD_CLOSING_BRACE 0xB9 + #define HID_KEYBOARD_SC_KEYPAD_TAB 0xBA + #define HID_KEYBOARD_SC_KEYPAD_BACKSPACE 0xBB + #define HID_KEYBOARD_SC_KEYPAD_A 0xBC + #define HID_KEYBOARD_SC_KEYPAD_B 0xBD + #define HID_KEYBOARD_SC_KEYPAD_C 0xBE + #define HID_KEYBOARD_SC_KEYPAD_D 0xBF + #define HID_KEYBOARD_SC_KEYPAD_E 0xC0 + #define HID_KEYBOARD_SC_KEYPAD_F 0xC1 + #define HID_KEYBOARD_SC_KEYPAD_XOR 0xC2 + #define HID_KEYBOARD_SC_KEYPAD_CARET 0xC3 + #define HID_KEYBOARD_SC_KEYPAD_PERCENTAGE 0xC4 + #define HID_KEYBOARD_SC_KEYPAD_LESS_THAN_SIGN 0xC5 + #define HID_KEYBOARD_SC_KEYPAD_GREATER_THAN_SIGN 0xC6 + #define HID_KEYBOARD_SC_KEYPAD_AMP 0xC7 + #define HID_KEYBOARD_SC_KEYPAD_AMP_AMP 0xC8 + #define HID_KEYBOARD_SC_KEYPAD_PIPE 0xC9 + #define HID_KEYBOARD_SC_KEYPAD_PIPE_PIPE 0xCA + #define HID_KEYBOARD_SC_KEYPAD_COLON 0xCB + #define HID_KEYBOARD_SC_KEYPAD_HASHMARK 0xCC + #define HID_KEYBOARD_SC_KEYPAD_SPACE 0xCD + #define HID_KEYBOARD_SC_KEYPAD_AT 0xCE + #define HID_KEYBOARD_SC_KEYPAD_EXCLAMATION_SIGN 0xCF + #define HID_KEYBOARD_SC_KEYPAD_MEMORY_STORE 0xD0 + #define HID_KEYBOARD_SC_KEYPAD_MEMORY_RECALL 0xD1 + #define HID_KEYBOARD_SC_KEYPAD_MEMORY_CLEAR 0xD2 + #define HID_KEYBOARD_SC_KEYPAD_MEMORY_ADD 0xD3 + #define HID_KEYBOARD_SC_KEYPAD_MEMORY_SUBTRACT 0xD4 + #define HID_KEYBOARD_SC_KEYPAD_MEMORY_MULTIPLY 0xD5 + #define HID_KEYBOARD_SC_KEYPAD_MEMORY_DIVIDE 0xD6 + #define HID_KEYBOARD_SC_KEYPAD_PLUS_AND_MINUS 0xD7 + #define HID_KEYBOARD_SC_KEYPAD_CLEAR 0xD8 + #define HID_KEYBOARD_SC_KEYPAD_CLEAR_ENTRY 0xD9 + #define HID_KEYBOARD_SC_KEYPAD_BINARY 0xDA + #define HID_KEYBOARD_SC_KEYPAD_OCTAL 0xDB + #define HID_KEYBOARD_SC_KEYPAD_DECIMAL 0xDC + #define HID_KEYBOARD_SC_KEYPAD_HEXADECIMAL 0xDD + #define HID_KEYBOARD_SC_LEFT_CONTROL 0xE0 + #define HID_KEYBOARD_SC_LEFT_SHIFT 0xE1 + #define HID_KEYBOARD_SC_LEFT_ALT 0xE2 + #define HID_KEYBOARD_SC_LEFT_GUI 0xE3 + #define HID_KEYBOARD_SC_RIGHT_CONTROL 0xE4 + #define HID_KEYBOARD_SC_RIGHT_SHIFT 0xE5 + #define HID_KEYBOARD_SC_RIGHT_ALT 0xE6 + #define HID_KEYBOARD_SC_RIGHT_GUI 0xE7 + //@} + + /** \name Common HID Device Report Descriptors */ + //@{ + /** \hideinitializer + * A list of HID report item array elements that describe a typical HID USB Joystick. The resulting report + * descriptor is structured according to the following layout: + * + * \code + * struct + * { + * intA_t X; // Signed X axis value + * intA_t Y; // Signed Y axis value + * intA_t Z; // Signed Z axis value + * uintB_t Buttons; // Pressed buttons bitmask + * } Joystick_Report; + * \endcode + * + * Where \c uintA_t is a type large enough to hold the ranges of the signed \c MinAxisVal and \c MaxAxisVal values, + * and \c intB_t is a type large enough to hold one bit per button. + * + * \param[in] MinAxisVal Minimum logical axis value (16-bit). + * \param[in] MaxAxisVal Maximum logical axis value (16-bit). + * \param[in] MinPhysicalVal Minimum physical axis value, for movement resolution calculations (16-bit). + * \param[in] MaxPhysicalVal Maximum physical axis value, for movement resolution calculations (16-bit). + * \param[in] Buttons Total number of buttons in the device (8-bit). + */ + #define HID_DESCRIPTOR_JOYSTICK(MinAxisVal, MaxAxisVal, MinPhysicalVal, MaxPhysicalVal, Buttons) \ + HID_RI_USAGE_PAGE(8, 0x01), \ + HID_RI_USAGE(8, 0x04), \ + HID_RI_COLLECTION(8, 0x01), \ + HID_RI_USAGE(8, 0x01), \ + HID_RI_COLLECTION(8, 0x00), \ + HID_RI_USAGE(8, 0x30), \ + HID_RI_USAGE(8, 0x31), \ + HID_RI_USAGE(8, 0x32), \ + HID_RI_LOGICAL_MINIMUM(16, MinAxisVal), \ + HID_RI_LOGICAL_MAXIMUM(16, MaxAxisVal), \ + HID_RI_PHYSICAL_MINIMUM(16, MinPhysicalVal), \ + HID_RI_PHYSICAL_MAXIMUM(16, MaxPhysicalVal), \ + HID_RI_REPORT_COUNT(8, 3), \ + HID_RI_REPORT_SIZE(8, ((((MinAxisVal >= -0xFF) && (MaxAxisVal <= 0xFF)) ? 8 : 16))), \ + HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), \ + HID_RI_END_COLLECTION(0), \ + HID_RI_USAGE_PAGE(8, 0x09), \ + HID_RI_USAGE_MINIMUM(8, 0x01), \ + HID_RI_USAGE_MAXIMUM(8, Buttons), \ + HID_RI_LOGICAL_MINIMUM(8, 0x00), \ + HID_RI_LOGICAL_MAXIMUM(8, 0x01), \ + HID_RI_REPORT_SIZE(8, 0x01), \ + HID_RI_REPORT_COUNT(8, Buttons), \ + HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), \ + HID_RI_REPORT_SIZE(8, (8 - (Buttons % 8))), \ + HID_RI_REPORT_COUNT(8, 0x01), \ + HID_RI_INPUT(8, HID_IOF_CONSTANT), \ + HID_RI_END_COLLECTION(0) + + /** \hideinitializer + * A list of HID report item array elements that describe a typical HID USB keyboard. The resulting report descriptor + * is compatible with \ref USB_KeyboardReport_Data_t when \c MaxKeys is equal to 6. For other values, the report will + * be structured according to the following layout: + * + * \code + * struct + * { + * uint8_t Modifier; // Keyboard modifier byte indicating pressed modifier keys (\c HID_KEYBOARD_MODIFER_* masks) + * uint8_t Reserved; // Reserved for OEM use, always set to 0. + * uint8_t KeyCode[MaxKeys]; // Length determined by the number of keys that can be reported + * } Keyboard_Report; + * \endcode + * + * \param[in] MaxKeys Number of simultaneous keys that can be reported at the one time (8-bit). + */ + #define HID_DESCRIPTOR_KEYBOARD(MaxKeys) \ + HID_RI_USAGE_PAGE(8, 0x01), \ + HID_RI_USAGE(8, 0x06), \ + HID_RI_COLLECTION(8, 0x01), \ + HID_RI_USAGE_PAGE(8, 0x07), \ + HID_RI_USAGE_MINIMUM(8, 0xE0), \ + HID_RI_USAGE_MAXIMUM(8, 0xE7), \ + HID_RI_LOGICAL_MINIMUM(8, 0x00), \ + HID_RI_LOGICAL_MAXIMUM(8, 0x01), \ + HID_RI_REPORT_SIZE(8, 0x01), \ + HID_RI_REPORT_COUNT(8, 0x08), \ + HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), \ + HID_RI_REPORT_COUNT(8, 0x01), \ + HID_RI_REPORT_SIZE(8, 0x08), \ + HID_RI_INPUT(8, HID_IOF_CONSTANT), \ + HID_RI_USAGE_PAGE(8, 0x08), \ + HID_RI_USAGE_MINIMUM(8, 0x01), \ + HID_RI_USAGE_MAXIMUM(8, 0x05), \ + HID_RI_REPORT_COUNT(8, 0x05), \ + HID_RI_REPORT_SIZE(8, 0x01), \ + HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE), \ + HID_RI_REPORT_COUNT(8, 0x01), \ + HID_RI_REPORT_SIZE(8, 0x03), \ + HID_RI_OUTPUT(8, HID_IOF_CONSTANT), \ + HID_RI_LOGICAL_MINIMUM(8, 0x00), \ + HID_RI_LOGICAL_MAXIMUM(8, 0x65), \ + HID_RI_USAGE_PAGE(8, 0x07), \ + HID_RI_USAGE_MINIMUM(8, 0x00), \ + HID_RI_USAGE_MAXIMUM(8, 0x65), \ + HID_RI_REPORT_COUNT(8, MaxKeys), \ + HID_RI_REPORT_SIZE(8, 0x08), \ + HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE), \ + HID_RI_END_COLLECTION(0) + + /** \hideinitializer + * A list of HID report item array elements that describe a typical HID USB mouse. The resulting report descriptor + * is compatible with \ref USB_MouseReport_Data_t if the \c MinAxisVal and \c MaxAxisVal values fit within a \c int8_t range + * and the number of Buttons is less than 8. For other values, the report is structured according to the following layout: + * + * \code + * struct + * { + * uintA_t Buttons; // Pressed buttons bitmask + * intB_t X; // X axis value + * intB_t Y; // Y axis value + * } Mouse_Report; + * \endcode + * + * Where \c intA_t is a type large enough to hold one bit per button, and \c intB_t is a type large enough to hold the + * ranges of the signed \c MinAxisVal and \c MaxAxisVal values. + * + * \param[in] MinAxisVal Minimum X/Y logical axis value (16-bit). + * \param[in] MaxAxisVal Maximum X/Y logical axis value (16-bit). + * \param[in] MinPhysicalVal Minimum X/Y physical axis value, for movement resolution calculations (16-bit). + * \param[in] MaxPhysicalVal Maximum X/Y physical axis value, for movement resolution calculations (16-bit). + * \param[in] Buttons Total number of buttons in the device (8-bit). + * \param[in] AbsoluteCoords Boolean \c true to use absolute X/Y coordinates (e.g. touchscreen). + */ + #define HID_DESCRIPTOR_MOUSE(MinAxisVal, MaxAxisVal, MinPhysicalVal, MaxPhysicalVal, Buttons, AbsoluteCoords) \ + HID_RI_USAGE_PAGE(8, 0x01), \ + HID_RI_USAGE(8, 0x02), \ + HID_RI_COLLECTION(8, 0x01), \ + HID_RI_USAGE(8, 0x01), \ + HID_RI_COLLECTION(8, 0x00), \ + HID_RI_USAGE_PAGE(8, 0x09), \ + HID_RI_USAGE_MINIMUM(8, 0x01), \ + HID_RI_USAGE_MAXIMUM(8, Buttons), \ + HID_RI_LOGICAL_MINIMUM(8, 0x00), \ + HID_RI_LOGICAL_MAXIMUM(8, 0x01), \ + HID_RI_REPORT_COUNT(8, Buttons), \ + HID_RI_REPORT_SIZE(8, 0x01), \ + HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), \ + HID_RI_REPORT_COUNT(8, 0x01), \ + HID_RI_REPORT_SIZE(8, (8 - (Buttons % 8))), \ + HID_RI_INPUT(8, HID_IOF_CONSTANT), \ + HID_RI_USAGE_PAGE(8, 0x01), \ + HID_RI_USAGE(8, 0x30), \ + HID_RI_USAGE(8, 0x31), \ + HID_RI_LOGICAL_MINIMUM(16, MinAxisVal), \ + HID_RI_LOGICAL_MAXIMUM(16, MaxAxisVal), \ + HID_RI_PHYSICAL_MINIMUM(16, MinPhysicalVal), \ + HID_RI_PHYSICAL_MAXIMUM(16, MaxPhysicalVal), \ + HID_RI_REPORT_COUNT(8, 0x02), \ + HID_RI_REPORT_SIZE(8, ((((MinAxisVal >= -0xFF) && (MaxAxisVal <= 0xFF)) ? 8 : 16))), \ + HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | (AbsoluteCoords ? HID_IOF_ABSOLUTE : HID_IOF_RELATIVE)), \ + HID_RI_END_COLLECTION(0), \ + HID_RI_END_COLLECTION(0) + + /** \hideinitializer + * A list of HID report item array elements that describe a typical Vendor Defined byte array HID report descriptor, + * used for transporting arbitrary data between the USB host and device via HID reports. The resulting report should be + * a \c uint8_t byte array of the specified length in both Device to Host (IN) and Host to Device (OUT) directions. + * + * \param[in] VendorPageNum Vendor Defined HID Usage Page index, ranging from 0x00 to 0xFF. + * \param[in] CollectionUsage Vendor Usage for the encompassing report IN and OUT collection, ranging from 0x00 to 0xFF. + * \param[in] DataINUsage Vendor Usage for the IN report data, ranging from 0x00 to 0xFF. + * \param[in] DataOUTUsage Vendor Usage for the OUT report data, ranging from 0x00 to 0xFF. + * \param[in] NumBytes Length of the data IN and OUT reports. + */ + #define HID_DESCRIPTOR_VENDOR(VendorPageNum, CollectionUsage, DataINUsage, DataOUTUsage, NumBytes) \ + HID_RI_USAGE_PAGE(16, (0xFF00 | VendorPageNum)), \ + HID_RI_USAGE(8, CollectionUsage), \ + HID_RI_COLLECTION(8, 0x01), \ + HID_RI_USAGE(8, DataINUsage), \ + HID_RI_LOGICAL_MINIMUM(8, 0x00), \ + HID_RI_LOGICAL_MAXIMUM(8, 0xFF), \ + HID_RI_REPORT_SIZE(8, 0x08), \ + HID_RI_REPORT_COUNT(8, NumBytes), \ + HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE), \ + HID_RI_USAGE(8, DataOUTUsage), \ + HID_RI_LOGICAL_MINIMUM(8, 0x00), \ + HID_RI_LOGICAL_MAXIMUM(8, 0xFF), \ + HID_RI_REPORT_SIZE(8, 0x08), \ + HID_RI_REPORT_COUNT(8, NumBytes), \ + HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE), \ + HID_RI_END_COLLECTION(0) + //@} + + /* Type Defines: */ + /** Enum for possible Class, Subclass and Protocol values of device and interface descriptors relating to the HID + * device class. + */ + enum HID_Descriptor_ClassSubclassProtocol_t + { + HID_CSCP_HIDClass = 0x03, /**< Descriptor Class value indicating that the device or interface + * belongs to the HID class. + */ + HID_CSCP_NonBootSubclass = 0x00, /**< Descriptor Subclass value indicating that the device or interface + * does not implement a HID boot protocol. + */ + HID_CSCP_BootSubclass = 0x01, /**< Descriptor Subclass value indicating that the device or interface + * implements a HID boot protocol. + */ + HID_CSCP_NonBootProtocol = 0x00, /**< Descriptor Protocol value indicating that the device or interface + * does not belong to a HID boot protocol. + */ + HID_CSCP_KeyboardBootProtocol = 0x01, /**< Descriptor Protocol value indicating that the device or interface + * belongs to the Keyboard HID boot protocol. + */ + HID_CSCP_MouseBootProtocol = 0x02, /**< Descriptor Protocol value indicating that the device or interface + * belongs to the Mouse HID boot protocol. + */ + }; + + /** Enum for the HID class specific control requests that can be issued by the USB bus host. */ + enum HID_ClassRequests_t + { + HID_REQ_GetReport = 0x01, /**< HID class-specific Request to get the current HID report from the device. */ + HID_REQ_GetIdle = 0x02, /**< HID class-specific Request to get the current device idle count. */ + HID_REQ_GetProtocol = 0x03, /**< HID class-specific Request to get the current HID report protocol mode. */ + HID_REQ_SetReport = 0x09, /**< HID class-specific Request to set the current HID report to the device. */ + HID_REQ_SetIdle = 0x0A, /**< HID class-specific Request to set the device's idle count. */ + HID_REQ_SetProtocol = 0x0B, /**< HID class-specific Request to set the current HID report protocol mode. */ + }; + + /** Enum for the HID class specific descriptor types. */ + enum HID_DescriptorTypes_t + { + HID_DTYPE_HID = 0x21, /**< Descriptor header type value, to indicate a HID class HID descriptor. */ + HID_DTYPE_Report = 0x22, /**< Descriptor header type value, to indicate a HID class HID report descriptor. */ + }; + + /** Enum for the different types of HID reports. */ + enum HID_ReportItemTypes_t + { + HID_REPORT_ITEM_In = 0, /**< Indicates that the item is an IN report type. */ + HID_REPORT_ITEM_Out = 1, /**< Indicates that the item is an OUT report type. */ + HID_REPORT_ITEM_Feature = 2, /**< Indicates that the item is a FEATURE report type. */ + }; + + /** \brief HID class-specific HID Descriptor (LUFA naming conventions). + * + * Type define for the HID class-specific HID descriptor, to describe the HID device's specifications. Refer to the HID + * specification for details on the structure elements. + * + * \see \ref USB_HID_StdDescriptor_HID_t for the version of this type with standard element names. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length. */ + + uint16_t HIDSpec; /**< BCD encoded version that the HID descriptor and device complies to. */ + uint8_t CountryCode; /**< Country code of the localized device, or zero if universal. */ + + uint8_t TotalReportDescriptors; /**< Total number of HID report descriptors for the interface. */ + + uint8_t HIDReportType; /**< Type of HID report, set to \ref HID_DTYPE_Report. */ + uint16_t HIDReportLength; /**< Length of the associated HID report descriptor, in bytes. */ + } ATTR_PACKED USB_HID_Descriptor_HID_t; + + /** \brief HID class-specific HID Descriptor (USB-IF naming conventions). + * + * Type define for the HID class-specific HID descriptor, to describe the HID device's specifications. Refer to the HID + * specification for details on the structure elements. + * + * \see \ref USB_HID_Descriptor_HID_t for the version of this type with non-standard LUFA specific + * element names. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + uint8_t bLength; /**< Size of the descriptor, in bytes. */ + uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value + * given by the specific class. + */ + + uint16_t bcdHID; /**< BCD encoded version that the HID descriptor and device complies to. */ + 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 bDescriptorType2; /**< Type of HID report, set to \ref HID_DTYPE_Report. */ + uint16_t wDescriptorLength; /**< Length of the associated HID report descriptor, in bytes. */ + } ATTR_PACKED USB_HID_StdDescriptor_HID_t; + + /** \brief Standard HID Boot Protocol Mouse Report. + * + * Type define for a standard Boot Protocol Mouse report + */ + typedef struct + { + uint8_t Button; /**< Button mask for currently pressed buttons in the mouse. */ + int8_t X; /**< Current delta X movement of the mouse. */ + int8_t Y; /**< Current delta Y movement on the mouse. */ + } ATTR_PACKED USB_MouseReport_Data_t; + + /** \brief Standard HID Boot Protocol Keyboard Report. + * + * Type define for a standard Boot Protocol Keyboard report + */ + typedef struct + { + uint8_t Modifier; /**< Keyboard modifier byte, indicating pressed modifier keys (a combination of + * \c HID_KEYBOARD_MODIFER_* masks). + */ + uint8_t Reserved; /**< Reserved for OEM use, always set to 0. */ + uint8_t KeyCode[6]; /**< Key codes of the currently pressed keys. */ + } ATTR_PACKED USB_KeyboardReport_Data_t; + + /** Type define for the data type used to store HID report descriptor elements. */ + typedef uint8_t USB_Descriptor_HIDReport_Datatype_t; + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Common/HIDParser.c b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Common/HIDParser.c new file mode 100644 index 00000000..f57d97b5 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Common/HIDParser.c @@ -0,0 +1,363 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#define __INCLUDE_FROM_USB_DRIVER +#define __INCLUDE_FROM_HID_DRIVER +#include "HIDParser.h" + +uint8_t USB_ProcessHIDReport(const uint8_t* ReportData, + uint16_t ReportSize, + HID_ReportInfo_t* const ParserData) +{ + HID_StateTable_t StateTable[HID_STATETABLE_STACK_DEPTH]; + HID_StateTable_t* CurrStateTable = &StateTable[0]; + HID_CollectionPath_t* CurrCollectionPath = NULL; + HID_ReportSizeInfo_t* CurrReportIDInfo = &ParserData->ReportIDSizes[0]; + uint16_t UsageList[HID_USAGE_STACK_DEPTH]; + uint8_t UsageListSize = 0; + HID_MinMax_t UsageMinMax = {0, 0}; + + memset(ParserData, 0x00, sizeof(HID_ReportInfo_t)); + memset(CurrStateTable, 0x00, sizeof(HID_StateTable_t)); + memset(CurrReportIDInfo, 0x00, sizeof(HID_ReportSizeInfo_t)); + + ParserData->TotalDeviceReports = 1; + + while (ReportSize) + { + uint8_t HIDReportItem = *ReportData; + uint32_t ReportItemData = 0; + + ReportData++; + ReportSize--; + + switch (HIDReportItem & HID_RI_DATA_SIZE_MASK) + { + case HID_RI_DATA_BITS_32: + ReportItemData = (((uint32_t)ReportData[3] << 24) | ((uint32_t)ReportData[2] << 16) | + ((uint16_t)ReportData[1] << 8) | ReportData[0]); + ReportSize -= 4; + ReportData += 4; + break; + case HID_RI_DATA_BITS_16: + ReportItemData = (((uint16_t)ReportData[1] << 8) | (ReportData[0])); + ReportSize -= 2; + ReportData += 2; + break; + case HID_RI_DATA_BITS_8: + ReportItemData = ReportData[0]; + ReportSize -= 1; + ReportData += 1; + break; + } + + switch (HIDReportItem & (HID_RI_TYPE_MASK | HID_RI_TAG_MASK)) + { + case HID_RI_PUSH(0): + if (CurrStateTable == &StateTable[HID_STATETABLE_STACK_DEPTH - 1]) + return HID_PARSE_HIDStackOverflow; + + memcpy((CurrStateTable + 1), + CurrStateTable, + sizeof(HID_ReportItem_t)); + + CurrStateTable++; + break; + case HID_RI_POP(0): + if (CurrStateTable == &StateTable[0]) + return HID_PARSE_HIDStackUnderflow; + + CurrStateTable--; + break; + case HID_RI_USAGE_PAGE(0): + if ((HIDReportItem & HID_RI_DATA_SIZE_MASK) == HID_RI_DATA_BITS_32) + CurrStateTable->Attributes.Usage.Page = (ReportItemData >> 16); + + CurrStateTable->Attributes.Usage.Page = ReportItemData; + break; + case HID_RI_LOGICAL_MINIMUM(0): + CurrStateTable->Attributes.Logical.Minimum = ReportItemData; + break; + case HID_RI_LOGICAL_MAXIMUM(0): + CurrStateTable->Attributes.Logical.Maximum = ReportItemData; + break; + case HID_RI_PHYSICAL_MINIMUM(0): + CurrStateTable->Attributes.Physical.Minimum = ReportItemData; + break; + case HID_RI_PHYSICAL_MAXIMUM(0): + CurrStateTable->Attributes.Physical.Maximum = ReportItemData; + break; + case HID_RI_UNIT_EXPONENT(0): + CurrStateTable->Attributes.Unit.Exponent = ReportItemData; + break; + case HID_RI_UNIT(0): + CurrStateTable->Attributes.Unit.Type = ReportItemData; + break; + case HID_RI_REPORT_SIZE(0): + CurrStateTable->Attributes.BitSize = ReportItemData; + break; + case HID_RI_REPORT_COUNT(0): + CurrStateTable->ReportCount = ReportItemData; + break; + case HID_RI_REPORT_ID(0): + CurrStateTable->ReportID = ReportItemData; + + if (ParserData->UsingReportIDs) + { + CurrReportIDInfo = NULL; + + for (uint8_t i = 0; i < ParserData->TotalDeviceReports; i++) + { + if (ParserData->ReportIDSizes[i].ReportID == CurrStateTable->ReportID) + { + CurrReportIDInfo = &ParserData->ReportIDSizes[i]; + break; + } + } + + if (CurrReportIDInfo == NULL) + { + if (ParserData->TotalDeviceReports == HID_MAX_REPORT_IDS) + return HID_PARSE_InsufficientReportIDItems; + + CurrReportIDInfo = &ParserData->ReportIDSizes[ParserData->TotalDeviceReports++]; + memset(CurrReportIDInfo, 0x00, sizeof(HID_ReportSizeInfo_t)); + } + } + + ParserData->UsingReportIDs = true; + + CurrReportIDInfo->ReportID = CurrStateTable->ReportID; + break; + case HID_RI_USAGE(0): + if (UsageListSize == HID_USAGE_STACK_DEPTH) + return HID_PARSE_UsageListOverflow; + + UsageList[UsageListSize++] = ReportItemData; + break; + case HID_RI_USAGE_MINIMUM(0): + UsageMinMax.Minimum = ReportItemData; + break; + case HID_RI_USAGE_MAXIMUM(0): + UsageMinMax.Maximum = ReportItemData; + break; + case HID_RI_COLLECTION(0): + if (CurrCollectionPath == NULL) + { + CurrCollectionPath = &ParserData->CollectionPaths[0]; + } + else + { + HID_CollectionPath_t* ParentCollectionPath = CurrCollectionPath; + + CurrCollectionPath = &ParserData->CollectionPaths[1]; + + while (CurrCollectionPath->Parent != NULL) + { + if (CurrCollectionPath == &ParserData->CollectionPaths[HID_MAX_COLLECTIONS - 1]) + return HID_PARSE_InsufficientCollectionPaths; + + CurrCollectionPath++; + } + + CurrCollectionPath->Parent = ParentCollectionPath; + } + + CurrCollectionPath->Type = ReportItemData; + CurrCollectionPath->Usage.Page = CurrStateTable->Attributes.Usage.Page; + + if (UsageListSize) + { + CurrCollectionPath->Usage.Usage = UsageList[0]; + + for (uint8_t i = 0; i < UsageListSize; i++) + UsageList[i] = UsageList[i + 1]; + + UsageListSize--; + } + else if (UsageMinMax.Minimum <= UsageMinMax.Maximum) + { + CurrCollectionPath->Usage.Usage = UsageMinMax.Minimum++; + } + + break; + case HID_RI_END_COLLECTION(0): + if (CurrCollectionPath == NULL) + return HID_PARSE_UnexpectedEndCollection; + + CurrCollectionPath = CurrCollectionPath->Parent; + break; + case HID_RI_INPUT(0): + case HID_RI_OUTPUT(0): + case HID_RI_FEATURE(0): + for (uint8_t ReportItemNum = 0; ReportItemNum < CurrStateTable->ReportCount; ReportItemNum++) + { + HID_ReportItem_t NewReportItem; + + memcpy(&NewReportItem.Attributes, + &CurrStateTable->Attributes, + sizeof(HID_ReportItem_Attributes_t)); + + NewReportItem.ItemFlags = ReportItemData; + NewReportItem.CollectionPath = CurrCollectionPath; + NewReportItem.ReportID = CurrStateTable->ReportID; + + if (UsageListSize) + { + NewReportItem.Attributes.Usage.Usage = UsageList[0]; + + for (uint8_t i = 0; i < UsageListSize; i++) + UsageList[i] = UsageList[i + 1]; + + UsageListSize--; + } + else if (UsageMinMax.Minimum <= UsageMinMax.Maximum) + { + NewReportItem.Attributes.Usage.Usage = UsageMinMax.Minimum++; + } + + uint8_t ItemTypeTag = (HIDReportItem & (HID_RI_TYPE_MASK | HID_RI_TAG_MASK)); + + if (ItemTypeTag == HID_RI_INPUT(0)) + NewReportItem.ItemType = HID_REPORT_ITEM_In; + else if (ItemTypeTag == HID_RI_OUTPUT(0)) + NewReportItem.ItemType = HID_REPORT_ITEM_Out; + else + NewReportItem.ItemType = HID_REPORT_ITEM_Feature; + + NewReportItem.BitOffset = CurrReportIDInfo->ReportSizeBits[NewReportItem.ItemType]; + + CurrReportIDInfo->ReportSizeBits[NewReportItem.ItemType] += CurrStateTable->Attributes.BitSize; + + ParserData->LargestReportSizeBits = MAX(ParserData->LargestReportSizeBits, CurrReportIDInfo->ReportSizeBits[NewReportItem.ItemType]); + + if (ParserData->TotalReportItems == HID_MAX_REPORTITEMS) + return HID_PARSE_InsufficientReportItems; + + memcpy(&ParserData->ReportItems[ParserData->TotalReportItems], + &NewReportItem, sizeof(HID_ReportItem_t)); + + if (!(ReportItemData & HID_IOF_CONSTANT) && CALLBACK_HIDParser_FilterHIDReportItem(&NewReportItem)) + ParserData->TotalReportItems++; + } + + break; + } + + if ((HIDReportItem & HID_RI_TYPE_MASK) == HID_RI_TYPE_MAIN) + { + UsageMinMax.Minimum = 0; + UsageMinMax.Maximum = 0; + UsageListSize = 0; + } + } + + if (!(ParserData->TotalReportItems)) + return HID_PARSE_NoUnfilteredReportItems; + + return HID_PARSE_Successful; +} + +bool USB_GetHIDReportItemInfo(const uint8_t* ReportData, + HID_ReportItem_t* const ReportItem) +{ + if (ReportItem == NULL) + return false; + + uint16_t DataBitsRem = ReportItem->Attributes.BitSize; + uint16_t CurrentBit = ReportItem->BitOffset; + uint32_t BitMask = (1 << 0); + + if (ReportItem->ReportID) + { + if (ReportItem->ReportID != ReportData[0]) + return false; + + ReportData++; + } + + ReportItem->PreviousValue = ReportItem->Value; + ReportItem->Value = 0; + + while (DataBitsRem--) + { + if (ReportData[CurrentBit / 8] & (1 << (CurrentBit % 8))) + ReportItem->Value |= BitMask; + + CurrentBit++; + BitMask <<= 1; + } + + return true; +} + +void USB_SetHIDReportItemInfo(uint8_t* ReportData, + HID_ReportItem_t* const ReportItem) +{ + if (ReportItem == NULL) + return; + + uint16_t DataBitsRem = ReportItem->Attributes.BitSize; + uint16_t CurrentBit = ReportItem->BitOffset; + uint32_t BitMask = (1 << 0); + + if (ReportItem->ReportID) + { + ReportData[0] = ReportItem->ReportID; + ReportData++; + } + + ReportItem->PreviousValue = ReportItem->Value; + + while (DataBitsRem--) + { + if (ReportItem->Value & (1 << (CurrentBit % 8))) + ReportData[CurrentBit / 8] |= BitMask; + + CurrentBit++; + BitMask <<= 1; + } +} + +uint16_t USB_GetHIDReportSize(HID_ReportInfo_t* const ParserData, + const uint8_t ReportID, + const uint8_t ReportType) +{ + for (uint8_t i = 0; i < HID_MAX_REPORT_IDS; i++) + { + uint16_t ReportSizeBits = ParserData->ReportIDSizes[i].ReportSizeBits[ReportType]; + + if (ParserData->ReportIDSizes[i].ReportID == ReportID) + return (ReportSizeBits / 8) + ((ReportSizeBits % 8) ? 1 : 0); + } + + return 0; +} + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Common/HIDParser.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Common/HIDParser.h new file mode 100644 index 00000000..dd14bea4 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Common/HIDParser.h @@ -0,0 +1,364 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief USB Human Interface Device (HID) Class report descriptor parser. + * + * This file allows for the easy parsing of complex HID report descriptors, which describes the data that + * a HID device transmits to the host. It also provides an easy API for extracting and processing the data + * elements inside a HID report sent from an attached HID device. + */ + +/** \ingroup Group_USB + * \defgroup Group_HIDParser HID Report Parser + * \brief USB Human Interface Device (HID) Class report descriptor parser. + * + * \section Sec_Dependencies Module Source Dependencies + * The following files must be built with any user project that uses this module: + * - LUFA/Drivers/USB/Class/Host/HIDParser.c (Makefile source module name: LUFA_SRC_USB) + * + * \section Sec_ModDescription Module Description + * Human Interface Device (HID) class report descriptor parser. This module implements a parser than is + * capable of processing a complete HID report descriptor, and outputting a flat structure containing the + * contents of the report in an a more friendly format. The parsed data may then be further processed and used + * within an application to process sent and received HID reports to and from an attached HID device. + * + * A HID report descriptor consists of a set of HID report items, which describe the function and layout + * of data exchanged between a HID device and a host, including both the physical encoding of each item + * (such as a button, key press or joystick axis) in the sent and received data packets - known as "reports" - + * as well as other information about each item such as the usages, data range, physical location and other + * characteristics. In this way a HID device can retain a high degree of flexibility in its capabilities, as it + * is not forced to comply with a given report layout or feature-set. + * + * This module also contains routines for the processing of data in an actual HID report, using the parsed report + * descriptor data as a guide for the encoding. + * + * @{ + */ + +#ifndef __HIDPARSER_H__ +#define __HIDPARSER_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + #include "HIDReportData.h" + #include "HIDClassCommon.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Macros: */ + #if !defined(HID_STATETABLE_STACK_DEPTH) || defined(__DOXYGEN__) + /** Constant indicating the maximum stack depth of the state table. A larger state table + * allows for more PUSH/POP report items to be nested, but consumes more memory. By default + * this is set to 2 levels (allowing non-nested PUSH items) but this can be overridden by + * defining \c HID_STATETABLE_STACK_DEPTH to another value in the user project makefile, passing the + * define to the compiler using the -D compiler switch. + */ + #define HID_STATETABLE_STACK_DEPTH 2 + #endif + + #if !defined(HID_USAGE_STACK_DEPTH) || defined(__DOXYGEN__) + /** Constant indicating the maximum stack depth of the usage table. A larger usage table + * allows for more USAGE items to be indicated sequentially for REPORT COUNT entries of more than + * one, but requires more stack space. By default this is set to 8 levels (allowing for a report + * item with a count of 8) but this can be overridden by defining \c HID_USAGE_STACK_DEPTH to another + * value in the user project makefile, passing the define to the compiler using the -D compiler + * switch. + */ + #define HID_USAGE_STACK_DEPTH 8 + #endif + + #if !defined(HID_MAX_COLLECTIONS) || defined(__DOXYGEN__) + /** Constant indicating the maximum number of COLLECTION items (nested or unnested) that can be + * processed in the report item descriptor. A large value allows for more COLLECTION items to be + * processed, but consumes more memory. By default this is set to 10 collections, but this can be + * overridden by defining \c HID_MAX_COLLECTIONS to another value in the user project makefile, passing + * the define to the compiler using the -D compiler switch. + */ + #define HID_MAX_COLLECTIONS 10 + #endif + + #if !defined(HID_MAX_REPORTITEMS) || defined(__DOXYGEN__) + /** Constant indicating the maximum number of report items (IN, OUT or FEATURE) that can be processed + * in the report item descriptor and stored in the user HID Report Info structure. A large value allows + * for more report items to be stored, but consumes more memory. By default this is set to 20 items, + * but this can be overridden by defining \c HID_MAX_REPORTITEMS to another value in the user project + * makefile, and passing the define to the compiler using the -D compiler switch. + */ + #define HID_MAX_REPORTITEMS 20 + #endif + + #if !defined(HID_MAX_REPORT_IDS) || defined(__DOXYGEN__) + /** Constant indicating the maximum number of unique report IDs that can be processed in the report item + * descriptor for the report size information array in the user HID Report Info structure. A large value + * allows for more report ID report sizes to be stored, but consumes more memory. By default this is set + * to 10 items, but this can be overridden by defining \c HID_MAX_REPORT_IDS to another value in the user project + * makefile, and passing the define to the compiler using the -D compiler switch. Note that IN, OUT and FEATURE + * items sharing the same report ID consume only one size item in the array. + */ + #define HID_MAX_REPORT_IDS 10 + #endif + + /** Returns the value a given HID report item (once its value has been fetched via \ref USB_GetHIDReportItemInfo()) + * left-aligned to the given data type. This allows for signed data to be interpreted correctly, by shifting the data + * leftwards until the data's sign bit is in the correct position. + * + * \param[in] ReportItem HID Report Item whose retrieved value is to be aligned. + * \param[in] Type Data type to align the HID report item's value to. + * + * \return Left-aligned data of the given report item's pre-retrieved value for the given datatype. + */ + #define HID_ALIGN_DATA(ReportItem, Type) ((Type)(ReportItem->Value << ((8 * sizeof(Type)) - ReportItem->Attributes.BitSize))) + + /* Public Interface - May be used in end-application: */ + /* Enums: */ + /** Enum for the possible error codes in the return value of the \ref USB_ProcessHIDReport() function. */ + enum HID_Parse_ErrorCodes_t + { + HID_PARSE_Successful = 0, /**< Successful parse of the HID report descriptor, no error. */ + HID_PARSE_HIDStackOverflow = 1, /**< More than \ref HID_STATETABLE_STACK_DEPTH nested PUSHes in the report. */ + HID_PARSE_HIDStackUnderflow = 2, /**< A POP was found when the state table stack was empty. */ + HID_PARSE_InsufficientReportItems = 3, /**< More than \ref HID_MAX_REPORTITEMS report items in the report. */ + HID_PARSE_UnexpectedEndCollection = 4, /**< An END COLLECTION item found without matching COLLECTION item. */ + HID_PARSE_InsufficientCollectionPaths = 5, /**< More than \ref HID_MAX_COLLECTIONS collections in the report. */ + HID_PARSE_UsageListOverflow = 6, /**< More than \ref HID_USAGE_STACK_DEPTH usages listed in a row. */ + HID_PARSE_InsufficientReportIDItems = 7, /**< More than \ref HID_MAX_REPORT_IDS report IDs in the device. */ + HID_PARSE_NoUnfilteredReportItems = 8, /**< All report items from the device were filtered by the filtering callback routine. */ + }; + + /* Type Defines: */ + /** \brief HID Parser Report Item Min/Max Structure. + * + * Type define for an attribute with both minimum and maximum values (e.g. Logical Min/Max). + */ + typedef struct + { + uint32_t Minimum; /**< Minimum value for the attribute. */ + uint32_t Maximum; /**< Maximum value for the attribute. */ + } HID_MinMax_t; + + /** \brief HID Parser Report Item Unit Structure. + * + * Type define for the Unit attributes of a report item. + */ + typedef struct + { + uint32_t Type; /**< Unit type (refer to HID specifications for details). */ + uint8_t Exponent; /**< Unit exponent (refer to HID specifications for details). */ + } HID_Unit_t; + + /** \brief HID Parser Report Item Usage Structure. + * + * Type define for the Usage attributes of a report item. + */ + typedef struct + { + uint16_t Page; /**< Usage page of the report item. */ + uint16_t Usage; /**< Usage of the report item. */ + } HID_Usage_t; + + /** \brief HID Parser Report Item Collection Path Structure. + * + * Type define for a COLLECTION object. Contains the collection attributes and a reference to the + * parent collection if any. + */ + typedef struct HID_CollectionPath + { + uint8_t Type; /**< Collection type (e.g. "Generic Desktop"). */ + HID_Usage_t Usage; /**< Collection usage. */ + struct HID_CollectionPath* Parent; /**< Reference to parent collection, or \c NULL if root collection. */ + } HID_CollectionPath_t; + + /** \brief HID Parser Report Item Attributes Structure. + * + * Type define for all the data attributes of a report item, except flags. + */ + typedef struct + { + uint8_t BitSize; /**< Size in bits of the report item's data. */ + + HID_Usage_t Usage; /**< Usage of the report item. */ + HID_Unit_t Unit; /**< Unit type and exponent of the report item. */ + HID_MinMax_t Logical; /**< Logical minimum and maximum of the report item. */ + HID_MinMax_t Physical; /**< Physical minimum and maximum of the report item. */ + } HID_ReportItem_Attributes_t; + + /** \brief HID Parser Report Item Details Structure. + * + * Type define for a report item (IN, OUT or FEATURE) layout attributes and other details. + */ + typedef struct + { + uint16_t BitOffset; /**< Bit offset in the IN, OUT or FEATURE report of the item. */ + uint8_t ItemType; /**< Report item type, a value in \ref HID_ReportItemTypes_t. */ + uint16_t ItemFlags; /**< Item data flags, a mask of \c HID_IOF_* constants. */ + uint8_t ReportID; /**< Report ID this item belongs to, or 0x00 if device has only one report */ + HID_CollectionPath_t* CollectionPath; /**< Collection path of the item. */ + + HID_ReportItem_Attributes_t Attributes; /**< Report item attributes. */ + + uint32_t Value; /**< Current value of the report item - use \ref HID_ALIGN_DATA() when processing + * a retrieved value so that it is aligned to a specific type. + */ + uint32_t PreviousValue; /**< Previous value of the report item. */ + } HID_ReportItem_t; + + /** \brief HID Parser Report Size Structure. + * + * Type define for a report item size information structure, to retain the size of a device's reports by ID. + */ + typedef struct + { + uint8_t ReportID; /**< Report ID of the report within the HID interface. */ + uint16_t ReportSizeBits[3]; /**< Total number of bits in each report type for the given Report ID, + * indexed by the \ref HID_ReportItemTypes_t enum. + */ + } HID_ReportSizeInfo_t; + + /** \brief HID Parser State Structure. + * + * Type define for a complete processed HID report, including all report item data and collections. + */ + typedef struct + { + uint8_t TotalReportItems; /**< Total number of report items stored in the \c ReportItems array. */ + HID_ReportItem_t ReportItems[HID_MAX_REPORTITEMS]; /**< Report items array, including all IN, OUT + * and FEATURE items. + */ + HID_CollectionPath_t CollectionPaths[HID_MAX_COLLECTIONS]; /**< All collection items, referenced + * by the report items. + */ + uint8_t TotalDeviceReports; /**< Number of reports within the HID interface */ + HID_ReportSizeInfo_t ReportIDSizes[HID_MAX_REPORT_IDS]; /**< Report sizes for each report in the interface */ + uint16_t LargestReportSizeBits; /**< Largest report that the attached device will generate, in bits */ + bool UsingReportIDs; /**< Indicates if the device has at least one REPORT ID + * element in its HID report descriptor. + */ + } HID_ReportInfo_t; + + /* Function Prototypes: */ + /** Function to process a given HID report returned from an attached device, and store it into a given + * \ref HID_ReportInfo_t structure. + * + * \param[in] ReportData Buffer containing the device's HID report table. + * \param[in] ReportSize Size in bytes of the HID report table. + * \param[out] ParserData Pointer to a \ref HID_ReportInfo_t instance for the parser output. + * + * \return A value in the \ref HID_Parse_ErrorCodes_t enum. + */ + uint8_t USB_ProcessHIDReport(const uint8_t* ReportData, + uint16_t ReportSize, + HID_ReportInfo_t* const ParserData) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3); + + /** Extracts the given report item's value out of the given HID report and places it into the Value + * member of the report item's \ref HID_ReportItem_t structure. + * + * When called on a report with an item that exists in that report, this copies the report item's \c Value + * to its \c PreviousValue element for easy checking to see if an item's value has changed before processing + * a report. If the given item does not exist in the report, the function does not modify the report item's + * data. + * + * \param[in] ReportData Buffer containing an IN or FEATURE report from an attached device. + * \param[in,out] ReportItem Pointer to the report item of interest in a \ref HID_ReportInfo_t ReportItem array. + * + * \returns Boolean \c true if the item to retrieve was located in the given report, \c false otherwise. + */ + bool USB_GetHIDReportItemInfo(const uint8_t* ReportData, + HID_ReportItem_t* const ReportItem) ATTR_NON_NULL_PTR_ARG(1); + + /** Retrieves the given report item's value out of the \c Value member of the report item's + * \ref HID_ReportItem_t structure and places it into the correct position in the HID report + * buffer. The report buffer is assumed to have the appropriate bits cleared before calling + * this function (i.e., the buffer should be explicitly cleared before report values are added). + * + * When called, this copies the report item's \c Value element to its \c PreviousValue element for easy + * checking to see if an item's value has changed before sending a report. + * + * If the device has multiple HID reports, the first byte in the report is set to the report ID of the given item. + * + * \param[out] ReportData Buffer holding the current OUT or FEATURE report data. + * \param[in] ReportItem Pointer to the report item of interest in a \ref HID_ReportInfo_t ReportItem array. + */ + void USB_SetHIDReportItemInfo(uint8_t* ReportData, + HID_ReportItem_t* const ReportItem) ATTR_NON_NULL_PTR_ARG(1); + + /** Retrieves the size of a given HID report in bytes from its Report ID. + * + * \param[in] ParserData Pointer to a \ref HID_ReportInfo_t instance containing the parser output. + * \param[in] ReportID Report ID of the report whose size is to be determined. + * \param[in] ReportType Type of the report whose size is to be determined, a value from the + * \ref HID_ReportItemTypes_t enum. + * + * \return Size of the report in bytes, or \c 0 if the report does not exist. + */ + uint16_t USB_GetHIDReportSize(HID_ReportInfo_t* const ParserData, + const uint8_t ReportID, + const uint8_t ReportType) ATTR_CONST ATTR_NON_NULL_PTR_ARG(1); + + /** Callback routine for the HID Report Parser. This callback must be implemented by the user code when + * the parser is used, to determine what report IN, OUT and FEATURE item's information is stored into the user + * \ref HID_ReportInfo_t structure. This can be used to filter only those items the application will be using, so that + * no RAM is wasted storing the attributes for report items which will never be referenced by the application. + * + * Report item pointers passed to this callback function may be cached by the user application for later use + * when processing report items. This provides faster report processing in the user application than would + * a search of the entire parsed report item table for each received or sent report. + * + * \param[in] CurrentItem Pointer to the current report item for user checking. + * + * \return Boolean \c true if the item should be stored into the \ref HID_ReportInfo_t structure, \c false if + * it should be ignored. + */ + bool CALLBACK_HIDParser_FilterHIDReportItem(HID_ReportItem_t* const CurrentItem); + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Type Defines: */ + typedef struct + { + HID_ReportItem_Attributes_t Attributes; + uint8_t ReportCount; + uint8_t ReportID; + } HID_StateTable_t; + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Common/HIDReportData.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Common/HIDReportData.h new file mode 100644 index 00000000..719739a5 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Common/HIDReportData.h @@ -0,0 +1,126 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Constants for HID report item attributes. + * + * HID report item constants for report item attributes. Refer to the HID specification for + * details on each flag's meaning when applied to an IN, OUT or FEATURE item. + */ + +/** \ingroup Group_HIDParser + * \defgroup Group_HIDReportItemConst HID Report Descriptor Item Constants + * + * General HID constant definitions for HID Report Descriptor elements. + * + * @{ + */ + +#ifndef __HIDREPORTDATA_H__ +#define __HIDREPORTDATA_H__ + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Macros: */ + #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) 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, ...) _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__) + //@} + +/** @} */ + +#endif + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Common/MIDIClassCommon.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Common/MIDIClassCommon.h new file mode 100644 index 00000000..e0b77eca --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Common/MIDIClassCommon.h @@ -0,0 +1,320 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Common definitions and declarations for the library USB MIDI Class driver. + * + * Common definitions and declarations for the library USB MIDI Class driver. + * + * \note This file should not be included directly. It is automatically included as needed by the USB module driver + * dispatch header located in LUFA/Drivers/USB.h. + */ + +/** \ingroup Group_USBClassMIDI + * \defgroup Group_USBClassMIDICommon Common Class Definitions + * + * \section Sec_ModDescription Module Description + * Constants, Types and Enum definitions that are common to both Device and Host modes for the USB + * MIDI Class. + * + * @{ + */ + +#ifndef _MIDI_CLASS_COMMON_H_ +#define _MIDI_CLASS_COMMON_H_ + + /* Macros: */ + #define __INCLUDE_FROM_AUDIO_DRIVER + + /* Includes: */ + #include "../../Core/StdDescriptors.h" + #include "AudioClassCommon.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_MIDI_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB.h instead. + #endif + + /* Macros: */ + /** \name MIDI Command Values */ + //@{ + /** MIDI command for a note on (activation) event. */ + #define MIDI_COMMAND_NOTE_ON 0x90 + + /** MIDI command for a note off (deactivation) event. */ + #define MIDI_COMMAND_NOTE_OFF 0x80 + //@} + + /** Standard key press velocity value used for all note events. */ + #define MIDI_STANDARD_VELOCITY 64 + + /** Convenience macro. MIDI channels are numbered from 1-10 (natural numbers) however the logical channel + * addresses are zero-indexed. This converts a natural MIDI channel number into the logical channel address. + * + * \param[in] channel MIDI channel number to address. + * + * \return Constructed MIDI channel ID. + */ + #define MIDI_CHANNEL(channel) ((channel) - 1) + + /** Constructs a MIDI event ID from a given MIDI command and a virtual MIDI cable index. This can then be + * used to create and decode \ref MIDI_EventPacket_t MIDI event packets. + * + * \param[in] virtualcable Index of the virtual MIDI cable the event relates to + * \param[in] command MIDI command to send through the virtual MIDI cable + * + * \return Constructed MIDI event ID. + */ + #define MIDI_EVENT(virtualcable, command) ((virtualcable << 4) | (command >> 4)) + + /* Enums: */ + /** Enum for the possible MIDI jack types in a MIDI device jack descriptor. */ + enum MIDI_JackTypes_t + { + MIDI_JACKTYPE_Embedded = 0x01, /**< MIDI class descriptor jack type value for an embedded (logical) MIDI input or output jack. */ + MIDI_JACKTYPE_External = 0x02, /**< MIDI class descriptor jack type value for an external (physical) MIDI input or output jack. */ + }; + + /* Type Defines: */ + /** \brief MIDI class-specific Streaming Interface Descriptor (LUFA naming conventions). + * + * Type define for an Audio class-specific MIDI streaming interface descriptor. This indicates to the host + * how MIDI the specification compliance of the device and the total length of the Audio class-specific descriptors. + * See the USB Audio specification for more details. + * + * \see \ref USB_MIDI_StdDescriptor_AudioInterface_AS_t for the version of this type with standard element names. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length. */ + uint8_t Subtype; /**< Sub type value used to distinguish between audio class-specific descriptors. */ + + uint16_t AudioSpecification; /**< Binary coded decimal value, indicating the supported Audio Class + * specification version. + */ + uint16_t TotalLength; /**< Total length of the Audio class-specific descriptors, including this descriptor. */ + } ATTR_PACKED USB_MIDI_Descriptor_AudioInterface_AS_t; + + /** \brief MIDI class-specific Streaming Interface Descriptor (USB-IF naming conventions). + * + * Type define for an Audio class-specific MIDI streaming interface descriptor. This indicates to the host + * how MIDI the specification compliance of the device and the total length of the Audio class-specific descriptors. + * See the USB Audio specification for more details. + * + * \see \ref USB_MIDI_Descriptor_AudioInterface_AS_t for the version of this type with non-standard LUFA specific + * element names. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + uint8_t bLength; /**< Size of the descriptor, in bytes. */ + uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value + * given by the specific class. + */ + + uint8_t bDescriptorSubtype; /**< Sub type value used to distinguish between audio class-specific descriptors. */ + + uint16_t bcdMSC; /**< Binary coded decimal value, indicating the supported MIDI Class specification version. */ + uint16_t wTotalLength; /**< Total length of the Audio class-specific descriptors, including this descriptor. */ + } ATTR_PACKED USB_MIDI_StdDescriptor_AudioInterface_AS_t; + + /** \brief MIDI class-specific Input Jack Descriptor (LUFA naming conventions). + * + * Type define for an Audio class-specific MIDI IN jack. This gives information to the host on a MIDI input, either + * a physical input jack, or a logical jack (receiving input data internally, or from the host via an endpoint). + * + * \see \ref USB_MIDI_StdDescriptor_InputJack_t for the version of this type with standard element names. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length. */ + uint8_t Subtype; /**< Sub type value used to distinguish between audio class-specific descriptors. */ + + uint8_t JackType; /**< Type of jack, one of the \c JACKTYPE_* mask values. */ + uint8_t JackID; /**< ID value of this jack - must be a unique value within the device. */ + + uint8_t JackStrIndex; /**< Index of a string descriptor describing this descriptor within the device. */ + } ATTR_PACKED USB_MIDI_Descriptor_InputJack_t; + + /** \brief MIDI class-specific Input Jack Descriptor (USB-IF naming conventions). + * + * Type define for an Audio class-specific MIDI IN jack. This gives information to the host on a MIDI input, either + * a physical input jack, or a logical jack (receiving input data internally, or from the host via an endpoint). + * + * \see \ref USB_MIDI_Descriptor_InputJack_t for the version of this type with non-standard LUFA specific + * element names. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + uint8_t bLength; /**< Size of the descriptor, in bytes. */ + uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value + * given by the specific class. + */ + + uint8_t bDescriptorSubtype; /**< Sub type value used to distinguish between audio class-specific descriptors. */ + + uint8_t bJackType; /**< Type of jack, one of the \c JACKTYPE_* mask values. */ + uint8_t bJackID; /**< ID value of this jack - must be a unique value within the device. */ + + uint8_t iJack; /**< Index of a string descriptor describing this descriptor within the device. */ + } ATTR_PACKED USB_MIDI_StdDescriptor_InputJack_t; + + /** \brief MIDI class-specific Output Jack Descriptor (LUFA naming conventions). + * + * Type define for an Audio class-specific MIDI OUT jack. This gives information to the host on a MIDI output, either + * a physical output jack, or a logical jack (sending output data internally, or to the host via an endpoint). + * + * \see \ref USB_MIDI_StdDescriptor_OutputJack_t for the version of this type with standard element names. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length. */ + uint8_t Subtype; /**< Sub type value used to distinguish between audio class-specific descriptors. */ + + uint8_t JackType; /**< Type of jack, one of the \c JACKTYPE_* mask values. */ + uint8_t JackID; /**< ID value of this jack - must be a unique value within the device. */ + + uint8_t NumberOfPins; /**< Number of output channels within the jack, either physical or logical. */ + uint8_t SourceJackID[1]; /**< ID of each output pin's source data jack. */ + uint8_t SourcePinID[1]; /**< Pin number in the input jack of each output pin's source data. */ + + uint8_t JackStrIndex; /**< Index of a string descriptor describing this descriptor within the device. */ + } ATTR_PACKED USB_MIDI_Descriptor_OutputJack_t; + + /** \brief MIDI class-specific Output Jack Descriptor (USB-IF naming conventions). + * + * Type define for an Audio class-specific MIDI OUT jack. This gives information to the host on a MIDI output, either + * a physical output jack, or a logical jack (sending output data internally, or to the host via an endpoint). + * + * \see \ref USB_MIDI_Descriptor_OutputJack_t for the version of this type with non-standard LUFA specific + * element names. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + uint8_t bLength; /**< Size of the descriptor, in bytes. */ + uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value + * given by the specific class. + */ + + uint8_t bDescriptorSubtype; /**< Sub type value used to distinguish between audio class-specific descriptors. */ + + uint8_t bJackType; /**< Type of jack, one of the \c JACKTYPE_* mask values. */ + uint8_t bJackID; /**< ID value of this jack - must be a unique value within the device. */ + + uint8_t bNrInputPins; /**< Number of output channels within the jack, either physical or logical. */ + uint8_t baSourceID[1]; /**< ID of each output pin's source data jack. */ + uint8_t baSourcePin[1]; /**< Pin number in the input jack of each output pin's source data. */ + + uint8_t iJack; /**< Index of a string descriptor describing this descriptor within the device. */ + } ATTR_PACKED USB_MIDI_StdDescriptor_OutputJack_t; + + /** \brief Audio class-specific Jack Endpoint Descriptor (LUFA naming conventions). + * + * Type define for an Audio class-specific extended MIDI jack endpoint descriptor. This contains extra information + * on the usage of MIDI endpoints used to stream MIDI events in and out of the USB Audio device, and follows an Audio + * class-specific extended MIDI endpoint descriptor. See the USB Audio specification for more details. + * + * \see \ref USB_MIDI_StdDescriptor_Jack_Endpoint_t for the version of this type with standard element names. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + USB_Descriptor_Header_t Header; /**< Regular descriptor header containing the descriptor's type and length. */ + uint8_t Subtype; /**< Sub type value used to distinguish between audio class-specific descriptors. */ + + uint8_t TotalEmbeddedJacks; /**< Total number of jacks inside this endpoint. */ + uint8_t AssociatedJackID[1]; /**< IDs of each jack inside the endpoint. */ + } ATTR_PACKED USB_MIDI_Descriptor_Jack_Endpoint_t; + + /** \brief Audio class-specific Jack Endpoint Descriptor (USB-IF naming conventions). + * + * Type define for an Audio class-specific extended MIDI jack endpoint descriptor. This contains extra information + * on the usage of MIDI endpoints used to stream MIDI events in and out of the USB Audio device, and follows an Audio + * class-specific extended MIDI endpoint descriptor. See the USB Audio specification for more details. + * + * \see \ref USB_MIDI_Descriptor_Jack_Endpoint_t for the version of this type with non-standard LUFA specific + * element names. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + uint8_t bLength; /**< Size of the descriptor, in bytes. */ + uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value + * given by the specific class. + */ + + uint8_t bDescriptorSubtype; /**< Sub type value used to distinguish between audio class-specific descriptors. */ + + uint8_t bNumEmbMIDIJack; /**< Total number of jacks inside this endpoint. */ + uint8_t bAssocJackID[1]; /**< IDs of each jack inside the endpoint. */ + } ATTR_PACKED USB_MIDI_StdDescriptor_Jack_Endpoint_t; + + /** \brief MIDI Class Driver Event Packet. + * + * Type define for a USB MIDI event packet, used to encapsulate sent and received MIDI messages from a USB MIDI interface. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + uint8_t Event; /**< MIDI event type, constructed with the \ref MIDI_EVENT() macro. */ + + uint8_t Data1; /**< First byte of data in the MIDI event. */ + uint8_t Data2; /**< Second byte of data in the MIDI event. */ + uint8_t Data3; /**< Third byte of data in the MIDI event. */ + } ATTR_PACKED MIDI_EventPacket_t; + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Common/MassStorageClassCommon.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Common/MassStorageClassCommon.h new file mode 100644 index 00000000..38167f64 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Common/MassStorageClassCommon.h @@ -0,0 +1,365 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Common definitions and declarations for the library USB Mass Storage Class driver. + * + * Common definitions and declarations for the library USB Mass Storage Class driver. + * + * \note This file should not be included directly. It is automatically included as needed by the USB module driver + * dispatch header located in LUFA/Drivers/USB.h. + */ + +/** \ingroup Group_USBClassMS + * \defgroup Group_USBClassMSCommon Common Class Definitions + * + * \section Sec_ModDescription Module Description + * Constants, Types and Enum definitions that are common to both Device and Host modes for the USB + * Mass Storage Class. + * + * @{ + */ + +#ifndef _MS_CLASS_COMMON_H_ +#define _MS_CLASS_COMMON_H_ + + /* Includes: */ + #include "../../Core/StdDescriptors.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_MS_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB.h instead. + #endif + + /* Macros: */ + /** Magic signature for a Command Block Wrapper used in the Mass Storage Bulk-Only transport protocol. */ + #define MS_CBW_SIGNATURE 0x43425355UL + + /** Magic signature for a Command Status Wrapper used in the Mass Storage Bulk-Only transport protocol. */ + #define MS_CSW_SIGNATURE 0x53425355UL + + /** Mask for a Command Block Wrapper's flags attribute to specify a command with data sent from host-to-device. */ + #define MS_COMMAND_DIR_DATA_OUT (0 << 7) + + /** Mask for a Command Block Wrapper's flags attribute to specify a command with data sent from device-to-host. */ + #define MS_COMMAND_DIR_DATA_IN (1 << 7) + + /** \name SCSI Commands*/ + //@{ + /** SCSI Command Code for an INQUIRY command. */ + #define SCSI_CMD_INQUIRY 0x12 + + /** SCSI Command Code for a REQUEST SENSE command. */ + #define SCSI_CMD_REQUEST_SENSE 0x03 + + /** SCSI Command Code for a TEST UNIT READY command. */ + #define SCSI_CMD_TEST_UNIT_READY 0x00 + + /** SCSI Command Code for a READ CAPACITY (10) command. */ + #define SCSI_CMD_READ_CAPACITY_10 0x25 + + /** SCSI Command Code for a SEND DIAGNOSTIC command. */ + #define SCSI_CMD_SEND_DIAGNOSTIC 0x1D + + /** SCSI Command Code for a PREVENT ALLOW MEDIUM REMOVAL command. */ + #define SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL 0x1E + + /** SCSI Command Code for a WRITE (10) command. */ + #define SCSI_CMD_WRITE_10 0x2A + + /** SCSI Command Code for a READ (10) command. */ + #define SCSI_CMD_READ_10 0x28 + + /** SCSI Command Code for a WRITE (6) command. */ + #define SCSI_CMD_WRITE_6 0x0A + + /** SCSI Command Code for a READ (6) command. */ + #define SCSI_CMD_READ_6 0x08 + + /** SCSI Command Code for a VERIFY (10) command. */ + #define SCSI_CMD_VERIFY_10 0x2F + + /** SCSI Command Code for a MODE SENSE (6) command. */ + #define SCSI_CMD_MODE_SENSE_6 0x1A + + /** SCSI Command Code for a MODE SENSE (10) command. */ + #define SCSI_CMD_MODE_SENSE_10 0x5A + //@} + + /** \name SCSI Sense Key Values */ + //@{ + /** SCSI Sense Code to indicate no error has occurred. */ + #define SCSI_SENSE_KEY_GOOD 0x00 + + /** SCSI Sense Code to indicate that the device has recovered from an error. */ + #define SCSI_SENSE_KEY_RECOVERED_ERROR 0x01 + + /** SCSI Sense Code to indicate that the device is not ready for a new command. */ + #define SCSI_SENSE_KEY_NOT_READY 0x02 + + /** SCSI Sense Code to indicate an error whilst accessing the medium. */ + #define SCSI_SENSE_KEY_MEDIUM_ERROR 0x03 + + /** SCSI Sense Code to indicate a hardware error has occurred. */ + #define SCSI_SENSE_KEY_HARDWARE_ERROR 0x04 + + /** SCSI Sense Code to indicate that an illegal request has been issued. */ + #define SCSI_SENSE_KEY_ILLEGAL_REQUEST 0x05 + + /** SCSI Sense Code to indicate that the unit requires attention from the host to indicate + * a reset event, medium removal or other condition. + */ + #define SCSI_SENSE_KEY_UNIT_ATTENTION 0x06 + + /** SCSI Sense Code to indicate that a write attempt on a protected block has been made. */ + #define SCSI_SENSE_KEY_DATA_PROTECT 0x07 + + /** SCSI Sense Code to indicate an error while trying to write to a write-once medium. */ + #define SCSI_SENSE_KEY_BLANK_CHECK 0x08 + + /** SCSI Sense Code to indicate a vendor specific error has occurred. */ + #define SCSI_SENSE_KEY_VENDOR_SPECIFIC 0x09 + + /** SCSI Sense Code to indicate that an EXTENDED COPY command has aborted due to an error. */ + #define SCSI_SENSE_KEY_COPY_ABORTED 0x0A + + /** SCSI Sense Code to indicate that the device has aborted the issued command. */ + #define SCSI_SENSE_KEY_ABORTED_COMMAND 0x0B + + /** SCSI Sense Code to indicate an attempt to write past the end of a partition has been made. */ + #define SCSI_SENSE_KEY_VOLUME_OVERFLOW 0x0D + + /** SCSI Sense Code to indicate that the source data did not match the data read from the medium. */ + #define SCSI_SENSE_KEY_MISCOMPARE 0x0E + //@} + + /** \name SCSI Additional Sense Codes */ + //@{ + /** SCSI Additional Sense Code to indicate no additional sense information is available. */ + #define SCSI_ASENSE_NO_ADDITIONAL_INFORMATION 0x00 + + /** SCSI Additional Sense Code to indicate that the logical unit (LUN) addressed is not ready. */ + #define SCSI_ASENSE_LOGICAL_UNIT_NOT_READY 0x04 + + /** SCSI Additional Sense Code to indicate an invalid field was encountered while processing the issued command. */ + #define SCSI_ASENSE_INVALID_FIELD_IN_CDB 0x24 + + /** SCSI Additional Sense Code to indicate that a medium that was previously indicated as not ready has now + * become ready for use. + */ + #define SCSI_ASENSE_NOT_READY_TO_READY_CHANGE 0x28 + + /** SCSI Additional Sense Code to indicate that an attempt to write to a protected area was made. */ + #define SCSI_ASENSE_WRITE_PROTECTED 0x27 + + /** SCSI Additional Sense Code to indicate an error whilst formatting the device medium. */ + #define SCSI_ASENSE_FORMAT_ERROR 0x31 + + /** SCSI Additional Sense Code to indicate an invalid command was issued. */ + #define SCSI_ASENSE_INVALID_COMMAND 0x20 + + /** SCSI Additional Sense Code to indicate a write to a block out outside of the medium's range was issued. */ + #define SCSI_ASENSE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE 0x21 + + /** SCSI Additional Sense Code to indicate that no removable medium is inserted into the device. */ + #define SCSI_ASENSE_MEDIUM_NOT_PRESENT 0x3A + //@} + + /** \name SCSI Additional Sense Key Code Qualifiers */ + //@{ + /** SCSI Additional Sense Qualifier Code to indicate no additional sense qualifier information is available. */ + #define SCSI_ASENSEQ_NO_QUALIFIER 0x00 + + /** SCSI Additional Sense Qualifier Code to indicate that a medium format command failed to complete. */ + #define SCSI_ASENSEQ_FORMAT_COMMAND_FAILED 0x01 + + /** SCSI Additional Sense Qualifier Code to indicate that an initializing command must be issued before the issued + * command can be executed. + */ + #define SCSI_ASENSEQ_INITIALIZING_COMMAND_REQUIRED 0x02 + + /** SCSI Additional Sense Qualifier Code to indicate that an operation is currently in progress. */ + #define SCSI_ASENSEQ_OPERATION_IN_PROGRESS 0x07 + //@} + + /* Enums: */ + /** Enum for possible Class, Subclass and Protocol values of device and interface descriptors relating to the Mass + * Storage device class. + */ + enum MS_Descriptor_ClassSubclassProtocol_t + { + MS_CSCP_MassStorageClass = 0x08, /**< Descriptor Class value indicating that the device or interface + * belongs to the Mass Storage class. + */ + MS_CSCP_SCSITransparentSubclass = 0x06, /**< Descriptor Subclass value indicating that the device or interface + * belongs to the SCSI Transparent Command Set subclass of the Mass + * storage class. + */ + MS_CSCP_BulkOnlyTransportProtocol = 0x50, /**< Descriptor Protocol value indicating that the device or interface + * belongs to the Bulk Only Transport protocol of the Mass Storage class. + */ + }; + + /** Enum for the Mass Storage class specific control requests that can be issued by the USB bus host. */ + enum MS_ClassRequests_t + { + MS_REQ_GetMaxLUN = 0xFE, /**< Mass Storage class-specific request to retrieve the total number of Logical + * Units (drives) in the SCSI device. + */ + MS_REQ_MassStorageReset = 0xFF, /**< Mass Storage class-specific request to reset the Mass Storage interface, + * ready for the next command. + */ + }; + + /** Enum for the possible command status wrapper return status codes. */ + enum MS_CommandStatusCodes_t + { + MS_SCSI_COMMAND_Pass = 0, /**< Command completed with no error */ + MS_SCSI_COMMAND_Fail = 1, /**< Command failed to complete - host may check the exact error via a + * SCSI REQUEST SENSE command. + */ + MS_SCSI_COMMAND_PhaseError = 2, /**< Command failed due to being invalid in the current phase. */ + }; + + /* Type Defines: */ + /** \brief Mass Storage Class Command Block Wrapper. + * + * Type define for a Command Block Wrapper, used in the Mass Storage Bulk-Only Transport protocol. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + uint32_t Signature; /**< Command block signature, must be \ref MS_CBW_SIGNATURE to indicate a valid Command Block. */ + uint32_t Tag; /**< Unique command ID value, to associate a command block wrapper with its command status wrapper. */ + uint32_t DataTransferLength; /**< Length of the optional data portion of the issued command, in bytes. */ + uint8_t Flags; /**< Command block flags, indicating command data direction. */ + uint8_t LUN; /**< Logical Unit number this command is issued to. */ + uint8_t SCSICommandLength; /**< Length of the issued SCSI command within the SCSI command data array. */ + uint8_t SCSICommandData[16]; /**< Issued SCSI command in the Command Block. */ + } ATTR_PACKED MS_CommandBlockWrapper_t; + + /** \brief Mass Storage Class Command Status Wrapper. + * + * Type define for a Command Status Wrapper, used in the Mass Storage Bulk-Only Transport protocol. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + uint32_t Signature; /**< Status block signature, must be \ref MS_CSW_SIGNATURE to indicate a valid Command Status. */ + uint32_t Tag; /**< Unique command ID value, to associate a command block wrapper with its command status wrapper. */ + uint32_t DataTransferResidue; /**< Number of bytes of data not processed in the SCSI command. */ + uint8_t Status; /**< Status code of the issued command - a value from the \ref MS_CommandStatusCodes_t enum. */ + } ATTR_PACKED MS_CommandStatusWrapper_t; + + /** \brief Mass Storage Class SCSI Sense Structure + * + * Type define for a SCSI Sense structure. Structures of this type are filled out by the + * device via the \ref MS_Host_RequestSense() function, indicating the current sense data of the + * device (giving explicit error codes for the last issued command). For details of the + * structure contents, refer to the SCSI specifications. + */ + typedef struct + { + uint8_t ResponseCode; + + uint8_t SegmentNumber; + + unsigned SenseKey : 4; + unsigned Reserved : 1; + unsigned ILI : 1; + unsigned EOM : 1; + unsigned FileMark : 1; + + uint8_t Information[4]; + uint8_t AdditionalLength; + uint8_t CmdSpecificInformation[4]; + uint8_t AdditionalSenseCode; + uint8_t AdditionalSenseQualifier; + uint8_t FieldReplaceableUnitCode; + uint8_t SenseKeySpecific[3]; + } ATTR_PACKED SCSI_Request_Sense_Response_t; + + /** \brief Mass Storage Class SCSI Inquiry Structure. + * + * Type define for a SCSI Inquiry structure. Structures of this type are filled out by the + * device via the \ref MS_Host_GetInquiryData() function, retrieving the attached device's + * information. + * + * For details of the structure contents, refer to the SCSI specifications. + */ + typedef struct + { + unsigned DeviceType : 5; + unsigned PeripheralQualifier : 3; + + unsigned Reserved : 7; + unsigned Removable : 1; + + uint8_t Version; + + unsigned ResponseDataFormat : 4; + unsigned Reserved2 : 1; + unsigned NormACA : 1; + unsigned TrmTsk : 1; + unsigned AERC : 1; + + uint8_t AdditionalLength; + uint8_t Reserved3[2]; + + unsigned SoftReset : 1; + unsigned CmdQue : 1; + unsigned Reserved4 : 1; + unsigned Linked : 1; + unsigned Sync : 1; + unsigned WideBus16Bit : 1; + unsigned WideBus32Bit : 1; + unsigned RelAddr : 1; + + uint8_t VendorID[8]; + uint8_t ProductID[16]; + uint8_t RevisionID[4]; + } ATTR_PACKED SCSI_Inquiry_Response_t; + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Common/PrinterClassCommon.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Common/PrinterClassCommon.h new file mode 100644 index 00000000..eea39297 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Common/PrinterClassCommon.h @@ -0,0 +1,119 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Common definitions and declarations for the library USB Printer Class driver. + * + * Common definitions and declarations for the library USB Printer Class driver. + * + * \note This file should not be included directly. It is automatically included as needed by the USB module driver + * dispatch header located in LUFA/Drivers/USB.h. + */ + +/** \ingroup Group_USBClassPrinter + * \defgroup Group_USBClassPrinterCommon Common Class Definitions + * + * \section Sec_ModDescription Module Description + * Constants, Types and Enum definitions that are common to both Device and Host modes for the USB + * Printer Class. + * + * @{ + */ + +#ifndef _PRINTER_CLASS_COMMON_H_ +#define _PRINTER_CLASS_COMMON_H_ + + /* Includes: */ + #include "../../Core/StdDescriptors.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_PRINTER_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB.h instead. + #endif + + /* Macros: */ + /** \name Virtual Printer Status Line Masks */ + //@{ + /** Port status mask for a printer device, indicating that an error has *not* occurred. */ + #define PRNT_PORTSTATUS_NOTERROR (1 << 3) + + /** Port status mask for a printer device, indicating that the device is currently selected. */ + #define PRNT_PORTSTATUS_SELECT (1 << 4) + + /** Port status mask for a printer device, indicating that the device is currently out of paper. */ + #define PRNT_PORTSTATUS_PAPEREMPTY (1 << 5) + //@} + + /* Enums: */ + /** Enum for possible Class, Subclass and Protocol values of device and interface descriptors relating to the Printer + * device class. + */ + enum PRNT_Descriptor_ClassSubclassProtocol_t + { + PRNT_CSCP_PrinterClass = 0x07, /**< Descriptor Class value indicating that the device or interface + * belongs to the Printer class. + */ + PRNT_CSCP_PrinterSubclass = 0x01, /**< Descriptor Subclass value indicating that the device or interface + * belongs to the Printer subclass. + */ + PRNT_CSCP_BidirectionalProtocol = 0x02, /**< Descriptor Protocol value indicating that the device or interface + * belongs to the Bidirectional protocol of the Printer class. + */ + }; + + /** Enum for the Printer class specific control requests that can be issued by the USB bus host. */ + enum PRNT_ClassRequests_t + { + PRNT_REQ_GetDeviceID = 0x00, /**< Printer class-specific request to retrieve the Unicode ID + * string of the device, containing the device's name, manufacturer + * and supported printer languages. + */ + PRNT_REQ_GetPortStatus = 0x01, /**< Printer class-specific request to get the current status of the + * virtual printer port, for device selection and ready states. + */ + PRNT_REQ_SoftReset = 0x02, /**< Printer class-specific request to reset the device, ready for new + * printer commands. + */ + }; + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Common/RNDISClassCommon.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Common/RNDISClassCommon.h new file mode 100644 index 00000000..bc411218 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Common/RNDISClassCommon.h @@ -0,0 +1,414 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Common definitions and declarations for the library USB RNDIS Class driver. + * + * Common definitions and declarations for the library USB RNDIS Class driver. + * + * \note This file should not be included directly. It is automatically included as needed by the USB module driver + * dispatch header located in LUFA/Drivers/USB.h. + */ + +/** \ingroup Group_USBClassRNDIS + * \defgroup Group_USBClassRNDISCommon Common Class Definitions + * + * \section Sec_ModDescription Module Description + * Constants, Types and Enum definitions that are common to both Device and Host modes for the USB + * RNDIS Class. + * + * @{ + */ + +#ifndef _RNDIS_CLASS_COMMON_H_ +#define _RNDIS_CLASS_COMMON_H_ + + /* Macros: */ + #define __INCLUDE_FROM_CDC_DRIVER + + /* Includes: */ + #include "../../Core/StdDescriptors.h" + #include "CDCClassCommon.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_RNDIS_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB.h instead. + #endif + + /* Macros: */ + /** Additional error code for RNDIS functions when a device returns a logical command failure. */ + #define RNDIS_ERROR_LOGICAL_CMD_FAILED 0x80 + + /** Implemented RNDIS Version Major. */ + #define REMOTE_NDIS_VERSION_MAJOR 0x01 + + /** Implemented RNDIS Version Minor. */ + #define REMOTE_NDIS_VERSION_MINOR 0x00 + + /** \name RNDIS Message Values */ + //@{ + #define REMOTE_NDIS_PACKET_MSG 0x00000001UL + #define REMOTE_NDIS_INITIALIZE_MSG 0x00000002UL + #define REMOTE_NDIS_HALT_MSG 0x00000003UL + #define REMOTE_NDIS_QUERY_MSG 0x00000004UL + #define REMOTE_NDIS_SET_MSG 0x00000005UL + #define REMOTE_NDIS_RESET_MSG 0x00000006UL + #define REMOTE_NDIS_INDICATE_STATUS_MSG 0x00000007UL + #define REMOTE_NDIS_KEEPALIVE_MSG 0x00000008UL + //@} + + /** \name RNDIS Response Values */ + //@{ + #define REMOTE_NDIS_INITIALIZE_CMPLT 0x80000002UL + #define REMOTE_NDIS_QUERY_CMPLT 0x80000004UL + #define REMOTE_NDIS_SET_CMPLT 0x80000005UL + #define REMOTE_NDIS_RESET_CMPLT 0x80000006UL + #define REMOTE_NDIS_KEEPALIVE_CMPLT 0x80000008UL + //@} + + /** \name RNDIS Status Values */ + //@{ + #define REMOTE_NDIS_STATUS_SUCCESS 0x00000000UL + #define REMOTE_NDIS_STATUS_FAILURE 0xC0000001UL + #define REMOTE_NDIS_STATUS_INVALID_DATA 0xC0010015UL + #define REMOTE_NDIS_STATUS_NOT_SUPPORTED 0xC00000BBUL + #define REMOTE_NDIS_STATUS_MEDIA_CONNECT 0x4001000BUL + #define REMOTE_NDIS_STATUS_MEDIA_DISCONNECT 0x4001000CUL + //@} + + /** \name RNDIS Media States */ + //@{ + #define REMOTE_NDIS_MEDIA_STATE_CONNECTED 0x00000000UL + #define REMOTE_NDIS_MEDIA_STATE_DISCONNECTED 0x00000001UL + //@} + + /** \name RNDIS Media Types */ + //@{ + #define REMOTE_NDIS_MEDIUM_802_3 0x00000000UL + //@} + + /** \name RNDIS Connection Types */ + //@{ + #define REMOTE_NDIS_DF_CONNECTIONLESS 0x00000001UL + #define REMOTE_NDIS_DF_CONNECTION_ORIENTED 0x00000002UL + //@} + + /** \name RNDIS Packet Types */ + //@{ + #define REMOTE_NDIS_PACKET_DIRECTED 0x00000001UL + #define REMOTE_NDIS_PACKET_MULTICAST 0x00000002UL + #define REMOTE_NDIS_PACKET_ALL_MULTICAST 0x00000004UL + #define REMOTE_NDIS_PACKET_BROADCAST 0x00000008UL + #define REMOTE_NDIS_PACKET_SOURCE_ROUTING 0x00000010UL + #define REMOTE_NDIS_PACKET_PROMISCUOUS 0x00000020UL + #define REMOTE_NDIS_PACKET_SMT 0x00000040UL + #define REMOTE_NDIS_PACKET_ALL_LOCAL 0x00000080UL + #define REMOTE_NDIS_PACKET_GROUP 0x00001000UL + #define REMOTE_NDIS_PACKET_ALL_FUNCTIONAL 0x00002000UL + #define REMOTE_NDIS_PACKET_FUNCTIONAL 0x00004000UL + #define REMOTE_NDIS_PACKET_MAC_FRAME 0x00008000UL + //@} + + /** \name RNDIS OID Values */ + //@{ + #define OID_GEN_SUPPORTED_LIST 0x00010101UL + #define OID_GEN_HARDWARE_STATUS 0x00010102UL + #define OID_GEN_MEDIA_SUPPORTED 0x00010103UL + #define OID_GEN_MEDIA_IN_USE 0x00010104UL + #define OID_GEN_MAXIMUM_FRAME_SIZE 0x00010106UL + #define OID_GEN_MAXIMUM_TOTAL_SIZE 0x00010111UL + #define OID_GEN_LINK_SPEED 0x00010107UL + #define OID_GEN_TRANSMIT_BLOCK_SIZE 0x0001010AUL + #define OID_GEN_RECEIVE_BLOCK_SIZE 0x0001010BUL + #define OID_GEN_VENDOR_ID 0x0001010CUL + #define OID_GEN_VENDOR_DESCRIPTION 0x0001010DUL + #define OID_GEN_CURRENT_PACKET_FILTER 0x0001010EUL + #define OID_GEN_MAXIMUM_TOTAL_SIZE 0x00010111UL + #define OID_GEN_MEDIA_CONNECT_STATUS 0x00010114UL + #define OID_GEN_PHYSICAL_MEDIUM 0x00010202UL + #define OID_GEN_XMIT_OK 0x00020101UL + #define OID_GEN_RCV_OK 0x00020102UL + #define OID_GEN_XMIT_ERROR 0x00020103UL + #define OID_GEN_RCV_ERROR 0x00020104UL + #define OID_GEN_RCV_NO_BUFFER 0x00020105UL + #define OID_802_3_PERMANENT_ADDRESS 0x01010101UL + #define OID_802_3_CURRENT_ADDRESS 0x01010102UL + #define OID_802_3_MULTICAST_LIST 0x01010103UL + #define OID_802_3_MAXIMUM_LIST_SIZE 0x01010104UL + #define OID_802_3_RCV_ERROR_ALIGNMENT 0x01020101UL + #define OID_802_3_XMIT_ONE_COLLISION 0x01020102UL + #define OID_802_3_XMIT_MORE_COLLISIONS 0x01020103UL + //@} + + /** Maximum size in bytes of a RNDIS control message which can be sent or received. */ + #define RNDIS_MESSAGE_BUFFER_SIZE 128 + + /** Maximum size in bytes of an Ethernet frame according to the Ethernet standard. */ + #define ETHERNET_FRAME_SIZE_MAX 1500 + + /* Enums: */ + /** Enum for the RNDIS class specific control requests that can be issued by the USB bus host. */ + enum RNDIS_ClassRequests_t + { + RNDIS_REQ_SendEncapsulatedCommand = 0x00, /**< RNDIS request to issue a host-to-device NDIS command. */ + RNDIS_REQ_GetEncapsulatedResponse = 0x01, /**< RNDIS request to issue a device-to-host NDIS response. */ + }; + + /** Enum for the possible NDIS adapter states. */ + enum RNDIS_States_t + { + RNDIS_Uninitialized = 0, /**< Adapter currently uninitialized. */ + RNDIS_Initialized = 1, /**< Adapter currently initialized but not ready for data transfers. */ + RNDIS_Data_Initialized = 2, /**< Adapter currently initialized and ready for data transfers. */ + }; + + /** Enum for the RNDIS class specific notification requests that can be issued by a RNDIS device to a host. */ + enum RNDIS_ClassNotifications_t + { + RNDIS_NOTIF_ResponseAvailable = 0x01, /**< Notification request value for a RNDIS Response Available notification. */ + }; + + /** Enum for the NDIS hardware states. */ + enum NDIS_Hardware_Status_t + { + NDIS_HardwareStatus_Ready, /**< Hardware Ready to accept commands from the host. */ + NDIS_HardwareStatus_Initializing, /**< Hardware busy initializing. */ + NDIS_HardwareStatus_Reset, /**< Hardware reset. */ + NDIS_HardwareStatus_Closing, /**< Hardware currently closing. */ + NDIS_HardwareStatus_NotReady /**< Hardware not ready to accept commands from the host. */ + }; + + /* Type Defines: */ + /** \brief MAC Address Structure. + * + * Type define for a physical MAC address of a device on a network. + */ + typedef struct + { + uint8_t Octets[6]; /**< Individual bytes of a MAC address */ + } ATTR_PACKED MAC_Address_t; + + /** \brief RNDIS Common Message Header Structure. + * + * Type define for a RNDIS message header, sent before RNDIS messages. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + uint32_t MessageType; /**< RNDIS message type, a \c REMOTE_NDIS_*_MSG constant */ + uint32_t MessageLength; /**< Total length of the RNDIS message, in bytes */ + } ATTR_PACKED RNDIS_Message_Header_t; + + /** \brief RNDIS Message Structure. + * + * Type define for a RNDIS packet message, used to encapsulate Ethernet packets sent to and from the adapter. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + uint32_t MessageType; + uint32_t MessageLength; + uint32_t DataOffset; + uint32_t DataLength; + uint32_t OOBDataOffset; + uint32_t OOBDataLength; + uint32_t NumOOBDataElements; + uint32_t PerPacketInfoOffset; + uint32_t PerPacketInfoLength; + uint32_t VcHandle; + uint32_t Reserved; + } ATTR_PACKED RNDIS_Packet_Message_t; + + /** \brief RNDIS Initialization Message Structure. + * + * Type define for a RNDIS Initialize command message. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + uint32_t MessageType; + uint32_t MessageLength; + uint32_t RequestId; + + uint32_t MajorVersion; + uint32_t MinorVersion; + uint32_t MaxTransferSize; + } ATTR_PACKED RNDIS_Initialize_Message_t; + + /** \brief RNDIS Initialize Complete Message Structure. + * + * Type define for a RNDIS Initialize Complete response message. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + uint32_t MessageType; + uint32_t MessageLength; + uint32_t RequestId; + uint32_t Status; + + uint32_t MajorVersion; + uint32_t MinorVersion; + uint32_t DeviceFlags; + uint32_t Medium; + uint32_t MaxPacketsPerTransfer; + uint32_t MaxTransferSize; + uint32_t PacketAlignmentFactor; + uint32_t AFListOffset; + uint32_t AFListSize; + } ATTR_PACKED RNDIS_Initialize_Complete_t; + + /** \brief RNDIS Keep Alive Message Structure. + * + * Type define for a RNDIS Keep Alive command message. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + uint32_t MessageType; + uint32_t MessageLength; + uint32_t RequestId; + } ATTR_PACKED RNDIS_KeepAlive_Message_t; + + /** \brief RNDIS Keep Alive Complete Message Structure. + * + * Type define for a RNDIS Keep Alive Complete response message. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + uint32_t MessageType; + uint32_t MessageLength; + uint32_t RequestId; + uint32_t Status; + } ATTR_PACKED RNDIS_KeepAlive_Complete_t; + + /** \brief RNDIS Reset Complete Message Structure. + * + * Type define for a RNDIS Reset Complete response message. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + uint32_t MessageType; + uint32_t MessageLength; + uint32_t Status; + + uint32_t AddressingReset; + } ATTR_PACKED RNDIS_Reset_Complete_t; + + /** \brief RNDIS OID Property Set Message Structure. + * + * Type define for a RNDIS OID Property Set command message. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + uint32_t MessageType; + uint32_t MessageLength; + uint32_t RequestId; + + uint32_t Oid; + uint32_t InformationBufferLength; + uint32_t InformationBufferOffset; + uint32_t DeviceVcHandle; + } ATTR_PACKED RNDIS_Set_Message_t; + + /** \brief RNDIS OID Property Set Complete Message Structure. + * + * Type define for a RNDIS OID Property Set Complete response message. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + uint32_t MessageType; + uint32_t MessageLength; + uint32_t RequestId; + uint32_t Status; + } ATTR_PACKED RNDIS_Set_Complete_t; + + /** \brief RNDIS OID Property Query Message Structure. + * + * Type define for a RNDIS OID Property Query command message. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + uint32_t MessageType; + uint32_t MessageLength; + uint32_t RequestId; + + uint32_t Oid; + uint32_t InformationBufferLength; + uint32_t InformationBufferOffset; + uint32_t DeviceVcHandle; + } ATTR_PACKED RNDIS_Query_Message_t; + + /** \brief RNDIS OID Property Query Complete Message Structure. + * + * Type define for a RNDIS OID Property Query Complete response message. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + uint32_t MessageType; + uint32_t MessageLength; + uint32_t RequestId; + uint32_t Status; + + uint32_t InformationBufferLength; + uint32_t InformationBufferOffset; + } ATTR_PACKED RNDIS_Query_Complete_t; + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Common/StillImageClassCommon.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Common/StillImageClassCommon.h new file mode 100644 index 00000000..a3388e2e --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Common/StillImageClassCommon.h @@ -0,0 +1,161 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Common definitions and declarations for the library USB Still Image Class driver. + * + * Common definitions and declarations for the library USB Still Image Class driver. + * + * \note This file should not be included directly. It is automatically included as needed by the USB module driver + * dispatch header located in LUFA/Drivers/USB.h. + */ + +/** \ingroup Group_USBClassSI + * \defgroup Group_USBClassSICommon Common Class Definitions + * + * \section Sec_ModDescription Module Description + * Constants, Types and Enum definitions that are common to both Device and Host modes for the USB + * Still Image Class. + * + * @{ + */ + +#ifndef _SI_CLASS_COMMON_H_ +#define _SI_CLASS_COMMON_H_ + + /* Includes: */ + #include "../../Core/StdDescriptors.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_SI_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB.h instead. + #endif + + /* Macros: */ + /** Length in bytes of a given Unicode string's character length. + * + * \param[in] Chars Total number of Unicode characters in the string. + * + * \return Number of bytes of the given unicode string. + */ + #define UNICODE_STRING_LENGTH(Chars) ((Chars) << 1) + + /** Used in the DataLength field of a PIMA container, to give the total container size in bytes for + * a command container. + * + * \param[in] Params Number of parameters which are to be sent in the \c Param field of the container. + */ + #define PIMA_COMMAND_SIZE(Params) ((sizeof(PIMA_Container_t) - 12) + ((Params) * sizeof(uint32_t))) + + /** Used in the DataLength field of a PIMA container, to give the total container size in bytes for + * a data container. + * + * \param[in] DataLen Length in bytes of the data in the container. + */ + #define PIMA_DATA_SIZE(DataLen) ((sizeof(PIMA_Container_t) - 12) + (DataLen)) + + /* Enums: */ + /** Enum for the possible PIMA contains types. */ + enum PIMA_Container_Types_t + { + PIMA_CONTAINER_Undefined = 0, /**< Undefined container type. */ + PIMA_CONTAINER_CommandBlock = 1, /**< Command Block container type. */ + PIMA_CONTAINER_DataBlock = 2, /**< Data Block container type. */ + PIMA_CONTAINER_ResponseBlock = 3, /**< Response container type. */ + PIMA_CONTAINER_EventBlock = 4, /**< Event Block container type. */ + }; + + /* Enums: */ + /** Enum for possible Class, Subclass and Protocol values of device and interface descriptors relating to the + * Still Image device class. + */ + enum SI_Descriptor_ClassSubclassProtocol_t + { + SI_CSCP_StillImageClass = 0x06, /**< Descriptor Class value indicating that the device or interface + * belongs to the Still Image class. + */ + SI_CSCP_StillImageSubclass = 0x01, /**< Descriptor Subclass value indicating that the device or interface + * belongs to the Still Image subclass. + */ + SI_CSCP_BulkOnlyProtocol = 0x01, /**< Descriptor Protocol value indicating that the device or interface + * belongs to the Bulk Only Transport protocol of the Still Image class. + */ + }; + + /** Enums for the possible status codes of a returned Response Block from an attached PIMA compliant Still Image device. */ + enum PIMA_ResponseCodes_t + { + PIMA_RESPONSE_OK = 1, /**< Response code indicating no error in the issued command. */ + PIMA_RESPONSE_GeneralError = 2, /**< Response code indicating a general error while processing the + * issued command. + */ + PIMA_RESPONSE_SessionNotOpen = 3, /**< Response code indicating that the sent command requires an open + * session before being issued. + */ + PIMA_RESPONSE_InvalidTransaction = 4, /**< Response code indicating an invalid transaction occurred. */ + PIMA_RESPONSE_OperationNotSupported = 5, /**< Response code indicating that the issued command is not supported + * by the attached device. + */ + PIMA_RESPONSE_ParameterNotSupported = 6, /**< Response code indicating that one or more of the issued command's + * parameters are not supported by the device. + */ + }; + + /* Type Defines: */ + /** \brief PIMA Still Image Device Command/Response Container. + * + * Type define for a PIMA container, use to send commands and receive responses to and from an + * attached Still Image device. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + uint32_t DataLength; /**< Length of the container and data, in bytes. */ + uint16_t Type; /**< Container type, a value from the \ref PIMA_Container_Types_t enum. */ + uint16_t Code; /**< Command, event or response code of the container. */ + uint32_t TransactionID; /**< Unique container ID to link blocks together. */ + uint32_t Params[3]; /**< Block parameters to be issued along with the block code (command blocks only). */ + } ATTR_PACKED PIMA_Container_t; + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Device/AudioClassDevice.c b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Device/AudioClassDevice.c new file mode 100644 index 00000000..3fb350a1 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Device/AudioClassDevice.c @@ -0,0 +1,198 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#define __INCLUDE_FROM_USB_DRIVER +#include "../../Core/USBMode.h" + +#if defined(USB_CAN_BE_DEVICE) + +#define __INCLUDE_FROM_AUDIO_DRIVER +#define __INCLUDE_FROM_AUDIO_DEVICE_C +#include "AudioClassDevice.h" + +void Audio_Device_ProcessControlRequest(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) +{ + if (!(Endpoint_IsSETUPReceived())) + return; + + if ((USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT) == REQREC_INTERFACE) + { + uint8_t InterfaceIndex = (USB_ControlRequest.wIndex & 0xFF); + + if ((InterfaceIndex != AudioInterfaceInfo->Config.ControlInterfaceNumber) && + (InterfaceIndex != AudioInterfaceInfo->Config.StreamingInterfaceNumber)) + { + return; + } + } + else if ((USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT) == REQREC_ENDPOINT) + { + uint8_t EndpointAddress = (USB_ControlRequest.wIndex & 0xFF); + + if ((EndpointAddress != AudioInterfaceInfo->Config.DataINEndpoint.Address) && + (EndpointAddress != AudioInterfaceInfo->Config.DataOUTEndpoint.Address)) + { + return; + } + } + + switch (USB_ControlRequest.bRequest) + { + case REQ_SetInterface: + if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_INTERFACE)) + { + Endpoint_ClearSETUP(); + Endpoint_ClearStatusStage(); + + AudioInterfaceInfo->State.InterfaceEnabled = ((USB_ControlRequest.wValue & 0xFF) != 0); + EVENT_Audio_Device_StreamStartStop(AudioInterfaceInfo); + } + + break; + case AUDIO_REQ_GetStatus: + if ((USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) || + (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_ENDPOINT))) + { + Endpoint_ClearSETUP(); + Endpoint_ClearStatusStage(); + } + + break; + case AUDIO_REQ_SetCurrent: + case AUDIO_REQ_SetMinimum: + case AUDIO_REQ_SetMaximum: + case AUDIO_REQ_SetResolution: + if ((USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT) == REQREC_ENDPOINT) + { + uint8_t EndpointProperty = USB_ControlRequest.bRequest; + uint8_t EndpointAddress = (uint8_t)USB_ControlRequest.wIndex; + uint8_t EndpointControl = (USB_ControlRequest.wValue >> 8); + + if (CALLBACK_Audio_Device_GetSetEndpointProperty(AudioInterfaceInfo, EndpointProperty, EndpointAddress, + EndpointControl, NULL, NULL)) + { + uint16_t ValueLength = USB_ControlRequest.wLength; + uint8_t Value[ValueLength]; + + Endpoint_ClearSETUP(); + Endpoint_Read_Control_Stream_LE(Value, ValueLength); + Endpoint_ClearIN(); + + CALLBACK_Audio_Device_GetSetEndpointProperty(AudioInterfaceInfo, EndpointProperty, EndpointAddress, + EndpointControl, &ValueLength, Value); + } + } + else if ((USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT) == REQREC_INTERFACE) + { + uint8_t Property = USB_ControlRequest.bRequest; + uint8_t Entity = (USB_ControlRequest.wIndex >> 8); + uint16_t Parameter = USB_ControlRequest.wValue; + + if (CALLBACK_Audio_Device_GetSetInterfaceProperty(AudioInterfaceInfo, Property, Entity, + Parameter, NULL, NULL)) + { + uint16_t ValueLength = USB_ControlRequest.wLength; + uint8_t Value[ValueLength]; + + Endpoint_ClearSETUP(); + Endpoint_Read_Control_Stream_LE(Value, ValueLength); + Endpoint_ClearIN(); + + CALLBACK_Audio_Device_GetSetInterfaceProperty(AudioInterfaceInfo, Property, Entity, + Parameter, &ValueLength, Value); + } + } + + break; + case AUDIO_REQ_GetCurrent: + case AUDIO_REQ_GetMinimum: + case AUDIO_REQ_GetMaximum: + case AUDIO_REQ_GetResolution: + if ((USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT) == REQREC_ENDPOINT) + { + uint8_t EndpointProperty = USB_ControlRequest.bRequest; + uint8_t EndpointAddress = (uint8_t)USB_ControlRequest.wIndex; + uint8_t EndpointControl = (USB_ControlRequest.wValue >> 8); + uint16_t ValueLength = USB_ControlRequest.wLength; + uint8_t Value[ValueLength]; + + if (CALLBACK_Audio_Device_GetSetEndpointProperty(AudioInterfaceInfo, EndpointProperty, EndpointAddress, + EndpointControl, &ValueLength, Value)) + { + Endpoint_ClearSETUP(); + Endpoint_Write_Control_Stream_LE(Value, ValueLength); + Endpoint_ClearOUT(); + } + } + else if ((USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT) == REQREC_INTERFACE) + { + uint8_t Property = USB_ControlRequest.bRequest; + uint8_t Entity = (USB_ControlRequest.wIndex >> 8); + uint16_t Parameter = USB_ControlRequest.wValue; + uint16_t ValueLength = USB_ControlRequest.wLength; + uint8_t Value[ValueLength]; + + if (CALLBACK_Audio_Device_GetSetInterfaceProperty(AudioInterfaceInfo, Property, Entity, + Parameter, &ValueLength, Value)) + { + Endpoint_ClearSETUP(); + Endpoint_Write_Control_Stream_LE(Value, ValueLength); + Endpoint_ClearOUT(); + } + } + + break; + } +} + +bool Audio_Device_ConfigureEndpoints(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) +{ + memset(&AudioInterfaceInfo->State, 0x00, sizeof(AudioInterfaceInfo->State)); + + AudioInterfaceInfo->Config.DataINEndpoint.Type = EP_TYPE_ISOCHRONOUS; + AudioInterfaceInfo->Config.DataOUTEndpoint.Type = EP_TYPE_ISOCHRONOUS; + + if (!(Endpoint_ConfigureEndpointTable(&AudioInterfaceInfo->Config.DataINEndpoint, 1))) + return false; + + if (!(Endpoint_ConfigureEndpointTable(&AudioInterfaceInfo->Config.DataOUTEndpoint, 1))) + return false; + + return true; +} + +// cppcheck-suppress unusedFunction +void Audio_Device_Event_Stub(void) +{ + +} + +#endif + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Device/AudioClassDevice.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Device/AudioClassDevice.h new file mode 100644 index 00000000..09a83280 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Device/AudioClassDevice.h @@ -0,0 +1,396 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Device mode driver for the library USB Audio 1.0 Class driver. + * + * Device mode driver for the library USB Audio 1.0 Class driver. + * + * \note This file should not be included directly. It is automatically included as needed by the USB module driver + * dispatch header located in LUFA/Drivers/USB.h. + */ + +/** \ingroup Group_USBClassAudio + * \defgroup Group_USBClassAudioDevice Audio 1.0 Class Device Mode Driver + * + * \section Sec_Dependencies Module Source Dependencies + * The following files must be built with any user project that uses this module: + * - LUFA/Drivers/USB/Class/Device/AudioClassDevice.c (Makefile source module name: LUFA_SRC_USBCLASS) + * + * \section Sec_ModDescription Module Description + * Device Mode USB Class driver framework interface, for the Audio 1.0 USB Class driver. + * + * @{ + */ + +#ifndef _AUDIO_CLASS_DEVICE_H_ +#define _AUDIO_CLASS_DEVICE_H_ + + /* Includes: */ + #include "../../USB.h" + #include "../Common/AudioClassCommon.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_AUDIO_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Type Defines: */ + /** \brief Audio Class Device Mode Configuration and State Structure. + * + * Class state structure. An instance of this structure should be made for each Audio interface + * within the user application, and passed to each of the Audio class driver functions as the + * \c AudioInterfaceInfo parameter. This stores each Audio interface's configuration and state information. + */ + typedef struct + { + struct + { + uint8_t ControlInterfaceNumber; /**< Index of the Audio Control interface within the device this + * structure controls. + */ + uint8_t StreamingInterfaceNumber; /**< Index of the Audio Streaming interface within the device this + * structure controls. + */ + + USB_Endpoint_Table_t DataINEndpoint; /**< Data IN endpoint configuration table. */ + USB_Endpoint_Table_t DataOUTEndpoint; /**< Data OUT endpoint configuration table. */ + } Config; /**< Config data for the USB class interface within the device. All elements in this section + * must be set or the interface will fail to enumerate and operate correctly. + */ + struct + { + bool InterfaceEnabled; /**< Set and cleared by the class driver to indicate if the host has enabled the streaming endpoints + * of the Audio Streaming interface. + */ + } State; /**< State data for the USB class interface within the device. All elements in this section + * are reset to their defaults when the interface is enumerated. + */ + } USB_ClassInfo_Audio_Device_t; + + /* Function Prototypes: */ + /** Configures the endpoints of a given Audio interface, ready for use. This should be linked to the library + * \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration containing the + * given Audio interface is selected. + * + * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state. + * + * \return Boolean \c true if the endpoints were successfully configured, \c false otherwise. + */ + bool Audio_Device_ConfigureEndpoints(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + /** Processes incoming control requests from the host, that are directed to the given Audio class interface. This should be + * linked to the library \ref EVENT_USB_Device_ControlRequest() event. + * + * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state. + */ + void Audio_Device_ProcessControlRequest(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + /** Audio class driver callback for the setting and retrieval of streaming endpoint properties. This callback must be implemented + * in the user application to handle property manipulations on streaming audio endpoints. + * + * When the DataLength parameter is NULL, this callback should only indicate whether the specified operation is valid for + * the given endpoint index, and should return as fast as possible. When non-NULL, this value may be altered for GET operations + * to indicate the size of the retrieved data. + * + * \note The length of the retrieved data stored into the Data buffer on GET operations should not exceed the initial value + * of the \c DataLength parameter. + * + * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state. + * \param[in] EndpointProperty Property of the endpoint to get or set, a value from \ref Audio_ClassRequests_t. + * \param[in] EndpointAddress Address of the streaming endpoint whose property is being referenced. + * \param[in] EndpointControl Parameter of the endpoint to get or set, a value from \ref Audio_EndpointControls_t. + * \param[in,out] DataLength For SET operations, the length of the parameter data to set. For GET operations, the maximum + * length of the retrieved data. When NULL, the function should return whether the given property + * and parameter is valid for the requested endpoint without reading or modifying the Data buffer. + * \param[in,out] Data Pointer to a location where the parameter data is stored for SET operations, or where + * the retrieved data is to be stored for GET operations. + * + * \return Boolean \c true if the property GET/SET was successful, \c false otherwise + */ + bool CALLBACK_Audio_Device_GetSetEndpointProperty(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo, + const uint8_t EndpointProperty, + const uint8_t EndpointAddress, + const uint8_t EndpointControl, + uint16_t* const DataLength, + uint8_t* Data) ATTR_NON_NULL_PTR_ARG(1); + + /** Audio class driver callback for the setting and retrieval of streaming interface properties. This callback must be implemented + * in the user application to handle property manipulations on streaming audio interfaces. + * + * When the DataLength parameter is NULL, this callback should only indicate whether the specified operation is valid for + * the given entity and should return as fast as possible. When non-NULL, this value may be altered for GET operations + * to indicate the size of the retrieved data. + * + * \note The length of the retrieved data stored into the Data buffer on GET operations should not exceed the initial value + * of the \c DataLength parameter. + * + * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state. + * \param[in] Property Property of the interface to get or set, a value from \ref Audio_ClassRequests_t. + * \param[in] EntityAddress Address of the audio entity whose property is being referenced. + * \param[in] Parameter Parameter of the entity to get or set, specific to each type of entity (see USB Audio specification). + * \param[in,out] DataLength For SET operations, the length of the parameter data to set. For GET operations, the maximum + * length of the retrieved data. When NULL, the function should return whether the given property + * and parameter is valid for the requested endpoint without reading or modifying the Data buffer. + * \param[in,out] Data Pointer to a location where the parameter data is stored for SET operations, or where + * the retrieved data is to be stored for GET operations. + * + * \return Boolean \c true if the property GET/SET was successful, \c false otherwise + */ + bool CALLBACK_Audio_Device_GetSetInterfaceProperty(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo, + const uint8_t Property, + const uint8_t EntityAddress, + const uint16_t Parameter, + uint16_t* const DataLength, + uint8_t* Data) ATTR_NON_NULL_PTR_ARG(1); + + /** Audio class driver event for an Audio Stream start/stop change. This event fires each time the device receives a stream enable or + * disable control request from the host, to start and stop the audio stream. The current state of the stream can be determined by the + * State.InterfaceEnabled value inside the Audio interface structure passed as a parameter. + * + * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state. + */ + void EVENT_Audio_Device_StreamStartStop(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo); + + /* Inline Functions: */ + /** General management task for a given Audio class interface, required for the correct operation of the interface. This should + * be called frequently in the main program loop, before the master USB management task \ref USB_USBTask(). + * + * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state. + */ + static inline void Audio_Device_USBTask(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) + ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE; + static inline void Audio_Device_USBTask(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) + { + (void)AudioInterfaceInfo; + } + + /** Determines if the given audio interface is ready for a sample to be read from it, and selects the streaming + * OUT endpoint ready for reading. + * + * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or + * the call will fail. + * + * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state. + * + * \return Boolean \c true if the given Audio interface has a sample to be read, \c false otherwise. + */ + static inline bool Audio_Device_IsSampleReceived(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) + ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE; + static inline bool Audio_Device_IsSampleReceived(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) + { + if ((USB_DeviceState != DEVICE_STATE_Configured) || !(AudioInterfaceInfo->State.InterfaceEnabled)) + return false; + + Endpoint_SelectEndpoint(AudioInterfaceInfo->Config.DataOUTEndpoint.Address); + return Endpoint_IsOUTReceived(); + } + + /** Determines if the given audio interface is ready to accept the next sample to be written to it, and selects + * the streaming IN endpoint ready for writing. + * + * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or + * the call will fail. + * + * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state. + * + * \return Boolean \c true if the given Audio interface is ready to accept the next sample, \c false otherwise. + */ + static inline bool Audio_Device_IsReadyForNextSample(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) + ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE; + static inline bool Audio_Device_IsReadyForNextSample(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) + { + if ((USB_DeviceState != DEVICE_STATE_Configured) || !(AudioInterfaceInfo->State.InterfaceEnabled)) + return false; + + Endpoint_SelectEndpoint(AudioInterfaceInfo->Config.DataINEndpoint.Address); + return Endpoint_IsINReady(); + } + + /** Reads the next 8-bit audio sample from the current audio interface. + * + * \pre This should be preceded immediately by a call to the \ref Audio_Device_IsSampleReceived() function to ensure + * that the correct endpoint is selected and ready for data. + * + * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state. + * + * \return Signed 8-bit audio sample from the audio interface. + */ + static inline int8_t Audio_Device_ReadSample8(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) + ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE; + static inline int8_t Audio_Device_ReadSample8(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) + { + int8_t Sample; + + (void)AudioInterfaceInfo; + + Sample = Endpoint_Read_8(); + + if (!(Endpoint_BytesInEndpoint())) + Endpoint_ClearOUT(); + + return Sample; + } + + /** Reads the next 16-bit audio sample from the current audio interface. + * + * \pre This should be preceded immediately by a call to the \ref Audio_Device_IsSampleReceived() function to ensure + * that the correct endpoint is selected and ready for data. + * + * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state. + * + * \return Signed 16-bit audio sample from the audio interface. + */ + static inline int16_t Audio_Device_ReadSample16(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) + ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE; + static inline int16_t Audio_Device_ReadSample16(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) + { + int16_t Sample; + + (void)AudioInterfaceInfo; + + Sample = (int16_t)Endpoint_Read_16_LE(); + + if (!(Endpoint_BytesInEndpoint())) + Endpoint_ClearOUT(); + + return Sample; + } + + /** Reads the next 24-bit audio sample from the current audio interface. + * + * \pre This should be preceded immediately by a call to the \ref Audio_Device_IsSampleReceived() function to ensure + * that the correct endpoint is selected and ready for data. + * + * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state. + * + * \return Signed 24-bit audio sample from the audio interface. + */ + static inline int32_t Audio_Device_ReadSample24(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) + ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE; + static inline int32_t Audio_Device_ReadSample24(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) + { + int32_t Sample; + + (void)AudioInterfaceInfo; + + Sample = (((uint32_t)Endpoint_Read_8() << 16) | Endpoint_Read_16_LE()); + + if (!(Endpoint_BytesInEndpoint())) + Endpoint_ClearOUT(); + + return Sample; + } + + /** Writes the next 8-bit audio sample to the current audio interface. + * + * \pre This should be preceded immediately by a call to the \ref Audio_Device_IsReadyForNextSample() function to + * ensure that the correct endpoint is selected and ready for data. + * + * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state. + * \param[in] Sample Signed 8-bit audio sample. + */ + static inline void Audio_Device_WriteSample8(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo, + const int8_t Sample) ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE; + static inline void Audio_Device_WriteSample8(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo, + const int8_t Sample) + { + Endpoint_Write_8(Sample); + + if (Endpoint_BytesInEndpoint() == AudioInterfaceInfo->Config.DataINEndpoint.Size) + Endpoint_ClearIN(); + } + + /** Writes the next 16-bit audio sample to the current audio interface. + * + * \pre This should be preceded immediately by a call to the \ref Audio_Device_IsReadyForNextSample() function to + * ensure that the correct endpoint is selected and ready for data. + * + * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state. + * \param[in] Sample Signed 16-bit audio sample. + */ + static inline void Audio_Device_WriteSample16(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo, + const int16_t Sample) ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE; + static inline void Audio_Device_WriteSample16(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo, + const int16_t Sample) + { + Endpoint_Write_16_LE(Sample); + + if (Endpoint_BytesInEndpoint() == AudioInterfaceInfo->Config.DataINEndpoint.Size) + Endpoint_ClearIN(); + } + + /** Writes the next 24-bit audio sample to the current audio interface. + * + * \pre This should be preceded immediately by a call to the \ref Audio_Device_IsReadyForNextSample() function to + * ensure that the correct endpoint is selected and ready for data. + * + * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state. + * \param[in] Sample Signed 24-bit audio sample. + */ + static inline void Audio_Device_WriteSample24(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo, + const int32_t Sample) ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE; + static inline void Audio_Device_WriteSample24(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo, + const int32_t Sample) + { + Endpoint_Write_16_LE(Sample); + Endpoint_Write_8(Sample >> 16); + + if (Endpoint_BytesInEndpoint() == AudioInterfaceInfo->Config.DataINEndpoint.Size) + Endpoint_ClearIN(); + } + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Function Prototypes: */ + #if defined(__INCLUDE_FROM_AUDIO_DEVICE_C) + void Audio_Device_Event_Stub(void) ATTR_CONST; + + void EVENT_Audio_Device_StreamStartStop(USB_ClassInfo_Audio_Device_t* const AudioInterfaceInfo) + ATTR_WEAK ATTR_NON_NULL_PTR_ARG(1) ATTR_ALIAS(Audio_Device_Event_Stub); + #endif + + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Device/CDCClassDevice.c b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Device/CDCClassDevice.c new file mode 100644 index 00000000..e77aa280 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Device/CDCClassDevice.c @@ -0,0 +1,339 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#define __INCLUDE_FROM_USB_DRIVER +#include "../../Core/USBMode.h" + +#if defined(USB_CAN_BE_DEVICE) + +#define __INCLUDE_FROM_CDC_DRIVER +#define __INCLUDE_FROM_CDC_DEVICE_C +#include "CDCClassDevice.h" + +void CDC_Device_ProcessControlRequest(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) +{ + if (!(Endpoint_IsSETUPReceived())) + return; + + if (USB_ControlRequest.wIndex != CDCInterfaceInfo->Config.ControlInterfaceNumber) + return; + + switch (USB_ControlRequest.bRequest) + { + case CDC_REQ_GetLineEncoding: + if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) + { + Endpoint_ClearSETUP(); + + while (!(Endpoint_IsINReady())); + + Endpoint_Write_32_LE(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS); + Endpoint_Write_8(CDCInterfaceInfo->State.LineEncoding.CharFormat); + Endpoint_Write_8(CDCInterfaceInfo->State.LineEncoding.ParityType); + Endpoint_Write_8(CDCInterfaceInfo->State.LineEncoding.DataBits); + + Endpoint_ClearIN(); + Endpoint_ClearStatusStage(); + } + + break; + case CDC_REQ_SetLineEncoding: + if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) + { + Endpoint_ClearSETUP(); + + while (!(Endpoint_IsOUTReceived())) + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return; + } + + CDCInterfaceInfo->State.LineEncoding.BaudRateBPS = Endpoint_Read_32_LE(); + CDCInterfaceInfo->State.LineEncoding.CharFormat = Endpoint_Read_8(); + CDCInterfaceInfo->State.LineEncoding.ParityType = Endpoint_Read_8(); + CDCInterfaceInfo->State.LineEncoding.DataBits = Endpoint_Read_8(); + + Endpoint_ClearOUT(); + Endpoint_ClearStatusStage(); + + EVENT_CDC_Device_LineEncodingChanged(CDCInterfaceInfo); + } + + break; + case CDC_REQ_SetControlLineState: + if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) + { + Endpoint_ClearSETUP(); + Endpoint_ClearStatusStage(); + + CDCInterfaceInfo->State.ControlLineStates.HostToDevice = USB_ControlRequest.wValue; + + EVENT_CDC_Device_ControLineStateChanged(CDCInterfaceInfo); + } + + break; + case CDC_REQ_SendBreak: + if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) + { + Endpoint_ClearSETUP(); + Endpoint_ClearStatusStage(); + + EVENT_CDC_Device_BreakSent(CDCInterfaceInfo, (uint8_t)USB_ControlRequest.wValue); + } + + break; + } +} + +bool CDC_Device_ConfigureEndpoints(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) +{ + memset(&CDCInterfaceInfo->State, 0x00, sizeof(CDCInterfaceInfo->State)); + + CDCInterfaceInfo->Config.DataINEndpoint.Type = EP_TYPE_BULK; + CDCInterfaceInfo->Config.DataOUTEndpoint.Type = EP_TYPE_BULK; + CDCInterfaceInfo->Config.NotificationEndpoint.Type = EP_TYPE_INTERRUPT; + + if (!(Endpoint_ConfigureEndpointTable(&CDCInterfaceInfo->Config.DataINEndpoint, 1))) + return false; + + if (!(Endpoint_ConfigureEndpointTable(&CDCInterfaceInfo->Config.DataOUTEndpoint, 1))) + return false; + + if (!(Endpoint_ConfigureEndpointTable(&CDCInterfaceInfo->Config.NotificationEndpoint, 1))) + return false; + + return true; +} + +void CDC_Device_USBTask(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) +{ + if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS)) + return; + + #if !defined(NO_CLASS_DRIVER_AUTOFLUSH) + CDC_Device_Flush(CDCInterfaceInfo); + #endif +} + +uint8_t CDC_Device_SendString(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, + const char* const String) +{ + if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS)) + return ENDPOINT_RWSTREAM_DeviceDisconnected; + + Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpoint.Address); + return Endpoint_Write_Stream_LE(String, strlen(String), NULL); +} + +uint8_t CDC_Device_SendData(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, + const char* const Buffer, + const uint16_t Length) +{ + if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS)) + return ENDPOINT_RWSTREAM_DeviceDisconnected; + + Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpoint.Address); + return Endpoint_Write_Stream_LE(Buffer, Length, NULL); +} + +uint8_t CDC_Device_SendByte(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, + const uint8_t Data) +{ + if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS)) + return ENDPOINT_RWSTREAM_DeviceDisconnected; + + Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpoint.Address); + + if (!(Endpoint_IsReadWriteAllowed())) + { + Endpoint_ClearIN(); + + uint8_t ErrorCode; + + if ((ErrorCode = Endpoint_WaitUntilReady()) != ENDPOINT_READYWAIT_NoError) + return ErrorCode; + } + + Endpoint_Write_8(Data); + return ENDPOINT_READYWAIT_NoError; +} + +uint8_t CDC_Device_Flush(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) +{ + if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS)) + return ENDPOINT_RWSTREAM_DeviceDisconnected; + + uint8_t ErrorCode; + + Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataINEndpoint.Address); + + if (!(Endpoint_BytesInEndpoint())) + return ENDPOINT_READYWAIT_NoError; + + bool BankFull = !(Endpoint_IsReadWriteAllowed()); + + Endpoint_ClearIN(); + + if (BankFull) + { + if ((ErrorCode = Endpoint_WaitUntilReady()) != ENDPOINT_READYWAIT_NoError) + return ErrorCode; + + Endpoint_ClearIN(); + } + + return ENDPOINT_READYWAIT_NoError; +} + +uint16_t CDC_Device_BytesReceived(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) +{ + if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS)) + return 0; + + Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataOUTEndpoint.Address); + + if (Endpoint_IsOUTReceived()) + { + if (!(Endpoint_BytesInEndpoint())) + { + Endpoint_ClearOUT(); + return 0; + } + else + { + return Endpoint_BytesInEndpoint(); + } + } + else + { + return 0; + } +} + +int16_t CDC_Device_ReceiveByte(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) +{ + if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS)) + return -1; + + int16_t ReceivedByte = -1; + + Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataOUTEndpoint.Address); + + if (Endpoint_IsOUTReceived()) + { + if (Endpoint_BytesInEndpoint()) + ReceivedByte = Endpoint_Read_8(); + + if (!(Endpoint_BytesInEndpoint())) + Endpoint_ClearOUT(); + } + + return ReceivedByte; +} + +void CDC_Device_SendControlLineStateChange(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) +{ + if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS)) + return; + + Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.NotificationEndpoint.Address); + + USB_Request_Header_t Notification = (USB_Request_Header_t) + { + .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE), + .bRequest = CDC_NOTIF_SerialState, + .wValue = CPU_TO_LE16(0), + .wIndex = CPU_TO_LE16(0), + .wLength = CPU_TO_LE16(sizeof(CDCInterfaceInfo->State.ControlLineStates.DeviceToHost)), + }; + + Endpoint_Write_Stream_LE(&Notification, sizeof(USB_Request_Header_t), NULL); + Endpoint_Write_Stream_LE(&CDCInterfaceInfo->State.ControlLineStates.DeviceToHost, + sizeof(CDCInterfaceInfo->State.ControlLineStates.DeviceToHost), + NULL); + Endpoint_ClearIN(); +} + +#if defined(FDEV_SETUP_STREAM) +void CDC_Device_CreateStream(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, + FILE* const Stream) +{ + *Stream = (FILE)FDEV_SETUP_STREAM(CDC_Device_putchar, CDC_Device_getchar, _FDEV_SETUP_RW); + fdev_set_udata(Stream, CDCInterfaceInfo); +} + +void CDC_Device_CreateBlockingStream(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, + FILE* const Stream) +{ + *Stream = (FILE)FDEV_SETUP_STREAM(CDC_Device_putchar, CDC_Device_getchar_Blocking, _FDEV_SETUP_RW); + fdev_set_udata(Stream, CDCInterfaceInfo); +} + +static int CDC_Device_putchar(char c, + FILE* Stream) +{ + return CDC_Device_SendByte((USB_ClassInfo_CDC_Device_t*)fdev_get_udata(Stream), c) ? _FDEV_ERR : 0; +} + +static int CDC_Device_getchar(FILE* Stream) +{ + int16_t ReceivedByte = CDC_Device_ReceiveByte((USB_ClassInfo_CDC_Device_t*)fdev_get_udata(Stream)); + + if (ReceivedByte < 0) + return _FDEV_EOF; + + return ReceivedByte; +} + +static int CDC_Device_getchar_Blocking(FILE* Stream) +{ + int16_t ReceivedByte; + + while ((ReceivedByte = CDC_Device_ReceiveByte((USB_ClassInfo_CDC_Device_t*)fdev_get_udata(Stream))) < 0) + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return _FDEV_EOF; + + CDC_Device_USBTask((USB_ClassInfo_CDC_Device_t*)fdev_get_udata(Stream)); + USB_USBTask(); + } + + return ReceivedByte; +} +#endif + +// cppcheck-suppress unusedFunction +void CDC_Device_Event_Stub(void) +{ + +} + +#endif + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Device/CDCClassDevice.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Device/CDCClassDevice.h new file mode 100644 index 00000000..a4528d1d --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Device/CDCClassDevice.h @@ -0,0 +1,352 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Device mode driver for the library USB CDC Class driver. + * + * Device mode driver for the library USB CDC Class driver. + * + * \note This file should not be included directly. It is automatically included as needed by the USB module driver + * dispatch header located in LUFA/Drivers/USB.h. + */ + +/** \ingroup Group_USBClassCDC + * \defgroup Group_USBClassCDCDevice CDC Class Device Mode Driver + * + * \section Sec_Dependencies Module Source Dependencies + * The following files must be built with any user project that uses this module: + * - LUFA/Drivers/USB/Class/Device/CDCClassDevice.c (Makefile source module name: LUFA_SRC_USBCLASS) + * + * \section Sec_ModDescription Module Description + * Device Mode USB Class driver framework interface, for the CDC USB Class driver. + * + * \note There are several major drawbacks to the CDC-ACM standard USB class, however + * it is very standardized and thus usually available as a built-in driver on + * most platforms, and so is a better choice than a proprietary serial class. + * + * One major issue with CDC-ACM is that it requires two Interface descriptors, + * which will upset most hosts when part of a multi-function "Composite" USB + * device. This is because each interface will be loaded into a separate driver + * instance, causing the two interfaces be become unlinked. To prevent this, you + * should use the "Interface Association Descriptor" addendum to the USB 2.0 standard + * which is available on most OSes when creating Composite devices. + * + * Another major oversight is that there is no mechanism for the host to notify the + * device that there is a data sink on the host side ready to accept data. This + * means that the device may try to send data while the host isn't listening, causing + * lengthy blocking timeouts in the transmission routines. It is thus highly recommended + * that the virtual serial line DTR (Data Terminal Ready) signal be used where possible + * to determine if a host application is ready for data. + * + * @{ + */ + +#ifndef _CDC_CLASS_DEVICE_H_ +#define _CDC_CLASS_DEVICE_H_ + + /* Includes: */ + #include "../../USB.h" + #include "../Common/CDCClassCommon.h" + + #include + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_CDC_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Type Defines: */ + /** \brief CDC Class Device Mode Configuration and State Structure. + * + * Class state structure. An instance of this structure should be made for each CDC interface + * within the user application, and passed to each of the CDC class driver functions as the + * CDCInterfaceInfo parameter. This stores each CDC interface's configuration and state information. + */ + typedef struct + { + struct + { + uint8_t ControlInterfaceNumber; /**< Interface number of the CDC control interface within the device. */ + + USB_Endpoint_Table_t DataINEndpoint; /**< Data IN endpoint configuration table. */ + USB_Endpoint_Table_t DataOUTEndpoint; /**< Data OUT endpoint configuration table. */ + USB_Endpoint_Table_t NotificationEndpoint; /**< Notification IN Endpoint configuration table. */ + } Config; /**< Config data for the USB class interface within the device. All elements in this section + * must be set or the interface will fail to enumerate and operate correctly. + */ + struct + { + struct + { + uint16_t HostToDevice; /**< Control line states from the host to device, as a set of \c CDC_CONTROL_LINE_OUT_* + * masks. This value is updated each time \ref CDC_Device_USBTask() is called. + */ + uint16_t DeviceToHost; /**< Control line states from the device to host, as a set of \c CDC_CONTROL_LINE_IN_* + * masks - to notify the host of changes to these values, call the + * \ref CDC_Device_SendControlLineStateChange() function. + */ + } ControlLineStates; /**< Current states of the virtual serial port's control lines between the device and host. */ + + CDC_LineEncoding_t LineEncoding; /** Line encoding used in the virtual serial port, for the device's information. + * This is generally only used if the virtual serial port data is to be + * reconstructed on a physical UART. + */ + } State; /**< State data for the USB class interface within the device. All elements in this section + * are reset to their defaults when the interface is enumerated. + */ + } USB_ClassInfo_CDC_Device_t; + + /* Function Prototypes: */ + /** Configures the endpoints of a given CDC interface, ready for use. This should be linked to the library + * \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration containing + * the given CDC interface is selected. + * + * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state. + * + * \return Boolean \c true if the endpoints were successfully configured, \c false otherwise. + */ + bool CDC_Device_ConfigureEndpoints(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + /** Processes incoming control requests from the host, that are directed to the given CDC class interface. This should be + * linked to the library \ref EVENT_USB_Device_ControlRequest() event. + * + * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state. + */ + void CDC_Device_ProcessControlRequest(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + /** General management task for a given CDC class interface, required for the correct operation of the interface. This should + * be called frequently in the main program loop, before the master USB management task \ref USB_USBTask(). + * + * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state. + */ + void CDC_Device_USBTask(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + /** CDC class driver event for a line encoding change on a CDC interface. This event fires each time the host requests a + * line encoding change (containing the serial parity, baud and other configuration information) and may be hooked in the + * user program by declaring a handler function with the same name and parameters listed here. The new line encoding + * settings are available in the LineEncoding structure inside the CDC interface structure passed as a parameter. + * + * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state. + */ + void EVENT_CDC_Device_LineEncodingChanged(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + /** CDC class driver event for a control line state change on a CDC interface. This event fires each time the host requests a + * control line state change (containing the virtual serial control line states, such as DTR) and may be hooked in the + * user program by declaring a handler function with the same name and parameters listed here. The new control line states + * are available in the \c ControlLineStates.HostToDevice value inside the CDC interface structure passed as a parameter, set as + * a mask of \c CDC_CONTROL_LINE_OUT_* masks. + * + * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state. + */ + void EVENT_CDC_Device_ControLineStateChanged(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + /** CDC class driver event for a send break request sent to the device from the host. This is generally used to separate + * data or to indicate a special condition to the receiving device. + * + * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state. + * \param[in] Duration Duration of the break that has been sent by the host, in milliseconds. + */ + void EVENT_CDC_Device_BreakSent(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, + const uint8_t Duration) ATTR_NON_NULL_PTR_ARG(1); + + /** Sends a given data buffer to the attached USB host, if connected. If a host is not connected when the function is + * called, the string is discarded. Bytes will be queued for transmission to the host until either the endpoint bank + * becomes full, or the \ref CDC_Device_Flush() function is called to flush the pending data to the host. This allows + * for multiple bytes to be packed into a single endpoint packet, increasing data throughput. + * + * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or + * the call will fail. + * + * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state. + * \param[in] Buffer Pointer to a buffer containing the data to send to the device. + * \param[in] Length Length of the data to send to the host. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t CDC_Device_SendData(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, + const char* const Buffer, + const uint16_t Length) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); + + /** Sends a given null terminated string to the attached USB host, if connected. If a host is not connected when + * the function is called, the string is discarded. Bytes will be queued for transmission to the host until either + * the endpoint bank becomes full, or the \ref CDC_Device_Flush() function is called to flush the pending data to + * the host. This allows for multiple bytes to be packed into a single endpoint packet, increasing data throughput. + * + * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or + * the call will fail. + * + * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state. + * \param[in] String Pointer to the null terminated string to send to the host. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t CDC_Device_SendString(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, + const char* const String) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); + + /** Sends a given byte to the attached USB host, if connected. If a host is not connected when the function is called, the + * byte is discarded. Bytes will be queued for transmission to the host until either the endpoint bank becomes full, or the + * \ref CDC_Device_Flush() function is called to flush the pending data to the host. This allows for multiple bytes to be + * packed into a single endpoint packet, increasing data throughput. + * + * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or + * the call will fail. + * + * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state. + * \param[in] Data Byte of data to send to the host. + * + * \return A value from the \ref Endpoint_WaitUntilReady_ErrorCodes_t enum. + */ + uint8_t CDC_Device_SendByte(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, + const uint8_t Data) ATTR_NON_NULL_PTR_ARG(1); + + /** Determines the number of bytes received by the CDC interface from the host, waiting to be read. This indicates the number + * of bytes in the OUT endpoint bank only, and thus the number of calls to \ref CDC_Device_ReceiveByte() which are guaranteed to + * succeed immediately. If multiple bytes are to be received, they should be buffered by the user application, as the endpoint + * bank will not be released back to the USB controller until all bytes are read. + * + * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or + * the call will fail. + * + * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state. + * + * \return Total number of buffered bytes received from the host. + */ + uint16_t CDC_Device_BytesReceived(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + /** Reads a byte of data from the host. If no data is waiting to be read of if a USB host is not connected, the function + * returns a negative value. The \ref CDC_Device_BytesReceived() function may be queried in advance to determine how many + * bytes are currently buffered in the CDC interface's data receive endpoint bank, and thus how many repeated calls to this + * function which are guaranteed to succeed. + * + * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or + * the call will fail. + * + * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state. + * + * \return Next received byte from the host, or a negative value if no data received. + */ + int16_t CDC_Device_ReceiveByte(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + /** Flushes any data waiting to be sent, ensuring that the send buffer is cleared. + * + * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or + * the call will fail. + * + * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state. + * + * \return A value from the \ref Endpoint_WaitUntilReady_ErrorCodes_t enum. + */ + uint8_t CDC_Device_Flush(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + /** Sends a Serial Control Line State Change notification to the host. This should be called when the virtual serial + * control lines (DCD, DSR, etc.) have changed states, or to give BREAK notifications to the host. Line states persist + * until they are cleared via a second notification. This should be called each time the CDC class driver's + * \c ControlLineStates.DeviceToHost value is updated to push the new states to the USB host. + * + * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or + * the call will fail. + * + * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state. + */ + void CDC_Device_SendControlLineStateChange(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + #if defined(FDEV_SETUP_STREAM) || defined(__DOXYGEN__) + /** Creates a standard character stream for the given CDC Device instance so that it can be used with all the regular + * functions in the standard library that accept a \c FILE stream as a destination (e.g. \c fprintf()). The created + * stream is bidirectional and can be used for both input and output functions. + * + * Reading data from this stream is non-blocking, i.e. in most instances, complete strings cannot be read in by a single + * fetch, as the endpoint will not be ready at some point in the transmission, aborting the transfer. However, this may + * be used when the read data is processed byte-per-bye (via \c getc()) or when the user application will implement its own + * line buffering. + * + * \note The created stream can be given as \c stdout if desired to direct the standard output from all functions + * to the given CDC interface. + * \n\n + * + * \note This function is not available on all microcontroller architectures. + * + * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state. + * \param[in,out] Stream Pointer to a FILE structure where the created stream should be placed. + */ + void CDC_Device_CreateStream(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, + FILE* const Stream) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); + + /** Identical to \ref CDC_Device_CreateStream(), except that reads are blocking until the calling stream function terminates + * the transfer. While blocking, the USB and CDC service tasks are called repeatedly to maintain USB communications. + * + * \note This function is not available on all microcontroller architectures. + * + * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state. + * \param[in,out] Stream Pointer to a FILE structure where the created stream should be placed. + */ + void CDC_Device_CreateBlockingStream(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, + FILE* const Stream) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); + #endif + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Function Prototypes: */ + #if defined(__INCLUDE_FROM_CDC_DEVICE_C) + #if defined(FDEV_SETUP_STREAM) + static int CDC_Device_putchar(char c, + FILE* Stream) ATTR_NON_NULL_PTR_ARG(2); + static int CDC_Device_getchar(FILE* Stream) ATTR_NON_NULL_PTR_ARG(1); + static int CDC_Device_getchar_Blocking(FILE* Stream) ATTR_NON_NULL_PTR_ARG(1); + #endif + + void CDC_Device_Event_Stub(void) ATTR_CONST; + + void EVENT_CDC_Device_LineEncodingChanged(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) + ATTR_WEAK ATTR_NON_NULL_PTR_ARG(1) ATTR_ALIAS(CDC_Device_Event_Stub); + void EVENT_CDC_Device_ControLineStateChanged(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo) + ATTR_WEAK ATTR_NON_NULL_PTR_ARG(1) ATTR_ALIAS(CDC_Device_Event_Stub); + void EVENT_CDC_Device_BreakSent(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo, + const uint8_t Duration) ATTR_WEAK ATTR_NON_NULL_PTR_ARG(1) + ATTR_ALIAS(CDC_Device_Event_Stub); + #endif + + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Device/HIDClassDevice.c b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Device/HIDClassDevice.c new file mode 100644 index 00000000..a56747b0 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Device/HIDClassDevice.c @@ -0,0 +1,200 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#define __INCLUDE_FROM_USB_DRIVER +#include "../../Core/USBMode.h" + +#if defined(USB_CAN_BE_DEVICE) + +#define __INCLUDE_FROM_HID_DRIVER +#define __INCLUDE_FROM_HID_DEVICE_C +#include "HIDClassDevice.h" + +void HID_Device_ProcessControlRequest(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo) +{ + if (!(Endpoint_IsSETUPReceived())) + return; + + if (USB_ControlRequest.wIndex != HIDInterfaceInfo->Config.InterfaceNumber) + return; + + switch (USB_ControlRequest.bRequest) + { + case HID_REQ_GetReport: + if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) + { + uint16_t ReportSize = 0; + uint8_t ReportID = (USB_ControlRequest.wValue & 0xFF); + uint8_t ReportType = (USB_ControlRequest.wValue >> 8) - 1; + uint8_t ReportData[HIDInterfaceInfo->Config.PrevReportINBufferSize]; + + memset(ReportData, 0, sizeof(ReportData)); + + CALLBACK_HID_Device_CreateHIDReport(HIDInterfaceInfo, &ReportID, ReportType, ReportData, &ReportSize); + + if (HIDInterfaceInfo->Config.PrevReportINBuffer != NULL) + { + memcpy(HIDInterfaceInfo->Config.PrevReportINBuffer, ReportData, + HIDInterfaceInfo->Config.PrevReportINBufferSize); + } + + Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP); + + Endpoint_ClearSETUP(); + Endpoint_Write_Control_Stream_LE(ReportData, ReportSize); + Endpoint_ClearOUT(); + } + + break; + case HID_REQ_SetReport: + if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) + { + uint16_t ReportSize = USB_ControlRequest.wLength; + uint8_t ReportID = (USB_ControlRequest.wValue & 0xFF); + uint8_t ReportType = (USB_ControlRequest.wValue >> 8) - 1; + uint8_t ReportData[ReportSize]; + + Endpoint_ClearSETUP(); + Endpoint_Read_Control_Stream_LE(ReportData, ReportSize); + Endpoint_ClearIN(); + + CALLBACK_HID_Device_ProcessHIDReport(HIDInterfaceInfo, ReportID, ReportType, + &ReportData[ReportID ? 1 : 0], ReportSize - (ReportID ? 1 : 0)); + } + + break; + case HID_REQ_GetProtocol: + if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) + { + Endpoint_ClearSETUP(); + while (!(Endpoint_IsINReady())); + Endpoint_Write_8(HIDInterfaceInfo->State.UsingReportProtocol); + Endpoint_ClearIN(); + Endpoint_ClearStatusStage(); + } + + break; + case HID_REQ_SetProtocol: + if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) + { + Endpoint_ClearSETUP(); + Endpoint_ClearStatusStage(); + + HIDInterfaceInfo->State.UsingReportProtocol = ((USB_ControlRequest.wValue & 0xFF) != 0x00); + } + + break; + case HID_REQ_SetIdle: + if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) + { + Endpoint_ClearSETUP(); + Endpoint_ClearStatusStage(); + + HIDInterfaceInfo->State.IdleCount = ((USB_ControlRequest.wValue & 0xFF00) >> 6); + } + + break; + case HID_REQ_GetIdle: + if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) + { + Endpoint_ClearSETUP(); + while (!(Endpoint_IsINReady())); + Endpoint_Write_8(HIDInterfaceInfo->State.IdleCount >> 2); + Endpoint_ClearIN(); + Endpoint_ClearStatusStage(); + } + + break; + } +} + +bool HID_Device_ConfigureEndpoints(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo) +{ + memset(&HIDInterfaceInfo->State, 0x00, sizeof(HIDInterfaceInfo->State)); + HIDInterfaceInfo->State.UsingReportProtocol = true; + HIDInterfaceInfo->State.IdleCount = 500; + + HIDInterfaceInfo->Config.ReportINEndpoint.Type = EP_TYPE_INTERRUPT; + + if (!(Endpoint_ConfigureEndpointTable(&HIDInterfaceInfo->Config.ReportINEndpoint, 1))) + return false; + + return true; +} + +void HID_Device_USBTask(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo) +{ + if (USB_DeviceState != DEVICE_STATE_Configured) + return; + + if (HIDInterfaceInfo->State.PrevFrameNum == USB_Device_GetFrameNumber()) + return; + + Endpoint_SelectEndpoint(HIDInterfaceInfo->Config.ReportINEndpoint.Address); + + if (Endpoint_IsReadWriteAllowed()) + { + uint8_t ReportINData[HIDInterfaceInfo->Config.PrevReportINBufferSize]; + uint8_t ReportID = 0; + uint16_t ReportINSize = 0; + + memset(ReportINData, 0, sizeof(ReportINData)); + + bool ForceSend = CALLBACK_HID_Device_CreateHIDReport(HIDInterfaceInfo, &ReportID, HID_REPORT_ITEM_In, + ReportINData, &ReportINSize); + bool StatesChanged = false; + bool IdlePeriodElapsed = (HIDInterfaceInfo->State.IdleCount && !(HIDInterfaceInfo->State.IdleMSRemaining)); + + if (HIDInterfaceInfo->Config.PrevReportINBuffer != NULL) + { + StatesChanged = (memcmp(ReportINData, HIDInterfaceInfo->Config.PrevReportINBuffer, ReportINSize) != 0); + memcpy(HIDInterfaceInfo->Config.PrevReportINBuffer, ReportINData, HIDInterfaceInfo->Config.PrevReportINBufferSize); + } + + if (ReportINSize && (ForceSend || StatesChanged || IdlePeriodElapsed)) + { + HIDInterfaceInfo->State.IdleMSRemaining = HIDInterfaceInfo->State.IdleCount; + + Endpoint_SelectEndpoint(HIDInterfaceInfo->Config.ReportINEndpoint.Address); + + if (ReportID) + Endpoint_Write_8(ReportID); + + Endpoint_Write_Stream_LE(ReportINData, ReportINSize, NULL); + + Endpoint_ClearIN(); + } + + HIDInterfaceInfo->State.PrevFrameNum = USB_Device_GetFrameNumber(); + } +} + +#endif + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Device/HIDClassDevice.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Device/HIDClassDevice.h new file mode 100644 index 00000000..ea212577 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Device/HIDClassDevice.h @@ -0,0 +1,210 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Device mode driver for the library USB HID Class driver. + * + * Device mode driver for the library USB HID Class driver. + * + * \note This file should not be included directly. It is automatically included as needed by the USB module driver + * dispatch header located in LUFA/Drivers/USB.h. + */ + +/** \ingroup Group_USBClassHID + * \defgroup Group_USBClassHIDDevice HID Class Device Mode Driver + * + * \section Sec_Dependencies Module Source Dependencies + * The following files must be built with any user project that uses this module: + * - LUFA/Drivers/USB/Class/Device/HIDClassDevice.c (Makefile source module name: LUFA_SRC_USBCLASS) + * + * \section Sec_ModDescription Module Description + * Device Mode USB Class driver framework interface, for the HID USB Class driver. + * + * @{ + */ + +#ifndef _HID_CLASS_DEVICE_H_ +#define _HID_CLASS_DEVICE_H_ + + /* Includes: */ + #include "../../USB.h" + #include "../Common/HIDClassCommon.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_HID_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Type Defines: */ + /** \brief HID Class Device Mode Configuration and State Structure. + * + * Class state structure. An instance of this structure should be made for each HID interface + * within the user application, and passed to each of the HID class driver functions as the + * \c HIDInterfaceInfo parameter. This stores each HID interface's configuration and state information. + * + * \note Due to technical limitations, the HID device class driver does not utilize a separate OUT + * endpoint for host->device communications. Instead, the host->device data (if any) is sent to + * the device via the control endpoint. + */ + typedef struct + { + struct + { + uint8_t InterfaceNumber; /**< Interface number of the HID interface within the device. */ + + USB_Endpoint_Table_t ReportINEndpoint; /**< Data IN HID report endpoint configuration table. */ + + void* PrevReportINBuffer; /**< Pointer to a buffer where the previously created HID input report can be + * stored by the driver, for comparison purposes to detect report changes that + * must be sent immediately to the host. This should point to a buffer big enough + * to hold the largest HID input report sent from the HID interface. If this is set + * to \c NULL, it is up to the user to force transfers when needed in the + * \ref CALLBACK_HID_Device_CreateHIDReport() callback function. + * + * \note Due to the single buffer, the internal driver can only correctly compare + * subsequent reports with identical report IDs. In multiple report devices, + * this buffer should be set to \c NULL and the decision to send reports made + * by the user application instead. + */ + uint8_t PrevReportINBufferSize; /**< Size in bytes of the given input report buffer. This is used to create a + * second buffer of the same size within the driver so that subsequent reports + * can be compared. If the user app is to determine when reports are to be sent + * exclusively (i.e. \ref PrevReportINBuffer is \c NULL) this value must still be + * set to the size of the largest report the device can issue to the host. + */ + } Config; /**< Config data for the USB class interface within the device. All elements in this section + * must be set or the interface will fail to enumerate and operate correctly. + */ + struct + { + bool UsingReportProtocol; /**< Indicates if the HID interface is set to Boot or Report protocol mode. */ + uint16_t PrevFrameNum; /**< Frame number of the previous HID report packet opportunity. */ + uint16_t IdleCount; /**< Report idle period, in milliseconds, set by the host. */ + uint16_t IdleMSRemaining; /**< Total number of milliseconds remaining before the idle period elapsed - this + * should be decremented by the user application if non-zero each millisecond. */ + } State; /**< State data for the USB class interface within the device. All elements in this section + * are reset to their defaults when the interface is enumerated. + */ + } USB_ClassInfo_HID_Device_t; + + /* Function Prototypes: */ + /** Configures the endpoints of a given HID interface, ready for use. This should be linked to the library + * \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration + * containing the given HID interface is selected. + * + * \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class configuration and state. + * + * \return Boolean \c true if the endpoints were successfully configured, \c false otherwise. + */ + bool HID_Device_ConfigureEndpoints(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + /** Processes incoming control requests from the host, that are directed to the given HID class interface. This should be + * linked to the library \ref EVENT_USB_Device_ControlRequest() event. + * + * \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class configuration and state. + */ + void HID_Device_ProcessControlRequest(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + /** General management task for a given HID class interface, required for the correct operation of the interface. This should + * be called frequently in the main program loop, before the master USB management task \ref USB_USBTask(). + * + * \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class configuration and state. + */ + void HID_Device_USBTask(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + /** HID class driver callback for the user creation of a HID IN report. This callback may fire in response to either + * HID class control requests from the host, or by the normal HID endpoint polling procedure. Inside this callback the + * user is responsible for the creation of the next HID input report to be sent to the host. + * + * \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class configuration and state. + * \param[in,out] ReportID If preset to a non-zero value, this is the report ID being requested by the host. If zero, + * this should be set to the report ID of the generated HID input report (if any). If multiple + * reports are not sent via the given HID interface, this parameter should be ignored. + * \param[in] ReportType Type of HID report to generate, either \ref HID_REPORT_ITEM_In or \ref HID_REPORT_ITEM_Feature. + * \param[out] ReportData Pointer to a buffer where the generated HID report should be stored. + * \param[out] ReportSize Number of bytes in the generated input report, or zero if no report is to be sent. + * + * \return Boolean \c true to force the sending of the report even if it is identical to the previous report and still within + * the idle period (useful for devices which report relative movement), \c false otherwise. + */ + bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, + uint8_t* const ReportID, + const uint8_t ReportType, + void* ReportData, + uint16_t* const ReportSize) ATTR_NON_NULL_PTR_ARG(1) + ATTR_NON_NULL_PTR_ARG(2) ATTR_NON_NULL_PTR_ARG(4) ATTR_NON_NULL_PTR_ARG(5); + + /** HID class driver callback for the user processing of a received HID OUT report. This callback may fire in response to + * either HID class control requests from the host, or by the normal HID endpoint polling procedure. Inside this callback + * the user is responsible for the processing of the received HID output report from the host. + * + * \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class configuration and state. + * \param[in] ReportID Report ID of the received output report. If multiple reports are not received via the given HID + * interface, this parameter should be ignored. + * \param[in] ReportType Type of received HID report, either \ref HID_REPORT_ITEM_Out or \ref HID_REPORT_ITEM_Feature. + * \param[in] ReportData Pointer to a buffer where the received HID report is stored. + * \param[in] ReportSize Size in bytes of the received report from the host. + */ + void CALLBACK_HID_Device_ProcessHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, + const uint8_t ReportID, + const uint8_t ReportType, + const void* ReportData, + const uint16_t ReportSize) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(4); + + /* Inline Functions: */ + /** Indicates that a millisecond of idle time has elapsed on the given HID interface, and the interface's idle count should be + * decremented. This should be called once per millisecond so that hardware key-repeats function correctly. It is recommended + * that this be called by the \ref EVENT_USB_Device_StartOfFrame() event, once SOF events have been enabled via + * \ref USB_Device_EnableSOFEvents(). + * + * \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class configuration and state. + */ + static inline void HID_Device_MillisecondElapsed(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo) ATTR_ALWAYS_INLINE ATTR_NON_NULL_PTR_ARG(1); + static inline void HID_Device_MillisecondElapsed(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo) + { + if (HIDInterfaceInfo->State.IdleMSRemaining) + HIDInterfaceInfo->State.IdleMSRemaining--; + } + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Device/MIDIClassDevice.c b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Device/MIDIClassDevice.c new file mode 100644 index 00000000..3ff339c0 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Device/MIDIClassDevice.c @@ -0,0 +1,125 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#define __INCLUDE_FROM_USB_DRIVER +#include "../../Core/USBMode.h" + +#if defined(USB_CAN_BE_DEVICE) + +#define __INCLUDE_FROM_MIDI_DRIVER +#define __INCLUDE_FROM_MIDI_DEVICE_C +#include "MIDIClassDevice.h" + +bool MIDI_Device_ConfigureEndpoints(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo) +{ + memset(&MIDIInterfaceInfo->State, 0x00, sizeof(MIDIInterfaceInfo->State)); + + MIDIInterfaceInfo->Config.DataINEndpoint.Type = EP_TYPE_BULK; + MIDIInterfaceInfo->Config.DataOUTEndpoint.Type = EP_TYPE_BULK; + + if (!(Endpoint_ConfigureEndpointTable(&MIDIInterfaceInfo->Config.DataINEndpoint, 1))) + return false; + + if (!(Endpoint_ConfigureEndpointTable(&MIDIInterfaceInfo->Config.DataOUTEndpoint, 1))) + return false; + + return true; +} + +void MIDI_Device_USBTask(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo) +{ + if (USB_DeviceState != DEVICE_STATE_Configured) + return; + + #if !defined(NO_CLASS_DRIVER_AUTOFLUSH) + MIDI_Device_Flush(MIDIInterfaceInfo); + #endif +} + +uint8_t MIDI_Device_SendEventPacket(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo, + const MIDI_EventPacket_t* const Event) +{ + if (USB_DeviceState != DEVICE_STATE_Configured) + return ENDPOINT_RWSTREAM_DeviceDisconnected; + + uint8_t ErrorCode; + + Endpoint_SelectEndpoint(MIDIInterfaceInfo->Config.DataINEndpoint.Address); + + if ((ErrorCode = Endpoint_Write_Stream_LE(Event, sizeof(MIDI_EventPacket_t), NULL)) != ENDPOINT_RWSTREAM_NoError) + return ErrorCode; + + if (!(Endpoint_IsReadWriteAllowed())) + Endpoint_ClearIN(); + + return ENDPOINT_RWSTREAM_NoError; +} + +uint8_t MIDI_Device_Flush(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo) +{ + if (USB_DeviceState != DEVICE_STATE_Configured) + return ENDPOINT_RWSTREAM_DeviceDisconnected; + + uint8_t ErrorCode; + + Endpoint_SelectEndpoint(MIDIInterfaceInfo->Config.DataINEndpoint.Address); + + if (Endpoint_BytesInEndpoint()) + { + Endpoint_ClearIN(); + + if ((ErrorCode = Endpoint_WaitUntilReady()) != ENDPOINT_READYWAIT_NoError) + return ErrorCode; + } + + return ENDPOINT_READYWAIT_NoError; +} + +bool MIDI_Device_ReceiveEventPacket(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo, + MIDI_EventPacket_t* const Event) +{ + if (USB_DeviceState != DEVICE_STATE_Configured) + return false; + + Endpoint_SelectEndpoint(MIDIInterfaceInfo->Config.DataOUTEndpoint.Address); + + if (!(Endpoint_IsReadWriteAllowed())) + return false; + + Endpoint_Read_Stream_LE(Event, sizeof(MIDI_EventPacket_t), NULL); + + if (!(Endpoint_IsReadWriteAllowed())) + Endpoint_ClearOUT(); + + return true; +} + +#endif + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Device/MIDIClassDevice.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Device/MIDIClassDevice.h new file mode 100644 index 00000000..c5b01be5 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Device/MIDIClassDevice.h @@ -0,0 +1,175 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Device mode driver for the library USB MIDI Class driver. + * + * Device mode driver for the library USB MIDI Class driver. + * + * \note This file should not be included directly. It is automatically included as needed by the USB module driver + * dispatch header located in LUFA/Drivers/USB.h. + */ + +/** \ingroup Group_USBClassMIDI + * \defgroup Group_USBClassMIDIDevice MIDI Class Device Mode Driver + * + * \section Sec_Dependencies Module Source Dependencies + * The following files must be built with any user project that uses this module: + * - LUFA/Drivers/USB/Class/Device/MIDIClassDevice.c (Makefile source module name: LUFA_SRC_USBCLASS) + * + * \section Sec_ModDescription Module Description + * Device Mode USB Class driver framework interface, for the MIDI USB Class driver. + * + * @{ + */ + +#ifndef _MIDI_CLASS_DEVICE_H_ +#define _MIDI_CLASS_DEVICE_H_ + + /* Includes: */ + #include "../../USB.h" + #include "../Common/MIDIClassCommon.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_MIDI_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Type Define: */ + /** \brief MIDI Class Device Mode Configuration and State Structure. + * + * Class state structure. An instance of this structure should be made for each MIDI interface + * within the user application, and passed to each of the MIDI class driver functions as the + * \c MIDIInterfaceInfo parameter. This stores each MIDI interface's configuration and state information. + */ + typedef struct + { + struct + { + uint8_t StreamingInterfaceNumber; /**< Index of the Audio Streaming interface within the device this structure controls. */ + + USB_Endpoint_Table_t DataINEndpoint; /**< Data IN endpoint configuration table. */ + USB_Endpoint_Table_t DataOUTEndpoint; /**< Data OUT endpoint configuration table. */ + } Config; /**< Config data for the USB class interface within the device. All elements in this section + * must be set or the interface will fail to enumerate and operate correctly. + */ + + struct + { + uint8_t RESERVED; // No state information for this class + } State; /**< State data for the USB class interface within the device. All elements in this section + * are reset to their defaults when the interface is enumerated. + */ + } USB_ClassInfo_MIDI_Device_t; + + /* Function Prototypes: */ + /** Configures the endpoints of a given MIDI interface, ready for use. This should be linked to the library + * \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration + * containing the given MIDI interface is selected. + * + * \param[in,out] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state. + * + * \return Boolean \c true if the endpoints were successfully configured, \c false otherwise. + */ + bool MIDI_Device_ConfigureEndpoints(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + /** General management task for a given MIDI class interface, required for the correct operation of the interface. This should + * be called frequently in the main program loop, before the master USB management task \ref USB_USBTask(). + * + * \param[in,out] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state. + */ + void MIDI_Device_USBTask(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + /** Sends a MIDI event packet to the host. If no host is connected, the event packet is discarded. Events are queued into the + * endpoint bank until either the endpoint bank is full, or \ref MIDI_Device_Flush() is called. This allows for multiple + * MIDI events to be packed into a single endpoint packet, increasing data throughput. + * + * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the + * call will fail. + * + * \param[in,out] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state. + * \param[in] Event Pointer to a populated \ref MIDI_EventPacket_t structure containing the MIDI event to send. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t MIDI_Device_SendEventPacket(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo, + const MIDI_EventPacket_t* const Event) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); + + + /** Flushes the MIDI send buffer, sending any queued MIDI events to the host. This should be called to override the + * \ref MIDI_Device_SendEventPacket() function's packing behavior, to flush queued events. + * + * \param[in,out] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state. + * + * \return A value from the \ref Endpoint_WaitUntilReady_ErrorCodes_t enum. + */ + uint8_t MIDI_Device_Flush(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + /** Receives a MIDI event packet from the host. Events are unpacked from the endpoint, thus if the endpoint bank contains + * multiple MIDI events from the host in the one packet, multiple calls to this function will return each individual event. + * + * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the + * call will fail. + * + * \param[in,out] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state. + * \param[out] Event Pointer to a USB_MIDI_EventPacket_t structure where the received MIDI event is to be placed. + * + * \return Boolean \c true if a MIDI event packet was received, \c false otherwise. + */ + bool MIDI_Device_ReceiveEventPacket(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo, + MIDI_EventPacket_t* const Event) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); + + /* Inline Functions: */ + /** Processes incoming control requests from the host, that are directed to the given MIDI class interface. This should be + * linked to the library \ref EVENT_USB_Device_ControlRequest() event. + * + * \param[in,out] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state. + */ + static inline void MIDI_Device_ProcessControlRequest(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + static inline void MIDI_Device_ProcessControlRequest(USB_ClassInfo_MIDI_Device_t* const MIDIInterfaceInfo) + { + (void)MIDIInterfaceInfo; + } + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Device/MassStorageClassDevice.c b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Device/MassStorageClassDevice.c new file mode 100644 index 00000000..735437e4 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Device/MassStorageClassDevice.c @@ -0,0 +1,215 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#define __INCLUDE_FROM_USB_DRIVER +#include "../../Core/USBMode.h" + +#if defined(USB_CAN_BE_DEVICE) + +#define __INCLUDE_FROM_MS_DRIVER +#define __INCLUDE_FROM_MASSSTORAGE_DEVICE_C +#include "MassStorageClassDevice.h" + +void MS_Device_ProcessControlRequest(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) +{ + if (!(Endpoint_IsSETUPReceived())) + return; + + if (USB_ControlRequest.wIndex != MSInterfaceInfo->Config.InterfaceNumber) + return; + + switch (USB_ControlRequest.bRequest) + { + case MS_REQ_MassStorageReset: + if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) + { + Endpoint_ClearSETUP(); + Endpoint_ClearStatusStage(); + + MSInterfaceInfo->State.IsMassStoreReset = true; + } + + break; + case MS_REQ_GetMaxLUN: + if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) + { + Endpoint_ClearSETUP(); + while (!(Endpoint_IsINReady())); + Endpoint_Write_8(MSInterfaceInfo->Config.TotalLUNs - 1); + Endpoint_ClearIN(); + Endpoint_ClearStatusStage(); + } + + break; + } +} + +bool MS_Device_ConfigureEndpoints(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) +{ + memset(&MSInterfaceInfo->State, 0x00, sizeof(MSInterfaceInfo->State)); + + MSInterfaceInfo->Config.DataINEndpoint.Type = EP_TYPE_BULK; + MSInterfaceInfo->Config.DataOUTEndpoint.Type = EP_TYPE_BULK; + + if (!(Endpoint_ConfigureEndpointTable(&MSInterfaceInfo->Config.DataINEndpoint, 1))) + return false; + + if (!(Endpoint_ConfigureEndpointTable(&MSInterfaceInfo->Config.DataOUTEndpoint, 1))) + return false; + + return true; +} + +void MS_Device_USBTask(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) +{ + if (USB_DeviceState != DEVICE_STATE_Configured) + return; + + Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataOUTEndpoint.Address); + + if (Endpoint_IsOUTReceived()) + { + if (MS_Device_ReadInCommandBlock(MSInterfaceInfo)) + { + if (MSInterfaceInfo->State.CommandBlock.Flags & MS_COMMAND_DIR_DATA_IN) + Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataINEndpoint.Address); + + bool SCSICommandResult = CALLBACK_MS_Device_SCSICommandReceived(MSInterfaceInfo); + + MSInterfaceInfo->State.CommandStatus.Status = (SCSICommandResult) ? MS_SCSI_COMMAND_Pass : MS_SCSI_COMMAND_Fail; + MSInterfaceInfo->State.CommandStatus.Signature = CPU_TO_LE32(MS_CSW_SIGNATURE); + MSInterfaceInfo->State.CommandStatus.Tag = MSInterfaceInfo->State.CommandBlock.Tag; + MSInterfaceInfo->State.CommandStatus.DataTransferResidue = MSInterfaceInfo->State.CommandBlock.DataTransferLength; + + if (!(SCSICommandResult) && (le32_to_cpu(MSInterfaceInfo->State.CommandStatus.DataTransferResidue))) + Endpoint_StallTransaction(); + + MS_Device_ReturnCommandStatus(MSInterfaceInfo); + } + } + + if (MSInterfaceInfo->State.IsMassStoreReset) + { + Endpoint_ResetEndpoint(MSInterfaceInfo->Config.DataOUTEndpoint.Address); + Endpoint_ResetEndpoint(MSInterfaceInfo->Config.DataINEndpoint.Address); + + Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataOUTEndpoint.Address); + Endpoint_ClearStall(); + Endpoint_ResetDataToggle(); + Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataINEndpoint.Address); + Endpoint_ClearStall(); + Endpoint_ResetDataToggle(); + + MSInterfaceInfo->State.IsMassStoreReset = false; + } +} + +static bool MS_Device_ReadInCommandBlock(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) +{ + uint16_t BytesProcessed; + + Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataOUTEndpoint.Address); + + BytesProcessed = 0; + while (Endpoint_Read_Stream_LE(&MSInterfaceInfo->State.CommandBlock, + (sizeof(MS_CommandBlockWrapper_t) - 16), &BytesProcessed) == + ENDPOINT_RWSTREAM_IncompleteTransfer) + { + if (MSInterfaceInfo->State.IsMassStoreReset) + return false; + } + + if ((MSInterfaceInfo->State.CommandBlock.Signature != CPU_TO_LE32(MS_CBW_SIGNATURE)) || + (MSInterfaceInfo->State.CommandBlock.LUN >= MSInterfaceInfo->Config.TotalLUNs) || + (MSInterfaceInfo->State.CommandBlock.Flags & 0x1F) || + (MSInterfaceInfo->State.CommandBlock.SCSICommandLength == 0) || + (MSInterfaceInfo->State.CommandBlock.SCSICommandLength > 16)) + { + Endpoint_StallTransaction(); + Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataINEndpoint.Address); + Endpoint_StallTransaction(); + + return false; + } + + BytesProcessed = 0; + while (Endpoint_Read_Stream_LE(&MSInterfaceInfo->State.CommandBlock.SCSICommandData, + MSInterfaceInfo->State.CommandBlock.SCSICommandLength, &BytesProcessed) == + ENDPOINT_RWSTREAM_IncompleteTransfer) + { + if (MSInterfaceInfo->State.IsMassStoreReset) + return false; + } + + Endpoint_ClearOUT(); + + return true; +} + +static void MS_Device_ReturnCommandStatus(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) +{ + Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataOUTEndpoint.Address); + + while (Endpoint_IsStalled()) + { + #if !defined(INTERRUPT_CONTROL_ENDPOINT) + USB_USBTask(); + #endif + + if (MSInterfaceInfo->State.IsMassStoreReset) + return; + } + + Endpoint_SelectEndpoint(MSInterfaceInfo->Config.DataINEndpoint.Address); + + while (Endpoint_IsStalled()) + { + #if !defined(INTERRUPT_CONTROL_ENDPOINT) + USB_USBTask(); + #endif + + if (MSInterfaceInfo->State.IsMassStoreReset) + return; + } + + uint16_t BytesProcessed = 0; + while (Endpoint_Write_Stream_LE(&MSInterfaceInfo->State.CommandStatus, + sizeof(MS_CommandStatusWrapper_t), &BytesProcessed) == + ENDPOINT_RWSTREAM_IncompleteTransfer) + { + if (MSInterfaceInfo->State.IsMassStoreReset) + return; + } + + Endpoint_ClearIN(); +} + +#endif + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Device/MassStorageClassDevice.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Device/MassStorageClassDevice.h new file mode 100644 index 00000000..b9bc832e --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Device/MassStorageClassDevice.h @@ -0,0 +1,161 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Device mode driver for the library USB Mass Storage Class driver. + * + * Device mode driver for the library USB Mass Storage Class driver. + * + * \note This file should not be included directly. It is automatically included as needed by the USB module driver + * dispatch header located in LUFA/Drivers/USB.h. + */ + +/** \ingroup Group_USBClassMS + * \defgroup Group_USBClassMSDevice Mass Storage Class Device Mode Driver + * + * \section Sec_Dependencies Module Source Dependencies + * The following files must be built with any user project that uses this module: + * - LUFA/Drivers/USB/Class/Device/MassStorageClassDevice.c (Makefile source module name: LUFA_SRC_USBCLASS) + * + * \section Sec_ModDescription Module Description + * Device Mode USB Class driver framework interface, for the Mass Storage USB Class driver. + * + * @{ + */ + +#ifndef _MS_CLASS_DEVICE_H_ +#define _MS_CLASS_DEVICE_H_ + + /* Includes: */ + #include "../../USB.h" + #include "../Common/MassStorageClassCommon.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_MS_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Type Defines: */ + /** \brief Mass Storage Class Device Mode Configuration and State Structure. + * + * Class state structure. An instance of this structure should be made for each Mass Storage interface + * within the user application, and passed to each of the Mass Storage class driver functions as the + * \c MSInterfaceInfo parameter. This stores each Mass Storage interface's configuration and state information. + */ + typedef struct + { + struct + { + uint8_t InterfaceNumber; /**< Interface number of the Mass Storage interface within the device. */ + + USB_Endpoint_Table_t DataINEndpoint; /**< Data IN endpoint configuration table. */ + USB_Endpoint_Table_t DataOUTEndpoint; /**< Data OUT endpoint configuration table. */ + + uint8_t TotalLUNs; /**< Total number of logical drives in the Mass Storage interface. */ + } Config; /**< Config data for the USB class interface within the device. All elements in this section + * must be set or the interface will fail to enumerate and operate correctly. + */ + struct + { + MS_CommandBlockWrapper_t CommandBlock; /**< Mass Storage class command block structure, stores the received SCSI + * command from the host which is to be processed. + */ + MS_CommandStatusWrapper_t CommandStatus; /**< Mass Storage class command status structure, set elements to indicate + * the issued command's success or failure to the host. + */ + volatile bool IsMassStoreReset; /**< Flag indicating that the host has requested that the Mass Storage interface be reset + * and that all current Mass Storage operations should immediately abort. + */ + } State; /**< State data for the USB class interface within the device. All elements in this section + * are reset to their defaults when the interface is enumerated. + */ + } USB_ClassInfo_MS_Device_t; + + /* Function Prototypes: */ + /** Configures the endpoints of a given Mass Storage interface, ready for use. This should be linked to the library + * \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration + * containing the given Mass Storage interface is selected. + * + * \param[in,out] MSInterfaceInfo Pointer to a structure containing a Mass Storage Class configuration and state. + * + * \return Boolean \c true if the endpoints were successfully configured, \c false otherwise. + */ + bool MS_Device_ConfigureEndpoints(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + /** Processes incoming control requests from the host, that are directed to the given Mass Storage class interface. This should be + * linked to the library \ref EVENT_USB_Device_ControlRequest() event. + * + * \param[in,out] MSInterfaceInfo Pointer to a structure containing a Mass Storage Class configuration and state. + */ + void MS_Device_ProcessControlRequest(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + /** General management task for a given Mass Storage class interface, required for the correct operation of the interface. This should + * be called frequently in the main program loop, before the master USB management task \ref USB_USBTask(). + * + * \param[in,out] MSInterfaceInfo Pointer to a structure containing a Mass Storage configuration and state. + */ + void MS_Device_USBTask(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + /** Mass Storage class driver callback for the user processing of a received SCSI command. This callback will fire each time the + * host sends a SCSI command which requires processing by the user application. Inside this callback the user is responsible + * for the processing of the received SCSI command from the host. The SCSI command is available in the CommandBlock structure + * inside the Mass Storage class state structure passed as a parameter to the callback function. + * + * \param[in,out] MSInterfaceInfo Pointer to a structure containing a Mass Storage Class configuration and state. + * + * \return Boolean \c true if the SCSI command was successfully processed, \c false otherwise. + */ + bool CALLBACK_MS_Device_SCSICommandReceived(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Function Prototypes: */ + #if defined(__INCLUDE_FROM_MASSSTORAGE_DEVICE_C) + static void MS_Device_ReturnCommandStatus(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + static bool MS_Device_ReadInCommandBlock(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + #endif + + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Device/RNDISClassDevice.c b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Device/RNDISClassDevice.c new file mode 100644 index 00000000..80aa723c --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Device/RNDISClassDevice.c @@ -0,0 +1,502 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#define __INCLUDE_FROM_USB_DRIVER +#include "../../Core/USBMode.h" + +#if defined(USB_CAN_BE_DEVICE) + +#define __INCLUDE_FROM_RNDIS_DRIVER +#define __INCLUDE_FROM_RNDIS_DEVICE_C +#include "RNDISClassDevice.h" + +static const uint32_t PROGMEM AdapterSupportedOIDList[] = + { + CPU_TO_LE32(OID_GEN_SUPPORTED_LIST), + CPU_TO_LE32(OID_GEN_PHYSICAL_MEDIUM), + CPU_TO_LE32(OID_GEN_HARDWARE_STATUS), + CPU_TO_LE32(OID_GEN_MEDIA_SUPPORTED), + CPU_TO_LE32(OID_GEN_MEDIA_IN_USE), + CPU_TO_LE32(OID_GEN_MAXIMUM_FRAME_SIZE), + CPU_TO_LE32(OID_GEN_MAXIMUM_TOTAL_SIZE), + CPU_TO_LE32(OID_GEN_LINK_SPEED), + CPU_TO_LE32(OID_GEN_TRANSMIT_BLOCK_SIZE), + CPU_TO_LE32(OID_GEN_RECEIVE_BLOCK_SIZE), + CPU_TO_LE32(OID_GEN_VENDOR_ID), + CPU_TO_LE32(OID_GEN_VENDOR_DESCRIPTION), + CPU_TO_LE32(OID_GEN_CURRENT_PACKET_FILTER), + CPU_TO_LE32(OID_GEN_MAXIMUM_TOTAL_SIZE), + CPU_TO_LE32(OID_GEN_MEDIA_CONNECT_STATUS), + CPU_TO_LE32(OID_GEN_XMIT_OK), + CPU_TO_LE32(OID_GEN_RCV_OK), + CPU_TO_LE32(OID_GEN_XMIT_ERROR), + CPU_TO_LE32(OID_GEN_RCV_ERROR), + CPU_TO_LE32(OID_GEN_RCV_NO_BUFFER), + CPU_TO_LE32(OID_802_3_PERMANENT_ADDRESS), + CPU_TO_LE32(OID_802_3_CURRENT_ADDRESS), + CPU_TO_LE32(OID_802_3_MULTICAST_LIST), + CPU_TO_LE32(OID_802_3_MAXIMUM_LIST_SIZE), + CPU_TO_LE32(OID_802_3_RCV_ERROR_ALIGNMENT), + CPU_TO_LE32(OID_802_3_XMIT_ONE_COLLISION), + CPU_TO_LE32(OID_802_3_XMIT_MORE_COLLISIONS), + }; + +void RNDIS_Device_ProcessControlRequest(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo) +{ + if (!(Endpoint_IsSETUPReceived())) + return; + + if (USB_ControlRequest.wIndex != RNDISInterfaceInfo->Config.ControlInterfaceNumber) + return; + + switch (USB_ControlRequest.bRequest) + { + case RNDIS_REQ_SendEncapsulatedCommand: + if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE)) + { + Endpoint_ClearSETUP(); + Endpoint_Read_Control_Stream_LE(RNDISInterfaceInfo->State.RNDISMessageBuffer, USB_ControlRequest.wLength); + Endpoint_ClearIN(); + + RNDIS_Device_ProcessRNDISControlMessage(RNDISInterfaceInfo); + } + + break; + case RNDIS_REQ_GetEncapsulatedResponse: + if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) + { + RNDIS_Message_Header_t* MessageHeader = (RNDIS_Message_Header_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer; + + if (!(MessageHeader->MessageLength)) + { + RNDISInterfaceInfo->State.RNDISMessageBuffer[0] = 0; + MessageHeader->MessageLength = CPU_TO_LE32(1); + } + + Endpoint_ClearSETUP(); + Endpoint_Write_Control_Stream_LE(RNDISInterfaceInfo->State.RNDISMessageBuffer, le32_to_cpu(MessageHeader->MessageLength)); + Endpoint_ClearOUT(); + + MessageHeader->MessageLength = CPU_TO_LE32(0); + } + + break; + } +} + +bool RNDIS_Device_ConfigureEndpoints(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo) +{ + memset(&RNDISInterfaceInfo->State, 0x00, sizeof(RNDISInterfaceInfo->State)); + + RNDISInterfaceInfo->Config.DataINEndpoint.Type = EP_TYPE_BULK; + RNDISInterfaceInfo->Config.DataOUTEndpoint.Type = EP_TYPE_BULK; + RNDISInterfaceInfo->Config.NotificationEndpoint.Type = EP_TYPE_INTERRUPT; + + if (!(Endpoint_ConfigureEndpointTable(&RNDISInterfaceInfo->Config.DataINEndpoint, 1))) + return false; + + if (!(Endpoint_ConfigureEndpointTable(&RNDISInterfaceInfo->Config.DataOUTEndpoint, 1))) + return false; + + if (!(Endpoint_ConfigureEndpointTable(&RNDISInterfaceInfo->Config.NotificationEndpoint, 1))) + return false; + + return true; +} + +void RNDIS_Device_USBTask(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo) +{ + if (USB_DeviceState != DEVICE_STATE_Configured) + return; + + Endpoint_SelectEndpoint(RNDISInterfaceInfo->Config.NotificationEndpoint.Address); + + if (Endpoint_IsINReady() && RNDISInterfaceInfo->State.ResponseReady) + { + USB_Request_Header_t Notification = (USB_Request_Header_t) + { + .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE), + .bRequest = RNDIS_NOTIF_ResponseAvailable, + .wValue = CPU_TO_LE16(0), + .wIndex = CPU_TO_LE16(0), + .wLength = CPU_TO_LE16(0), + }; + + Endpoint_Write_Stream_LE(&Notification, sizeof(USB_Request_Header_t), NULL); + + Endpoint_ClearIN(); + + RNDISInterfaceInfo->State.ResponseReady = false; + } +} + +void RNDIS_Device_ProcessRNDISControlMessage(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo) +{ + /* Note: Only a single buffer is used for both the received message and its response to save SRAM. Because of + this, response bytes should be filled in order so that they do not clobber unread data in the buffer. */ + + RNDIS_Message_Header_t* MessageHeader = (RNDIS_Message_Header_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer; + + switch (le32_to_cpu(MessageHeader->MessageType)) + { + case REMOTE_NDIS_INITIALIZE_MSG: + RNDISInterfaceInfo->State.ResponseReady = true; + + RNDIS_Initialize_Message_t* INITIALIZE_Message = + (RNDIS_Initialize_Message_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer; + RNDIS_Initialize_Complete_t* INITIALIZE_Response = + (RNDIS_Initialize_Complete_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer; + + INITIALIZE_Response->MessageType = CPU_TO_LE32(REMOTE_NDIS_INITIALIZE_CMPLT); + INITIALIZE_Response->MessageLength = CPU_TO_LE32(sizeof(RNDIS_Initialize_Complete_t)); + INITIALIZE_Response->RequestId = INITIALIZE_Message->RequestId; + INITIALIZE_Response->Status = CPU_TO_LE32(REMOTE_NDIS_STATUS_SUCCESS); + + INITIALIZE_Response->MajorVersion = CPU_TO_LE32(REMOTE_NDIS_VERSION_MAJOR); + INITIALIZE_Response->MinorVersion = CPU_TO_LE32(REMOTE_NDIS_VERSION_MINOR); + INITIALIZE_Response->DeviceFlags = CPU_TO_LE32(REMOTE_NDIS_DF_CONNECTIONLESS); + INITIALIZE_Response->Medium = CPU_TO_LE32(REMOTE_NDIS_MEDIUM_802_3); + INITIALIZE_Response->MaxPacketsPerTransfer = CPU_TO_LE32(1); + INITIALIZE_Response->MaxTransferSize = CPU_TO_LE32(sizeof(RNDIS_Packet_Message_t) + ETHERNET_FRAME_SIZE_MAX); + INITIALIZE_Response->PacketAlignmentFactor = CPU_TO_LE32(0); + INITIALIZE_Response->AFListOffset = CPU_TO_LE32(0); + INITIALIZE_Response->AFListSize = CPU_TO_LE32(0); + + RNDISInterfaceInfo->State.CurrRNDISState = RNDIS_Initialized; + break; + case REMOTE_NDIS_HALT_MSG: + RNDISInterfaceInfo->State.ResponseReady = false; + + MessageHeader->MessageLength = CPU_TO_LE32(0); + + RNDISInterfaceInfo->State.CurrRNDISState = RNDIS_Uninitialized; + break; + case REMOTE_NDIS_QUERY_MSG: + RNDISInterfaceInfo->State.ResponseReady = true; + + RNDIS_Query_Message_t* QUERY_Message = (RNDIS_Query_Message_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer; + RNDIS_Query_Complete_t* QUERY_Response = (RNDIS_Query_Complete_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer; + uint32_t Query_Oid = CPU_TO_LE32(QUERY_Message->Oid); + + void* QueryData = &RNDISInterfaceInfo->State.RNDISMessageBuffer[sizeof(RNDIS_Message_Header_t) + + le32_to_cpu(QUERY_Message->InformationBufferOffset)]; + void* ResponseData = &RNDISInterfaceInfo->State.RNDISMessageBuffer[sizeof(RNDIS_Query_Complete_t)]; + uint16_t ResponseSize; + + QUERY_Response->MessageType = CPU_TO_LE32(REMOTE_NDIS_QUERY_CMPLT); + + if (RNDIS_Device_ProcessNDISQuery(RNDISInterfaceInfo, Query_Oid, QueryData, le32_to_cpu(QUERY_Message->InformationBufferLength), + ResponseData, &ResponseSize)) + { + QUERY_Response->Status = CPU_TO_LE32(REMOTE_NDIS_STATUS_SUCCESS); + QUERY_Response->MessageLength = cpu_to_le32(sizeof(RNDIS_Query_Complete_t) + ResponseSize); + + QUERY_Response->InformationBufferLength = CPU_TO_LE32(ResponseSize); + QUERY_Response->InformationBufferOffset = CPU_TO_LE32(sizeof(RNDIS_Query_Complete_t) - sizeof(RNDIS_Message_Header_t)); + } + else + { + QUERY_Response->Status = CPU_TO_LE32(REMOTE_NDIS_STATUS_NOT_SUPPORTED); + QUERY_Response->MessageLength = CPU_TO_LE32(sizeof(RNDIS_Query_Complete_t)); + + QUERY_Response->InformationBufferLength = CPU_TO_LE32(0); + QUERY_Response->InformationBufferOffset = CPU_TO_LE32(0); + } + + break; + case REMOTE_NDIS_SET_MSG: + RNDISInterfaceInfo->State.ResponseReady = true; + + RNDIS_Set_Message_t* SET_Message = (RNDIS_Set_Message_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer; + RNDIS_Set_Complete_t* SET_Response = (RNDIS_Set_Complete_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer; + uint32_t SET_Oid = le32_to_cpu(SET_Message->Oid); + + SET_Response->MessageType = CPU_TO_LE32(REMOTE_NDIS_SET_CMPLT); + SET_Response->MessageLength = CPU_TO_LE32(sizeof(RNDIS_Set_Complete_t)); + SET_Response->RequestId = SET_Message->RequestId; + + void* SetData = &RNDISInterfaceInfo->State.RNDISMessageBuffer[sizeof(RNDIS_Message_Header_t) + + le32_to_cpu(SET_Message->InformationBufferOffset)]; + + SET_Response->Status = RNDIS_Device_ProcessNDISSet(RNDISInterfaceInfo, SET_Oid, SetData, + le32_to_cpu(SET_Message->InformationBufferLength)) ? + REMOTE_NDIS_STATUS_SUCCESS : REMOTE_NDIS_STATUS_NOT_SUPPORTED; + break; + case REMOTE_NDIS_RESET_MSG: + RNDISInterfaceInfo->State.ResponseReady = true; + + RNDIS_Reset_Complete_t* RESET_Response = (RNDIS_Reset_Complete_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer; + + RESET_Response->MessageType = CPU_TO_LE32(REMOTE_NDIS_RESET_CMPLT); + RESET_Response->MessageLength = CPU_TO_LE32(sizeof(RNDIS_Reset_Complete_t)); + RESET_Response->Status = CPU_TO_LE32(REMOTE_NDIS_STATUS_SUCCESS); + RESET_Response->AddressingReset = CPU_TO_LE32(0); + + break; + case REMOTE_NDIS_KEEPALIVE_MSG: + RNDISInterfaceInfo->State.ResponseReady = true; + + RNDIS_KeepAlive_Message_t* KEEPALIVE_Message = + (RNDIS_KeepAlive_Message_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer; + RNDIS_KeepAlive_Complete_t* KEEPALIVE_Response = + (RNDIS_KeepAlive_Complete_t*)&RNDISInterfaceInfo->State.RNDISMessageBuffer; + + KEEPALIVE_Response->MessageType = CPU_TO_LE32(REMOTE_NDIS_KEEPALIVE_CMPLT); + KEEPALIVE_Response->MessageLength = CPU_TO_LE32(sizeof(RNDIS_KeepAlive_Complete_t)); + KEEPALIVE_Response->RequestId = KEEPALIVE_Message->RequestId; + KEEPALIVE_Response->Status = CPU_TO_LE32(REMOTE_NDIS_STATUS_SUCCESS); + + break; + } +} + +static bool RNDIS_Device_ProcessNDISQuery(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo, + const uint32_t OId, + void* const QueryData, + const uint16_t QuerySize, + void* ResponseData, + uint16_t* const ResponseSize) +{ + (void)QueryData; + (void)QuerySize; + + switch (OId) + { + case OID_GEN_SUPPORTED_LIST: + *ResponseSize = sizeof(AdapterSupportedOIDList); + + memcpy_P(ResponseData, AdapterSupportedOIDList, sizeof(AdapterSupportedOIDList)); + + return true; + case OID_GEN_PHYSICAL_MEDIUM: + *ResponseSize = sizeof(uint32_t); + + /* Indicate that the device is a true ethernet link */ + *((uint32_t*)ResponseData) = CPU_TO_LE32(0); + + return true; + case OID_GEN_HARDWARE_STATUS: + *ResponseSize = sizeof(uint32_t); + + *((uint32_t*)ResponseData) = CPU_TO_LE32(NDIS_HardwareStatus_Ready); + + return true; + case OID_GEN_MEDIA_SUPPORTED: + case OID_GEN_MEDIA_IN_USE: + *ResponseSize = sizeof(uint32_t); + + *((uint32_t*)ResponseData) = CPU_TO_LE32(REMOTE_NDIS_MEDIUM_802_3); + + return true; + case OID_GEN_VENDOR_ID: + *ResponseSize = sizeof(uint32_t); + + /* Vendor ID 0x0xFFFFFF is reserved for vendors who have not purchased a NDIS VID */ + *((uint32_t*)ResponseData) = CPU_TO_LE32(0x00FFFFFF); + + return true; + case OID_GEN_MAXIMUM_FRAME_SIZE: + case OID_GEN_TRANSMIT_BLOCK_SIZE: + case OID_GEN_RECEIVE_BLOCK_SIZE: + *ResponseSize = sizeof(uint32_t); + + *((uint32_t*)ResponseData) = CPU_TO_LE32(ETHERNET_FRAME_SIZE_MAX); + + return true; + case OID_GEN_VENDOR_DESCRIPTION: + *ResponseSize = (strlen(RNDISInterfaceInfo->Config.AdapterVendorDescription) + 1); + + memcpy(ResponseData, RNDISInterfaceInfo->Config.AdapterVendorDescription, *ResponseSize); + + return true; + case OID_GEN_MEDIA_CONNECT_STATUS: + *ResponseSize = sizeof(uint32_t); + + *((uint32_t*)ResponseData) = CPU_TO_LE32(REMOTE_NDIS_MEDIA_STATE_CONNECTED); + + return true; + case OID_GEN_LINK_SPEED: + *ResponseSize = sizeof(uint32_t); + + /* Indicate 10Mb/s link speed */ + *((uint32_t*)ResponseData) = CPU_TO_LE32(100000); + + return true; + case OID_802_3_PERMANENT_ADDRESS: + case OID_802_3_CURRENT_ADDRESS: + *ResponseSize = sizeof(MAC_Address_t); + + memcpy(ResponseData, &RNDISInterfaceInfo->Config.AdapterMACAddress, sizeof(MAC_Address_t)); + + return true; + case OID_802_3_MAXIMUM_LIST_SIZE: + *ResponseSize = sizeof(uint32_t); + + /* Indicate only one multicast address supported */ + *((uint32_t*)ResponseData) = CPU_TO_LE32(1); + + return true; + case OID_GEN_CURRENT_PACKET_FILTER: + *ResponseSize = sizeof(uint32_t); + + *((uint32_t*)ResponseData) = cpu_to_le32(RNDISInterfaceInfo->State.CurrPacketFilter); + + return true; + case OID_GEN_XMIT_OK: + case OID_GEN_RCV_OK: + case OID_GEN_XMIT_ERROR: + case OID_GEN_RCV_ERROR: + case OID_GEN_RCV_NO_BUFFER: + case OID_802_3_RCV_ERROR_ALIGNMENT: + case OID_802_3_XMIT_ONE_COLLISION: + case OID_802_3_XMIT_MORE_COLLISIONS: + *ResponseSize = sizeof(uint32_t); + + /* Unused statistic OIDs - always return 0 for each */ + *((uint32_t*)ResponseData) = CPU_TO_LE32(0); + + return true; + case OID_GEN_MAXIMUM_TOTAL_SIZE: + *ResponseSize = sizeof(uint32_t); + + /* Indicate maximum overall buffer (Ethernet frame and RNDIS header) the adapter can handle */ + *((uint32_t*)ResponseData) = CPU_TO_LE32(RNDIS_MESSAGE_BUFFER_SIZE + ETHERNET_FRAME_SIZE_MAX); + + return true; + default: + return false; + } +} + +static bool RNDIS_Device_ProcessNDISSet(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo, + const uint32_t OId, + const void* SetData, + const uint16_t SetSize) +{ + (void)SetSize; + + switch (OId) + { + case OID_GEN_CURRENT_PACKET_FILTER: + RNDISInterfaceInfo->State.CurrPacketFilter = le32_to_cpu(*((uint32_t*)SetData)); + RNDISInterfaceInfo->State.CurrRNDISState = (RNDISInterfaceInfo->State.CurrPacketFilter) ? RNDIS_Data_Initialized : RNDIS_Initialized; + + return true; + case OID_802_3_MULTICAST_LIST: + /* Do nothing - throw away the value from the host as it is unused */ + + return true; + default: + return false; + } +} + +bool RNDIS_Device_IsPacketReceived(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo) +{ + if ((USB_DeviceState != DEVICE_STATE_Configured) || + (RNDISInterfaceInfo->State.CurrRNDISState != RNDIS_Data_Initialized)) + { + return false; + } + + Endpoint_SelectEndpoint(RNDISInterfaceInfo->Config.DataOUTEndpoint.Address); + return Endpoint_IsOUTReceived(); +} + +uint8_t RNDIS_Device_ReadPacket(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo, + void* Buffer, + uint16_t* const PacketLength) +{ + if ((USB_DeviceState != DEVICE_STATE_Configured) || + (RNDISInterfaceInfo->State.CurrRNDISState != RNDIS_Data_Initialized)) + { + return ENDPOINT_RWSTREAM_DeviceDisconnected; + } + + Endpoint_SelectEndpoint(RNDISInterfaceInfo->Config.DataOUTEndpoint.Address); + + *PacketLength = 0; + + if (!(Endpoint_IsOUTReceived())) + return ENDPOINT_RWSTREAM_NoError; + + RNDIS_Packet_Message_t RNDISPacketHeader; + Endpoint_Read_Stream_LE(&RNDISPacketHeader, sizeof(RNDIS_Packet_Message_t), NULL); + + if (le32_to_cpu(RNDISPacketHeader.DataLength) > ETHERNET_FRAME_SIZE_MAX) + { + Endpoint_StallTransaction(); + + return RNDIS_ERROR_LOGICAL_CMD_FAILED; + } + + *PacketLength = (uint16_t)le32_to_cpu(RNDISPacketHeader.DataLength); + + Endpoint_Read_Stream_LE(Buffer, *PacketLength, NULL); + Endpoint_ClearOUT(); + + return ENDPOINT_RWSTREAM_NoError; +} + +uint8_t RNDIS_Device_SendPacket(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo, + void* Buffer, + const uint16_t PacketLength) +{ + uint8_t ErrorCode; + + if ((USB_DeviceState != DEVICE_STATE_Configured) || + (RNDISInterfaceInfo->State.CurrRNDISState != RNDIS_Data_Initialized)) + { + return ENDPOINT_RWSTREAM_DeviceDisconnected; + } + + Endpoint_SelectEndpoint(RNDISInterfaceInfo->Config.DataINEndpoint.Address); + + if ((ErrorCode = Endpoint_WaitUntilReady()) != ENDPOINT_READYWAIT_NoError) + return ErrorCode; + + RNDIS_Packet_Message_t RNDISPacketHeader; + + memset(&RNDISPacketHeader, 0, sizeof(RNDIS_Packet_Message_t)); + + RNDISPacketHeader.MessageType = CPU_TO_LE32(REMOTE_NDIS_PACKET_MSG); + RNDISPacketHeader.MessageLength = cpu_to_le32(sizeof(RNDIS_Packet_Message_t) + PacketLength); + RNDISPacketHeader.DataOffset = CPU_TO_LE32(sizeof(RNDIS_Packet_Message_t) - sizeof(RNDIS_Message_Header_t)); + RNDISPacketHeader.DataLength = cpu_to_le32(PacketLength); + + Endpoint_Write_Stream_LE(&RNDISPacketHeader, sizeof(RNDIS_Packet_Message_t), NULL); + Endpoint_Write_Stream_LE(Buffer, PacketLength, NULL); + Endpoint_ClearIN(); + + return ENDPOINT_RWSTREAM_NoError; +} + +#endif + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Device/RNDISClassDevice.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Device/RNDISClassDevice.h new file mode 100644 index 00000000..4d1a4cff --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Device/RNDISClassDevice.h @@ -0,0 +1,203 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Device mode driver for the library USB RNDIS Class driver. + * + * Device mode driver for the library USB RNDIS Class driver. + * + * \note This file should not be included directly. It is automatically included as needed by the USB module driver + * dispatch header located in LUFA/Drivers/USB.h. + */ + +/** \ingroup Group_USBClassRNDIS + * \defgroup Group_USBClassRNDISDevice RNDIS Class Device Mode Driver + * + * \section Sec_Dependencies Module Source Dependencies + * The following files must be built with any user project that uses this module: + * - LUFA/Drivers/USB/Class/Device/RNDISClassDevice.c (Makefile source module name: LUFA_SRC_USBCLASS) + * + * \section Sec_ModDescription Module Description + * Device Mode USB Class driver framework interface, for the RNDIS USB Class driver. + * + * @{ + */ + +#ifndef _RNDIS_CLASS_DEVICE_H_ +#define _RNDIS_CLASS_DEVICE_H_ + + /* Includes: */ + #include "../../USB.h" + #include "../Common/RNDISClassCommon.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_RNDIS_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Type Defines: */ + /** \brief RNDIS Class Device Mode Configuration and State Structure. + * + * Class state structure. An instance of this structure should be made for each RNDIS interface + * within the user application, and passed to each of the RNDIS class driver functions as the + * \c RNDISInterfaceInfo parameter. This stores each RNDIS interface's configuration and state information. + */ + typedef struct + { + struct + { + uint8_t ControlInterfaceNumber; /**< Interface number of the RNDIS control interface within the device. */ + + USB_Endpoint_Table_t DataINEndpoint; /**< Data IN endpoint configuration table. */ + USB_Endpoint_Table_t DataOUTEndpoint; /**< Data OUT endpoint configuration table. */ + USB_Endpoint_Table_t NotificationEndpoint; /**< Notification IN Endpoint configuration table. */ + + char* AdapterVendorDescription; /**< String description of the adapter vendor. */ + MAC_Address_t AdapterMACAddress; /**< MAC address of the adapter. */ + } Config; /**< Config data for the USB class interface within the device. All elements in this section + * must be set or the interface will fail to enumerate and operate correctly. + */ + struct + { + uint8_t RNDISMessageBuffer[RNDIS_MESSAGE_BUFFER_SIZE]; /**< Buffer to hold RNDIS messages to and from the host, + * managed by the class driver. + */ + bool ResponseReady; /**< Internal flag indicating if a RNDIS message is waiting to be returned to the host. */ + uint8_t CurrRNDISState; /**< Current RNDIS state of the adapter, a value from the \ref RNDIS_States_t enum. */ + uint32_t CurrPacketFilter; /**< Current packet filter mode, used internally by the class driver. */ + } State; /**< State data for the USB class interface within the device. All elements in this section + * are reset to their defaults when the interface is enumerated. + */ + } USB_ClassInfo_RNDIS_Device_t; + + /* Function Prototypes: */ + /** Configures the endpoints of a given RNDIS interface, ready for use. This should be linked to the library + * \ref EVENT_USB_Device_ConfigurationChanged() event so that the endpoints are configured when the configuration + * containing the given RNDIS interface is selected. + * + * \param[in,out] RNDISInterfaceInfo Pointer to a structure containing a RNDIS Class configuration and state. + * + * \return Boolean \c true if the endpoints were successfully configured, \c false otherwise. + */ + bool RNDIS_Device_ConfigureEndpoints(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + /** Processes incoming control requests from the host, that are directed to the given RNDIS class interface. This should be + * linked to the library \ref EVENT_USB_Device_ControlRequest() event. + * + * \param[in,out] RNDISInterfaceInfo Pointer to a structure containing a RNDIS Class configuration and state. + */ + void RNDIS_Device_ProcessControlRequest(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + /** General management task for a given RNDIS class interface, required for the correct operation of the interface. This should + * be called frequently in the main program loop, before the master USB management task \ref USB_USBTask(). + * + * \param[in,out] RNDISInterfaceInfo Pointer to a structure containing a RNDIS Class configuration and state. + */ + void RNDIS_Device_USBTask(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + /** Determines if a packet is currently waiting for the device to read in and process. + * + * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or the + * call will fail. + * + * \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class configuration and state. + * + * \return Boolean \c true if a packet is waiting to be read in by the host, \c false otherwise. + */ + bool RNDIS_Device_IsPacketReceived(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo); + + /** Retrieves the next pending packet from the device, discarding the remainder of the RNDIS packet header to leave + * only the packet contents for processing by the device in the nominated buffer. + * + * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or the + * call will fail. + * + * \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class configuration and state. + * \param[out] Buffer Pointer to a buffer where the packer data is to be written to. + * \param[out] PacketLength Pointer to where the length in bytes of the read packet is to be stored. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t RNDIS_Device_ReadPacket(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo, + void* Buffer, + uint16_t* const PacketLength); + + /** Sends the given packet to the attached RNDIS device, after adding a RNDIS packet message header. + * + * \pre This function must only be called when the Device state machine is in the \ref DEVICE_STATE_Configured state or the + * call will fail. + * + * \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class configuration and state. + * \param[in] Buffer Pointer to a buffer where the packer data is to be read from. + * \param[in] PacketLength Length in bytes of the packet to send. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t RNDIS_Device_SendPacket(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo, + void* Buffer, + const uint16_t PacketLength); + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Function Prototypes: */ + #if defined(__INCLUDE_FROM_RNDIS_DEVICE_C) + static void RNDIS_Device_ProcessRNDISControlMessage(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo) + ATTR_NON_NULL_PTR_ARG(1); + static bool RNDIS_Device_ProcessNDISQuery(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo, + const uint32_t OId, + void* const QueryData, + const uint16_t QuerySize, + void* ResponseData, + uint16_t* const ResponseSize) ATTR_NON_NULL_PTR_ARG(1) + ATTR_NON_NULL_PTR_ARG(5) ATTR_NON_NULL_PTR_ARG(6); + static bool RNDIS_Device_ProcessNDISSet(USB_ClassInfo_RNDIS_Device_t* const RNDISInterfaceInfo, + const uint32_t OId, + const void* SetData, + const uint16_t SetSize) ATTR_NON_NULL_PTR_ARG(1) + ATTR_NON_NULL_PTR_ARG(3); + #endif + + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/HIDClass.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/HIDClass.h new file mode 100644 index 00000000..288559c7 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/HIDClass.h @@ -0,0 +1,81 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Master include file for the library USB HID Class driver. + * + * Master include file for the library USB HID Class driver, for both host and device modes, where available. + * + * This file should be included in all user projects making use of this optional class driver, instead of + * including any headers in the USB/ClassDriver/Device, USB/ClassDriver/Host or USB/ClassDriver/Common subdirectories. + */ + +/** \ingroup Group_USBClassDrivers + * \defgroup Group_USBClassHID HID Class Driver + * + * \section Sec_Dependencies Module Source Dependencies + * The following files must be built with any user project that uses this module: + * - LUFA/Drivers/USB/Class/Device/HIDClassDevice.c (Makefile source module name: LUFA_SRC_USBCLASS) + * - LUFA/Drivers/USB/Class/Host/HIDClassHost.c (Makefile source module name: LUFA_SRC_USBCLASS) + * - LUFA/Drivers/USB/Class/Host/HIDParser.c (Makefile source module name: LUFA_SRC_USB) + * + * \section Sec_ModDescription Module Description + * HID Class Driver module. This module contains an internal implementation of the USB HID Class, for both Device + * and Host USB modes. User applications can use this class driver instead of implementing the HID class manually + * via the low-level LUFA APIs. + * + * This module is designed to simplify the user code by exposing only the required interface needed to interface with + * Hosts or Devices using the USB HID Class. + * + * @{ + */ + +#ifndef _HID_CLASS_H_ +#define _HID_CLASS_H_ + + /* Macros: */ + #define __INCLUDE_FROM_USB_DRIVER + #define __INCLUDE_FROM_HID_DRIVER + + /* Includes: */ + #include "../Core/USBMode.h" + + #if defined(USB_CAN_BE_DEVICE) + #include "Device/HIDClassDevice.h" + #endif + + #if defined(USB_CAN_BE_HOST) + #include "Host/HIDClassHost.h" + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/AndroidAccessoryClassHost.c b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/AndroidAccessoryClassHost.c new file mode 100644 index 00000000..67a1352b --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/AndroidAccessoryClassHost.c @@ -0,0 +1,422 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#define __INCLUDE_FROM_USB_DRIVER +#include "../../Core/USBMode.h" + +#if defined(USB_CAN_BE_HOST) + +#define __INCLUDE_FROM_AOA_DRIVER +#define __INCLUDE_FROM_ANDROIDACCESSORY_HOST_C +#include "AndroidAccessoryClassHost.h" + +bool AOA_Host_ValidateAccessoryDevice(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, + const USB_Descriptor_Device_t* const DeviceDescriptor, + bool* const NeedModeSwitch) +{ + (void)AOAInterfaceInfo; + + if (DeviceDescriptor->Header.Type != DTYPE_Device) + return false; + + *NeedModeSwitch = ((DeviceDescriptor->ProductID != ANDROID_ACCESSORY_PRODUCT_ID) && + (DeviceDescriptor->ProductID != ANDROID_ACCESSORY_ADB_PRODUCT_ID)); + + return true; +} + +uint8_t AOA_Host_ConfigurePipes(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, + uint16_t ConfigDescriptorSize, + void* ConfigDescriptorData) +{ + USB_Descriptor_Endpoint_t* DataINEndpoint = NULL; + USB_Descriptor_Endpoint_t* DataOUTEndpoint = NULL; + USB_Descriptor_Interface_t* AOAInterface = NULL; + + memset(&AOAInterfaceInfo->State, 0x00, sizeof(AOAInterfaceInfo->State)); + + if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration) + return AOA_ENUMERROR_InvalidConfigDescriptor; + + if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, + DCOMP_AOA_Host_NextAndroidAccessoryInterface) != DESCRIPTOR_SEARCH_COMP_Found) + { + return AOA_ENUMERROR_NoCompatibleInterfaceFound; + } + + AOAInterface = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Interface_t); + + while (!(DataINEndpoint) || !(DataOUTEndpoint)) + { + if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, + DCOMP_AOA_Host_NextInterfaceBulkEndpoint) != DESCRIPTOR_SEARCH_COMP_Found) + { + return AOA_ENUMERROR_NoCompatibleInterfaceFound; + } + + USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Endpoint_t); + + if ((EndpointData->EndpointAddress & ENDPOINT_DIR_MASK) == ENDPOINT_DIR_IN) + DataINEndpoint = EndpointData; + else + DataOUTEndpoint = EndpointData; + } + + AOAInterfaceInfo->Config.DataINPipe.Size = le16_to_cpu(DataINEndpoint->EndpointSize); + AOAInterfaceInfo->Config.DataINPipe.EndpointAddress = DataINEndpoint->EndpointAddress; + AOAInterfaceInfo->Config.DataINPipe.Type = EP_TYPE_BULK; + + AOAInterfaceInfo->Config.DataOUTPipe.Size = le16_to_cpu(DataOUTEndpoint->EndpointSize); + AOAInterfaceInfo->Config.DataOUTPipe.EndpointAddress = DataOUTEndpoint->EndpointAddress; + AOAInterfaceInfo->Config.DataOUTPipe.Type = EP_TYPE_BULK; + + if (!(Pipe_ConfigurePipeTable(&AOAInterfaceInfo->Config.DataINPipe, 1))) + return false; + + if (!(Pipe_ConfigurePipeTable(&AOAInterfaceInfo->Config.DataOUTPipe, 1))) + return false; + + AOAInterfaceInfo->State.IsActive = true; + AOAInterfaceInfo->State.InterfaceNumber = AOAInterface->InterfaceNumber; + + return AOA_ENUMERROR_NoError; +} + +static uint8_t DCOMP_AOA_Host_NextAndroidAccessoryInterface(void* const CurrentDescriptor) +{ + USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t); + + if (Header->Type == DTYPE_Interface) + { + USB_Descriptor_Interface_t* Interface = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Interface_t); + + if ((Interface->Class == AOA_CSCP_AOADataClass) && + (Interface->SubClass == AOA_CSCP_AOADataSubclass) && + (Interface->Protocol == AOA_CSCP_AOADataProtocol)) + { + return DESCRIPTOR_SEARCH_Found; + } + } + + return DESCRIPTOR_SEARCH_NotFound; +} + +static uint8_t DCOMP_AOA_Host_NextInterfaceBulkEndpoint(void* const CurrentDescriptor) +{ + USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t); + + if (Header->Type == DTYPE_Endpoint) + { + USB_Descriptor_Endpoint_t* Endpoint = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Endpoint_t); + + uint8_t EndpointType = (Endpoint->Attributes & EP_TYPE_MASK); + + if ((EndpointType == EP_TYPE_BULK) && (!(Pipe_IsEndpointBound(Endpoint->EndpointAddress)))) + return DESCRIPTOR_SEARCH_Found; + } + else if (Header->Type == DTYPE_Interface) + { + return DESCRIPTOR_SEARCH_Fail; + } + + return DESCRIPTOR_SEARCH_NotFound; +} + +void AOA_Host_USBTask(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo) +{ + if ((USB_HostState != HOST_STATE_Configured) || !(AOAInterfaceInfo->State.IsActive)) + return; + + #if !defined(NO_CLASS_DRIVER_AUTOFLUSH) + AOA_Host_Flush(AOAInterfaceInfo); + #endif +} + +uint8_t AOA_Host_StartAccessoryMode(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo) +{ + uint8_t ErrorCode; + + uint16_t AccessoryProtocol; + if ((ErrorCode = AOA_Host_GetAccessoryProtocol(&AccessoryProtocol)) != HOST_WAITERROR_Successful) + return ErrorCode; + + if (AccessoryProtocol != CPU_TO_LE16(AOA_PROTOCOL_AccessoryV1)) + return AOA_ERROR_LOGICAL_CMD_FAILED; + + for (uint8_t PropertyIndex = 0; PropertyIndex < AOA_STRING_TOTAL_STRINGS; PropertyIndex++) + { + if ((ErrorCode = AOA_Host_SendPropertyString(AOAInterfaceInfo, PropertyIndex)) != HOST_WAITERROR_Successful) + return ErrorCode; + } + + USB_ControlRequest = (USB_Request_Header_t) + { + .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_VENDOR | REQREC_DEVICE), + .bRequest = AOA_REQ_StartAccessoryMode, + .wValue = 0, + .wIndex = 0, + .wLength = 0, + }; + + Pipe_SelectPipe(PIPE_CONTROLPIPE); + return USB_Host_SendControlRequest(NULL); +} + +static uint8_t AOA_Host_GetAccessoryProtocol(uint16_t* const Protocol) +{ + USB_ControlRequest = (USB_Request_Header_t) + { + .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_VENDOR | REQREC_DEVICE), + .bRequest = AOA_REQ_GetAccessoryProtocol, + .wValue = 0, + .wIndex = 0, + .wLength = sizeof(uint16_t), + }; + + Pipe_SelectPipe(PIPE_CONTROLPIPE); + return USB_Host_SendControlRequest(Protocol); +} + +static uint8_t AOA_Host_SendPropertyString(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, + const uint8_t StringIndex) +{ + const char* String = AOAInterfaceInfo->Config.PropertyStrings[StringIndex]; + + if (String == NULL) + String = ""; + + USB_ControlRequest = (USB_Request_Header_t) + { + .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_VENDOR | REQREC_DEVICE), + .bRequest = AOA_REQ_SendString, + .wValue = 0, + .wIndex = StringIndex, + .wLength = (strlen(String) + 1), + }; + + Pipe_SelectPipe(PIPE_CONTROLPIPE); + return USB_Host_SendControlRequest((char*)String); +} + +uint8_t AOA_Host_SendData(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, + const uint8_t* const Buffer, + const uint16_t Length) +{ + if ((USB_HostState != HOST_STATE_Configured) || !(AOAInterfaceInfo->State.IsActive)) + return PIPE_READYWAIT_DeviceDisconnected; + + uint8_t ErrorCode; + + Pipe_SelectPipe(AOAInterfaceInfo->Config.DataOUTPipe.Address); + + Pipe_Unfreeze(); + ErrorCode = Pipe_Write_Stream_LE(Buffer, Length, NULL); + Pipe_Freeze(); + + return ErrorCode; +} + +uint8_t AOA_Host_SendString(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, + const char* const String) +{ + if ((USB_HostState != HOST_STATE_Configured) || !(AOAInterfaceInfo->State.IsActive)) + return PIPE_READYWAIT_DeviceDisconnected; + + uint8_t ErrorCode; + + Pipe_SelectPipe(AOAInterfaceInfo->Config.DataOUTPipe.Address); + + Pipe_Unfreeze(); + ErrorCode = Pipe_Write_Stream_LE(String, strlen(String), NULL); + Pipe_Freeze(); + + return ErrorCode; +} + +uint8_t AOA_Host_SendByte(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, + const uint8_t Data) +{ + if ((USB_HostState != HOST_STATE_Configured) || !(AOAInterfaceInfo->State.IsActive)) + return PIPE_READYWAIT_DeviceDisconnected; + + uint8_t ErrorCode; + + Pipe_SelectPipe(AOAInterfaceInfo->Config.DataOUTPipe.Address); + Pipe_Unfreeze(); + + if (!(Pipe_IsReadWriteAllowed())) + { + Pipe_ClearOUT(); + + if ((ErrorCode = Pipe_WaitUntilReady()) != PIPE_READYWAIT_NoError) + return ErrorCode; + } + + Pipe_Write_8(Data); + Pipe_Freeze(); + + return PIPE_READYWAIT_NoError; +} + +uint16_t AOA_Host_BytesReceived(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo) +{ + if ((USB_HostState != HOST_STATE_Configured) || !(AOAInterfaceInfo->State.IsActive)) + return 0; + + Pipe_SelectPipe(AOAInterfaceInfo->Config.DataINPipe.Address); + Pipe_Unfreeze(); + + if (Pipe_IsINReceived()) + { + if (!(Pipe_BytesInPipe())) + { + Pipe_ClearIN(); + Pipe_Freeze(); + return 0; + } + else + { + Pipe_Freeze(); + return Pipe_BytesInPipe(); + } + } + else + { + Pipe_Freeze(); + + return 0; + } +} + +int16_t AOA_Host_ReceiveByte(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo) +{ + if ((USB_HostState != HOST_STATE_Configured) || !(AOAInterfaceInfo->State.IsActive)) + return -1; + + int16_t ReceivedByte = -1; + + Pipe_SelectPipe(AOAInterfaceInfo->Config.DataINPipe.Address); + Pipe_Unfreeze(); + + if (Pipe_IsINReceived()) + { + if (Pipe_BytesInPipe()) + ReceivedByte = Pipe_Read_8(); + + if (!(Pipe_BytesInPipe())) + Pipe_ClearIN(); + } + + Pipe_Freeze(); + + return ReceivedByte; +} + +uint8_t AOA_Host_Flush(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo) +{ + if ((USB_HostState != HOST_STATE_Configured) || !(AOAInterfaceInfo->State.IsActive)) + return PIPE_READYWAIT_DeviceDisconnected; + + uint8_t ErrorCode; + + Pipe_SelectPipe(AOAInterfaceInfo->Config.DataOUTPipe.Address); + Pipe_Unfreeze(); + + if (!(Pipe_BytesInPipe())) + return PIPE_READYWAIT_NoError; + + bool BankFull = !(Pipe_IsReadWriteAllowed()); + + Pipe_ClearOUT(); + + if (BankFull) + { + if ((ErrorCode = Pipe_WaitUntilReady()) != PIPE_READYWAIT_NoError) + return ErrorCode; + + Pipe_ClearOUT(); + } + + Pipe_Freeze(); + + return PIPE_READYWAIT_NoError; +} + +#if defined(FDEV_SETUP_STREAM) +void AOA_Host_CreateStream(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, + FILE* const Stream) +{ + *Stream = (FILE)FDEV_SETUP_STREAM(AOA_Host_putchar, AOA_Host_getchar, _FDEV_SETUP_RW); + fdev_set_udata(Stream, AOAInterfaceInfo); +} + +void AOA_Host_CreateBlockingStream(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, + FILE* const Stream) +{ + *Stream = (FILE)FDEV_SETUP_STREAM(AOA_Host_putchar, AOA_Host_getchar_Blocking, _FDEV_SETUP_RW); + fdev_set_udata(Stream, AOAInterfaceInfo); +} + +static int AOA_Host_putchar(char c, + FILE* Stream) +{ + return AOA_Host_SendByte((USB_ClassInfo_AOA_Host_t*)fdev_get_udata(Stream), c) ? _FDEV_ERR : 0; +} + +static int AOA_Host_getchar(FILE* Stream) +{ + int16_t ReceivedByte = AOA_Host_ReceiveByte((USB_ClassInfo_AOA_Host_t*)fdev_get_udata(Stream)); + + if (ReceivedByte < 0) + return _FDEV_EOF; + + return ReceivedByte; +} + +static int AOA_Host_getchar_Blocking(FILE* Stream) +{ + int16_t ReceivedByte; + + while ((ReceivedByte = AOA_Host_ReceiveByte((USB_ClassInfo_AOA_Host_t*)fdev_get_udata(Stream))) < 0) + { + if (USB_HostState == HOST_STATE_Unattached) + return _FDEV_EOF; + + AOA_Host_USBTask((USB_ClassInfo_AOA_Host_t*)fdev_get_udata(Stream)); + USB_USBTask(); + } + + return ReceivedByte; +} +#endif + +#endif + + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/AndroidAccessoryClassHost.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/AndroidAccessoryClassHost.h new file mode 100644 index 00000000..f55cd340 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/AndroidAccessoryClassHost.h @@ -0,0 +1,314 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Host mode driver for the library USB Android Open Accessory Class driver. + * + * Host mode driver for the library USB Android Open Accessory Class driver. + * + * \note This file should not be included directly. It is automatically included as needed by the USB module driver + * dispatch header located in LUFA/Drivers/USB.h. + */ + +/** \ingroup Group_USBClassAOA + * \defgroup Group_USBClassAndroidAccessoryHost Android Open Accessory Class Host Mode Driver + * + * \section Sec_Dependencies Module Source Dependencies + * The following files must be built with any user project that uses this module: + * - LUFA/Drivers/USB/Class/Host/AndroidAccessoryClassHost.c (Makefile source module name: LUFA_SRC_USBCLASS) + * + * \section Sec_ModDescription Module Description + * Host Mode USB Class driver framework interface, for the Android Open Accessory USB Class driver. + * + * @{ + */ + +#ifndef __AOA_CLASS_HOST_H__ +#define __AOA_CLASS_HOST_H__ + + /* Includes: */ + #include "../../USB.h" + #include "../Common/AndroidAccessoryClassCommon.h" + + #include + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_AOA_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Error code for some Android Open Accessory Host functions, indicating a logical (and not hardware) error. */ + #define AOA_ERROR_LOGICAL_CMD_FAILED 0x80 + + /* Type Defines: */ + /** \brief Android Open Accessory Class Host Mode Configuration and State Structure. + * + * Class state structure. An instance of this structure should be made within the user application, + * and passed to each of the Android Open Accessory class driver functions as the \c AOAInterfaceInfo + * parameter. This stores each Android Open Accessory interface's configuration and state information. + */ + typedef struct + { + struct + { + USB_Pipe_Table_t DataINPipe; /**< Data IN Pipe configuration table. */ + USB_Pipe_Table_t DataOUTPipe; /**< Data OUT Pipe configuration table. */ + + char* PropertyStrings[AOA_STRING_TOTAL_STRINGS]; /**< Android Accessory property strings, sent to identify the accessory when the + * Android device is switched into Open Accessory mode. */ + } Config; /**< Config data for the USB class interface within the device. All elements in this section + * must be set or the interface will fail to enumerate and operate correctly. + */ + struct + { + bool IsActive; /**< Indicates if the current interface instance is connected to an attached device, valid + * after \ref AOA_Host_ConfigurePipes() is called and the Host state machine is in the + * Configured state. + */ + uint8_t InterfaceNumber; /**< Interface index of the AOA interface within the attached device. */ + } State; /**< State data for the USB class interface within the device. All elements in this section + * may be set to initial values, but may also be ignored to default to sane values when + * the interface is enumerated. + */ + } USB_ClassInfo_AOA_Host_t; + + /* Enums: */ + /** Enum for the possible error codes returned by the \ref AOA_Host_ConfigurePipes() function. */ + enum AOA_Host_EnumerationFailure_ErrorCodes_t + { + AOA_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully. */ + AOA_ENUMERROR_InvalidConfigDescriptor = 1, /**< The device returned an invalid Configuration Descriptor. */ + AOA_ENUMERROR_NoCompatibleInterfaceFound = 2, /**< A compatible Android Open Accessory interface was not found in the device's Configuration Descriptor. */ + AOA_ENUMERROR_PipeConfigurationFailed = 3, /**< One or more pipes for the specified interface could not be configured correctly. */ + }; + + /* Function Prototypes: */ + /** General management task for a given Android Open Accessory host class interface, required for the correct operation of the interface. + * This should be called frequently in the main program loop, before the master USB management task \ref USB_USBTask(). + * + * \param[in,out] AOAInterfaceInfo Pointer to a structure containing an Android Open Accessory Class host configuration and state. + */ + void AOA_Host_USBTask(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + /** Validates a device descriptor, to check if the device is a valid Android device, and if it is currently in Android Open Accessory mode. + * + * \param[in,out] AOAInterfaceInfo Pointer to a structure containing an AOA Class host configuration and state. + * \param[in] DeviceDescriptor Pointer a buffer containing the attached device's Device Descriptor. + * \param[out] NeedModeSwitch Pointer to a boolean where the mode switch requirement of the attached device is to be stored. + * + * \return Boolean \c true if the attached device is a valid Android device, \c false otherwise. + */ + bool AOA_Host_ValidateAccessoryDevice(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, + const USB_Descriptor_Device_t* const DeviceDescriptor, + bool* const NeedModeSwitch) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2) ATTR_NON_NULL_PTR_ARG(3); + + /** Host interface configuration routine, to configure a given Android Open Accessory host interface instance using the Configuration + * Descriptor read from an attached USB device. This function automatically updates the given Android Open Accessory Host instance's + * state values and configures the pipes required to communicate with the interface if it is found within the device. This should be + * called once after the stack has enumerated the attached device, while the host state machine is in the Addressed state. + * + * \param[in,out] AOAInterfaceInfo Pointer to a structure containing an AOA Class host configuration and state. + * \param[in] ConfigDescriptorSize Length of the attached device's Configuration Descriptor. + * \param[in] ConfigDescriptorData Pointer to a buffer containing the attached device's Configuration Descriptor. + * + * \return A value from the \ref AOA_Host_EnumerationFailure_ErrorCodes_t enum. + */ + uint8_t AOA_Host_ConfigurePipes(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, + uint16_t ConfigDescriptorSize, + void* ConfigDescriptorData) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3); + + /** Starts Accessory Mode in the attached Android device. This function will validate the device's Android Open Accessory protocol + * version, send the configured property strings, and request a switch to Android Open Accessory mode. + * + * \param[in,out] AOAInterfaceInfo Pointer to a structure containing an AOA Class host configuration and state. + * + * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum, or \ref AOA_ERROR_LOGICAL_CMD_FAILED if a logical error occurred.. + */ + uint8_t AOA_Host_StartAccessoryMode(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + /** Sends a given data buffer to the attached USB device, if connected. If a device is not connected when the function is + * called, the data will be discarded. Bytes will be queued for transmission to the device until either the pipe bank + * becomes full, or the \ref AOA_Host_Flush() function is called to flush the pending data to the device. This allows for + * multiple bytes to be packed into a single pipe packet, increasing data throughput. + * + * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the + * call will fail. + * + * \param[in,out] AOAInterfaceInfo Pointer to a structure containing a AOA Class host configuration and state. + * \param[in] Buffer Pointer to a buffer containing the data to send to the device. + * \param[in] Length Length of the data to send to the device. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. + */ + uint8_t AOA_Host_SendData(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, + const uint8_t* const Buffer, + const uint16_t Length); + + /** Sends a given null-terminated string to the attached USB device, if connected. If a device is not connected when the + * function is called, the string is discarded. Bytes will be queued for transmission to the device until either the pipe + * bank becomes full, or the \ref AOA_Host_Flush() function is called to flush the pending data to the device. This allows + * for multiple bytes to be packed into a single pipe packet, increasing data throughput. + * + * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the + * call will fail. + * + * \param[in,out] AOAInterfaceInfo Pointer to a structure containing a AOA Class host configuration and state. + * \param[in] String Pointer to the null terminated string to send to the device. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. + */ + uint8_t AOA_Host_SendString(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, + const char* const String) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); + + /** Sends a given byte to the attached USB device, if connected. If a device is not connected when the function is called, the + * byte is discarded. Bytes will be queued for transmission to the device until either the pipe bank becomes full, or the + * \ref AOA_Host_Flush() function is called to flush the pending data to the host. This allows for multiple bytes to be + * packed into a single pipe packet, increasing data throughput. + * + * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the + * call will fail. + * + * \param[in,out] AOAInterfaceInfo Pointer to a structure containing a AOA Class host configuration and state. + * \param[in] Data Byte of data to send to the device. + * + * \return A value from the \ref Pipe_WaitUntilReady_ErrorCodes_t enum. + */ + uint8_t AOA_Host_SendByte(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, + const uint8_t Data) ATTR_NON_NULL_PTR_ARG(1); + + /** Determines the number of bytes received by the AOA interface from the device, waiting to be read. This indicates the number + * of bytes in the IN pipe bank only, and thus the number of calls to \ref AOA_Host_ReceiveByte() which are guaranteed to succeed + * immediately. If multiple bytes are to be received, they should be buffered by the user application, as the pipe bank will not be + * released back to the USB controller until all bytes are read. + * + * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the + * call will fail. + * + * \param[in,out] AOAInterfaceInfo Pointer to a structure containing a AOA Class host configuration and state. + * + * \return Total number of buffered bytes received from the device. + */ + uint16_t AOA_Host_BytesReceived(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + /** Reads a byte of data from the device. If no data is waiting to be read of if a USB device is not connected, the function + * returns a negative value. The \ref AOA_Host_BytesReceived() function may be queried in advance to determine how many bytes + * are currently buffered in the AOA interface's data receive pipe. + * + * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the + * call will fail. + * + * \param[in,out] AOAInterfaceInfo Pointer to a structure containing a AOA Class host configuration and state. + * + * \return Next received byte from the device, or a negative value if no data received. + */ + int16_t AOA_Host_ReceiveByte(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + /** Flushes any data waiting to be sent, ensuring that the send buffer is cleared. + * + * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the + * call will fail. + * + * \param[in,out] AOAInterfaceInfo Pointer to a structure containing a AOA Class host configuration and state. + * + * \return A value from the \ref Pipe_WaitUntilReady_ErrorCodes_t enum. + */ + uint8_t AOA_Host_Flush(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + /** Creates a standard character stream for the given AOA Device instance so that it can be used with all the regular + * functions in the standard \c library that accept a \c FILE stream as a destination (e.g. \c fprintf). The created + * stream is bidirectional and can be used for both input and output functions. + * + * Reading data from this stream is non-blocking, i.e. in most instances, complete strings cannot be read in by a single + * fetch, as the endpoint will not be ready at some point in the transmission, aborting the transfer. However, this may + * be used when the read data is processed byte-per-bye (via \c getc()) or when the user application will implement its own + * line buffering. + * + * \note The created stream can be given as \c stdout if desired to direct the standard output from all \c functions + * to the given AOA interface. + * \n\n + * + * \note This function is not available on all microcontroller architectures. + * + * \param[in,out] AOAInterfaceInfo Pointer to a structure containing a AOA Class configuration and state. + * \param[in,out] Stream Pointer to a FILE structure where the created stream should be placed. + */ + void AOA_Host_CreateStream(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, + FILE* const Stream); + + /** Identical to \ref AOA_Host_CreateStream(), except that reads are blocking until the calling stream function terminates + * the transfer. While blocking, the USB and AOA service tasks are called repeatedly to maintain USB communications. + * + * \note This function is not available on all microcontroller architectures. + * + * \param[in,out] AOAInterfaceInfo Pointer to a structure containing a AOA Class configuration and state. + * \param[in,out] Stream Pointer to a FILE structure where the created stream should be placed. + */ + void AOA_Host_CreateBlockingStream(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, + FILE* const Stream); + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Function Prototypes: */ + #if defined(__INCLUDE_FROM_ANDROIDACCESSORY_HOST_C) + #if defined(FDEV_SETUP_STREAM) + static int AOA_Host_putchar(char c, + FILE* Stream) ATTR_NON_NULL_PTR_ARG(2); + static int AOA_Host_getchar(FILE* Stream) ATTR_NON_NULL_PTR_ARG(1); + static int AOA_Host_getchar_Blocking(FILE* Stream) ATTR_NON_NULL_PTR_ARG(1); + #endif + + static uint8_t AOA_Host_GetAccessoryProtocol(uint16_t* const Protocol) ATTR_NON_NULL_PTR_ARG(1); + static uint8_t AOA_Host_SendPropertyString(USB_ClassInfo_AOA_Host_t* const AOAInterfaceInfo, + const uint8_t StringIndex) ATTR_NON_NULL_PTR_ARG(1); + + static uint8_t DCOMP_AOA_Host_NextAndroidAccessoryInterface(void* const CurrentDescriptor) + ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1); + static uint8_t DCOMP_AOA_Host_NextInterfaceBulkEndpoint(void* const CurrentDescriptor) + ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1); + #endif + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/AudioClassHost.c b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/AudioClassHost.c new file mode 100644 index 00000000..1e869e83 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/AudioClassHost.c @@ -0,0 +1,223 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#define __INCLUDE_FROM_USB_DRIVER +#include "../../Core/USBMode.h" + +#if defined(USB_CAN_BE_HOST) + +#define __INCLUDE_FROM_AUDIO_DRIVER +#define __INCLUDE_FROM_AUDIO_HOST_C +#include "AudioClassHost.h" + +uint8_t Audio_Host_ConfigurePipes(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo, + uint16_t ConfigDescriptorSize, + void* ConfigDescriptorData) +{ + USB_Descriptor_Endpoint_t* DataINEndpoint = NULL; + USB_Descriptor_Endpoint_t* DataOUTEndpoint = NULL; + USB_Descriptor_Interface_t* AudioControlInterface = NULL; + USB_Descriptor_Interface_t* AudioStreamingInterface = NULL; + + memset(&AudioInterfaceInfo->State, 0x00, sizeof(AudioInterfaceInfo->State)); + + if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration) + return AUDIO_ENUMERROR_InvalidConfigDescriptor; + + while ((AudioInterfaceInfo->Config.DataINPipe.Address && !(DataINEndpoint)) || + (AudioInterfaceInfo->Config.DataOUTPipe.Address && !(DataOUTEndpoint))) + { + if (!(AudioControlInterface) || + USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, + DCOMP_Audio_Host_NextAudioInterfaceDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found) + { + if (!(AudioControlInterface) || + USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, + DCOMP_Audio_Host_NextAudioStreamInterface) != DESCRIPTOR_SEARCH_COMP_Found) + { + if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, + DCOMP_Audio_Host_NextAudioControlInterface) != DESCRIPTOR_SEARCH_COMP_Found) + { + return AUDIO_ENUMERROR_NoCompatibleInterfaceFound; + } + + AudioControlInterface = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Interface_t); + + if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, + DCOMP_Audio_Host_NextAudioStreamInterface) != DESCRIPTOR_SEARCH_COMP_Found) + { + return AUDIO_ENUMERROR_NoCompatibleInterfaceFound; + } + } + + AudioStreamingInterface = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Interface_t); + + DataINEndpoint = NULL; + DataOUTEndpoint = NULL; + + continue; + } + + USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Endpoint_t); + + if ((EndpointData->EndpointAddress & ENDPOINT_DIR_MASK) == ENDPOINT_DIR_IN) + DataINEndpoint = EndpointData; + else + DataOUTEndpoint = EndpointData; + } + + AudioInterfaceInfo->Config.DataINPipe.Size = le16_to_cpu(DataINEndpoint->EndpointSize); + AudioInterfaceInfo->Config.DataINPipe.EndpointAddress = DataINEndpoint->EndpointAddress; + AudioInterfaceInfo->Config.DataINPipe.Type = EP_TYPE_ISOCHRONOUS; + AudioInterfaceInfo->Config.DataINPipe.Banks = 2; + + AudioInterfaceInfo->Config.DataOUTPipe.Size = le16_to_cpu(DataOUTEndpoint->EndpointSize); + AudioInterfaceInfo->Config.DataOUTPipe.EndpointAddress = DataOUTEndpoint->EndpointAddress; + AudioInterfaceInfo->Config.DataOUTPipe.Type = EP_TYPE_ISOCHRONOUS; + AudioInterfaceInfo->Config.DataOUTPipe.Banks = 2; + + if (!(Pipe_ConfigurePipeTable(&AudioInterfaceInfo->Config.DataINPipe, 1))) + return false; + + if (!(Pipe_ConfigurePipeTable(&AudioInterfaceInfo->Config.DataOUTPipe, 1))) + return false; + + AudioInterfaceInfo->State.ControlInterfaceNumber = AudioControlInterface->InterfaceNumber; + AudioInterfaceInfo->State.StreamingInterfaceNumber = AudioStreamingInterface->InterfaceNumber; + AudioInterfaceInfo->State.EnabledStreamingAltIndex = AudioStreamingInterface->AlternateSetting; + AudioInterfaceInfo->State.IsActive = true; + + return AUDIO_ENUMERROR_NoError; +} + +static uint8_t DCOMP_Audio_Host_NextAudioControlInterface(void* CurrentDescriptor) +{ + USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t); + + if (Header->Type == DTYPE_Interface) + { + USB_Descriptor_Interface_t* Interface = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Interface_t); + + if ((Interface->Class == AUDIO_CSCP_AudioClass) && + (Interface->SubClass == AUDIO_CSCP_ControlSubclass) && + (Interface->Protocol == AUDIO_CSCP_ControlProtocol)) + { + return DESCRIPTOR_SEARCH_Found; + } + } + + return DESCRIPTOR_SEARCH_NotFound; +} + +static uint8_t DCOMP_Audio_Host_NextAudioStreamInterface(void* CurrentDescriptor) +{ + USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t); + + if (Header->Type == DTYPE_Interface) + { + USB_Descriptor_Interface_t* Interface = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Interface_t); + + if ((Interface->Class == AUDIO_CSCP_AudioClass) && + (Interface->SubClass == AUDIO_CSCP_AudioStreamingSubclass) && + (Interface->Protocol == AUDIO_CSCP_StreamingProtocol)) + { + return DESCRIPTOR_SEARCH_Found; + } + } + + return DESCRIPTOR_SEARCH_NotFound; +} + +static uint8_t DCOMP_Audio_Host_NextAudioInterfaceDataEndpoint(void* CurrentDescriptor) +{ + USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t); + + if (Header->Type == DTYPE_Endpoint) + { + USB_Descriptor_Endpoint_t* Endpoint = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Endpoint_t); + + if ((Endpoint->Attributes & EP_TYPE_MASK) == EP_TYPE_ISOCHRONOUS) + return DESCRIPTOR_SEARCH_Found; + } + else if (Header->Type == DTYPE_Interface) + { + return DESCRIPTOR_SEARCH_Fail; + } + + return DESCRIPTOR_SEARCH_NotFound; +} + +uint8_t Audio_Host_StartStopStreaming(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo, + const bool EnableStreaming) +{ + if (!(AudioInterfaceInfo->State.IsActive)) + return HOST_SENDCONTROL_DeviceDisconnected; + + return USB_Host_SetInterfaceAltSetting(AudioInterfaceInfo->State.StreamingInterfaceNumber, + EnableStreaming ? AudioInterfaceInfo->State.EnabledStreamingAltIndex : 0); +} + +uint8_t Audio_Host_GetSetEndpointProperty(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo, + const uint8_t DataPipeIndex, + const uint8_t EndpointProperty, + const uint8_t EndpointControl, + const uint16_t DataLength, + void* const Data) +{ + if (!(AudioInterfaceInfo->State.IsActive)) + return HOST_SENDCONTROL_DeviceDisconnected; + + uint8_t RequestType; + uint8_t EndpointAddress; + + if (EndpointProperty & 0x80) + RequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_ENDPOINT); + else + RequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_ENDPOINT); + + Pipe_SelectPipe(DataPipeIndex); + EndpointAddress = Pipe_GetBoundEndpointAddress(); + + USB_ControlRequest = (USB_Request_Header_t) + { + .bmRequestType = RequestType, + .bRequest = EndpointProperty, + .wValue = ((uint16_t)EndpointControl << 8), + .wIndex = EndpointAddress, + .wLength = DataLength, + }; + + Pipe_SelectPipe(PIPE_CONTROLPIPE); + + return USB_Host_SendControlRequest(Data); +} + +#endif + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/AudioClassHost.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/AudioClassHost.h new file mode 100644 index 00000000..6cb78a62 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/AudioClassHost.h @@ -0,0 +1,411 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Host mode driver for the library USB Audio 1.0 Class driver. + * + * Host mode driver for the library USB Audio 1.0 Class driver. + * + * \note This file should not be included directly. It is automatically included as needed by the USB module driver + * dispatch header located in LUFA/Drivers/USB.h. + */ + +/** \ingroup Group_USBClassAudio + * \defgroup Group_USBClassAudioHost Audio 1.0 Class Host Mode Driver + * + * \section Sec_Dependencies Module Source Dependencies + * The following files must be built with any user project that uses this module: + * - LUFA/Drivers/USB/Class/Host/AudioClassHost.c (Makefile source module name: LUFA_SRC_USBCLASS) + * + * \section Sec_ModDescription Module Description + * Host Mode USB Class driver framework interface, for the Audio 1.0 USB Class driver. + * + * @{ + */ + +#ifndef __AUDIO_CLASS_HOST_H__ +#define __AUDIO_CLASS_HOST_H__ + + /* Includes: */ + #include "../../USB.h" + #include "../Common/AudioClassCommon.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_AUDIO_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Type Defines: */ + /** \brief Audio Class Host Mode Configuration and State Structure. + * + * Class state structure. An instance of this structure should be made within the user application, + * and passed to each of the Audio class driver functions as the \c AudioInterfaceInfo parameter. This + * stores each Audio interface's configuration and state information. + */ + typedef struct + { + struct + { + USB_Pipe_Table_t DataINPipe; /**< Data IN Pipe configuration table. */ + USB_Pipe_Table_t DataOUTPipe; /**< Data OUT Pipe configuration table. */ + } Config; /**< Config data for the USB class interface within the device. All elements in this section + * must be set or the interface will fail to enumerate and operate correctly. + */ + struct + { + bool IsActive; /**< Indicates if the current interface instance is connected to an attached device, valid + * after \ref Audio_Host_ConfigurePipes() is called and the Host state machine is in the + * Configured state. + */ + uint8_t ControlInterfaceNumber; /**< Interface index of the Audio Control interface within the attached device. */ + uint8_t StreamingInterfaceNumber; /**< Interface index of the Audio Streaming interface within the attached device. */ + + uint8_t EnabledStreamingAltIndex; /**< Alternative setting index of the Audio Streaming interface when the stream is enabled. */ + } State; /**< State data for the USB class interface within the device. All elements in this section + * may be set to initial values, but may also be ignored to default to sane values when + * the interface is enumerated. + */ + } USB_ClassInfo_Audio_Host_t; + + /* Enums: */ + /** Enum for the possible error codes returned by the \ref Audio_Host_ConfigurePipes() function. */ + enum AUDIO_Host_EnumerationFailure_ErrorCodes_t + { + AUDIO_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully. */ + AUDIO_ENUMERROR_InvalidConfigDescriptor = 1, /**< The device returned an invalid Configuration Descriptor. */ + AUDIO_ENUMERROR_NoCompatibleInterfaceFound = 2, /**< A compatible AUDIO interface was not found in the device's Configuration Descriptor. */ + AUDIO_ENUMERROR_PipeConfigurationFailed = 3, /**< One or more pipes for the specified interface could not be configured correctly. */ + }; + + /* Function Prototypes: */ + /** Host interface configuration routine, to configure a given Audio host interface instance using the Configuration + * Descriptor read from an attached USB device. This function automatically updates the given Audio Host instance's + * state values and configures the pipes required to communicate with the interface if it is found within the + * device. This should be called once after the stack has enumerated the attached device, while the host state + * machine is in the Addressed state. + * + * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class host configuration and state. + * \param[in] ConfigDescriptorSize Length of the attached device's Configuration Descriptor. + * \param[in] ConfigDescriptorData Pointer to a buffer containing the attached device's Configuration Descriptor. + * + * \return A value from the \ref AUDIO_Host_EnumerationFailure_ErrorCodes_t enum. + */ + uint8_t Audio_Host_ConfigurePipes(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo, + uint16_t ConfigDescriptorSize, + void* ConfigDescriptorData) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3); + + /** Starts or stops the audio streaming for the given configured Audio Host interface, allowing for audio samples to be + * send and/or received. + * + * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class host configuration and state. + * \param[in] EnableStreaming Boolean true to enable streaming of the specified interface, false to disable + * + * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum. + */ + uint8_t Audio_Host_StartStopStreaming(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo, + const bool EnableStreaming) ATTR_NON_NULL_PTR_ARG(1); + + /** Gets or sets the specified property of a streaming audio class endpoint that is bound to a pipe in the given + * class instance. + * + * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class host configuration and state. + * \param[in] DataPipeIndex Index of the data pipe whose bound endpoint is to be altered. + * \param[in] EndpointProperty Property of the endpoint to get or set, a value from \ref Audio_ClassRequests_t. + * \param[in] EndpointControl Parameter of the endpoint to get or set, a value from \ref Audio_EndpointControls_t. + * \param[in,out] DataLength For SET operations, the length of the parameter data to set. For GET operations, the maximum + * length of the retrieved data. + * \param[in,out] Data Pointer to a location where the parameter data is stored for SET operations, or where + * the retrieved data is to be stored for GET operations. + * + * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum. + */ + uint8_t Audio_Host_GetSetEndpointProperty(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo, + const uint8_t DataPipeIndex, + const uint8_t EndpointProperty, + const uint8_t EndpointControl, + const uint16_t DataLength, + void* const Data) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(6); + + /* Inline Functions: */ + /** General management task for a given Audio host class interface, required for the correct operation of + * the interface. This should be called frequently in the main program loop, before the master USB management task + * \ref USB_USBTask(). + * + * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class host configuration and state. + */ + static inline void Audio_Host_USBTask(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo) + ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE; + static inline void Audio_Host_USBTask(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo) + { + (void)AudioInterfaceInfo; + } + + /** Determines if the given audio interface is ready for a sample to be read from it, and selects the streaming + * IN pipe ready for reading. + * + * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or + * the call will fail. + * + * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state. + * + * \return Boolean \c true if the given Audio interface has a sample to be read, \c false otherwise. + */ + static inline bool Audio_Host_IsSampleReceived(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo) + ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE; + static inline bool Audio_Host_IsSampleReceived(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo) + { + if ((USB_HostState != HOST_STATE_Configured) || !(AudioInterfaceInfo->State.IsActive)) + return false; + + bool SampleReceived = false; + + Pipe_SelectPipe(AudioInterfaceInfo->Config.DataINPipe.Address); + Pipe_Unfreeze(); + SampleReceived = Pipe_IsINReceived(); + Pipe_Freeze(); + + return SampleReceived; + } + + /** Determines if the given audio interface is ready to accept the next sample to be written to it, and selects + * the streaming OUT pipe ready for writing. + * + * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or + * the call will fail. + * + * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state. + * + * \return Boolean \c true if the given Audio interface is ready to accept the next sample, \c false otherwise. + */ + static inline bool Audio_Host_IsReadyForNextSample(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo) + ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE; + static inline bool Audio_Host_IsReadyForNextSample(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo) + { + if ((USB_HostState != HOST_STATE_Configured) || !(AudioInterfaceInfo->State.IsActive)) + return false; + + Pipe_SelectPipe(AudioInterfaceInfo->Config.DataOUTPipe.Address); + return Pipe_IsOUTReady(); + } + + /** Reads the next 8-bit audio sample from the current audio interface. + * + * \pre This should be preceded immediately by a call to the \ref Audio_Host_IsSampleReceived() function to ensure + * that the correct pipe is selected and ready for data. + * + * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state. + * + * \return Signed 8-bit audio sample from the audio interface. + */ + static inline int8_t Audio_Host_ReadSample8(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo) + ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE; + static inline int8_t Audio_Host_ReadSample8(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo) + { + int8_t Sample; + + (void)AudioInterfaceInfo; + + Sample = Pipe_Read_8(); + + if (!(Pipe_BytesInPipe())) + { + Pipe_Unfreeze(); + Pipe_ClearIN(); + Pipe_Freeze(); + } + + return Sample; + } + + /** Reads the next 16-bit audio sample from the current audio interface. + * + * \pre This should be preceded immediately by a call to the \ref Audio_Host_IsSampleReceived() function to ensure + * that the correct pipe is selected and ready for data. + * + * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state. + * + * \return Signed 16-bit audio sample from the audio interface. + */ + static inline int16_t Audio_Host_ReadSample16(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo) + ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE; + static inline int16_t Audio_Host_ReadSample16(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo) + { + int16_t Sample; + + (void)AudioInterfaceInfo; + + Sample = (int16_t)Pipe_Read_16_LE(); + + if (!(Pipe_BytesInPipe())) + { + Pipe_Unfreeze(); + Pipe_ClearIN(); + Pipe_Freeze(); + } + + return Sample; + } + + /** Reads the next 24-bit audio sample from the current audio interface. + * + * \pre This should be preceded immediately by a call to the \ref Audio_Host_IsSampleReceived() function to ensure + * that the correct pipe is selected and ready for data. + * + * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state. + * + * \return Signed 24-bit audio sample from the audio interface. + */ + static inline int32_t Audio_Host_ReadSample24(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo) + ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE; + static inline int32_t Audio_Host_ReadSample24(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo) + { + int32_t Sample; + + (void)AudioInterfaceInfo; + + Sample = (((uint32_t)Pipe_Read_8() << 16) | Pipe_Read_16_LE()); + + if (!(Pipe_BytesInPipe())) + { + Pipe_Unfreeze(); + Pipe_ClearIN(); + Pipe_Freeze(); + } + + return Sample; + } + + /** Writes the next 8-bit audio sample to the current audio interface. + * + * \pre This should be preceded immediately by a call to the \ref Audio_Host_IsReadyForNextSample() function to + * ensure that the correct pipe is selected and ready for data. + * + * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state. + * \param[in] Sample Signed 8-bit audio sample. + */ + static inline void Audio_Host_WriteSample8(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo, + const int8_t Sample) ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE; + static inline void Audio_Host_WriteSample8(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo, + const int8_t Sample) + { + (void)AudioInterfaceInfo; + + Pipe_Write_8(Sample); + + if (!(Pipe_IsReadWriteAllowed())) + { + Pipe_Unfreeze(); + Pipe_ClearOUT(); + Pipe_WaitUntilReady(); + Pipe_Freeze(); + } + } + + /** Writes the next 16-bit audio sample to the current audio interface. + * + * \pre This should be preceded immediately by a call to the \ref Audio_Host_IsReadyForNextSample() function to + * ensure that the correct pipe is selected and ready for data. + * + * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state. + * \param[in] Sample Signed 16-bit audio sample. + */ + static inline void Audio_Host_WriteSample16(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo, + const int16_t Sample) ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE; + static inline void Audio_Host_WriteSample16(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo, + const int16_t Sample) + { + (void)AudioInterfaceInfo; + + Pipe_Write_16_LE(Sample); + + if (!(Pipe_IsReadWriteAllowed())) + { + Pipe_Unfreeze(); + Pipe_ClearOUT(); + Pipe_WaitUntilReady(); + Pipe_Freeze(); + } + } + + /** Writes the next 24-bit audio sample to the current audio interface. + * + * \pre This should be preceded immediately by a call to the \ref Audio_Host_IsReadyForNextSample() function to + * ensure that the correct pipe is selected and ready for data. + * + * \param[in,out] AudioInterfaceInfo Pointer to a structure containing an Audio Class configuration and state. + * \param[in] Sample Signed 24-bit audio sample. + */ + static inline void Audio_Host_WriteSample24(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo, + const int32_t Sample) ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE; + static inline void Audio_Host_WriteSample24(USB_ClassInfo_Audio_Host_t* const AudioInterfaceInfo, + const int32_t Sample) + { + (void)AudioInterfaceInfo; + + Pipe_Write_16_LE(Sample); + Pipe_Write_8(Sample >> 16); + + if (!(Pipe_IsReadWriteAllowed())) + { + Pipe_Unfreeze(); + Pipe_ClearOUT(); + Pipe_WaitUntilReady(); + Pipe_Freeze(); + } + } + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Function Prototypes: */ + #if defined(__INCLUDE_FROM_AUDIO_HOST_C) + static uint8_t DCOMP_Audio_Host_NextAudioControlInterface(void* CurrentDescriptor) + ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1); + static uint8_t DCOMP_Audio_Host_NextAudioStreamInterface(void* CurrentDescriptor) + ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1); + static uint8_t DCOMP_Audio_Host_NextAudioInterfaceDataEndpoint(void* CurrentDescriptor) + ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1); + #endif + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/CDCClassHost.c b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/CDCClassHost.c new file mode 100644 index 00000000..dd48da1d --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/CDCClassHost.c @@ -0,0 +1,478 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#define __INCLUDE_FROM_USB_DRIVER +#include "../../Core/USBMode.h" + +#if defined(USB_CAN_BE_HOST) + +#define __INCLUDE_FROM_CDC_DRIVER +#define __INCLUDE_FROM_CDC_HOST_C +#include "CDCClassHost.h" + +uint8_t CDC_Host_ConfigurePipes(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, + uint16_t ConfigDescriptorSize, + void* ConfigDescriptorData) +{ + USB_Descriptor_Endpoint_t* DataINEndpoint = NULL; + USB_Descriptor_Endpoint_t* DataOUTEndpoint = NULL; + USB_Descriptor_Endpoint_t* NotificationEndpoint = NULL; + USB_Descriptor_Interface_t* CDCControlInterface = NULL; + + memset(&CDCInterfaceInfo->State, 0x00, sizeof(CDCInterfaceInfo->State)); + + if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration) + return CDC_ENUMERROR_InvalidConfigDescriptor; + + while (!(DataINEndpoint) || !(DataOUTEndpoint) || !(NotificationEndpoint)) + { + if (!(CDCControlInterface) || + USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, + DCOMP_CDC_Host_NextCDCInterfaceEndpoint) != DESCRIPTOR_SEARCH_COMP_Found) + { + if (NotificationEndpoint) + { + if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, + DCOMP_CDC_Host_NextCDCDataInterface) != DESCRIPTOR_SEARCH_COMP_Found) + { + return CDC_ENUMERROR_NoCompatibleInterfaceFound; + } + + DataINEndpoint = NULL; + DataOUTEndpoint = NULL; + } + else + { + if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, + DCOMP_CDC_Host_NextCDCControlInterface) != DESCRIPTOR_SEARCH_COMP_Found) + { + return CDC_ENUMERROR_NoCompatibleInterfaceFound; + } + + CDCControlInterface = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Interface_t); + + NotificationEndpoint = NULL; + } + + continue; + } + + USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Endpoint_t); + + if ((EndpointData->EndpointAddress & ENDPOINT_DIR_MASK) == ENDPOINT_DIR_IN) + { + if ((EndpointData->Attributes & EP_TYPE_MASK) == EP_TYPE_INTERRUPT) + NotificationEndpoint = EndpointData; + else + DataINEndpoint = EndpointData; + } + else + { + DataOUTEndpoint = EndpointData; + } + } + + CDCInterfaceInfo->Config.DataINPipe.Size = le16_to_cpu(DataINEndpoint->EndpointSize); + CDCInterfaceInfo->Config.DataINPipe.EndpointAddress = DataINEndpoint->EndpointAddress; + CDCInterfaceInfo->Config.DataINPipe.Type = EP_TYPE_BULK; + + CDCInterfaceInfo->Config.DataOUTPipe.Size = le16_to_cpu(DataOUTEndpoint->EndpointSize); + CDCInterfaceInfo->Config.DataOUTPipe.EndpointAddress = DataOUTEndpoint->EndpointAddress; + CDCInterfaceInfo->Config.DataOUTPipe.Type = EP_TYPE_BULK; + + CDCInterfaceInfo->Config.NotificationPipe.Size = le16_to_cpu(NotificationEndpoint->EndpointSize); + CDCInterfaceInfo->Config.NotificationPipe.EndpointAddress = NotificationEndpoint->EndpointAddress; + CDCInterfaceInfo->Config.NotificationPipe.Type = EP_TYPE_INTERRUPT; + + if (!(Pipe_ConfigurePipeTable(&CDCInterfaceInfo->Config.DataINPipe, 1))) + return false; + + if (!(Pipe_ConfigurePipeTable(&CDCInterfaceInfo->Config.DataOUTPipe, 1))) + return false; + + if (!(Pipe_ConfigurePipeTable(&CDCInterfaceInfo->Config.NotificationPipe, 1))) + return false; + + CDCInterfaceInfo->State.ControlInterfaceNumber = CDCControlInterface->InterfaceNumber; + CDCInterfaceInfo->State.ControlLineStates.HostToDevice = (CDC_CONTROL_LINE_OUT_RTS | CDC_CONTROL_LINE_OUT_DTR); + CDCInterfaceInfo->State.ControlLineStates.DeviceToHost = (CDC_CONTROL_LINE_IN_DCD | CDC_CONTROL_LINE_IN_DSR); + CDCInterfaceInfo->State.IsActive = true; + + return CDC_ENUMERROR_NoError; +} + +static uint8_t DCOMP_CDC_Host_NextCDCControlInterface(void* const CurrentDescriptor) +{ + USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t); + + if (Header->Type == DTYPE_Interface) + { + USB_Descriptor_Interface_t* Interface = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Interface_t); + + if ((Interface->Class == CDC_CSCP_CDCClass) && + (Interface->SubClass == CDC_CSCP_ACMSubclass) && + (Interface->Protocol == CDC_CSCP_ATCommandProtocol)) + { + return DESCRIPTOR_SEARCH_Found; + } + } + + return DESCRIPTOR_SEARCH_NotFound; +} + +static uint8_t DCOMP_CDC_Host_NextCDCDataInterface(void* const CurrentDescriptor) +{ + USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t); + + if (Header->Type == DTYPE_Interface) + { + USB_Descriptor_Interface_t* Interface = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Interface_t); + + if ((Interface->Class == CDC_CSCP_CDCDataClass) && + (Interface->SubClass == CDC_CSCP_NoDataSubclass) && + (Interface->Protocol == CDC_CSCP_NoDataProtocol)) + { + return DESCRIPTOR_SEARCH_Found; + } + } + + return DESCRIPTOR_SEARCH_NotFound; +} + +static uint8_t DCOMP_CDC_Host_NextCDCInterfaceEndpoint(void* const CurrentDescriptor) +{ + USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t); + + if (Header->Type == DTYPE_Endpoint) + { + USB_Descriptor_Endpoint_t* Endpoint = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Endpoint_t); + + uint8_t EndpointType = (Endpoint->Attributes & EP_TYPE_MASK); + + if (((EndpointType == EP_TYPE_BULK) || (EndpointType == EP_TYPE_INTERRUPT)) && + !(Pipe_IsEndpointBound(Endpoint->EndpointAddress))) + { + return DESCRIPTOR_SEARCH_Found; + } + } + else if (Header->Type == DTYPE_Interface) + { + return DESCRIPTOR_SEARCH_Fail; + } + + return DESCRIPTOR_SEARCH_NotFound; +} + +void CDC_Host_USBTask(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo) +{ + if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.IsActive)) + return; + + Pipe_SelectPipe(CDCInterfaceInfo->Config.NotificationPipe.Address); + Pipe_Unfreeze(); + + if (Pipe_IsINReceived()) + { + USB_Request_Header_t Notification; + Pipe_Read_Stream_LE(&Notification, sizeof(USB_Request_Header_t), NULL); + + if ((Notification.bRequest == CDC_NOTIF_SerialState) && + (Notification.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))) + { + Pipe_Read_Stream_LE(&CDCInterfaceInfo->State.ControlLineStates.DeviceToHost, + sizeof(CDCInterfaceInfo->State.ControlLineStates.DeviceToHost), + NULL); + + Pipe_ClearIN(); + + EVENT_CDC_Host_ControLineStateChanged(CDCInterfaceInfo); + } + else + { + Pipe_ClearIN(); + } + } + + Pipe_Freeze(); + + #if !defined(NO_CLASS_DRIVER_AUTOFLUSH) + CDC_Host_Flush(CDCInterfaceInfo); + #endif +} + +uint8_t CDC_Host_SetLineEncoding(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo) +{ + USB_ControlRequest = (USB_Request_Header_t) + { + .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE), + .bRequest = CDC_REQ_SetLineEncoding, + .wValue = 0, + .wIndex = CDCInterfaceInfo->State.ControlInterfaceNumber, + .wLength = sizeof(CDCInterfaceInfo->State.LineEncoding), + }; + + Pipe_SelectPipe(PIPE_CONTROLPIPE); + + return USB_Host_SendControlRequest(&CDCInterfaceInfo->State.LineEncoding); +} + +uint8_t CDC_Host_SendControlLineStateChange(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo) +{ + USB_ControlRequest = (USB_Request_Header_t) + { + .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE), + .bRequest = CDC_REQ_SetControlLineState, + .wValue = CDCInterfaceInfo->State.ControlLineStates.HostToDevice, + .wIndex = CDCInterfaceInfo->State.ControlInterfaceNumber, + .wLength = 0, + }; + + Pipe_SelectPipe(PIPE_CONTROLPIPE); + + return USB_Host_SendControlRequest(NULL); +} + +uint8_t CDC_Host_SendBreak(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, + const uint8_t Duration) +{ + USB_ControlRequest = (USB_Request_Header_t) + { + .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE), + .bRequest = CDC_REQ_SendBreak, + .wValue = Duration, + .wIndex = CDCInterfaceInfo->State.ControlInterfaceNumber, + .wLength = 0, + }; + + Pipe_SelectPipe(PIPE_CONTROLPIPE); + + return USB_Host_SendControlRequest(NULL); +} + +uint8_t CDC_Host_SendData(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, + const uint8_t* const Buffer, + const uint16_t Length) +{ + if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.IsActive)) + return PIPE_READYWAIT_DeviceDisconnected; + + uint8_t ErrorCode; + + Pipe_SelectPipe(CDCInterfaceInfo->Config.DataOUTPipe.Address); + + Pipe_Unfreeze(); + ErrorCode = Pipe_Write_Stream_LE(Buffer, Length, NULL); + Pipe_Freeze(); + + return ErrorCode; +} + +uint8_t CDC_Host_SendString(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, + const char* const String) +{ + if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.IsActive)) + return PIPE_READYWAIT_DeviceDisconnected; + + uint8_t ErrorCode; + + Pipe_SelectPipe(CDCInterfaceInfo->Config.DataOUTPipe.Address); + + Pipe_Unfreeze(); + ErrorCode = Pipe_Write_Stream_LE(String, strlen(String), NULL); + Pipe_Freeze(); + + return ErrorCode; +} + +uint8_t CDC_Host_SendByte(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, + const uint8_t Data) +{ + if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.IsActive)) + return PIPE_READYWAIT_DeviceDisconnected; + + uint8_t ErrorCode; + + Pipe_SelectPipe(CDCInterfaceInfo->Config.DataOUTPipe.Address); + Pipe_Unfreeze(); + + if (!(Pipe_IsReadWriteAllowed())) + { + Pipe_ClearOUT(); + + if ((ErrorCode = Pipe_WaitUntilReady()) != PIPE_READYWAIT_NoError) + return ErrorCode; + } + + Pipe_Write_8(Data); + Pipe_Freeze(); + + return PIPE_READYWAIT_NoError; +} + +uint16_t CDC_Host_BytesReceived(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo) +{ + if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.IsActive)) + return 0; + + Pipe_SelectPipe(CDCInterfaceInfo->Config.DataINPipe.Address); + Pipe_Unfreeze(); + + if (Pipe_IsINReceived()) + { + if (!(Pipe_BytesInPipe())) + { + Pipe_ClearIN(); + Pipe_Freeze(); + return 0; + } + else + { + Pipe_Freeze(); + return Pipe_BytesInPipe(); + } + } + else + { + Pipe_Freeze(); + + return 0; + } +} + +int16_t CDC_Host_ReceiveByte(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo) +{ + if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.IsActive)) + return -1; + + int16_t ReceivedByte = -1; + + Pipe_SelectPipe(CDCInterfaceInfo->Config.DataINPipe.Address); + Pipe_Unfreeze(); + + if (Pipe_IsINReceived()) + { + if (Pipe_BytesInPipe()) + ReceivedByte = Pipe_Read_8(); + + if (!(Pipe_BytesInPipe())) + Pipe_ClearIN(); + } + + Pipe_Freeze(); + + return ReceivedByte; +} + +uint8_t CDC_Host_Flush(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo) +{ + if ((USB_HostState != HOST_STATE_Configured) || !(CDCInterfaceInfo->State.IsActive)) + return PIPE_READYWAIT_DeviceDisconnected; + + uint8_t ErrorCode; + + Pipe_SelectPipe(CDCInterfaceInfo->Config.DataOUTPipe.Address); + Pipe_Unfreeze(); + + if (!(Pipe_BytesInPipe())) + return PIPE_READYWAIT_NoError; + + bool BankFull = !(Pipe_IsReadWriteAllowed()); + + Pipe_ClearOUT(); + + if (BankFull) + { + if ((ErrorCode = Pipe_WaitUntilReady()) != PIPE_READYWAIT_NoError) + return ErrorCode; + + Pipe_ClearOUT(); + } + + Pipe_Freeze(); + + return PIPE_READYWAIT_NoError; +} + +#if defined(FDEV_SETUP_STREAM) +void CDC_Host_CreateStream(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, + FILE* const Stream) +{ + *Stream = (FILE)FDEV_SETUP_STREAM(CDC_Host_putchar, CDC_Host_getchar, _FDEV_SETUP_RW); + fdev_set_udata(Stream, CDCInterfaceInfo); +} + +void CDC_Host_CreateBlockingStream(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, + FILE* const Stream) +{ + *Stream = (FILE)FDEV_SETUP_STREAM(CDC_Host_putchar, CDC_Host_getchar_Blocking, _FDEV_SETUP_RW); + fdev_set_udata(Stream, CDCInterfaceInfo); +} + +static int CDC_Host_putchar(char c, + FILE* Stream) +{ + return CDC_Host_SendByte((USB_ClassInfo_CDC_Host_t*)fdev_get_udata(Stream), c) ? _FDEV_ERR : 0; +} + +static int CDC_Host_getchar(FILE* Stream) +{ + int16_t ReceivedByte = CDC_Host_ReceiveByte((USB_ClassInfo_CDC_Host_t*)fdev_get_udata(Stream)); + + if (ReceivedByte < 0) + return _FDEV_EOF; + + return ReceivedByte; +} + +static int CDC_Host_getchar_Blocking(FILE* Stream) +{ + int16_t ReceivedByte; + + while ((ReceivedByte = CDC_Host_ReceiveByte((USB_ClassInfo_CDC_Host_t*)fdev_get_udata(Stream))) < 0) + { + if (USB_HostState == HOST_STATE_Unattached) + return _FDEV_EOF; + + CDC_Host_USBTask((USB_ClassInfo_CDC_Host_t*)fdev_get_udata(Stream)); + USB_USBTask(); + } + + return ReceivedByte; +} +#endif + +// cppcheck-suppress unusedFunction +void CDC_Host_Event_Stub(void) +{ + +} + +#endif + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/CDCClassHost.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/CDCClassHost.h new file mode 100644 index 00000000..f5faab93 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/CDCClassHost.h @@ -0,0 +1,351 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Host mode driver for the library USB CDC Class driver. + * + * Host mode driver for the library USB CDC Class driver. + * + * \note This file should not be included directly. It is automatically included as needed by the USB module driver + * dispatch header located in LUFA/Drivers/USB.h. + */ + +/** \ingroup Group_USBClassCDC + * \defgroup Group_USBClassCDCHost CDC Class Host Mode Driver + * + * \section Sec_Dependencies Module Source Dependencies + * The following files must be built with any user project that uses this module: + * - LUFA/Drivers/USB/Class/Host/CDCClassHost.c (Makefile source module name: LUFA_SRC_USBCLASS) + * + * \section Sec_ModDescription Module Description + * Host Mode USB Class driver framework interface, for the CDC USB Class driver. + * + * @{ + */ + +#ifndef __CDC_CLASS_HOST_H__ +#define __CDC_CLASS_HOST_H__ + + /* Includes: */ + #include "../../USB.h" + #include "../Common/CDCClassCommon.h" + + #include + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_CDC_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Type Defines: */ + /** \brief CDC Class Host Mode Configuration and State Structure. + * + * Class state structure. An instance of this structure should be made within the user application, + * and passed to each of the CDC class driver functions as the \c CDCInterfaceInfo parameter. This + * stores each CDC interface's configuration and state information. + */ + typedef struct + { + struct + { + USB_Pipe_Table_t DataINPipe; /**< Data IN Pipe configuration table. */ + USB_Pipe_Table_t DataOUTPipe; /**< Data OUT Pipe configuration table. */ + USB_Pipe_Table_t NotificationPipe; /**< Notification IN Pipe configuration table. */ + } Config; /**< Config data for the USB class interface within the device. All elements in this section + * must be set or the interface will fail to enumerate and operate correctly. + */ + struct + { + bool IsActive; /**< Indicates if the current interface instance is connected to an attached device, valid + * after \ref CDC_Host_ConfigurePipes() is called and the Host state machine is in the + * Configured state. + */ + uint8_t ControlInterfaceNumber; /**< Interface index of the CDC-ACM control interface within the attached device. */ + + struct + { + uint16_t HostToDevice; /**< Control line states from the host to device, as a set of \c CDC_CONTROL_LINE_OUT_* + * masks - to notify the device of changes to these values, call the + * \ref CDC_Host_SendControlLineStateChange() function. + */ + uint16_t DeviceToHost; /**< Control line states from the device to host, as a set of \c CDC_CONTROL_LINE_IN_* + * masks. This value is updated each time \ref CDC_Host_USBTask() is called. + */ + } ControlLineStates; /**< Current states of the virtual serial port's control lines between the device and host. */ + + CDC_LineEncoding_t LineEncoding; /**< Line encoding used in the virtual serial port, for the device's information. + * This is generally only used if the virtual serial port data is to be + * reconstructed on a physical UART. When set by the host application, the + * \ref CDC_Host_SetLineEncoding() function must be called to push the changes + * to the device. + */ + } State; /**< State data for the USB class interface within the device. All elements in this section + * may be set to initial values, but may also be ignored to default to sane values when + * the interface is enumerated. + */ + } USB_ClassInfo_CDC_Host_t; + + /* Enums: */ + /** Enum for the possible error codes returned by the \ref CDC_Host_ConfigurePipes() function. */ + enum CDC_Host_EnumerationFailure_ErrorCodes_t + { + CDC_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully. */ + CDC_ENUMERROR_InvalidConfigDescriptor = 1, /**< The device returned an invalid Configuration Descriptor. */ + CDC_ENUMERROR_NoCompatibleInterfaceFound = 2, /**< A compatible CDC interface was not found in the device's Configuration Descriptor. */ + CDC_ENUMERROR_PipeConfigurationFailed = 3, /**< One or more pipes for the specified interface could not be configured correctly. */ + }; + + /* Function Prototypes: */ + /** General management task for a given CDC host class interface, required for the correct operation of the interface. This should + * be called frequently in the main program loop, before the master USB management task \ref USB_USBTask(). + * + * \param[in,out] CDCInterfaceInfo Pointer to a structure containing an CDC Class host configuration and state. + */ + void CDC_Host_USBTask(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + /** Host interface configuration routine, to configure a given CDC host interface instance using the Configuration + * Descriptor read from an attached USB device. This function automatically updates the given CDC Host instance's + * state values and configures the pipes required to communicate with the interface if it is found within the device. + * This should be called once after the stack has enumerated the attached device, while the host state machine is in + * the Addressed state. + * + * \param[in,out] CDCInterfaceInfo Pointer to a structure containing an CDC Class host configuration and state. + * \param[in] ConfigDescriptorSize Length of the attached device's Configuration Descriptor. + * \param[in] ConfigDescriptorData Pointer to a buffer containing the attached device's Configuration Descriptor. + * + * \return A value from the \ref CDC_Host_EnumerationFailure_ErrorCodes_t enum. + */ + uint8_t CDC_Host_ConfigurePipes(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, + uint16_t ConfigDescriptorSize, + void* ConfigDescriptorData) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3); + + /** Sets the line encoding for the attached device's virtual serial port. This should be called when the \c LineEncoding + * values of the interface have been changed to push the new settings to the USB device. + * + * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state. + * + * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum. + */ + uint8_t CDC_Host_SetLineEncoding(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + /** Sends a Serial Control Line State Change notification to the device. This should be called when the virtual serial + * control lines (DTR, RTS, etc.) have changed states. Line states persist until they are cleared via a second + * notification. This should be called each time the CDC class driver's \c ControlLineStates.HostToDevice value is updated + * to push the new states to the USB device. + * + * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state. + * + * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum. + */ + uint8_t CDC_Host_SendControlLineStateChange(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + /** Sends a Send Break request to the device. This is generally used to separate data or to indicate a special condition + * to the receiving device. + * + * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state. + * \param[in] Duration Duration of the break, in milliseconds. + * + * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum. + */ + uint8_t CDC_Host_SendBreak(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, + const uint8_t Duration) ATTR_NON_NULL_PTR_ARG(1); + + /** Sends a given data buffer to the attached USB device, if connected. If a device is not connected when the function is + * called, the data will be discarded. Bytes will be queued for transmission to the device until either the pipe bank + * becomes full, or the \ref CDC_Host_Flush() function is called to flush the pending data to the device. This allows for + * multiple bytes to be packed into a single pipe packet, increasing data throughput. + * + * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the + * call will fail. + * + * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state. + * \param[in] Buffer Pointer to a buffer containing the data to send to the device. + * \param[in] Length Length of the data to send to the device. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. + */ + uint8_t CDC_Host_SendData(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, + const uint8_t* const Buffer, + const uint16_t Length); + + /** Sends a given null-terminated string to the attached USB device, if connected. If a device is not connected when the + * function is called, the string is discarded. Bytes will be queued for transmission to the device until either the pipe + * bank becomes full, or the \ref CDC_Host_Flush() function is called to flush the pending data to the device. This allows + * for multiple bytes to be packed into a single pipe packet, increasing data throughput. + * + * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the + * call will fail. + * + * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state. + * \param[in] String Pointer to the null terminated string to send to the device. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. + */ + uint8_t CDC_Host_SendString(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, + const char* const String) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); + + /** Sends a given byte to the attached USB device, if connected. If a device is not connected when the function is called, the + * byte is discarded. Bytes will be queued for transmission to the device until either the pipe bank becomes full, or the + * \ref CDC_Host_Flush() function is called to flush the pending data to the host. This allows for multiple bytes to be + * packed into a single pipe packet, increasing data throughput. + * + * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the + * call will fail. + * + * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state. + * \param[in] Data Byte of data to send to the device. + * + * \return A value from the \ref Pipe_WaitUntilReady_ErrorCodes_t enum. + */ + uint8_t CDC_Host_SendByte(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, + const uint8_t Data) ATTR_NON_NULL_PTR_ARG(1); + + /** Determines the number of bytes received by the CDC interface from the device, waiting to be read. This indicates the number + * of bytes in the IN pipe bank only, and thus the number of calls to \ref CDC_Host_ReceiveByte() which are guaranteed to succeed + * immediately. If multiple bytes are to be received, they should be buffered by the user application, as the pipe bank will not be + * released back to the USB controller until all bytes are read. + * + * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the + * call will fail. + * + * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state. + * + * \return Total number of buffered bytes received from the device. + */ + uint16_t CDC_Host_BytesReceived(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + /** Reads a byte of data from the device. If no data is waiting to be read of if a USB device is not connected, the function + * returns a negative value. The \ref CDC_Host_BytesReceived() function may be queried in advance to determine how many bytes + * are currently buffered in the CDC interface's data receive pipe. + * + * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the + * call will fail. + * + * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state. + * + * \return Next received byte from the device, or a negative value if no data received. + */ + int16_t CDC_Host_ReceiveByte(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + /** Flushes any data waiting to be sent, ensuring that the send buffer is cleared. + * + * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the + * call will fail. + * + * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state. + * + * \return A value from the \ref Pipe_WaitUntilReady_ErrorCodes_t enum. + */ + uint8_t CDC_Host_Flush(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + #if defined(FDEV_SETUP_STREAM) || defined(__DOXYGEN__) + /** Creates a standard character stream for the given CDC Device instance so that it can be used with all the regular + * functions in the standard \c library that accept a \c FILE stream as a destination (e.g. \c fprintf). The created + * stream is bidirectional and can be used for both input and output functions. + * + * Reading data from this stream is non-blocking, i.e. in most instances, complete strings cannot be read in by a single + * fetch, as the endpoint will not be ready at some point in the transmission, aborting the transfer. However, this may + * be used when the read data is processed byte-per-bye (via \c getc()) or when the user application will implement its own + * line buffering. + * + * \note The created stream can be given as \c stdout if desired to direct the standard output from all \c functions + * to the given CDC interface. + * \n\n + * + * \note This function is not available on all microcontroller architectures. + * + * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state. + * \param[in,out] Stream Pointer to a FILE structure where the created stream should be placed. + */ + void CDC_Host_CreateStream(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, + FILE* const Stream); + + /** Identical to \ref CDC_Host_CreateStream(), except that reads are blocking until the calling stream function terminates + * the transfer. While blocking, the USB and CDC service tasks are called repeatedly to maintain USB communications. + * + * \note This function is not available on all microcontroller architectures. + * + * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class configuration and state. + * \param[in,out] Stream Pointer to a FILE structure where the created stream should be placed. + */ + void CDC_Host_CreateBlockingStream(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo, + FILE* const Stream); + #endif + + /** CDC class driver event for a control line state change on a CDC host interface. This event fires each time the device notifies + * the host of a control line state change (containing the virtual serial control line states, such as DCD) and may be hooked in the + * user program by declaring a handler function with the same name and parameters listed here. The new control line states + * are available in the \c ControlLineStates.DeviceToHost value inside the CDC host interface structure passed as a parameter, set as + * a mask of \c CDC_CONTROL_LINE_IN_* masks. + * + * \param[in,out] CDCInterfaceInfo Pointer to a structure containing a CDC Class host configuration and state. + */ + void EVENT_CDC_Host_ControLineStateChanged(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Function Prototypes: */ + #if defined(__INCLUDE_FROM_CDC_HOST_C) + #if defined(FDEV_SETUP_STREAM) + static int CDC_Host_putchar(char c, + FILE* Stream) ATTR_NON_NULL_PTR_ARG(2); + static int CDC_Host_getchar(FILE* Stream) ATTR_NON_NULL_PTR_ARG(1); + static int CDC_Host_getchar_Blocking(FILE* Stream) ATTR_NON_NULL_PTR_ARG(1); + #endif + + void CDC_Host_Event_Stub(void) ATTR_CONST; + + void EVENT_CDC_Host_ControLineStateChanged(USB_ClassInfo_CDC_Host_t* const CDCInterfaceInfo) + ATTR_WEAK ATTR_NON_NULL_PTR_ARG(1) ATTR_ALIAS(CDC_Host_Event_Stub); + + static uint8_t DCOMP_CDC_Host_NextCDCControlInterface(void* const CurrentDescriptor) + ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1); + static uint8_t DCOMP_CDC_Host_NextCDCDataInterface(void* const CurrentDescriptor) + ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1); + static uint8_t DCOMP_CDC_Host_NextCDCInterfaceEndpoint(void* const CurrentDescriptor) + ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1); + #endif + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/HIDClassHost.c b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/HIDClassHost.c new file mode 100644 index 00000000..ae2395bc --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/HIDClassHost.c @@ -0,0 +1,396 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#define __INCLUDE_FROM_USB_DRIVER +#include "../../Core/USBMode.h" + +#if defined(USB_CAN_BE_HOST) + +#define __INCLUDE_FROM_HID_DRIVER +#define __INCLUDE_FROM_HID_HOST_C +#include "HIDClassHost.h" + +uint8_t HID_Host_ConfigurePipes(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo, + uint16_t ConfigDescriptorSize, + void* ConfigDescriptorData) +{ + USB_Descriptor_Endpoint_t* DataINEndpoint = NULL; + USB_Descriptor_Endpoint_t* DataOUTEndpoint = NULL; + USB_Descriptor_Interface_t* HIDInterface = NULL; + USB_HID_Descriptor_HID_t* HIDDescriptor = NULL; + + memset(&HIDInterfaceInfo->State, 0x00, sizeof(HIDInterfaceInfo->State)); + + if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration) + return HID_ENUMERROR_InvalidConfigDescriptor; + + while (!(DataINEndpoint) || !(DataOUTEndpoint)) + { + if (!(HIDInterface) || + USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, + DCOMP_HID_Host_NextHIDInterfaceEndpoint) != DESCRIPTOR_SEARCH_COMP_Found) + { + if (DataINEndpoint || DataOUTEndpoint) + break; + + do + { + if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, + DCOMP_HID_Host_NextHIDInterface) != DESCRIPTOR_SEARCH_COMP_Found) + { + return HID_ENUMERROR_NoCompatibleInterfaceFound; + } + + HIDInterface = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Interface_t); + } while (HIDInterfaceInfo->Config.HIDInterfaceProtocol && + (HIDInterface->Protocol != HIDInterfaceInfo->Config.HIDInterfaceProtocol)); + + if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, + DCOMP_HID_Host_NextHIDDescriptor) != DESCRIPTOR_SEARCH_COMP_Found) + { + return HID_ENUMERROR_NoCompatibleInterfaceFound; + } + + HIDDescriptor = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_HID_Descriptor_HID_t); + + DataINEndpoint = NULL; + DataOUTEndpoint = NULL; + + continue; + } + + USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Endpoint_t); + + if ((EndpointData->EndpointAddress & ENDPOINT_DIR_MASK) == ENDPOINT_DIR_IN) + DataINEndpoint = EndpointData; + else + DataOUTEndpoint = EndpointData; + } + + HIDInterfaceInfo->Config.DataINPipe.Size = le16_to_cpu(DataINEndpoint->EndpointSize); + HIDInterfaceInfo->Config.DataINPipe.EndpointAddress = DataINEndpoint->EndpointAddress; + HIDInterfaceInfo->Config.DataINPipe.Type = EP_TYPE_INTERRUPT; + + HIDInterfaceInfo->Config.DataOUTPipe.Size = le16_to_cpu(DataOUTEndpoint->EndpointSize); + HIDInterfaceInfo->Config.DataOUTPipe.EndpointAddress = DataOUTEndpoint->EndpointAddress; + HIDInterfaceInfo->Config.DataOUTPipe.Type = EP_TYPE_INTERRUPT; + + if (!(Pipe_ConfigurePipeTable(&HIDInterfaceInfo->Config.DataINPipe, 1))) + return false; + + if (!(Pipe_ConfigurePipeTable(&HIDInterfaceInfo->Config.DataOUTPipe, 1))) + return false; + + HIDInterfaceInfo->State.InterfaceNumber = HIDInterface->InterfaceNumber; + HIDInterfaceInfo->State.HIDReportSize = LE16_TO_CPU(HIDDescriptor->HIDReportLength); + HIDInterfaceInfo->State.SupportsBootProtocol = (HIDInterface->SubClass != HID_CSCP_NonBootProtocol); + HIDInterfaceInfo->State.LargestReportSize = 8; + HIDInterfaceInfo->State.IsActive = true; + + return HID_ENUMERROR_NoError; +} + +static uint8_t DCOMP_HID_Host_NextHIDInterface(void* const CurrentDescriptor) +{ + USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t); + + if (Header->Type == DTYPE_Interface) + { + USB_Descriptor_Interface_t* Interface = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Interface_t); + + if (Interface->Class == HID_CSCP_HIDClass) + return DESCRIPTOR_SEARCH_Found; + } + + return DESCRIPTOR_SEARCH_NotFound; +} + +static uint8_t DCOMP_HID_Host_NextHIDDescriptor(void* const CurrentDescriptor) +{ + USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t); + + if (Header->Type == HID_DTYPE_HID) + return DESCRIPTOR_SEARCH_Found; + else if (Header->Type == DTYPE_Interface) + return DESCRIPTOR_SEARCH_Fail; + else + return DESCRIPTOR_SEARCH_NotFound; +} + +static uint8_t DCOMP_HID_Host_NextHIDInterfaceEndpoint(void* const CurrentDescriptor) +{ + USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t); + + if (Header->Type == DTYPE_Endpoint) + { + USB_Descriptor_Endpoint_t* Endpoint = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Endpoint_t); + + if (!(Pipe_IsEndpointBound(Endpoint->EndpointAddress))) + return DESCRIPTOR_SEARCH_Found; + } + else if (Header->Type == DTYPE_Interface) + { + return DESCRIPTOR_SEARCH_Fail; + } + + return DESCRIPTOR_SEARCH_NotFound; +} + +#if !defined(HID_HOST_BOOT_PROTOCOL_ONLY) +uint8_t HID_Host_ReceiveReportByID(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo, + const uint8_t ReportID, + void* Buffer) +{ + USB_ControlRequest = (USB_Request_Header_t) + { + .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE), + .bRequest = HID_REQ_SetReport, + .wValue = ((HID_REPORT_ITEM_In + 1) << 8) | ReportID, + .wIndex = HIDInterfaceInfo->State.InterfaceNumber, + .wLength = USB_GetHIDReportSize(HIDInterfaceInfo->Config.HIDParserData, ReportID, HID_REPORT_ITEM_In), + }; + + Pipe_SelectPipe(PIPE_CONTROLPIPE); + + return USB_Host_SendControlRequest(Buffer); +} +#endif + +uint8_t HID_Host_ReceiveReport(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo, + void* Buffer) +{ + if ((USB_HostState != HOST_STATE_Configured) || !(HIDInterfaceInfo->State.IsActive)) + return PIPE_READYWAIT_DeviceDisconnected; + + uint8_t ErrorCode; + + Pipe_SelectPipe(HIDInterfaceInfo->Config.DataINPipe.Address); + Pipe_Unfreeze(); + + uint16_t ReportSize; + uint8_t* BufferPos = Buffer; + +#if !defined(HID_HOST_BOOT_PROTOCOL_ONLY) + if (!(HIDInterfaceInfo->State.UsingBootProtocol)) + { + uint8_t ReportID = 0; + + if (HIDInterfaceInfo->Config.HIDParserData->UsingReportIDs) + { + ReportID = Pipe_Read_8(); + *(BufferPos++) = ReportID; + } + + ReportSize = USB_GetHIDReportSize(HIDInterfaceInfo->Config.HIDParserData, ReportID, HID_REPORT_ITEM_In); + } + else +#endif + { + ReportSize = Pipe_BytesInPipe(); + } + + if ((ErrorCode = Pipe_Read_Stream_LE(BufferPos, ReportSize, NULL)) != PIPE_RWSTREAM_NoError) + return ErrorCode; + + Pipe_ClearIN(); + Pipe_Freeze(); + + return PIPE_RWSTREAM_NoError; +} + +uint8_t HID_Host_SendReportByID(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo, +#if !defined(HID_HOST_BOOT_PROTOCOL_ONLY) + const uint8_t ReportID, +#endif + const uint8_t ReportType, + void* Buffer, + const uint16_t ReportSize) +{ +#if !defined(HID_HOST_BOOT_PROTOCOL_ONLY) + if ((USB_HostState != HOST_STATE_Configured) || !(HIDInterfaceInfo->State.IsActive)) + return false; + + if (HIDInterfaceInfo->State.DeviceUsesOUTPipe && (ReportType == HID_REPORT_ITEM_Out)) + { + uint8_t ErrorCode; + + Pipe_SelectPipe(HIDInterfaceInfo->Config.DataOUTPipe.Address); + Pipe_Unfreeze(); + + if (ReportID) + Pipe_Write_Stream_LE(&ReportID, sizeof(ReportID), NULL); + + if ((ErrorCode = Pipe_Write_Stream_LE(Buffer, ReportSize, NULL)) != PIPE_RWSTREAM_NoError) + return ErrorCode; + + Pipe_ClearOUT(); + Pipe_Freeze(); + + return PIPE_RWSTREAM_NoError; + } + else +#endif + { + USB_ControlRequest = (USB_Request_Header_t) + { + .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE), + .bRequest = HID_REQ_SetReport, +#if !defined(HID_HOST_BOOT_PROTOCOL_ONLY) + .wValue = ((ReportType + 1) << 8) | ReportID, +#else + .wValue = ((ReportType + 1) << 8), +#endif + .wIndex = HIDInterfaceInfo->State.InterfaceNumber, + .wLength = ReportSize, + }; + + Pipe_SelectPipe(PIPE_CONTROLPIPE); + + return USB_Host_SendControlRequest(Buffer); + } +} + +bool HID_Host_IsReportReceived(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo) +{ + if ((USB_HostState != HOST_STATE_Configured) || !(HIDInterfaceInfo->State.IsActive)) + return false; + + bool ReportReceived; + + Pipe_SelectPipe(HIDInterfaceInfo->Config.DataINPipe.Address); + Pipe_Unfreeze(); + + ReportReceived = Pipe_IsINReceived(); + + Pipe_Freeze(); + + return ReportReceived; +} + +uint8_t HID_Host_SetBootProtocol(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo) +{ + uint8_t ErrorCode; + + if (!(HIDInterfaceInfo->State.SupportsBootProtocol)) + return HID_ERROR_LOGICAL; + + USB_ControlRequest = (USB_Request_Header_t) + { + .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE), + .bRequest = HID_REQ_SetProtocol, + .wValue = 0, + .wIndex = HIDInterfaceInfo->State.InterfaceNumber, + .wLength = 0, + }; + + Pipe_SelectPipe(PIPE_CONTROLPIPE); + + if ((ErrorCode = USB_Host_SendControlRequest(NULL)) != HOST_SENDCONTROL_Successful) + return ErrorCode; + + HIDInterfaceInfo->State.LargestReportSize = 8; + HIDInterfaceInfo->State.UsingBootProtocol = true; + + return HOST_SENDCONTROL_Successful; +} + +uint8_t HID_Host_SetIdlePeriod(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo, + const uint16_t MS) +{ + USB_ControlRequest = (USB_Request_Header_t) + { + .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE), + .bRequest = HID_REQ_SetIdle, + .wValue = ((MS << 6) & 0xFF00), + .wIndex = HIDInterfaceInfo->State.InterfaceNumber, + .wLength = 0, + }; + + Pipe_SelectPipe(PIPE_CONTROLPIPE); + + return USB_Host_SendControlRequest(NULL); +} + +#if !defined(HID_HOST_BOOT_PROTOCOL_ONLY) +uint8_t HID_Host_SetReportProtocol(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo) +{ + uint8_t ErrorCode; + + uint8_t HIDReportData[HIDInterfaceInfo->State.HIDReportSize]; + + USB_ControlRequest = (USB_Request_Header_t) + { + .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_INTERFACE), + .bRequest = REQ_GetDescriptor, + .wValue = (HID_DTYPE_Report << 8), + .wIndex = HIDInterfaceInfo->State.InterfaceNumber, + .wLength = HIDInterfaceInfo->State.HIDReportSize, + }; + + Pipe_SelectPipe(PIPE_CONTROLPIPE); + + if ((ErrorCode = USB_Host_SendControlRequest(HIDReportData)) != HOST_SENDCONTROL_Successful) + return ErrorCode; + + if (HIDInterfaceInfo->State.UsingBootProtocol) + { + USB_ControlRequest = (USB_Request_Header_t) + { + .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE), + .bRequest = HID_REQ_SetProtocol, + .wValue = 1, + .wIndex = HIDInterfaceInfo->State.InterfaceNumber, + .wLength = 0, + }; + + if ((ErrorCode = USB_Host_SendControlRequest(NULL)) != HOST_SENDCONTROL_Successful) + return ErrorCode; + + HIDInterfaceInfo->State.UsingBootProtocol = false; + } + + if (HIDInterfaceInfo->Config.HIDParserData == NULL) + return HID_ERROR_LOGICAL; + + if ((ErrorCode = USB_ProcessHIDReport(HIDReportData, HIDInterfaceInfo->State.HIDReportSize, + HIDInterfaceInfo->Config.HIDParserData)) != HID_PARSE_Successful) + { + return HID_ERROR_LOGICAL | ErrorCode; + } + + uint16_t LargestReportSizeBits = HIDInterfaceInfo->Config.HIDParserData->LargestReportSizeBits; + HIDInterfaceInfo->State.LargestReportSize = (LargestReportSizeBits >> 3) + ((LargestReportSizeBits & 0x07) != 0); + + return 0; +} +#endif + +#endif + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/HIDClassHost.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/HIDClassHost.h new file mode 100644 index 00000000..5d617b92 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/HIDClassHost.h @@ -0,0 +1,313 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Host mode driver for the library USB HID Class driver. + * + * Host mode driver for the library USB HID Class driver. + * + * \note This file should not be included directly. It is automatically included as needed by the USB module driver + * dispatch header located in LUFA/Drivers/USB.h. + */ + +/** \ingroup Group_USBClassHID + * \defgroup Group_USBClassHIDHost HID Class Host Mode Driver + * + * \section Sec_Dependencies Module Source Dependencies + * The following files must be built with any user project that uses this module: + * - LUFA/Drivers/USB/Class/Host/HIDClassHost.c (Makefile source module name: LUFA_SRC_USBCLASS) + * + * \section Sec_ModDescription Module Description + * Host Mode USB Class driver framework interface, for the HID USB Class driver. + * + * @{ + */ + +#ifndef __HID_CLASS_HOST_H__ +#define __HID_CLASS_HOST_H__ + + /* Includes: */ + #include "../../USB.h" + #include "../Common/HIDClassCommon.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_HID_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Error code for some HID Host functions, indicating a logical (and not hardware) error. */ + #define HID_ERROR_LOGICAL 0x80 + + /* Type Defines: */ + /** \brief HID Class Host Mode Configuration and State Structure. + * + * Class state structure. An instance of this structure should be made within the user application, + * and passed to each of the HID class driver functions as the \c HIDInterfaceInfo parameter. This + * stores each HID interface's configuration and state information. + */ + typedef struct + { + struct + { + USB_Pipe_Table_t DataINPipe; /**< Data IN Pipe configuration table. */ + USB_Pipe_Table_t DataOUTPipe; /**< Data OUT Pipe configuration table. */ + + uint8_t HIDInterfaceProtocol; /**< HID interface protocol value to match against if a specific + * boot subclass protocol is required, a protocol value from the + * \ref HID_Descriptor_ClassSubclassProtocol_t enum. + */ + #if !defined(HID_HOST_BOOT_PROTOCOL_ONLY) + HID_ReportInfo_t* HIDParserData; /**< HID parser data to store the parsed HID report data, when boot protocol + * is not used. + * + * \note When the \c HID_HOST_BOOT_PROTOCOL_ONLY compile time token is defined, + * this method is unavailable. + */ + #endif + } Config; /**< Config data for the USB class interface within the device. All elements in this section + * must be set or the interface will fail to enumerate and operate correctly. + */ + struct + { + bool IsActive; /**< Indicates if the current interface instance is connected to an attached device, valid + * after \ref HID_Host_ConfigurePipes() is called and the Host state machine is in the + * Configured state. + */ + uint8_t InterfaceNumber; /**< Interface index of the HID interface within the attached device. */ + + bool SupportsBootProtocol; /**< Indicates if the current interface instance supports the HID Boot + * Protocol when enabled via \ref HID_Host_SetBootProtocol(). + */ + bool DeviceUsesOUTPipe; /**< Indicates if the current interface instance uses a separate OUT data pipe for + * OUT reports, or if OUT reports are sent via the control pipe instead. + */ + bool UsingBootProtocol; /**< Indicates that the interface is currently initialized in Boot Protocol mode */ + uint16_t HIDReportSize; /**< Size in bytes of the HID report descriptor in the device. */ + + uint8_t LargestReportSize; /**< Largest report the device will send, in bytes. */ + } State; /**< State data for the USB class interface within the device. All elements in this section + * may be set to initial values, but may also be ignored to default to sane values when + * the interface is enumerated. + */ + } USB_ClassInfo_HID_Host_t; + + /* Enums: */ + /** Enum for the possible error codes returned by the \ref HID_Host_ConfigurePipes() function. */ + enum HID_Host_EnumerationFailure_ErrorCodes_t + { + HID_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully. */ + HID_ENUMERROR_InvalidConfigDescriptor = 1, /**< The device returned an invalid Configuration Descriptor. */ + HID_ENUMERROR_NoCompatibleInterfaceFound = 2, /**< A compatible HID interface was not found in the device's Configuration Descriptor. */ + HID_ENUMERROR_PipeConfigurationFailed = 3, /**< One or more pipes for the specified interface could not be configured correctly. */ + }; + + /* Function Prototypes: */ + /** Host interface configuration routine, to configure a given HID host interface instance using the Configuration + * Descriptor read from an attached USB device. This function automatically updates the given HID Host instance's + * state values and configures the pipes required to communicate with the interface if it is found within the + * device. This should be called once after the stack has enumerated the attached device, while the host state + * machine is in the Addressed state. + * + * \attention Once the device pipes are configured, the HID device's reporting protocol must be set via a call + * to either the \ref HID_Host_SetBootProtocol() or \ref HID_Host_SetReportProtocol() function. + * + * \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class host configuration and state. + * \param[in] ConfigDescriptorSize Length of the attached device's Configuration Descriptor. + * \param[in] ConfigDescriptorData Pointer to a buffer containing the attached device's Configuration Descriptor. + * + * \return A value from the \ref HID_Host_EnumerationFailure_ErrorCodes_t enum. + */ + uint8_t HID_Host_ConfigurePipes(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo, + uint16_t ConfigDescriptorSize, + void* ConfigDescriptorData) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3); + + + /** Receives a HID IN report from the attached HID device, when a report has been received on the HID IN Data pipe. + * + * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the + * call will fail. + * + * \attention The destination buffer should be large enough to accommodate the largest report that the attached device + * can generate. + * + * \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class host configuration and state. + * \param[in] Buffer Buffer to store the received report into. + * + * \return An error code from the \ref Pipe_Stream_RW_ErrorCodes_t enum. + */ + uint8_t HID_Host_ReceiveReport(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo, + void* Buffer) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); + + #if !defined(HID_HOST_BOOT_PROTOCOL_ONLY) + /** Receives a HID IN report from the attached device, by the report ID. + * + * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the + * call will fail. + * + * \note When the \c HID_HOST_BOOT_PROTOCOL_ONLY compile time token is defined, this method is unavailable. + * + * \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class host configuration and state. + * \param[in] ReportID Report ID of the received report if ControlRequest is false, set by the to the Report ID to fetch. + * \param[in] Buffer Buffer to store the received report into. + * + * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum. + */ + uint8_t HID_Host_ReceiveReportByID(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo, + const uint8_t ReportID, + void* Buffer) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3); + #endif + + /** Sends an OUT or FEATURE report to the currently attached HID device, using the device's OUT pipe if available, + * or the device's Control pipe if not. + * + * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the + * call will fail. + * + * \note When the \c HID_HOST_BOOT_PROTOCOL_ONLY compile time token is defined, the ReportID parameter is removed + * from the parameter list of this function. + * + * \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class host configuration and state. + * \param[in] ReportID Report ID of the report to send to the device, or 0 if the device does not use report IDs. + * \param[in] ReportType Type of report to issue to the device, either \ref HID_REPORT_ITEM_Out or \ref HID_REPORT_ITEM_Feature. + * \param[in] Buffer Buffer containing the report to send to the attached device. + * \param[in] ReportSize Report size in bytes to send to the attached device. + * + * \return An error code from the \ref USB_Host_SendControlErrorCodes_t enum if the DeviceUsesOUTPipe flag is set in + * the interface's state structure, a value from the \ref Pipe_Stream_RW_ErrorCodes_t enum otherwise. + */ + uint8_t HID_Host_SendReportByID(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo, + #if !defined(HID_HOST_BOOT_PROTOCOL_ONLY) + const uint8_t ReportID, + #endif + const uint8_t ReportType, + void* Buffer, + const uint16_t ReportSize) ATTR_NON_NULL_PTR_ARG(1) + #if !defined(HID_HOST_BOOT_PROTOCOL_ONLY) + ATTR_NON_NULL_PTR_ARG(4); + #else + ATTR_NON_NULL_PTR_ARG(3); + #endif + + /** Determines if a HID IN report has been received from the attached device on the data IN pipe. + * + * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the + * call will fail. + * + * \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class host configuration and state. + * + * \return Boolean \c true if a report has been received, \c false otherwise. + */ + bool HID_Host_IsReportReceived(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + /** Switches the attached HID device's reporting protocol over to the Boot Report protocol mode, on supported devices. + * + * \note When the \c HID_HOST_BOOT_PROTOCOL_ONLY compile time token is defined, this method must still be called + * to explicitly place the attached device into boot protocol mode before use. + * + * \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class host configuration and state. + * + * \return \ref HID_ERROR_LOGICAL if the device does not support Boot Protocol mode, a value from the + * \ref USB_Host_SendControlErrorCodes_t enum otherwise. + */ + uint8_t HID_Host_SetBootProtocol(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + /** Sets the idle period for the attached HID device to the specified interval. The HID idle period determines the rate + * at which the device should send a report, when no state changes have occurred; i.e. on HID keyboards, this sets the + * hardware key repeat interval. + * + * \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class host configuration and state. + * \param[in] MS Idle period as a multiple of four milliseconds, zero to disable hardware repeats + * + * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum. + */ + uint8_t HID_Host_SetIdlePeriod(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo, + const uint16_t MS) ATTR_NON_NULL_PTR_ARG(1); + + #if !defined(HID_HOST_BOOT_PROTOCOL_ONLY) + /** Switches the attached HID device's reporting protocol over to the standard Report protocol mode. This also retrieves + * and parses the device's HID report descriptor, so that the size of each report can be determined in advance. + * + * \attention Whether this function is used or not, the \ref CALLBACK_HIDParser_FilterHIDReportItem() callback from the HID + * Report Parser this function references must be implemented in the user code. + * + * \note When the \c HID_HOST_BOOT_PROTOCOL_ONLY compile time token is defined, this method is unavailable. + * + * \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class host configuration and state. + * + * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum if an error occurs while retrieving the HID + * Report descriptor or the setting of the Report protocol, \ref HID_ERROR_LOGICAL if the HID interface does + * not have a valid \ref HID_ReportInfo_t structure set in its configuration, a mask of \ref HID_ERROR_LOGICAL + * and a value from the \ref HID_Parse_ErrorCodes_t otherwise. + */ + uint8_t HID_Host_SetReportProtocol(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + #endif + + /* Inline Functions: */ + /** General management task for a given Human Interface Class host class interface, required for the correct operation of + * the interface. This should be called frequently in the main program loop, before the master USB management task + * \ref USB_USBTask(). + * + * \param[in,out] HIDInterfaceInfo Pointer to a structure containing a HID Class host configuration and state. + */ + static inline void HID_Host_USBTask(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + static inline void HID_Host_USBTask(USB_ClassInfo_HID_Host_t* const HIDInterfaceInfo) + { + (void)HIDInterfaceInfo; + } + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Function Prototypes: */ + #if defined(__INCLUDE_FROM_HID_HOST_C) + static uint8_t DCOMP_HID_Host_NextHIDInterface(void* const CurrentDescriptor) + ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1); + static uint8_t DCOMP_HID_Host_NextHIDDescriptor(void* const CurrentDescriptor) + ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1); + static uint8_t DCOMP_HID_Host_NextHIDInterfaceEndpoint(void* const CurrentDescriptor) + ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1); + #endif + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/MIDIClassHost.c b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/MIDIClassHost.c new file mode 100644 index 00000000..29a6696d --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/MIDIClassHost.c @@ -0,0 +1,231 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#define __INCLUDE_FROM_USB_DRIVER +#include "../../Core/USBMode.h" + +#if defined(USB_CAN_BE_HOST) + +#define __INCLUDE_FROM_MIDI_DRIVER +#define __INCLUDE_FROM_MIDI_HOST_C +#include "MIDIClassHost.h" + +uint8_t MIDI_Host_ConfigurePipes(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo, + uint16_t ConfigDescriptorSize, + void* ConfigDescriptorData) +{ + USB_Descriptor_Endpoint_t* DataINEndpoint = NULL; + USB_Descriptor_Endpoint_t* DataOUTEndpoint = NULL; + USB_Descriptor_Interface_t* MIDIInterface = NULL; + + memset(&MIDIInterfaceInfo->State, 0x00, sizeof(MIDIInterfaceInfo->State)); + + if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration) + return MIDI_ENUMERROR_InvalidConfigDescriptor; + + while (!(DataINEndpoint) || !(DataOUTEndpoint)) + { + if (!(MIDIInterface) || + USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, + DCOMP_MIDI_Host_NextMIDIStreamingDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found) + { + if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, + DCOMP_MIDI_Host_NextMIDIStreamingInterface) != DESCRIPTOR_SEARCH_COMP_Found) + { + return MIDI_ENUMERROR_NoCompatibleInterfaceFound; + } + + MIDIInterface = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Interface_t); + + DataINEndpoint = NULL; + DataOUTEndpoint = NULL; + + continue; + } + + USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Endpoint_t); + + if ((EndpointData->EndpointAddress & ENDPOINT_DIR_MASK) == ENDPOINT_DIR_IN) + DataINEndpoint = EndpointData; + else + DataOUTEndpoint = EndpointData; + } + + MIDIInterfaceInfo->Config.DataINPipe.Size = le16_to_cpu(DataINEndpoint->EndpointSize); + MIDIInterfaceInfo->Config.DataINPipe.EndpointAddress = DataINEndpoint->EndpointAddress; + MIDIInterfaceInfo->Config.DataINPipe.Type = EP_TYPE_BULK; + + MIDIInterfaceInfo->Config.DataOUTPipe.Size = le16_to_cpu(DataOUTEndpoint->EndpointSize); + MIDIInterfaceInfo->Config.DataOUTPipe.EndpointAddress = DataOUTEndpoint->EndpointAddress; + MIDIInterfaceInfo->Config.DataOUTPipe.Type = EP_TYPE_BULK; + + if (!(Pipe_ConfigurePipeTable(&MIDIInterfaceInfo->Config.DataINPipe, 1))) + return false; + + if (!(Pipe_ConfigurePipeTable(&MIDIInterfaceInfo->Config.DataOUTPipe, 1))) + return false; + + MIDIInterfaceInfo->State.InterfaceNumber = MIDIInterface->InterfaceNumber; + MIDIInterfaceInfo->State.IsActive = true; + + return MIDI_ENUMERROR_NoError; +} + +static uint8_t DCOMP_MIDI_Host_NextMIDIStreamingInterface(void* const CurrentDescriptor) +{ + USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t); + + if (Header->Type == DTYPE_Interface) + { + USB_Descriptor_Interface_t* Interface = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Interface_t); + + if ((Interface->Class == AUDIO_CSCP_AudioClass) && + (Interface->SubClass == AUDIO_CSCP_MIDIStreamingSubclass) && + (Interface->Protocol == AUDIO_CSCP_StreamingProtocol)) + { + return DESCRIPTOR_SEARCH_Found; + } + } + + return DESCRIPTOR_SEARCH_NotFound; +} + +static uint8_t DCOMP_MIDI_Host_NextMIDIStreamingDataEndpoint(void* const CurrentDescriptor) +{ + USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t); + + if (Header->Type == DTYPE_Endpoint) + { + USB_Descriptor_Endpoint_t* Endpoint = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Endpoint_t); + + uint8_t EndpointType = (Endpoint->Attributes & EP_TYPE_MASK); + + if ((EndpointType == EP_TYPE_BULK) && !(Pipe_IsEndpointBound(Endpoint->EndpointAddress))) + return DESCRIPTOR_SEARCH_Found; + } + else if (Header->Type == DTYPE_Interface) + { + return DESCRIPTOR_SEARCH_Fail; + } + + return DESCRIPTOR_SEARCH_NotFound; +} + +void MIDI_Host_USBTask(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo) +{ + if ((USB_HostState != HOST_STATE_Configured) || !(MIDIInterfaceInfo->State.IsActive)) + return; + + #if !defined(NO_CLASS_DRIVER_AUTOFLUSH) + MIDI_Host_Flush(MIDIInterfaceInfo); + #endif +} + +uint8_t MIDI_Host_Flush(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo) +{ + if ((USB_HostState != HOST_STATE_Configured) || !(MIDIInterfaceInfo->State.IsActive)) + return PIPE_RWSTREAM_DeviceDisconnected; + + uint8_t ErrorCode; + + Pipe_SelectPipe(MIDIInterfaceInfo->Config.DataOUTPipe.Address); + Pipe_Unfreeze(); + + if (Pipe_BytesInPipe()) + { + Pipe_ClearOUT(); + + if ((ErrorCode = Pipe_WaitUntilReady()) != PIPE_READYWAIT_NoError) + { + Pipe_Freeze(); + return ErrorCode; + } + } + + Pipe_Freeze(); + + return PIPE_READYWAIT_NoError; +} + +uint8_t MIDI_Host_SendEventPacket(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo, + MIDI_EventPacket_t* const Event) +{ + if ((USB_HostState != HOST_STATE_Configured) || !(MIDIInterfaceInfo->State.IsActive)) + return HOST_SENDCONTROL_DeviceDisconnected; + + uint8_t ErrorCode; + + Pipe_SelectPipe(MIDIInterfaceInfo->Config.DataOUTPipe.Address); + Pipe_Unfreeze(); + + if ((ErrorCode = Pipe_Write_Stream_LE(Event, sizeof(MIDI_EventPacket_t), NULL)) != PIPE_RWSTREAM_NoError) + { + Pipe_Freeze(); + return ErrorCode; + } + + if (!(Pipe_IsReadWriteAllowed())) + Pipe_ClearOUT(); + + Pipe_Freeze(); + + return PIPE_RWSTREAM_NoError; +} + +bool MIDI_Host_ReceiveEventPacket(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo, + MIDI_EventPacket_t* const Event) +{ + if ((USB_HostState != HOST_STATE_Configured) || !(MIDIInterfaceInfo->State.IsActive)) + return HOST_SENDCONTROL_DeviceDisconnected; + + bool DataReady = false; + + Pipe_SelectPipe(MIDIInterfaceInfo->Config.DataINPipe.Address); + Pipe_Unfreeze(); + + if (Pipe_IsINReceived()) + { + if (Pipe_BytesInPipe()) + { + Pipe_Read_Stream_LE(Event, sizeof(MIDI_EventPacket_t), NULL); + DataReady = true; + } + + if (!(Pipe_BytesInPipe())) + Pipe_ClearIN(); + } + + Pipe_Freeze(); + + return DataReady; +} + +#endif + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/MIDIClassHost.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/MIDIClassHost.h new file mode 100644 index 00000000..15b9e4fc --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/MIDIClassHost.h @@ -0,0 +1,190 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Host mode driver for the library USB MIDI Class driver. + * + * Host mode driver for the library USB MIDI Class driver. + * + * \note This file should not be included directly. It is automatically included as needed by the USB module driver + * dispatch header located in LUFA/Drivers/USB.h. + */ + +/** \ingroup Group_USBClassMIDI + * \defgroup Group_USBClassMIDIHost MIDI Class Host Mode Driver + * + * \section Sec_Dependencies Module Source Dependencies + * The following files must be built with any user project that uses this module: + * - LUFA/Drivers/USB/Class/Host/MIDIClassHost.c (Makefile source module name: LUFA_SRC_USBCLASS) + * + * \section Sec_ModDescription Module Description + * Host Mode USB Class driver framework interface, for the MIDI USB Class driver. + * + * @{ + */ + +#ifndef __MIDI_CLASS_HOST_H__ +#define __MIDI_CLASS_HOST_H__ + + /* Includes: */ + #include "../../USB.h" + #include "../Common/MIDIClassCommon.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_MIDI_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Type Defines: */ + /** \brief MIDI Class Host Mode Configuration and State Structure. + * + * Class state structure. An instance of this structure should be made within the user application, + * and passed to each of the MIDI class driver functions as the \c MIDIInterfaceInfo parameter. This + * stores each MIDI interface's configuration and state information. + */ + typedef struct + { + struct + { + USB_Pipe_Table_t DataINPipe; /**< Data IN Pipe configuration table. */ + USB_Pipe_Table_t DataOUTPipe; /**< Data OUT Pipe configuration table. */ + } Config; /**< Config data for the USB class interface within the device. All elements in this section + * must be set or the interface will fail to enumerate and operate correctly. + */ + struct + { + bool IsActive; /**< Indicates if the current interface instance is connected to an attached device, valid + * after \ref MIDI_Host_ConfigurePipes() is called and the Host state machine is in the + * Configured state. + */ + uint8_t InterfaceNumber; /**< Interface index of the MIDI interface within the attached device. */ + } State; /**< State data for the USB class interface within the device. All elements in this section + * may be set to initial values, but may also be ignored to default to sane values when + * the interface is enumerated. + */ + } USB_ClassInfo_MIDI_Host_t; + + /* Enums: */ + /** Enum for the possible error codes returned by the \ref MIDI_Host_ConfigurePipes() function. */ + enum MIDI_Host_EnumerationFailure_ErrorCodes_t + { + MIDI_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully. */ + MIDI_ENUMERROR_InvalidConfigDescriptor = 1, /**< The device returned an invalid Configuration Descriptor. */ + MIDI_ENUMERROR_NoCompatibleInterfaceFound = 2, /**< A compatible MIDI interface was not found in the device's Configuration Descriptor. */ + MIDI_ENUMERROR_PipeConfigurationFailed = 3, /**< One or more pipes for the specified interface could not be configured correctly. */ + }; + + /* Function Prototypes: */ + /** Host interface configuration routine, to configure a given MIDI host interface instance using the Configuration + * Descriptor read from an attached USB device. This function automatically updates the given MIDI Host instance's + * state values and configures the pipes required to communicate with the interface if it is found within the device. + * This should be called once after the stack has enumerated the attached device, while the host state machine is in + * the Addressed state. + * + * \param[in,out] MIDIInterfaceInfo Pointer to a structure containing an MIDI Class host configuration and state. + * \param[in] ConfigDescriptorSize Length of the attached device's Configuration Descriptor. + * \param[in] ConfigDescriptorData Pointer to a buffer containing the attached device's Configuration Descriptor. + * + * \return A value from the \ref MIDI_Host_EnumerationFailure_ErrorCodes_t enum. + */ + uint8_t MIDI_Host_ConfigurePipes(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo, + uint16_t ConfigDescriptorSize, + void* ConfigDescriptorData) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3); + + /** General management task for a given MIDI host class interface, required for the correct operation of the interface. This should + * be called frequently in the main program loop, before the master USB management task \ref USB_USBTask(). + * + * \param[in,out] MIDIInterfaceInfo Pointer to a structure containing an MIDI Class host configuration and state. + */ + void MIDI_Host_USBTask(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + /** Sends a MIDI event packet to the device. If no device is connected, the event packet is discarded. + * + * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the + * call will fail. + * + * \param[in,out] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state. + * \param[in] Event Pointer to a populated USB_MIDI_EventPacket_t structure containing the MIDI event to send. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. + */ + uint8_t MIDI_Host_SendEventPacket(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo, + MIDI_EventPacket_t* const Event) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); + + /** Flushes the MIDI send buffer, sending any queued MIDI events to the device. This should be called to override the + * \ref MIDI_Host_SendEventPacket() function's packing behavior, to flush queued events. Events are queued into the + * pipe bank until either the pipe bank is full, or \ref MIDI_Host_Flush() is called. This allows for multiple MIDI + * events to be packed into a single pipe packet, increasing data throughput. + * + * \param[in,out] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state. + * + * \return A value from the \ref Pipe_WaitUntilReady_ErrorCodes_t enum. + */ + uint8_t MIDI_Host_Flush(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + /** Receives a MIDI event packet from the device. + * + * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the + * call will fail. + * + * \param[in,out] MIDIInterfaceInfo Pointer to a structure containing a MIDI Class configuration and state. + * \param[out] Event Pointer to a USB_MIDI_EventPacket_t structure where the received MIDI event is to be placed. + * + * \return Boolean \c true if a MIDI event packet was received, \c false otherwise. + */ + bool MIDI_Host_ReceiveEventPacket(USB_ClassInfo_MIDI_Host_t* const MIDIInterfaceInfo, + MIDI_EventPacket_t* const Event) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Function Prototypes: */ + #if defined(__INCLUDE_FROM_MIDI_HOST_C) + static uint8_t DCOMP_MIDI_Host_NextMIDIStreamingInterface(void* const CurrentDescriptor) + ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1); + static uint8_t DCOMP_MIDI_Host_NextMIDIStreamingDataEndpoint(void* const CurrentDescriptor) + ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1); + #endif + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/MassStorageClassHost.c b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/MassStorageClassHost.c new file mode 100644 index 00000000..91e2ef02 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/MassStorageClassHost.c @@ -0,0 +1,579 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#define __INCLUDE_FROM_USB_DRIVER +#include "../../Core/USBMode.h" + +#if defined(USB_CAN_BE_HOST) + +#define __INCLUDE_FROM_MS_DRIVER +#define __INCLUDE_FROM_MASSSTORAGE_HOST_C +#include "MassStorageClassHost.h" + +uint8_t MS_Host_ConfigurePipes(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, + uint16_t ConfigDescriptorSize, + void* ConfigDescriptorData) +{ + USB_Descriptor_Endpoint_t* DataINEndpoint = NULL; + USB_Descriptor_Endpoint_t* DataOUTEndpoint = NULL; + USB_Descriptor_Interface_t* MassStorageInterface = NULL; + + memset(&MSInterfaceInfo->State, 0x00, sizeof(MSInterfaceInfo->State)); + + if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration) + return MS_ENUMERROR_InvalidConfigDescriptor; + + while (!(DataINEndpoint) || !(DataOUTEndpoint)) + { + if (!(MassStorageInterface) || + USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, + DCOMP_MS_Host_NextMSInterfaceEndpoint) != DESCRIPTOR_SEARCH_COMP_Found) + { + if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, + DCOMP_MS_Host_NextMSInterface) != DESCRIPTOR_SEARCH_COMP_Found) + { + return MS_ENUMERROR_NoCompatibleInterfaceFound; + } + + MassStorageInterface = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Interface_t); + + DataINEndpoint = NULL; + DataOUTEndpoint = NULL; + + continue; + } + + USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Endpoint_t); + + if ((EndpointData->EndpointAddress & ENDPOINT_DIR_MASK) == ENDPOINT_DIR_IN) + DataINEndpoint = EndpointData; + else + DataOUTEndpoint = EndpointData; + } + + MSInterfaceInfo->Config.DataINPipe.Size = le16_to_cpu(DataINEndpoint->EndpointSize); + MSInterfaceInfo->Config.DataINPipe.EndpointAddress = DataINEndpoint->EndpointAddress; + MSInterfaceInfo->Config.DataINPipe.Type = EP_TYPE_BULK; + + MSInterfaceInfo->Config.DataOUTPipe.Size = le16_to_cpu(DataOUTEndpoint->EndpointSize); + MSInterfaceInfo->Config.DataOUTPipe.EndpointAddress = DataOUTEndpoint->EndpointAddress; + MSInterfaceInfo->Config.DataOUTPipe.Type = EP_TYPE_BULK; + + if (!(Pipe_ConfigurePipeTable(&MSInterfaceInfo->Config.DataINPipe, 1))) + return false; + + if (!(Pipe_ConfigurePipeTable(&MSInterfaceInfo->Config.DataOUTPipe, 1))) + return false; + + MSInterfaceInfo->State.InterfaceNumber = MassStorageInterface->InterfaceNumber; + MSInterfaceInfo->State.IsActive = true; + + return MS_ENUMERROR_NoError; +} + +static uint8_t DCOMP_MS_Host_NextMSInterface(void* const CurrentDescriptor) +{ + USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t); + + if (Header->Type == DTYPE_Interface) + { + USB_Descriptor_Interface_t* Interface = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Interface_t); + + if ((Interface->Class == MS_CSCP_MassStorageClass) && + (Interface->SubClass == MS_CSCP_SCSITransparentSubclass) && + (Interface->Protocol == MS_CSCP_BulkOnlyTransportProtocol)) + { + return DESCRIPTOR_SEARCH_Found; + } + } + + return DESCRIPTOR_SEARCH_NotFound; +} + +static uint8_t DCOMP_MS_Host_NextMSInterfaceEndpoint(void* const CurrentDescriptor) +{ + USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t); + + if (Header->Type == DTYPE_Endpoint) + { + USB_Descriptor_Endpoint_t* Endpoint = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Endpoint_t); + + uint8_t EndpointType = (Endpoint->Attributes & EP_TYPE_MASK); + + if ((EndpointType == EP_TYPE_BULK) && (!(Pipe_IsEndpointBound(Endpoint->EndpointAddress)))) + { + return DESCRIPTOR_SEARCH_Found; + } + } + else if (Header->Type == DTYPE_Interface) + { + return DESCRIPTOR_SEARCH_Fail; + } + + return DESCRIPTOR_SEARCH_NotFound; +} + +static uint8_t MS_Host_SendCommand(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, + MS_CommandBlockWrapper_t* const SCSICommandBlock, + const void* const BufferPtr) +{ + uint8_t ErrorCode = PIPE_RWSTREAM_NoError; + + if (++MSInterfaceInfo->State.TransactionTag == 0xFFFFFFFF) + MSInterfaceInfo->State.TransactionTag = 1; + + SCSICommandBlock->Signature = CPU_TO_LE32(MS_CBW_SIGNATURE); + SCSICommandBlock->Tag = cpu_to_le32(MSInterfaceInfo->State.TransactionTag); + + Pipe_SelectPipe(MSInterfaceInfo->Config.DataOUTPipe.Address); + Pipe_Unfreeze(); + + if ((ErrorCode = Pipe_Write_Stream_LE(SCSICommandBlock, sizeof(MS_CommandBlockWrapper_t), + NULL)) != PIPE_RWSTREAM_NoError) + { + return ErrorCode; + } + + Pipe_ClearOUT(); + Pipe_WaitUntilReady(); + + Pipe_Freeze(); + + if (BufferPtr != NULL) + { + ErrorCode = MS_Host_SendReceiveData(MSInterfaceInfo, SCSICommandBlock, (void*)BufferPtr); + + if ((ErrorCode != PIPE_RWSTREAM_NoError) && (ErrorCode != PIPE_RWSTREAM_PipeStalled)) + { + Pipe_Freeze(); + return ErrorCode; + } + } + + MS_CommandStatusWrapper_t SCSIStatusBlock; + return MS_Host_GetReturnedStatus(MSInterfaceInfo, &SCSIStatusBlock); +} + +static uint8_t MS_Host_WaitForDataReceived(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo) +{ + uint16_t TimeoutMSRem = MS_COMMAND_DATA_TIMEOUT_MS; + uint16_t PreviousFrameNumber = USB_Host_GetFrameNumber(); + + Pipe_SelectPipe(MSInterfaceInfo->Config.DataINPipe.Address); + Pipe_Unfreeze(); + + while (!(Pipe_IsINReceived())) + { + uint16_t CurrentFrameNumber = USB_Host_GetFrameNumber(); + + if (CurrentFrameNumber != PreviousFrameNumber) + { + PreviousFrameNumber = CurrentFrameNumber; + + if (!(TimeoutMSRem--)) + return PIPE_RWSTREAM_Timeout; + } + + Pipe_Freeze(); + Pipe_SelectPipe(MSInterfaceInfo->Config.DataOUTPipe.Address); + Pipe_Unfreeze(); + + if (Pipe_IsStalled()) + { + USB_Host_ClearEndpointStall(Pipe_GetBoundEndpointAddress()); + return PIPE_RWSTREAM_PipeStalled; + } + + Pipe_Freeze(); + Pipe_SelectPipe(MSInterfaceInfo->Config.DataINPipe.Address); + Pipe_Unfreeze(); + + if (Pipe_IsStalled()) + { + USB_Host_ClearEndpointStall(Pipe_GetBoundEndpointAddress()); + return PIPE_RWSTREAM_PipeStalled; + } + + if (USB_HostState == HOST_STATE_Unattached) + return PIPE_RWSTREAM_DeviceDisconnected; + }; + + Pipe_SelectPipe(MSInterfaceInfo->Config.DataINPipe.Address); + Pipe_Freeze(); + + Pipe_SelectPipe(MSInterfaceInfo->Config.DataOUTPipe.Address); + Pipe_Freeze(); + + return PIPE_RWSTREAM_NoError; +} + +static uint8_t MS_Host_SendReceiveData(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, + MS_CommandBlockWrapper_t* const SCSICommandBlock, + void* BufferPtr) +{ + uint8_t ErrorCode = PIPE_RWSTREAM_NoError; + uint16_t BytesRem = le32_to_cpu(SCSICommandBlock->DataTransferLength); + + if (SCSICommandBlock->Flags & MS_COMMAND_DIR_DATA_IN) + { + if ((ErrorCode = MS_Host_WaitForDataReceived(MSInterfaceInfo)) != PIPE_RWSTREAM_NoError) + { + Pipe_Freeze(); + return ErrorCode; + } + + Pipe_SelectPipe(MSInterfaceInfo->Config.DataINPipe.Address); + Pipe_Unfreeze(); + + if ((ErrorCode = Pipe_Read_Stream_LE(BufferPtr, BytesRem, NULL)) != PIPE_RWSTREAM_NoError) + return ErrorCode; + + Pipe_ClearIN(); + } + else + { + Pipe_SelectPipe(MSInterfaceInfo->Config.DataOUTPipe.Address); + Pipe_Unfreeze(); + + if ((ErrorCode = Pipe_Write_Stream_LE(BufferPtr, BytesRem, NULL)) != PIPE_RWSTREAM_NoError) + return ErrorCode; + + Pipe_ClearOUT(); + + while (!(Pipe_IsOUTReady())) + { + if (USB_HostState == HOST_STATE_Unattached) + return PIPE_RWSTREAM_DeviceDisconnected; + } + } + + Pipe_Freeze(); + + return ErrorCode; +} + +static uint8_t MS_Host_GetReturnedStatus(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, + MS_CommandStatusWrapper_t* const SCSICommandStatus) +{ + uint8_t ErrorCode = PIPE_RWSTREAM_NoError; + + if ((ErrorCode = MS_Host_WaitForDataReceived(MSInterfaceInfo)) != PIPE_RWSTREAM_NoError) + return ErrorCode; + + Pipe_SelectPipe(MSInterfaceInfo->Config.DataINPipe.Address); + Pipe_Unfreeze(); + + if ((ErrorCode = Pipe_Read_Stream_LE(SCSICommandStatus, sizeof(MS_CommandStatusWrapper_t), + NULL)) != PIPE_RWSTREAM_NoError) + { + return ErrorCode; + } + + Pipe_ClearIN(); + Pipe_Freeze(); + + if (SCSICommandStatus->Status != MS_SCSI_COMMAND_Pass) + ErrorCode = MS_ERROR_LOGICAL_CMD_FAILED; + + return ErrorCode; +} + +uint8_t MS_Host_ResetMSInterface(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo) +{ + uint8_t ErrorCode; + + USB_ControlRequest = (USB_Request_Header_t) + { + .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE), + .bRequest = MS_REQ_MassStorageReset, + .wValue = 0, + .wIndex = MSInterfaceInfo->State.InterfaceNumber, + .wLength = 0, + }; + + Pipe_SelectPipe(PIPE_CONTROLPIPE); + + if ((ErrorCode = USB_Host_SendControlRequest(NULL)) != HOST_SENDCONTROL_Successful) + return ErrorCode; + + Pipe_SelectPipe(MSInterfaceInfo->Config.DataINPipe.Address); + + if ((ErrorCode = USB_Host_ClearEndpointStall(Pipe_GetBoundEndpointAddress())) != HOST_SENDCONTROL_Successful) + return ErrorCode; + + Pipe_SelectPipe(MSInterfaceInfo->Config.DataOUTPipe.Address); + + if ((ErrorCode = USB_Host_ClearEndpointStall(Pipe_GetBoundEndpointAddress())) != HOST_SENDCONTROL_Successful) + return ErrorCode; + + return HOST_SENDCONTROL_Successful; +} + +uint8_t MS_Host_GetMaxLUN(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, + uint8_t* const MaxLUNIndex) +{ + uint8_t ErrorCode; + + USB_ControlRequest = (USB_Request_Header_t) + { + .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE), + .bRequest = MS_REQ_GetMaxLUN, + .wValue = 0, + .wIndex = MSInterfaceInfo->State.InterfaceNumber, + .wLength = 1, + }; + + Pipe_SelectPipe(PIPE_CONTROLPIPE); + + if ((ErrorCode = USB_Host_SendControlRequest(MaxLUNIndex)) == HOST_SENDCONTROL_SetupStalled) + { + *MaxLUNIndex = 0; + ErrorCode = HOST_SENDCONTROL_Successful; + } + + return ErrorCode; +} + +uint8_t MS_Host_GetInquiryData(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, + const uint8_t LUNIndex, + SCSI_Inquiry_Response_t* const InquiryData) +{ + if ((USB_HostState != HOST_STATE_Configured) || !(MSInterfaceInfo->State.IsActive)) + return HOST_SENDCONTROL_DeviceDisconnected; + + MS_CommandBlockWrapper_t SCSICommandBlock = (MS_CommandBlockWrapper_t) + { + .DataTransferLength = CPU_TO_LE32(sizeof(SCSI_Inquiry_Response_t)), + .Flags = MS_COMMAND_DIR_DATA_IN, + .LUN = LUNIndex, + .SCSICommandLength = 6, + .SCSICommandData = + { + SCSI_CMD_INQUIRY, + 0x00, // Reserved + 0x00, // Reserved + 0x00, // Reserved + sizeof(SCSI_Inquiry_Response_t), // Allocation Length + 0x00 // Unused (control) + } + }; + + return MS_Host_SendCommand(MSInterfaceInfo, &SCSICommandBlock, InquiryData); +} + +uint8_t MS_Host_TestUnitReady(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, + const uint8_t LUNIndex) +{ + if ((USB_HostState != HOST_STATE_Configured) || !(MSInterfaceInfo->State.IsActive)) + return HOST_SENDCONTROL_DeviceDisconnected; + + MS_CommandBlockWrapper_t SCSICommandBlock = (MS_CommandBlockWrapper_t) + { + .DataTransferLength = CPU_TO_LE32(0), + .Flags = MS_COMMAND_DIR_DATA_IN, + .LUN = LUNIndex, + .SCSICommandLength = 6, + .SCSICommandData = + { + SCSI_CMD_TEST_UNIT_READY, + 0x00, // Reserved + 0x00, // Reserved + 0x00, // Reserved + 0x00, // Reserved + 0x00 // Unused (control) + } + }; + + return MS_Host_SendCommand(MSInterfaceInfo, &SCSICommandBlock, NULL); +} + +uint8_t MS_Host_ReadDeviceCapacity(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, + const uint8_t LUNIndex, + SCSI_Capacity_t* const DeviceCapacity) +{ + if ((USB_HostState != HOST_STATE_Configured) || !(MSInterfaceInfo->State.IsActive)) + return HOST_SENDCONTROL_DeviceDisconnected; + + uint8_t ErrorCode; + + MS_CommandBlockWrapper_t SCSICommandBlock = (MS_CommandBlockWrapper_t) + { + .DataTransferLength = CPU_TO_LE32(sizeof(SCSI_Capacity_t)), + .Flags = MS_COMMAND_DIR_DATA_IN, + .LUN = LUNIndex, + .SCSICommandLength = 10, + .SCSICommandData = + { + SCSI_CMD_READ_CAPACITY_10, + 0x00, // Reserved + 0x00, // MSB of Logical block address + 0x00, + 0x00, + 0x00, // LSB of Logical block address + 0x00, // Reserved + 0x00, // Reserved + 0x00, // Partial Medium Indicator + 0x00 // Unused (control) + } + }; + + if ((ErrorCode = MS_Host_SendCommand(MSInterfaceInfo, &SCSICommandBlock, DeviceCapacity)) != PIPE_RWSTREAM_NoError) + return ErrorCode; + + DeviceCapacity->Blocks = BE32_TO_CPU(DeviceCapacity->Blocks); + DeviceCapacity->BlockSize = BE32_TO_CPU(DeviceCapacity->BlockSize); + + return PIPE_RWSTREAM_NoError; +} + +uint8_t MS_Host_RequestSense(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, + const uint8_t LUNIndex, + SCSI_Request_Sense_Response_t* const SenseData) +{ + if ((USB_HostState != HOST_STATE_Configured) || !(MSInterfaceInfo->State.IsActive)) + return HOST_SENDCONTROL_DeviceDisconnected; + + MS_CommandBlockWrapper_t SCSICommandBlock = (MS_CommandBlockWrapper_t) + { + .DataTransferLength = CPU_TO_LE32(sizeof(SCSI_Request_Sense_Response_t)), + .Flags = MS_COMMAND_DIR_DATA_IN, + .LUN = LUNIndex, + .SCSICommandLength = 6, + .SCSICommandData = + { + SCSI_CMD_REQUEST_SENSE, + 0x00, // Reserved + 0x00, // Reserved + 0x00, // Reserved + sizeof(SCSI_Request_Sense_Response_t), // Allocation Length + 0x00 // Unused (control) + } + }; + + return MS_Host_SendCommand(MSInterfaceInfo, &SCSICommandBlock, SenseData); +} + +uint8_t MS_Host_PreventAllowMediumRemoval(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, + const uint8_t LUNIndex, + const bool PreventRemoval) +{ + if ((USB_HostState != HOST_STATE_Configured) || !(MSInterfaceInfo->State.IsActive)) + return HOST_SENDCONTROL_DeviceDisconnected; + + MS_CommandBlockWrapper_t SCSICommandBlock = (MS_CommandBlockWrapper_t) + { + .DataTransferLength = CPU_TO_LE32(0), + .Flags = MS_COMMAND_DIR_DATA_OUT, + .LUN = LUNIndex, + .SCSICommandLength = 6, + .SCSICommandData = + { + SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL, + 0x00, // Reserved + 0x00, // Reserved + PreventRemoval, // Prevent flag + 0x00, // Reserved + 0x00 // Unused (control) + } + }; + + return MS_Host_SendCommand(MSInterfaceInfo, &SCSICommandBlock, NULL); +} + +uint8_t MS_Host_ReadDeviceBlocks(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, + const uint8_t LUNIndex, + const uint32_t BlockAddress, + const uint8_t Blocks, + const uint16_t BlockSize, + void* BlockBuffer) +{ + if ((USB_HostState != HOST_STATE_Configured) || !(MSInterfaceInfo->State.IsActive)) + return HOST_SENDCONTROL_DeviceDisconnected; + + MS_CommandBlockWrapper_t SCSICommandBlock = (MS_CommandBlockWrapper_t) + { + .DataTransferLength = cpu_to_le32((uint32_t)Blocks * BlockSize), + .Flags = MS_COMMAND_DIR_DATA_IN, + .LUN = LUNIndex, + .SCSICommandLength = 10, + .SCSICommandData = + { + SCSI_CMD_READ_10, + 0x00, // Unused (control bits, all off) + (BlockAddress >> 24), // MSB of Block Address + (BlockAddress >> 16), + (BlockAddress >> 8), + (BlockAddress & 0xFF), // LSB of Block Address + 0x00, // Reserved + 0x00, // MSB of Total Blocks to Read + Blocks, // LSB of Total Blocks to Read + 0x00 // Unused (control) + } + }; + + return MS_Host_SendCommand(MSInterfaceInfo, &SCSICommandBlock, BlockBuffer); +} + +uint8_t MS_Host_WriteDeviceBlocks(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, + const uint8_t LUNIndex, + const uint32_t BlockAddress, + const uint8_t Blocks, + const uint16_t BlockSize, + const void* BlockBuffer) +{ + if ((USB_HostState != HOST_STATE_Configured) || !(MSInterfaceInfo->State.IsActive)) + return HOST_SENDCONTROL_DeviceDisconnected; + + MS_CommandBlockWrapper_t SCSICommandBlock = (MS_CommandBlockWrapper_t) + { + .DataTransferLength = cpu_to_le32((uint32_t)Blocks * BlockSize), + .Flags = MS_COMMAND_DIR_DATA_OUT, + .LUN = LUNIndex, + .SCSICommandLength = 10, + .SCSICommandData = + { + SCSI_CMD_WRITE_10, + 0x00, // Unused (control bits, all off) + (BlockAddress >> 24), // MSB of Block Address + (BlockAddress >> 16), + (BlockAddress >> 8), + (BlockAddress & 0xFF), // LSB of Block Address + 0x00, // Reserved + 0x00, // MSB of Total Blocks to Write + Blocks, // LSB of Total Blocks to Write + 0x00 // Unused (control) + } + }; + + return MS_Host_SendCommand(MSInterfaceInfo, &SCSICommandBlock, BlockBuffer); +} + +#endif + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/MassStorageClassHost.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/MassStorageClassHost.h new file mode 100644 index 00000000..2e784318 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/MassStorageClassHost.h @@ -0,0 +1,335 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Host mode driver for the library USB Mass Storage Class driver. + * + * Host mode driver for the library USB Mass Storage Class driver. + * + * \note This file should not be included directly. It is automatically included as needed by the USB module driver + * dispatch header located in LUFA/Drivers/USB.h. + */ + +/** \ingroup Group_USBClassMS + * \defgroup Group_USBClassMassStorageHost Mass Storage Class Host Mode Driver + * + * \section Sec_Dependencies Module Source Dependencies + * The following files must be built with any user project that uses this module: + * - LUFA/Drivers/USB/Class/Host/MassStorageClassHost.c (Makefile source module name: LUFA_SRC_USBCLASS) + * + * \section Sec_ModDescription Module Description + * Host Mode USB Class driver framework interface, for the Mass Storage USB Class driver. + * + * @{ + */ + +#ifndef __MS_CLASS_HOST_H__ +#define __MS_CLASS_HOST_H__ + + /* Includes: */ + #include "../../USB.h" + #include "../Common/MassStorageClassCommon.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_MS_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Error code for some Mass Storage Host functions, indicating a logical (and not hardware) error. */ + #define MS_ERROR_LOGICAL_CMD_FAILED 0x80 + + /* Type Defines: */ + /** \brief Mass Storage Class Host Mode Configuration and State Structure. + * + * Class state structure. An instance of this structure should be made within the user application, + * and passed to each of the Mass Storage class driver functions as the \c MSInterfaceInfo parameter. This + * stores each Mass Storage interface's configuration and state information. + */ + typedef struct + { + struct + { + USB_Pipe_Table_t DataINPipe; /**< Data IN Pipe configuration table. */ + USB_Pipe_Table_t DataOUTPipe; /**< Data OUT Pipe configuration table. */ + } Config; /**< Config data for the USB class interface within the device. All elements in this section + * must be set or the interface will fail to enumerate and operate correctly. + */ + struct + { + bool IsActive; /**< Indicates if the current interface instance is connected to an attached device, valid + * after \ref MS_Host_ConfigurePipes() is called and the Host state machine is in the + * Configured state. + */ + uint8_t InterfaceNumber; /**< Interface index of the Mass Storage interface within the attached device. */ + + uint32_t TransactionTag; /**< Current transaction tag for data synchronizing of packets. */ + } State; /**< State data for the USB class interface within the device. All elements in this section + * may be set to initial values, but may also be ignored to default to sane values when + * the interface is enumerated. + */ + } USB_ClassInfo_MS_Host_t; + + /** \brief SCSI Device LUN Capacity Structure. + * + * SCSI capacity structure, to hold the total capacity of the device in both the number + * of blocks in the current LUN, and the size of each block. This structure is filled by + * the device when the \ref MS_Host_ReadDeviceCapacity() function is called. + */ + typedef struct + { + uint32_t Blocks; /**< Number of blocks in the addressed LUN of the device. */ + uint32_t BlockSize; /**< Number of bytes in each block in the addressed LUN. */ + } SCSI_Capacity_t; + + /* Enums: */ + /** Enum for the possible error codes returned by the \ref MS_Host_ConfigurePipes() function. */ + enum MS_Host_EnumerationFailure_ErrorCodes_t + { + MS_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully. */ + MS_ENUMERROR_InvalidConfigDescriptor = 1, /**< The device returned an invalid Configuration Descriptor. */ + MS_ENUMERROR_NoCompatibleInterfaceFound = 2, /**< A compatible Mass Storage interface was not found in the device's Configuration Descriptor. */ + MS_ENUMERROR_PipeConfigurationFailed = 3, /**< One or more pipes for the specified interface could not be configured correctly. */ + }; + + /* Function Prototypes: */ + /** Host interface configuration routine, to configure a given Mass Storage host interface instance using the + * Configuration Descriptor read from an attached USB device. This function automatically updates the given Mass + * Storage Host instance's state values and configures the pipes required to communicate with the interface if it + * is found within the device. This should be called once after the stack has enumerated the attached device, while + * the host state machine is in the Addressed state. + * + * \param[in,out] MSInterfaceInfo Pointer to a structure containing an MS Class host configuration and state. + * \param[in] ConfigDescriptorSize Length of the attached device's Configuration Descriptor. + * \param[in] DeviceConfigDescriptor Pointer to a buffer containing the attached device's Configuration Descriptor. + * + * \return A value from the \ref MS_Host_EnumerationFailure_ErrorCodes_t enum. + */ + uint8_t MS_Host_ConfigurePipes(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, + uint16_t ConfigDescriptorSize, + void* DeviceConfigDescriptor) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3); + + /** Sends a MASS STORAGE RESET control request to the attached device, resetting the Mass Storage Interface + * and readying it for the next Mass Storage command. This should be called after a failed SCSI request to + * ensure the attached Mass Storage device is ready to receive the next command. + * + * \param[in,out] MSInterfaceInfo Pointer to a structure containing a MS Class host configuration and state. + * + * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum. + */ + uint8_t MS_Host_ResetMSInterface(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + /** Sends a GET MAX LUN control request to the attached device, retrieving the index of the highest LUN (Logical + * UNit, a logical drive) in the device. This value can then be used in the other functions of the Mass Storage + * Host mode Class driver to address a specific LUN within the device. + * + * \note Some devices do not support this request, and will STALL it when issued. To get around this, + * on unsupported devices the max LUN index will be reported as zero and no error will be returned + * if the device STALLs the request. + * + * \param[in,out] MSInterfaceInfo Pointer to a structure containing a MS Class host configuration and state. + * \param[out] MaxLUNIndex Pointer to a location where the highest LUN index value should be stored. + * + * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum. + */ + uint8_t MS_Host_GetMaxLUN(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, + uint8_t* const MaxLUNIndex) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); + + /** Retrieves the Mass Storage device's inquiry data for the specified LUN, indicating the device characteristics and + * properties. + * + * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the + * call will fail. + * + * \param[in,out] MSInterfaceInfo Pointer to a structure containing a MS Class host configuration and state. + * \param[in] LUNIndex LUN index within the device the command is being issued to. + * \param[out] InquiryData Location where the read inquiry data should be stored. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum or \ref MS_ERROR_LOGICAL_CMD_FAILED. + */ + uint8_t MS_Host_GetInquiryData(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, + const uint8_t LUNIndex, + SCSI_Inquiry_Response_t* const InquiryData) ATTR_NON_NULL_PTR_ARG(1) + ATTR_NON_NULL_PTR_ARG(3); + + /** Sends a TEST UNIT READY command to the device, to determine if it is ready to accept other SCSI commands. + * + * \param[in,out] MSInterfaceInfo Pointer to a structure containing a MS Class host configuration and state. + * \param[in] LUNIndex LUN index within the device the command is being issued to. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum or \ref MS_ERROR_LOGICAL_CMD_FAILED if not ready. + */ + uint8_t MS_Host_TestUnitReady(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, + const uint8_t LUNIndex) ATTR_NON_NULL_PTR_ARG(1); + + /** Retrieves the total capacity of the attached USB Mass Storage device, in blocks, and block size. + * + * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the + * call will fail. + * + * \param[in,out] MSInterfaceInfo Pointer to a structure containing a MS Class host configuration and state. + * \param[in] LUNIndex LUN index within the device the command is being issued to. + * \param[out] DeviceCapacity Pointer to the location where the capacity information should be stored. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum or \ref MS_ERROR_LOGICAL_CMD_FAILED if not ready. + */ + uint8_t MS_Host_ReadDeviceCapacity(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, + const uint8_t LUNIndex, + SCSI_Capacity_t* const DeviceCapacity) ATTR_NON_NULL_PTR_ARG(1) + ATTR_NON_NULL_PTR_ARG(3); + + /** Retrieves the device sense data, indicating the current device state and error codes for the previously + * issued command. + * + * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the + * call will fail. + * + * \param[in,out] MSInterfaceInfo Pointer to a structure containing a MS Class host configuration and state. + * \param[in] LUNIndex LUN index within the device the command is being issued to. + * \param[out] SenseData Pointer to the location where the sense information should be stored. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum or \ref MS_ERROR_LOGICAL_CMD_FAILED if not ready. + */ + uint8_t MS_Host_RequestSense(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, + const uint8_t LUNIndex, + SCSI_Request_Sense_Response_t* const SenseData) ATTR_NON_NULL_PTR_ARG(1) + ATTR_NON_NULL_PTR_ARG(3); + + /** Issues a PREVENT MEDIUM REMOVAL command, to logically (or, depending on the type of device, physically) lock + * the device from removal so that blocks of data on the medium can be read or altered. + * + * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the + * call will fail. + * + * \param[in,out] MSInterfaceInfo Pointer to a structure containing a MS Class host configuration and state. + * \param[in] LUNIndex LUN index within the device the command is being issued to. + * \param[in] PreventRemoval Boolean \c true if the device should be locked from removal, \c false otherwise. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum or \ref MS_ERROR_LOGICAL_CMD_FAILED if not ready. + */ + uint8_t MS_Host_PreventAllowMediumRemoval(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, + const uint8_t LUNIndex, + const bool PreventRemoval) ATTR_NON_NULL_PTR_ARG(1); + + /** Reads blocks of data from the attached Mass Storage device's medium. + * + * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the + * call will fail. + * + * \param[in,out] MSInterfaceInfo Pointer to a structure containing a MS Class host configuration and state. + * \param[in] LUNIndex LUN index within the device the command is being issued to. + * \param[in] BlockAddress Starting block address within the device to read from. + * \param[in] Blocks Total number of blocks to read. + * \param[in] BlockSize Size in bytes of each block within the device. + * \param[out] BlockBuffer Pointer to where the read data from the device should be stored. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum or \ref MS_ERROR_LOGICAL_CMD_FAILED if not ready. + */ + uint8_t MS_Host_ReadDeviceBlocks(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, + const uint8_t LUNIndex, + const uint32_t BlockAddress, + const uint8_t Blocks, + const uint16_t BlockSize, + void* BlockBuffer) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(6); + + /** Writes blocks of data to the attached Mass Storage device's medium. + * + * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the + * call will fail. + * + * \param[in,out] MSInterfaceInfo Pointer to a structure containing a MS Class host configuration and state. + * \param[in] LUNIndex LUN index within the device the command is being issued to. + * \param[in] BlockAddress Starting block address within the device to write to. + * \param[in] Blocks Total number of blocks to read. + * \param[in] BlockSize Size in bytes of each block within the device. + * \param[in] BlockBuffer Pointer to where the data to write should be sourced from. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum or \ref MS_ERROR_LOGICAL_CMD_FAILED if not ready. + */ + uint8_t MS_Host_WriteDeviceBlocks(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, + const uint8_t LUNIndex, + const uint32_t BlockAddress, + const uint8_t Blocks, + const uint16_t BlockSize, + const void* BlockBuffer) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(6); + + /* Inline Functions: */ + /** General management task for a given Mass Storage host class interface, required for the correct operation of + * the interface. This should be called frequently in the main program loop, before the master USB management task + * \ref USB_USBTask(). + * + * \param[in,out] MSInterfaceInfo Pointer to a structure containing an Mass Storage Class host configuration and state. + */ + static inline void MS_Host_USBTask(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE; + static inline void MS_Host_USBTask(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo) + { + (void)MSInterfaceInfo; + } + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Macros: */ + #define MS_COMMAND_DATA_TIMEOUT_MS 10000 + + /* Function Prototypes: */ + #if defined(__INCLUDE_FROM_MASSSTORAGE_HOST_C) + static uint8_t MS_Host_SendCommand(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, + MS_CommandBlockWrapper_t* const SCSICommandBlock, + const void* const BufferPtr) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); + static uint8_t MS_Host_WaitForDataReceived(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + static uint8_t MS_Host_SendReceiveData(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, + MS_CommandBlockWrapper_t* const SCSICommandBlock, + void* BufferPtr) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); + static uint8_t MS_Host_GetReturnedStatus(USB_ClassInfo_MS_Host_t* const MSInterfaceInfo, + MS_CommandStatusWrapper_t* const SCSICommandStatus) + ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); + + static uint8_t DCOMP_MS_Host_NextMSInterface(void* const CurrentDescriptor) + ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1); + static uint8_t DCOMP_MS_Host_NextMSInterfaceEndpoint(void* const CurrentDescriptor) + ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1); + #endif + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/PrinterClassHost.c b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/PrinterClassHost.c new file mode 100644 index 00000000..1ecf1911 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/PrinterClassHost.c @@ -0,0 +1,400 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#define __INCLUDE_FROM_USB_DRIVER +#include "../../Core/USBMode.h" + +#if defined(USB_CAN_BE_HOST) + +#define __INCLUDE_FROM_PRINTER_DRIVER +#define __INCLUDE_FROM_PRINTER_HOST_C +#include "PrinterClassHost.h" + +uint8_t PRNT_Host_ConfigurePipes(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo, + uint16_t ConfigDescriptorSize, + void* ConfigDescriptorData) +{ + USB_Descriptor_Endpoint_t* DataINEndpoint = NULL; + USB_Descriptor_Endpoint_t* DataOUTEndpoint = NULL; + USB_Descriptor_Interface_t* PrinterInterface = NULL; + + memset(&PRNTInterfaceInfo->State, 0x00, sizeof(PRNTInterfaceInfo->State)); + + if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration) + return PRNT_ENUMERROR_InvalidConfigDescriptor; + + while (!(DataINEndpoint) || !(DataOUTEndpoint)) + { + if (!(PrinterInterface) || + USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, + DCOMP_PRNT_Host_NextPRNTInterfaceEndpoint) != DESCRIPTOR_SEARCH_COMP_Found) + { + if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, + DCOMP_PRNT_Host_NextPRNTInterface) != DESCRIPTOR_SEARCH_COMP_Found) + { + return PRNT_ENUMERROR_NoCompatibleInterfaceFound; + } + + PrinterInterface = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Interface_t); + + DataINEndpoint = NULL; + DataOUTEndpoint = NULL; + + continue; + } + + USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Endpoint_t); + + if ((EndpointData->EndpointAddress & ENDPOINT_DIR_MASK) == ENDPOINT_DIR_IN) + DataINEndpoint = EndpointData; + else + DataOUTEndpoint = EndpointData; + } + + PRNTInterfaceInfo->Config.DataINPipe.Size = le16_to_cpu(DataINEndpoint->EndpointSize); + PRNTInterfaceInfo->Config.DataINPipe.EndpointAddress = DataINEndpoint->EndpointAddress; + PRNTInterfaceInfo->Config.DataINPipe.Type = EP_TYPE_BULK; + + PRNTInterfaceInfo->Config.DataOUTPipe.Size = le16_to_cpu(DataOUTEndpoint->EndpointSize); + PRNTInterfaceInfo->Config.DataOUTPipe.EndpointAddress = DataOUTEndpoint->EndpointAddress; + PRNTInterfaceInfo->Config.DataOUTPipe.Type = EP_TYPE_BULK; + + if (!(Pipe_ConfigurePipeTable(&PRNTInterfaceInfo->Config.DataINPipe, 1))) + return false; + + if (!(Pipe_ConfigurePipeTable(&PRNTInterfaceInfo->Config.DataOUTPipe, 1))) + return false; + + PRNTInterfaceInfo->State.InterfaceNumber = PrinterInterface->InterfaceNumber; + PRNTInterfaceInfo->State.AlternateSetting = PrinterInterface->AlternateSetting; + PRNTInterfaceInfo->State.IsActive = true; + + return PRNT_ENUMERROR_NoError; +} + +static uint8_t DCOMP_PRNT_Host_NextPRNTInterface(void* CurrentDescriptor) +{ + USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t); + + if (Header->Type == DTYPE_Interface) + { + USB_Descriptor_Interface_t* Interface = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Interface_t); + + if ((Interface->Class == PRNT_CSCP_PrinterClass) && + (Interface->SubClass == PRNT_CSCP_PrinterSubclass) && + (Interface->Protocol == PRNT_CSCP_BidirectionalProtocol)) + { + return DESCRIPTOR_SEARCH_Found; + } + } + + return DESCRIPTOR_SEARCH_NotFound; +} + +static uint8_t DCOMP_PRNT_Host_NextPRNTInterfaceEndpoint(void* CurrentDescriptor) +{ + USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t); + + if (Header->Type == DTYPE_Endpoint) + { + USB_Descriptor_Endpoint_t* Endpoint = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Endpoint_t); + + uint8_t EndpointType = (Endpoint->Attributes & EP_TYPE_MASK); + + if (EndpointType == EP_TYPE_BULK) + return DESCRIPTOR_SEARCH_Found; + } + else if (Header->Type == DTYPE_Interface) + { + return DESCRIPTOR_SEARCH_Fail; + } + + return DESCRIPTOR_SEARCH_NotFound; +} + +void PRNT_Host_USBTask(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo) +{ + if ((USB_HostState != HOST_STATE_Configured) || !(PRNTInterfaceInfo->State.IsActive)) + return; + + #if !defined(NO_CLASS_DRIVER_AUTOFLUSH) + PRNT_Host_Flush(PRNTInterfaceInfo); + #endif +} + +uint8_t PRNT_Host_SetBidirectionalMode(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo) +{ + if (PRNTInterfaceInfo->State.AlternateSetting) + { + uint8_t ErrorCode; + + if ((ErrorCode = USB_Host_SetInterfaceAltSetting(PRNTInterfaceInfo->State.InterfaceNumber, + PRNTInterfaceInfo->State.AlternateSetting)) != HOST_SENDCONTROL_Successful) + { + return ErrorCode; + } + } + + return HOST_SENDCONTROL_Successful; +} + +uint8_t PRNT_Host_GetPortStatus(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo, + uint8_t* const PortStatus) +{ + USB_ControlRequest = (USB_Request_Header_t) + { + .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE), + .bRequest = PRNT_REQ_GetPortStatus, + .wValue = 0, + .wIndex = PRNTInterfaceInfo->State.InterfaceNumber, + .wLength = sizeof(uint8_t), + }; + + Pipe_SelectPipe(PIPE_CONTROLPIPE); + return USB_Host_SendControlRequest(PortStatus); +} + +uint8_t PRNT_Host_SoftReset(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo) +{ + USB_ControlRequest = (USB_Request_Header_t) + { + .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE), + .bRequest = PRNT_REQ_SoftReset, + .wValue = 0, + .wIndex = PRNTInterfaceInfo->State.InterfaceNumber, + .wLength = 0, + }; + + Pipe_SelectPipe(PIPE_CONTROLPIPE); + return USB_Host_SendControlRequest(NULL); +} + +uint8_t PRNT_Host_Flush(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo) +{ + if ((USB_HostState != HOST_STATE_Configured) || !(PRNTInterfaceInfo->State.IsActive)) + return PIPE_READYWAIT_DeviceDisconnected; + + uint8_t ErrorCode; + + Pipe_SelectPipe(PRNTInterfaceInfo->Config.DataOUTPipe.Address); + Pipe_Unfreeze(); + + if (!(Pipe_BytesInPipe())) + return PIPE_READYWAIT_NoError; + + bool BankFull = !(Pipe_IsReadWriteAllowed()); + + Pipe_ClearOUT(); + + if (BankFull) + { + if ((ErrorCode = Pipe_WaitUntilReady()) != PIPE_READYWAIT_NoError) + return ErrorCode; + + Pipe_ClearOUT(); + } + + Pipe_Freeze(); + + return PIPE_READYWAIT_NoError; +} + +uint8_t PRNT_Host_SendByte(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo, + const uint8_t Data) +{ + if ((USB_HostState != HOST_STATE_Configured) || !(PRNTInterfaceInfo->State.IsActive)) + return PIPE_READYWAIT_DeviceDisconnected; + + uint8_t ErrorCode; + + Pipe_SelectPipe(PRNTInterfaceInfo->Config.DataOUTPipe.Address); + Pipe_Unfreeze(); + + if (!(Pipe_IsReadWriteAllowed())) + { + Pipe_ClearOUT(); + + if ((ErrorCode = Pipe_WaitUntilReady()) != PIPE_READYWAIT_NoError) + return ErrorCode; + } + + Pipe_Write_8(Data); + Pipe_Freeze(); + + return PIPE_READYWAIT_NoError; +} + +uint8_t PRNT_Host_SendString(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo, + const char* const String) +{ + uint8_t ErrorCode; + + if ((USB_HostState != HOST_STATE_Configured) || !(PRNTInterfaceInfo->State.IsActive)) + return PIPE_RWSTREAM_DeviceDisconnected; + + Pipe_SelectPipe(PRNTInterfaceInfo->Config.DataOUTPipe.Address); + Pipe_Unfreeze(); + + if ((ErrorCode = Pipe_Write_Stream_LE(String, strlen(String), NULL)) != PIPE_RWSTREAM_NoError) + return ErrorCode; + + Pipe_ClearOUT(); + + ErrorCode = Pipe_WaitUntilReady(); + + Pipe_Freeze(); + + return ErrorCode; +} + +uint8_t PRNT_Host_SendData(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo, + void* Buffer, + const uint16_t Length) +{ + uint8_t ErrorCode; + + if ((USB_HostState != HOST_STATE_Configured) || !(PRNTInterfaceInfo->State.IsActive)) + return PIPE_RWSTREAM_DeviceDisconnected; + + Pipe_SelectPipe(PRNTInterfaceInfo->Config.DataOUTPipe.Address); + Pipe_Unfreeze(); + + if ((ErrorCode = Pipe_Write_Stream_LE(Buffer, Length, NULL)) != PIPE_RWSTREAM_NoError) + return ErrorCode; + + Pipe_ClearOUT(); + + ErrorCode = Pipe_WaitUntilReady(); + + Pipe_Freeze(); + + return ErrorCode; +} + +uint16_t PRNT_Host_BytesReceived(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo) +{ + if ((USB_HostState != HOST_STATE_Configured) || !(PRNTInterfaceInfo->State.IsActive)) + return 0; + + Pipe_SelectPipe(PRNTInterfaceInfo->Config.DataINPipe.Address); + Pipe_Unfreeze(); + + if (Pipe_IsINReceived()) + { + if (!(Pipe_BytesInPipe())) + { + Pipe_ClearIN(); + Pipe_Freeze(); + return 0; + } + else + { + Pipe_Freeze(); + return Pipe_BytesInPipe(); + } + } + else + { + Pipe_Freeze(); + + return 0; + } +} + +int16_t PRNT_Host_ReceiveByte(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo) +{ + if ((USB_HostState != HOST_STATE_Configured) || !(PRNTInterfaceInfo->State.IsActive)) + return PIPE_RWSTREAM_DeviceDisconnected; + + int16_t ReceivedByte = -1; + + Pipe_SelectPipe(PRNTInterfaceInfo->Config.DataINPipe.Address); + Pipe_Unfreeze(); + + if (Pipe_IsINReceived()) + { + if (Pipe_BytesInPipe()) + ReceivedByte = Pipe_Read_8(); + + if (!(Pipe_BytesInPipe())) + Pipe_ClearIN(); + } + + Pipe_Freeze(); + + return ReceivedByte; +} + +uint8_t PRNT_Host_GetDeviceID(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo, + char* const DeviceIDString, + const uint16_t BufferSize) +{ + uint8_t ErrorCode; + uint16_t DeviceIDStringLength = 0; + + USB_ControlRequest = (USB_Request_Header_t) + { + .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE), + .bRequest = PRNT_REQ_GetDeviceID, + .wValue = 0, + .wIndex = PRNTInterfaceInfo->State.InterfaceNumber, + .wLength = sizeof(DeviceIDStringLength), + }; + + Pipe_SelectPipe(PIPE_CONTROLPIPE); + + if ((ErrorCode = USB_Host_SendControlRequest(&DeviceIDStringLength)) != HOST_SENDCONTROL_Successful) + return ErrorCode; + + if (!(DeviceIDStringLength)) + { + DeviceIDString[0] = 0x00; + return HOST_SENDCONTROL_Successful; + } + + DeviceIDStringLength = be16_to_cpu(DeviceIDStringLength); + + if (DeviceIDStringLength > BufferSize) + DeviceIDStringLength = BufferSize; + + USB_ControlRequest.wLength = DeviceIDStringLength; + + if ((ErrorCode = USB_Host_SendControlRequest(DeviceIDString)) != HOST_SENDCONTROL_Successful) + return ErrorCode; + + memmove(&DeviceIDString[0], &DeviceIDString[2], DeviceIDStringLength - 2); + + DeviceIDString[DeviceIDStringLength - 2] = 0x00; + + return HOST_SENDCONTROL_Successful; +} + +#endif + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/PrinterClassHost.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/PrinterClassHost.h new file mode 100644 index 00000000..64494b1f --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/PrinterClassHost.h @@ -0,0 +1,285 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Host mode driver for the library USB Printer Class driver. + * + * Host mode driver for the library USB Printer Class driver. + * + * \note This file should not be included directly. It is automatically included as needed by the USB module driver + * dispatch header located in LUFA/Drivers/USB.h. + */ + +/** \ingroup Group_USBClassPrinter + * \defgroup Group_USBClassPrinterHost Printer Class Host Mode Driver + * + * \section Sec_Dependencies Module Source Dependencies + * The following files must be built with any user project that uses this module: + * - LUFA/Drivers/USB/Class/Host/PrinterClassHost.c (Makefile source module name: LUFA_SRC_USBCLASS) + * + * \section Sec_ModDescription Module Description + * Host Mode USB Class driver framework interface, for the Printer USB Class driver. + * + * @{ + */ + +#ifndef __PRINTER_CLASS_HOST_H__ +#define __PRINTER_CLASS_HOST_H__ + + /* Includes: */ + #include "../../USB.h" + #include "../Common/PrinterClassCommon.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_PRINTER_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Type Defines: */ + /** \brief Printer Class Host Mode Configuration and State Structure. + * + * Class state structure. An instance of this structure should be made within the user application, + * and passed to each of the Printer class driver functions as the \c PRNTInterfaceInfo parameter. This + * stores each Printer interface's configuration and state information. + */ + typedef struct + { + struct + { + USB_Pipe_Table_t DataINPipe; /**< Data IN Pipe configuration table. */ + USB_Pipe_Table_t DataOUTPipe; /**< Data OUT Pipe configuration table. */ + } Config; /**< Config data for the USB class interface within the device. All elements in this section + * must be set or the interface will fail to enumerate and operate correctly. + */ + struct + { + bool IsActive; /**< Indicates if the current interface instance is connected to an attached device, valid + * after \ref PRNT_Host_ConfigurePipes() is called and the Host state machine is in the + * Configured state. + */ + uint8_t InterfaceNumber; /**< Interface index of the Printer interface within the attached device. */ + uint8_t AlternateSetting; /**< Alternate setting within the Printer Interface in the attached device. */ + } State; /**< State data for the USB class interface within the device. All elements in this section + * may be set to initial values, but may also be ignored to default to sane values when + * the interface is enumerated. + */ + } USB_ClassInfo_PRNT_Host_t; + + /* Enums: */ + /** Enum for the possible error codes returned by the \ref PRNT_Host_ConfigurePipes() function. */ + enum PRNT_Host_EnumerationFailure_ErrorCodes_t + { + PRNT_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully. */ + PRNT_ENUMERROR_InvalidConfigDescriptor = 1, /**< The device returned an invalid Configuration Descriptor. */ + PRNT_ENUMERROR_NoCompatibleInterfaceFound = 2, /**< A compatible Printer interface was not found in the device's Configuration Descriptor. */ + PRNT_ENUMERROR_PipeConfigurationFailed = 3, /**< One or more pipes for the specified interface could not be configured correctly. */ + }; + + /* Function Prototypes: */ + /** Host interface configuration routine, to configure a given Printer host interface instance using the + * Configuration Descriptor read from an attached USB device. This function automatically updates the given Printer + * instance's state values and configures the pipes required to communicate with the interface if it is found within + * the device. This should be called once after the stack has enumerated the attached device, while the host state + * machine is in the Addressed state. + * + * \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state. + * \param[in] ConfigDescriptorSize Length of the attached device's Configuration Descriptor. + * \param[in] ConfigDescriptorData Pointer to a buffer containing the attached device's Configuration Descriptor. + * + * \return A value from the \ref PRNT_Host_EnumerationFailure_ErrorCodes_t enum. + */ + uint8_t PRNT_Host_ConfigurePipes(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo, + uint16_t ConfigDescriptorSize, + void* ConfigDescriptorData) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3); + + /** General management task for a given Printer host class interface, required for the correct operation of + * the interface. This should be called frequently in the main program loop, before the master USB management task + * \ref USB_USBTask(). + * + * \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state. + */ + void PRNT_Host_USBTask(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + /** Configures the printer to enable Bidirectional mode, if it is not already in this mode. This should be called + * once the connected device's configuration has been set, to ensure the printer is ready to accept commands. + * + * \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state. + * + * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum. + */ + uint8_t PRNT_Host_SetBidirectionalMode(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + /** Retrieves the status of the virtual Printer port's inbound status lines. The result can then be masked against the + * \c PRNT_PORTSTATUS_* macros to determine the printer port's status. + * + * \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state. + * \param[out] PortStatus Location where the retrieved port status should be stored. + * + * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum. + */ + uint8_t PRNT_Host_GetPortStatus(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo, + uint8_t* const PortStatus) + ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); + + /** Soft-resets the attached printer, readying it for new commands. + * + * \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state. + * + * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum. + */ + uint8_t PRNT_Host_SoftReset(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + /** Flushes any data waiting to be sent, ensuring that the send buffer is cleared. + * + * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the + * call will fail. + * + * \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state. + * + * \return A value from the \ref Pipe_WaitUntilReady_ErrorCodes_t enum. + */ + uint8_t PRNT_Host_Flush(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + /** Sends the given null terminated string to the attached printer's input endpoint. + * + * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the + * call will fail. + * + * \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state. + * \param[in] String Pointer to a null terminated string to send. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. + */ + uint8_t PRNT_Host_SendString(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo, + const char* const String) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); + + /** Sends the given raw data stream to the attached printer's input endpoint. This should contain commands that the + * printer is able to understand - for example, PCL data. Not all printers accept all printer languages; see + * \ref PRNT_Host_GetDeviceID() for details on determining acceptable languages for an attached printer. + * + * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the + * call will fail. + * + * \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state. + * \param[in] Buffer Pointer to a buffer containing the raw command stream to send to the printer. + * \param[in] Length Size in bytes of the command stream to be sent. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. + */ + uint8_t PRNT_Host_SendData(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo, + void* Buffer, + const uint16_t Length) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); + + /** Sends a given byte to the attached USB device, if connected. If a device is not connected when the function is called, the + * byte is discarded. Bytes will be queued for transmission to the device until either the pipe bank becomes full, or the + * \ref PRNT_Host_Flush() function is called to flush the pending data to the host. This allows for multiple bytes to be + * packed into a single pipe packet, increasing data throughput. + * + * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the + * call will fail. + * + * \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state. + * \param[in] Data Byte of data to send to the device. + * + * \return A value from the \ref Pipe_WaitUntilReady_ErrorCodes_t enum. + */ + uint8_t PRNT_Host_SendByte(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo, + const uint8_t Data) ATTR_NON_NULL_PTR_ARG(1); + + /** Determines the number of bytes received by the printer interface from the device, waiting to be read. This indicates the number + * of bytes in the IN pipe bank only, and thus the number of calls to \ref PRNT_Host_ReceiveByte() which are guaranteed to succeed + * immediately. If multiple bytes are to be received, they should be buffered by the user application, as the pipe bank will not be + * released back to the USB controller until all bytes are read. + * + * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the + * call will fail. + * + * \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state. + * + * \return Total number of buffered bytes received from the device. + */ + uint16_t PRNT_Host_BytesReceived(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo); + + /** Reads a byte of data from the device. If no data is waiting to be read of if a USB device is not connected, the function + * returns a negative value. The \ref PRNT_Host_BytesReceived() function may be queried in advance to determine how many bytes + * are currently buffered in the Printer interface's data receive pipe. + * + * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the + * call will fail. + * + * \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state. + * + * \return Next received byte from the device, or a negative value if no data received. + */ + int16_t PRNT_Host_ReceiveByte(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo); + + /** Retrieves the attached printer device's ID string, formatted according to IEEE 1284. This string is sent as a + * Unicode string from the device and is automatically converted to an ASCII encoded C string by this function, thus + * the maximum reportable string length is two less than the size given (to accommodate the Unicode string length + * bytes which are removed). + * + * This string, when supported, contains the model, manufacturer and acceptable printer languages for the attached device. + * + * \param[in,out] PRNTInterfaceInfo Pointer to a structure containing a Printer Class host configuration and state. + * \param[out] DeviceIDString Pointer to a buffer where the Device ID string should be stored, in ASCII format. + * \param[in] BufferSize Size in bytes of the buffer allocated for the Device ID string. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. + */ + uint8_t PRNT_Host_GetDeviceID(USB_ClassInfo_PRNT_Host_t* const PRNTInterfaceInfo, + char* const DeviceIDString, + const uint16_t BufferSize) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Function Prototypes: */ + #if defined(__INCLUDE_FROM_PRINTER_HOST_C) + static uint8_t DCOMP_PRNT_Host_NextPRNTInterface(void* const CurrentDescriptor) + ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1); + static uint8_t DCOMP_PRNT_Host_NextPRNTInterfaceEndpoint(void* const CurrentDescriptor) + ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1); + #endif + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/RNDISClassHost.c b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/RNDISClassHost.c new file mode 100644 index 00000000..1e23f8e7 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/RNDISClassHost.c @@ -0,0 +1,476 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#define __INCLUDE_FROM_USB_DRIVER +#include "../../Core/USBMode.h" + +#if defined(USB_CAN_BE_HOST) + +#define __INCLUDE_FROM_RNDIS_DRIVER +#define __INCLUDE_FROM_RNDIS_HOST_C +#include "RNDISClassHost.h" + +uint8_t RNDIS_Host_ConfigurePipes(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo, + uint16_t ConfigDescriptorSize, + void* ConfigDescriptorData) +{ + USB_Descriptor_Endpoint_t* DataINEndpoint = NULL; + USB_Descriptor_Endpoint_t* DataOUTEndpoint = NULL; + USB_Descriptor_Endpoint_t* NotificationEndpoint = NULL; + USB_Descriptor_Interface_t* RNDISControlInterface = NULL; + + memset(&RNDISInterfaceInfo->State, 0x00, sizeof(RNDISInterfaceInfo->State)); + + if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration) + return RNDIS_ENUMERROR_InvalidConfigDescriptor; + + RNDISControlInterface = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Interface_t); + + while (!(DataINEndpoint) || !(DataOUTEndpoint) || !(NotificationEndpoint)) + { + if (!(RNDISControlInterface) || + USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, + DCOMP_RNDIS_Host_NextRNDISInterfaceEndpoint) != DESCRIPTOR_SEARCH_COMP_Found) + { + if (NotificationEndpoint) + { + if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, + DCOMP_RNDIS_Host_NextRNDISDataInterface) != DESCRIPTOR_SEARCH_COMP_Found) + { + return RNDIS_ENUMERROR_NoCompatibleInterfaceFound; + } + + DataINEndpoint = NULL; + DataOUTEndpoint = NULL; + } + else + { + if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, + DCOMP_RNDIS_Host_NextRNDISControlInterface) != DESCRIPTOR_SEARCH_COMP_Found) + { + return RNDIS_ENUMERROR_NoCompatibleInterfaceFound; + } + + RNDISControlInterface = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Interface_t); + + NotificationEndpoint = NULL; + } + + continue; + } + + USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Endpoint_t); + + if ((EndpointData->EndpointAddress & ENDPOINT_DIR_MASK) == ENDPOINT_DIR_IN) + { + if ((EndpointData->Attributes & EP_TYPE_MASK) == EP_TYPE_INTERRUPT) + NotificationEndpoint = EndpointData; + else + DataINEndpoint = EndpointData; + } + else + { + DataOUTEndpoint = EndpointData; + } + } + + RNDISInterfaceInfo->Config.DataINPipe.Size = le16_to_cpu(DataINEndpoint->EndpointSize); + RNDISInterfaceInfo->Config.DataINPipe.EndpointAddress = DataINEndpoint->EndpointAddress; + RNDISInterfaceInfo->Config.DataINPipe.Type = EP_TYPE_BULK; + + RNDISInterfaceInfo->Config.DataOUTPipe.Size = le16_to_cpu(DataOUTEndpoint->EndpointSize); + RNDISInterfaceInfo->Config.DataOUTPipe.EndpointAddress = DataOUTEndpoint->EndpointAddress; + RNDISInterfaceInfo->Config.DataOUTPipe.Type = EP_TYPE_BULK; + + RNDISInterfaceInfo->Config.NotificationPipe.Size = le16_to_cpu(NotificationEndpoint->EndpointSize); + RNDISInterfaceInfo->Config.NotificationPipe.EndpointAddress = NotificationEndpoint->EndpointAddress; + RNDISInterfaceInfo->Config.NotificationPipe.Type = EP_TYPE_INTERRUPT; + + if (!(Pipe_ConfigurePipeTable(&RNDISInterfaceInfo->Config.DataINPipe, 1))) + return false; + + if (!(Pipe_ConfigurePipeTable(&RNDISInterfaceInfo->Config.DataOUTPipe, 1))) + return false; + + if (!(Pipe_ConfigurePipeTable(&RNDISInterfaceInfo->Config.NotificationPipe, 1))) + return false; + + RNDISInterfaceInfo->State.ControlInterfaceNumber = RNDISControlInterface->InterfaceNumber; + RNDISInterfaceInfo->State.IsActive = true; + + return RNDIS_ENUMERROR_NoError; +} + +static uint8_t DCOMP_RNDIS_Host_NextRNDISControlInterface(void* const CurrentDescriptor) +{ + USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t); + + if (Header->Type == DTYPE_Interface) + { + USB_Descriptor_Interface_t* Interface = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Interface_t); + + if ((Interface->Class == CDC_CSCP_CDCClass) && + (Interface->SubClass == CDC_CSCP_ACMSubclass) && + (Interface->Protocol == CDC_CSCP_VendorSpecificProtocol)) + { + return DESCRIPTOR_SEARCH_Found; + } + } + + return DESCRIPTOR_SEARCH_NotFound; +} + +static uint8_t DCOMP_RNDIS_Host_NextRNDISDataInterface(void* const CurrentDescriptor) +{ + USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t); + + if (Header->Type == DTYPE_Interface) + { + USB_Descriptor_Interface_t* Interface = DESCRIPTOR_PCAST(CurrentDescriptor, + USB_Descriptor_Interface_t); + + if ((Interface->Class == CDC_CSCP_CDCDataClass) && + (Interface->SubClass == CDC_CSCP_NoDataSubclass) && + (Interface->Protocol == CDC_CSCP_NoDataProtocol)) + { + return DESCRIPTOR_SEARCH_Found; + } + } + + return DESCRIPTOR_SEARCH_NotFound; +} + +static uint8_t DCOMP_RNDIS_Host_NextRNDISInterfaceEndpoint(void* const CurrentDescriptor) +{ + USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t); + + if (Header->Type == DTYPE_Endpoint) + { + USB_Descriptor_Endpoint_t* Endpoint = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Endpoint_t); + + uint8_t EndpointType = (Endpoint->Attributes & EP_TYPE_MASK); + + if (((EndpointType == EP_TYPE_BULK) || (EndpointType == EP_TYPE_INTERRUPT)) && + !(Pipe_IsEndpointBound(Endpoint->EndpointAddress))) + { + return DESCRIPTOR_SEARCH_Found; + } + } + else if (Header->Type == DTYPE_Interface) + { + return DESCRIPTOR_SEARCH_Fail; + } + + return DESCRIPTOR_SEARCH_NotFound; +} + +static uint8_t RNDIS_SendEncapsulatedCommand(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo, + void* Buffer, + const uint16_t Length) +{ + USB_ControlRequest = (USB_Request_Header_t) + { + .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE), + .bRequest = RNDIS_REQ_SendEncapsulatedCommand, + .wValue = 0, + .wIndex = RNDISInterfaceInfo->State.ControlInterfaceNumber, + .wLength = Length, + }; + + Pipe_SelectPipe(PIPE_CONTROLPIPE); + + return USB_Host_SendControlRequest(Buffer); +} + +static uint8_t RNDIS_GetEncapsulatedResponse(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo, + void* Buffer, + const uint16_t Length) +{ + USB_ControlRequest = (USB_Request_Header_t) + { + .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE), + .bRequest = RNDIS_REQ_GetEncapsulatedResponse, + .wValue = 0, + .wIndex = RNDISInterfaceInfo->State.ControlInterfaceNumber, + .wLength = Length, + }; + + Pipe_SelectPipe(PIPE_CONTROLPIPE); + + return USB_Host_SendControlRequest(Buffer); +} + +uint8_t RNDIS_Host_SendKeepAlive(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo) +{ + uint8_t ErrorCode; + + RNDIS_KeepAlive_Message_t KeepAliveMessage; + RNDIS_KeepAlive_Complete_t KeepAliveMessageResponse; + + KeepAliveMessage.MessageType = CPU_TO_LE32(REMOTE_NDIS_KEEPALIVE_MSG); + KeepAliveMessage.MessageLength = CPU_TO_LE32(sizeof(RNDIS_KeepAlive_Message_t)); + KeepAliveMessage.RequestId = cpu_to_le32(RNDISInterfaceInfo->State.RequestID++); + + if ((ErrorCode = RNDIS_SendEncapsulatedCommand(RNDISInterfaceInfo, &KeepAliveMessage, + sizeof(RNDIS_KeepAlive_Message_t))) != HOST_SENDCONTROL_Successful) + { + return ErrorCode; + } + + if ((ErrorCode = RNDIS_GetEncapsulatedResponse(RNDISInterfaceInfo, &KeepAliveMessageResponse, + sizeof(RNDIS_KeepAlive_Complete_t))) != HOST_SENDCONTROL_Successful) + { + return ErrorCode; + } + + return HOST_SENDCONTROL_Successful; +} + +uint8_t RNDIS_Host_InitializeDevice(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo) +{ + uint8_t ErrorCode; + + RNDIS_Initialize_Message_t InitMessage; + RNDIS_Initialize_Complete_t InitMessageResponse; + + InitMessage.MessageType = CPU_TO_LE32(REMOTE_NDIS_INITIALIZE_MSG); + InitMessage.MessageLength = CPU_TO_LE32(sizeof(RNDIS_Initialize_Message_t)); + InitMessage.RequestId = cpu_to_le32(RNDISInterfaceInfo->State.RequestID++); + + InitMessage.MajorVersion = CPU_TO_LE32(REMOTE_NDIS_VERSION_MAJOR); + InitMessage.MinorVersion = CPU_TO_LE32(REMOTE_NDIS_VERSION_MINOR); + InitMessage.MaxTransferSize = cpu_to_le32(RNDISInterfaceInfo->Config.HostMaxPacketSize); + + if ((ErrorCode = RNDIS_SendEncapsulatedCommand(RNDISInterfaceInfo, &InitMessage, + sizeof(RNDIS_Initialize_Message_t))) != HOST_SENDCONTROL_Successful) + { + return ErrorCode; + } + + if ((ErrorCode = RNDIS_GetEncapsulatedResponse(RNDISInterfaceInfo, &InitMessageResponse, + sizeof(RNDIS_Initialize_Complete_t))) != HOST_SENDCONTROL_Successful) + { + return ErrorCode; + } + + if (InitMessageResponse.Status != CPU_TO_LE32(REMOTE_NDIS_STATUS_SUCCESS)) + return RNDIS_ERROR_LOGICAL_CMD_FAILED; + + RNDISInterfaceInfo->State.DeviceMaxPacketSize = le32_to_cpu(InitMessageResponse.MaxTransferSize); + + return HOST_SENDCONTROL_Successful; +} + +uint8_t RNDIS_Host_SetRNDISProperty(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo, + const uint32_t Oid, + void* Buffer, + const uint16_t Length) +{ + uint8_t ErrorCode; + + struct + { + RNDIS_Set_Message_t SetMessage; + uint8_t ContiguousBuffer[Length]; + } SetMessageData; + + RNDIS_Set_Complete_t SetMessageResponse; + + SetMessageData.SetMessage.MessageType = CPU_TO_LE32(REMOTE_NDIS_SET_MSG); + SetMessageData.SetMessage.MessageLength = cpu_to_le32(sizeof(RNDIS_Set_Message_t) + Length); + SetMessageData.SetMessage.RequestId = cpu_to_le32(RNDISInterfaceInfo->State.RequestID++); + + SetMessageData.SetMessage.Oid = cpu_to_le32(Oid); + SetMessageData.SetMessage.InformationBufferLength = cpu_to_le32(Length); + SetMessageData.SetMessage.InformationBufferOffset = CPU_TO_LE32(sizeof(RNDIS_Set_Message_t) - sizeof(RNDIS_Message_Header_t)); + SetMessageData.SetMessage.DeviceVcHandle = CPU_TO_LE32(0); + + memcpy(&SetMessageData.ContiguousBuffer, Buffer, Length); + + if ((ErrorCode = RNDIS_SendEncapsulatedCommand(RNDISInterfaceInfo, &SetMessageData, + (sizeof(RNDIS_Set_Message_t) + Length))) != HOST_SENDCONTROL_Successful) + { + return ErrorCode; + } + + if ((ErrorCode = RNDIS_GetEncapsulatedResponse(RNDISInterfaceInfo, &SetMessageResponse, + sizeof(RNDIS_Set_Complete_t))) != HOST_SENDCONTROL_Successful) + { + return ErrorCode; + } + + if (SetMessageResponse.Status != CPU_TO_LE32(REMOTE_NDIS_STATUS_SUCCESS)) + return RNDIS_ERROR_LOGICAL_CMD_FAILED; + + return HOST_SENDCONTROL_Successful; +} + +uint8_t RNDIS_Host_QueryRNDISProperty(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo, + const uint32_t Oid, + void* Buffer, + const uint16_t MaxLength) +{ + uint8_t ErrorCode; + + RNDIS_Query_Message_t QueryMessage; + + struct + { + RNDIS_Query_Complete_t QueryMessageResponse; + uint8_t ContiguousBuffer[MaxLength]; + } QueryMessageResponseData; + + QueryMessage.MessageType = CPU_TO_LE32(REMOTE_NDIS_QUERY_MSG); + QueryMessage.MessageLength = CPU_TO_LE32(sizeof(RNDIS_Query_Message_t)); + QueryMessage.RequestId = cpu_to_le32(RNDISInterfaceInfo->State.RequestID++); + + QueryMessage.Oid = cpu_to_le32(Oid); + QueryMessage.InformationBufferLength = CPU_TO_LE32(0); + QueryMessage.InformationBufferOffset = CPU_TO_LE32(0); + QueryMessage.DeviceVcHandle = CPU_TO_LE32(0); + + if ((ErrorCode = RNDIS_SendEncapsulatedCommand(RNDISInterfaceInfo, &QueryMessage, + sizeof(RNDIS_Query_Message_t))) != HOST_SENDCONTROL_Successful) + { + return ErrorCode; + } + + if ((ErrorCode = RNDIS_GetEncapsulatedResponse(RNDISInterfaceInfo, &QueryMessageResponseData, + sizeof(QueryMessageResponseData))) != HOST_SENDCONTROL_Successful) + { + return ErrorCode; + } + + if (QueryMessageResponseData.QueryMessageResponse.Status != CPU_TO_LE32(REMOTE_NDIS_STATUS_SUCCESS)) + return RNDIS_ERROR_LOGICAL_CMD_FAILED; + + memcpy(Buffer, &QueryMessageResponseData.ContiguousBuffer, MaxLength); + + return HOST_SENDCONTROL_Successful; +} + +bool RNDIS_Host_IsPacketReceived(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo) +{ + bool PacketWaiting; + + if ((USB_HostState != HOST_STATE_Configured) || !(RNDISInterfaceInfo->State.IsActive)) + return false; + + Pipe_SelectPipe(RNDISInterfaceInfo->Config.DataINPipe.Address); + + Pipe_Unfreeze(); + PacketWaiting = Pipe_IsINReceived(); + Pipe_Freeze(); + + return PacketWaiting; +} + +uint8_t RNDIS_Host_ReadPacket(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo, + void* Buffer, + uint16_t* const PacketLength) +{ + uint8_t ErrorCode; + + if ((USB_HostState != HOST_STATE_Configured) || !(RNDISInterfaceInfo->State.IsActive)) + return PIPE_READYWAIT_DeviceDisconnected; + + Pipe_SelectPipe(RNDISInterfaceInfo->Config.DataINPipe.Address); + Pipe_Unfreeze(); + + if (!(Pipe_IsReadWriteAllowed())) + { + if (Pipe_IsINReceived()) + Pipe_ClearIN(); + + *PacketLength = 0; + Pipe_Freeze(); + return PIPE_RWSTREAM_NoError; + } + + RNDIS_Packet_Message_t DeviceMessage; + + if ((ErrorCode = Pipe_Read_Stream_LE(&DeviceMessage, sizeof(RNDIS_Packet_Message_t), + NULL)) != PIPE_RWSTREAM_NoError) + { + return ErrorCode; + } + + *PacketLength = (uint16_t)le32_to_cpu(DeviceMessage.DataLength); + + Pipe_Discard_Stream(le32_to_cpu(DeviceMessage.DataOffset) - + (sizeof(RNDIS_Packet_Message_t) - sizeof(RNDIS_Message_Header_t)), + NULL); + + Pipe_Read_Stream_LE(Buffer, *PacketLength, NULL); + + if (!(Pipe_BytesInPipe())) + Pipe_ClearIN(); + + Pipe_Freeze(); + + return PIPE_RWSTREAM_NoError; +} + +uint8_t RNDIS_Host_SendPacket(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo, + void* Buffer, + const uint16_t PacketLength) +{ + uint8_t ErrorCode; + + if ((USB_HostState != HOST_STATE_Configured) || !(RNDISInterfaceInfo->State.IsActive)) + return PIPE_READYWAIT_DeviceDisconnected; + + RNDIS_Packet_Message_t DeviceMessage; + + memset(&DeviceMessage, 0, sizeof(RNDIS_Packet_Message_t)); + DeviceMessage.MessageType = CPU_TO_LE32(REMOTE_NDIS_PACKET_MSG); + DeviceMessage.MessageLength = CPU_TO_LE32(sizeof(RNDIS_Packet_Message_t) + PacketLength); + DeviceMessage.DataOffset = CPU_TO_LE32(sizeof(RNDIS_Packet_Message_t) - sizeof(RNDIS_Message_Header_t)); + DeviceMessage.DataLength = cpu_to_le32(PacketLength); + + Pipe_SelectPipe(RNDISInterfaceInfo->Config.DataOUTPipe.Address); + Pipe_Unfreeze(); + + if ((ErrorCode = Pipe_Write_Stream_LE(&DeviceMessage, sizeof(RNDIS_Packet_Message_t), + NULL)) != PIPE_RWSTREAM_NoError) + { + return ErrorCode; + } + + Pipe_Write_Stream_LE(Buffer, PacketLength, NULL); + Pipe_ClearOUT(); + + Pipe_Freeze(); + + return PIPE_RWSTREAM_NoError; +} + +#endif + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/RNDISClassHost.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/RNDISClassHost.h new file mode 100644 index 00000000..bac6d5c2 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/RNDISClassHost.h @@ -0,0 +1,270 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Host mode driver for the library USB RNDIS Class driver. + * + * Host mode driver for the library USB RNDIS Class driver. + * + * \note This file should not be included directly. It is automatically included as needed by the USB module driver + * dispatch header located in LUFA/Drivers/USB.h. + */ + +/** \ingroup Group_USBClassRNDIS + * \defgroup Group_USBClassRNDISHost RNDIS Class Host Mode Driver + * + * \section Sec_Dependencies Module Source Dependencies + * The following files must be built with any user project that uses this module: + * - LUFA/Drivers/USB/Class/Host/RNDISClassHost.c (Makefile source module name: LUFA_SRC_USBCLASS) + * + * \section Sec_ModDescription Module Description + * Host Mode USB Class driver framework interface, for the Microsoft RNDIS Ethernet + * USB Class driver. + * + * @{ + */ + +#ifndef __RNDIS_CLASS_HOST_H__ +#define __RNDIS_CLASS_HOST_H__ + + /* Includes: */ + #include "../../USB.h" + #include "../Common/RNDISClassCommon.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_RNDIS_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Type Defines: */ + /** \brief RNDIS Class Host Mode Configuration and State Structure. + * + * Class state structure. An instance of this structure should be made within the user application, + * and passed to each of the RNDIS class driver functions as the \c RNDISInterfaceInfo parameter. This + * stores each RNDIS interface's configuration and state information. + */ + typedef struct + { + struct + { + USB_Pipe_Table_t DataINPipe; /**< Data IN Pipe configuration table. */ + USB_Pipe_Table_t DataOUTPipe; /**< Data OUT Pipe configuration table. */ + USB_Pipe_Table_t NotificationPipe; /**< Notification IN Pipe configuration table. */ + + uint32_t HostMaxPacketSize; /**< Maximum size of a packet which can be buffered by the host. */ + } Config; /**< Config data for the USB class interface within the device. All elements in this section + * must be set or the interface will fail to enumerate and operate correctly. + */ + struct + { + bool IsActive; /**< Indicates if the current interface instance is connected to an attached device, valid + * after \ref RNDIS_Host_ConfigurePipes() is called and the Host state machine is in the + * Configured state. + */ + uint8_t ControlInterfaceNumber; /**< Interface index of the RNDIS control interface within the attached device. */ + + uint32_t DeviceMaxPacketSize; /**< Maximum size of a packet which can be buffered by the attached RNDIS device. */ + + uint32_t RequestID; /**< Request ID counter to give a unique ID for each command/response pair. */ + } State; /**< State data for the USB class interface within the device. All elements in this section + * may be set to initial values, but may also be ignored to default to sane values when + * the interface is enumerated. + */ + } USB_ClassInfo_RNDIS_Host_t; + + /* Enums: */ + /** Enum for the possible error codes returned by the \ref RNDIS_Host_ConfigurePipes() function. */ + enum RNDIS_Host_EnumerationFailure_ErrorCodes_t + { + RNDIS_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully. */ + RNDIS_ENUMERROR_InvalidConfigDescriptor = 1, /**< The device returned an invalid Configuration Descriptor. */ + RNDIS_ENUMERROR_NoCompatibleInterfaceFound = 2, /**< A compatible RNDIS interface was not found in the device's Configuration Descriptor. */ + RNDIS_ENUMERROR_PipeConfigurationFailed = 3, /**< One or more pipes for the specified interface could not be configured correctly. */ + }; + + /* Function Prototypes: */ + /** Host interface configuration routine, to configure a given RNDIS host interface instance using the Configuration + * Descriptor read from an attached USB device. This function automatically updates the given RNDIS Host instance's + * state values and configures the pipes required to communicate with the interface if it is found within the device. + * This should be called once after the stack has enumerated the attached device, while the host state machine is in + * the Addressed state. + * + * \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class host configuration and state. + * \param[in] ConfigDescriptorSize Length of the attached device's Configuration Descriptor. + * \param[in] ConfigDescriptorData Pointer to a buffer containing the attached device's Configuration Descriptor. + * + * \return A value from the \ref RNDIS_Host_EnumerationFailure_ErrorCodes_t enum. + */ + uint8_t RNDIS_Host_ConfigurePipes(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo, + uint16_t ConfigDescriptorSize, + void* ConfigDescriptorData) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3); + + /** Sends a RNDIS KEEPALIVE command to the device, to ensure that it does not enter standby mode after periods + * of long inactivity. + * + * \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class host configuration and state. + * + * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum or \ref RNDIS_ERROR_LOGICAL_CMD_FAILED if the device returned a + * logical command failure. + */ + uint8_t RNDIS_Host_SendKeepAlive(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + /** Initializes the attached RNDIS device's RNDIS interface. This should be called after the device's pipes have been + * configured via the call to \ref RNDIS_Host_ConfigurePipes(). + * + * \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class host configuration and state. + * + * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum or \ref RNDIS_ERROR_LOGICAL_CMD_FAILED if the + * device returned a logical command failure. + */ + uint8_t RNDIS_Host_InitializeDevice(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + /** Sets a given RNDIS property of an attached RNDIS device. + * + * \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class host configuration and state. + * \param[in] Oid OID number of the parameter to set. + * \param[in] Buffer Pointer to where the property data is to be sourced from. + * \param[in] Length Length in bytes of the property data to sent to the device. + * + * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum or \ref RNDIS_ERROR_LOGICAL_CMD_FAILED if the + * device returned a logical command failure. + */ + uint8_t RNDIS_Host_SetRNDISProperty(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo, + const uint32_t Oid, + void* Buffer, + const uint16_t Length) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3); + + /** Gets a given RNDIS property of an attached RNDIS device. + * + * \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class host configuration and state. + * \param[in] Oid OID number of the parameter to get. + * \param[in] Buffer Pointer to where the property data is to be written to. + * \param[in] MaxLength Length in bytes of the destination buffer size. + * + * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum or \ref RNDIS_ERROR_LOGICAL_CMD_FAILED if the + * device returned a logical command failure. + */ + uint8_t RNDIS_Host_QueryRNDISProperty(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo, + const uint32_t Oid, + void* Buffer, + const uint16_t MaxLength) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3); + + /** Determines if a packet is currently waiting for the host to read in and process. + * + * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the + * call will fail. + * + * \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class host configuration and state. + * + * \return Boolean \c true if a packet is waiting to be read in by the host, \c false otherwise. + */ + bool RNDIS_Host_IsPacketReceived(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + /** Retrieves the next pending packet from the device, discarding the remainder of the RNDIS packet header to leave + * only the packet contents for processing by the host in the nominated buffer. + * + * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the + * call will fail. + * + * \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class host configuration and state. + * \param[out] Buffer Pointer to a buffer where the packer data is to be written to. + * \param[out] PacketLength Pointer to where the length in bytes of the read packet is to be stored. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. + */ + uint8_t RNDIS_Host_ReadPacket(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo, + void* Buffer, + uint16_t* const PacketLength) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2) + ATTR_NON_NULL_PTR_ARG(3); + + /** Sends the given packet to the attached RNDIS device, after adding a RNDIS packet message header. + * + * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the + * call will fail. + * + * \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class host configuration and state. + * \param[in] Buffer Pointer to a buffer where the packer data is to be read from. + * \param[in] PacketLength Length in bytes of the packet to send. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. + */ + uint8_t RNDIS_Host_SendPacket(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo, + void* Buffer, + const uint16_t PacketLength) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); + + /* Inline Functions: */ + /** General management task for a given RNDIS host class interface, required for the correct operation of the interface. This should + * be called frequently in the main program loop, before the master USB management task \ref USB_USBTask(). + * + * \param[in,out] RNDISInterfaceInfo Pointer to a structure containing an RNDIS Class host configuration and state. + */ + static inline void RNDIS_Host_USBTask(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE; + static inline void RNDIS_Host_USBTask(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo) + { + (void)RNDISInterfaceInfo; + } + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Function Prototypes: */ + #if defined(__INCLUDE_FROM_RNDIS_HOST_C) + static uint8_t RNDIS_SendEncapsulatedCommand(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo, + void* Buffer, + const uint16_t Length) ATTR_NON_NULL_PTR_ARG(1) + ATTR_NON_NULL_PTR_ARG(2); + static uint8_t RNDIS_GetEncapsulatedResponse(USB_ClassInfo_RNDIS_Host_t* const RNDISInterfaceInfo, + void* Buffer, + const uint16_t Length) ATTR_NON_NULL_PTR_ARG(1) + ATTR_NON_NULL_PTR_ARG(2); + + static uint8_t DCOMP_RNDIS_Host_NextRNDISControlInterface(void* const CurrentDescriptor) + ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1); + static uint8_t DCOMP_RNDIS_Host_NextRNDISDataInterface(void* const CurrentDescriptor) + ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1); + static uint8_t DCOMP_RNDIS_Host_NextRNDISInterfaceEndpoint(void* const CurrentDescriptor) + ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1); + #endif + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/StillImageClassHost.c b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/StillImageClassHost.c new file mode 100644 index 00000000..a6137b19 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/StillImageClassHost.c @@ -0,0 +1,436 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#define __INCLUDE_FROM_USB_DRIVER +#include "../../Core/USBMode.h" + +#if defined(USB_CAN_BE_HOST) + +#define __INCLUDE_FROM_SI_DRIVER +#define __INCLUDE_FROM_STILLIMAGE_HOST_C +#include "StillImageClassHost.h" + +uint8_t SI_Host_ConfigurePipes(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo, + uint16_t ConfigDescriptorSize, + void* ConfigDescriptorData) +{ + USB_Descriptor_Endpoint_t* DataINEndpoint = NULL; + USB_Descriptor_Endpoint_t* DataOUTEndpoint = NULL; + USB_Descriptor_Endpoint_t* EventsEndpoint = NULL; + USB_Descriptor_Interface_t* StillImageInterface = NULL; + + memset(&SIInterfaceInfo->State, 0x00, sizeof(SIInterfaceInfo->State)); + + if (DESCRIPTOR_TYPE(ConfigDescriptorData) != DTYPE_Configuration) + return SI_ENUMERROR_InvalidConfigDescriptor; + + while (!(DataINEndpoint) || !(DataOUTEndpoint) || !(EventsEndpoint)) + { + if (!(StillImageInterface) || + USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, + DCOMP_SI_Host_NextSIInterfaceEndpoint) != DESCRIPTOR_SEARCH_COMP_Found) + { + if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData, + DCOMP_SI_Host_NextSIInterface) != DESCRIPTOR_SEARCH_COMP_Found) + { + return SI_ENUMERROR_NoCompatibleInterfaceFound; + } + + StillImageInterface = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Interface_t); + + DataINEndpoint = NULL; + DataOUTEndpoint = NULL; + EventsEndpoint = NULL; + + continue; + } + + USB_Descriptor_Endpoint_t* EndpointData = DESCRIPTOR_PCAST(ConfigDescriptorData, USB_Descriptor_Endpoint_t); + + if ((EndpointData->EndpointAddress & ENDPOINT_DIR_MASK) == ENDPOINT_DIR_IN) + { + if ((EndpointData->Attributes & EP_TYPE_MASK) == EP_TYPE_INTERRUPT) + EventsEndpoint = EndpointData; + else + DataINEndpoint = EndpointData; + } + else + { + DataOUTEndpoint = EndpointData; + } + } + + SIInterfaceInfo->Config.DataINPipe.Size = le16_to_cpu(DataINEndpoint->EndpointSize); + SIInterfaceInfo->Config.DataINPipe.EndpointAddress = DataINEndpoint->EndpointAddress; + SIInterfaceInfo->Config.DataINPipe.Type = EP_TYPE_BULK; + + SIInterfaceInfo->Config.DataOUTPipe.Size = le16_to_cpu(DataOUTEndpoint->EndpointSize); + SIInterfaceInfo->Config.DataOUTPipe.EndpointAddress = DataOUTEndpoint->EndpointAddress; + SIInterfaceInfo->Config.DataOUTPipe.Type = EP_TYPE_BULK; + + SIInterfaceInfo->Config.EventsPipe.Size = le16_to_cpu(EventsEndpoint->EndpointSize); + SIInterfaceInfo->Config.EventsPipe.EndpointAddress = EventsEndpoint->EndpointAddress; + SIInterfaceInfo->Config.EventsPipe.Type = EP_TYPE_INTERRUPT; + + if (!(Pipe_ConfigurePipeTable(&SIInterfaceInfo->Config.DataINPipe, 1))) + return false; + + if (!(Pipe_ConfigurePipeTable(&SIInterfaceInfo->Config.DataOUTPipe, 1))) + return false; + + if (!(Pipe_ConfigurePipeTable(&SIInterfaceInfo->Config.EventsPipe, 1))) + return false; + + SIInterfaceInfo->State.InterfaceNumber = StillImageInterface->InterfaceNumber; + SIInterfaceInfo->State.IsActive = true; + + return SI_ENUMERROR_NoError; +} + +uint8_t DCOMP_SI_Host_NextSIInterface(void* const CurrentDescriptor) +{ + USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t); + + if (Header->Type == DTYPE_Interface) + { + USB_Descriptor_Interface_t* Interface = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Interface_t); + + if ((Interface->Class == SI_CSCP_StillImageClass) && + (Interface->SubClass == SI_CSCP_StillImageSubclass) && + (Interface->Protocol == SI_CSCP_BulkOnlyProtocol)) + { + return DESCRIPTOR_SEARCH_Found; + } + } + + return DESCRIPTOR_SEARCH_NotFound; +} + +uint8_t DCOMP_SI_Host_NextSIInterfaceEndpoint(void* const CurrentDescriptor) +{ + USB_Descriptor_Header_t* Header = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Header_t); + + if (Header->Type == DTYPE_Endpoint) + { + USB_Descriptor_Endpoint_t* Endpoint = DESCRIPTOR_PCAST(CurrentDescriptor, USB_Descriptor_Endpoint_t); + + uint8_t EndpointType = (Endpoint->Attributes & EP_TYPE_MASK); + + if (((EndpointType == EP_TYPE_BULK) || (EndpointType == EP_TYPE_INTERRUPT)) && + (!(Pipe_IsEndpointBound(Endpoint->EndpointAddress)))) + { + return DESCRIPTOR_SEARCH_Found; + } + } + else if (Header->Type == DTYPE_Interface) + { + return DESCRIPTOR_SEARCH_Fail; + } + + return DESCRIPTOR_SEARCH_NotFound; +} + +uint8_t SI_Host_SendBlockHeader(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo, + PIMA_Container_t* const PIMAHeader) +{ + uint8_t ErrorCode; + + if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive)) + return PIPE_RWSTREAM_DeviceDisconnected; + + if (SIInterfaceInfo->State.IsSessionOpen) + PIMAHeader->TransactionID = cpu_to_le32(SIInterfaceInfo->State.TransactionID++); + + Pipe_SelectPipe(SIInterfaceInfo->Config.DataOUTPipe.Address); + Pipe_Unfreeze(); + + if ((ErrorCode = Pipe_Write_Stream_LE(PIMAHeader, PIMA_COMMAND_SIZE(0), NULL)) != PIPE_RWSTREAM_NoError) + return ErrorCode; + + uint8_t ParamBytes = (PIMAHeader->DataLength - PIMA_COMMAND_SIZE(0)); + + if (ParamBytes) + { + if ((ErrorCode = Pipe_Write_Stream_LE(&PIMAHeader->Params, ParamBytes, NULL)) != PIPE_RWSTREAM_NoError) + return ErrorCode; + } + + Pipe_ClearOUT(); + Pipe_Freeze(); + + return PIPE_RWSTREAM_NoError; +} + +uint8_t SI_Host_ReceiveBlockHeader(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo, + PIMA_Container_t* const PIMAHeader) +{ + uint16_t TimeoutMSRem = SI_COMMAND_DATA_TIMEOUT_MS; + uint16_t PreviousFrameNumber = USB_Host_GetFrameNumber(); + + if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive)) + return PIPE_RWSTREAM_DeviceDisconnected; + + Pipe_SelectPipe(SIInterfaceInfo->Config.DataINPipe.Address); + Pipe_Unfreeze(); + + while (!(Pipe_IsINReceived())) + { + uint16_t CurrentFrameNumber = USB_Host_GetFrameNumber(); + + if (CurrentFrameNumber != PreviousFrameNumber) + { + PreviousFrameNumber = CurrentFrameNumber; + + if (!(TimeoutMSRem--)) + return PIPE_RWSTREAM_Timeout; + } + + Pipe_Freeze(); + Pipe_SelectPipe(SIInterfaceInfo->Config.DataOUTPipe.Address); + Pipe_Unfreeze(); + + if (Pipe_IsStalled()) + { + USB_Host_ClearEndpointStall(Pipe_GetBoundEndpointAddress()); + return PIPE_RWSTREAM_PipeStalled; + } + + Pipe_Freeze(); + Pipe_SelectPipe(SIInterfaceInfo->Config.DataINPipe.Address); + Pipe_Unfreeze(); + + if (Pipe_IsStalled()) + { + USB_Host_ClearEndpointStall(Pipe_GetBoundEndpointAddress()); + return PIPE_RWSTREAM_PipeStalled; + } + + if (USB_HostState == HOST_STATE_Unattached) + return PIPE_RWSTREAM_DeviceDisconnected; + } + + Pipe_Read_Stream_LE(PIMAHeader, PIMA_COMMAND_SIZE(0), NULL); + + if (PIMAHeader->Type == CPU_TO_LE16(PIMA_CONTAINER_ResponseBlock)) + { + uint8_t ParamBytes = (PIMAHeader->DataLength - PIMA_COMMAND_SIZE(0)); + + if (ParamBytes) + Pipe_Read_Stream_LE(&PIMAHeader->Params, ParamBytes, NULL); + + Pipe_ClearIN(); + } + + Pipe_Freeze(); + + return PIPE_RWSTREAM_NoError; +} + +uint8_t SI_Host_SendData(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo, + void* Buffer, + const uint16_t Bytes) +{ + uint8_t ErrorCode; + + if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive)) + return PIPE_RWSTREAM_DeviceDisconnected; + + Pipe_SelectPipe(SIInterfaceInfo->Config.DataOUTPipe.Address); + Pipe_Unfreeze(); + + ErrorCode = Pipe_Write_Stream_LE(Buffer, Bytes, NULL); + + Pipe_ClearOUT(); + Pipe_Freeze(); + + return ErrorCode; +} + +uint8_t SI_Host_ReadData(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo, + void* Buffer, + const uint16_t Bytes) +{ + uint8_t ErrorCode; + + if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive)) + return PIPE_RWSTREAM_DeviceDisconnected; + + Pipe_SelectPipe(SIInterfaceInfo->Config.DataINPipe.Address); + Pipe_Unfreeze(); + + ErrorCode = Pipe_Read_Stream_LE(Buffer, Bytes, NULL); + + Pipe_Freeze(); + + return ErrorCode; +} + +bool SI_Host_IsEventReceived(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo) +{ + bool IsEventReceived = false; + + if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive)) + return false; + + Pipe_SelectPipe(SIInterfaceInfo->Config.EventsPipe.Address); + Pipe_Unfreeze(); + + if (Pipe_BytesInPipe()) + IsEventReceived = true; + + Pipe_Freeze(); + + return IsEventReceived; +} + +uint8_t SI_Host_ReceiveEventHeader(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo, + PIMA_Container_t* const PIMAHeader) +{ + uint8_t ErrorCode; + + if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive)) + return PIPE_RWSTREAM_DeviceDisconnected; + + Pipe_SelectPipe(SIInterfaceInfo->Config.EventsPipe.Address); + Pipe_Unfreeze(); + + ErrorCode = Pipe_Read_Stream_LE(PIMAHeader, sizeof(PIMA_Container_t), NULL); + + Pipe_ClearIN(); + Pipe_Freeze(); + + return ErrorCode; +} + +uint8_t SI_Host_OpenSession(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo) +{ + if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive)) + return PIPE_RWSTREAM_DeviceDisconnected; + + uint8_t ErrorCode; + + SIInterfaceInfo->State.TransactionID = 0; + SIInterfaceInfo->State.IsSessionOpen = false; + + PIMA_Container_t PIMABlock = (PIMA_Container_t) + { + .DataLength = CPU_TO_LE32(PIMA_COMMAND_SIZE(1)), + .Type = CPU_TO_LE16(PIMA_CONTAINER_CommandBlock), + .Code = CPU_TO_LE16(0x1002), + .Params = {CPU_TO_LE32(1)}, + }; + + if ((ErrorCode = SI_Host_SendBlockHeader(SIInterfaceInfo, &PIMABlock)) != PIPE_RWSTREAM_NoError) + return ErrorCode; + + if ((ErrorCode = SI_Host_ReceiveBlockHeader(SIInterfaceInfo, &PIMABlock)) != PIPE_RWSTREAM_NoError) + return ErrorCode; + + if ((PIMABlock.Type != CPU_TO_LE16(PIMA_CONTAINER_ResponseBlock)) || (PIMABlock.Code != CPU_TO_LE16(0x2001))) + return SI_ERROR_LOGICAL_CMD_FAILED; + + SIInterfaceInfo->State.IsSessionOpen = true; + + return PIPE_RWSTREAM_NoError; +} + +uint8_t SI_Host_CloseSession(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo) +{ + if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive)) + return PIPE_RWSTREAM_DeviceDisconnected; + + uint8_t ErrorCode; + + PIMA_Container_t PIMABlock = (PIMA_Container_t) + { + .DataLength = CPU_TO_LE32(PIMA_COMMAND_SIZE(1)), + .Type = CPU_TO_LE16(PIMA_CONTAINER_CommandBlock), + .Code = CPU_TO_LE16(0x1003), + .Params = {CPU_TO_LE32(1)}, + }; + + if ((ErrorCode = SI_Host_SendBlockHeader(SIInterfaceInfo, &PIMABlock)) != PIPE_RWSTREAM_NoError) + return ErrorCode; + + if ((ErrorCode = SI_Host_ReceiveBlockHeader(SIInterfaceInfo, &PIMABlock)) != PIPE_RWSTREAM_NoError) + return ErrorCode; + + SIInterfaceInfo->State.IsSessionOpen = false; + + if ((PIMABlock.Type != CPU_TO_LE16(PIMA_CONTAINER_ResponseBlock)) || (PIMABlock.Code != CPU_TO_LE16(0x2001))) + return SI_ERROR_LOGICAL_CMD_FAILED; + + return PIPE_RWSTREAM_NoError; +} + +uint8_t SI_Host_SendCommand(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo, + const uint16_t Operation, + const uint8_t TotalParams, + uint32_t* const Params) +{ + if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive)) + return PIPE_RWSTREAM_DeviceDisconnected; + + uint8_t ErrorCode; + + PIMA_Container_t PIMABlock = (PIMA_Container_t) + { + .DataLength = cpu_to_le32(PIMA_COMMAND_SIZE(TotalParams)), + .Type = CPU_TO_LE16(PIMA_CONTAINER_CommandBlock), + .Code = cpu_to_le16(Operation), + }; + + memcpy(&PIMABlock.Params, Params, sizeof(uint32_t) * TotalParams); + + if ((ErrorCode = SI_Host_SendBlockHeader(SIInterfaceInfo, &PIMABlock)) != PIPE_RWSTREAM_NoError) + return ErrorCode; + + return PIPE_RWSTREAM_NoError; +} + +uint8_t SI_Host_ReceiveResponse(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo) +{ + uint8_t ErrorCode; + PIMA_Container_t PIMABlock; + + if ((USB_HostState != HOST_STATE_Configured) || !(SIInterfaceInfo->State.IsActive)) + return PIPE_RWSTREAM_DeviceDisconnected; + + if ((ErrorCode = SI_Host_ReceiveBlockHeader(SIInterfaceInfo, &PIMABlock)) != PIPE_RWSTREAM_NoError) + return ErrorCode; + + if ((PIMABlock.Type != CPU_TO_LE16(PIMA_CONTAINER_ResponseBlock)) || (PIMABlock.Code != CPU_TO_LE16(0x2001))) + return SI_ERROR_LOGICAL_CMD_FAILED; + + return PIPE_RWSTREAM_NoError; +} + +#endif + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/StillImageClassHost.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/StillImageClassHost.h new file mode 100644 index 00000000..acfbd7d6 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/Host/StillImageClassHost.h @@ -0,0 +1,317 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Host mode driver for the library USB Still Image Class driver. + * + * Host mode driver for the library USB Still Image Class driver. + * + * \note This file should not be included directly. It is automatically included as needed by the USB module driver + * dispatch header located in LUFA/Drivers/USB.h. + */ + +/** \ingroup Group_USBClassSI + * \defgroup Group_USBClassStillImageHost Still Image Class Host Mode Driver + * + * \section Sec_Dependencies Module Source Dependencies + * The following files must be built with any user project that uses this module: + * - LUFA/Drivers/USB/Class/Host/StillImageClassHost.c (Makefile source module name: LUFA_SRC_USBCLASS) + * + * \section Sec_ModDescription Module Description + * Host Mode USB Class driver framework interface, for the Still Image USB Class driver. + * + * @{ + */ + +#ifndef __SI_CLASS_HOST_H__ +#define __SI_CLASS_HOST_H__ + + /* Includes: */ + #include "../../USB.h" + #include "../Common/StillImageClassCommon.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_SI_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Error code for some Still Image Host functions, indicating a logical (and not hardware) error. */ + #define SI_ERROR_LOGICAL_CMD_FAILED 0x80 + + /* Type Defines: */ + /** \brief Still Image Class Host Mode Configuration and State Structure. + * + * Class state structure. An instance of this structure should be made within the user application, + * and passed to each of the Still Image class driver functions as the \c SIInterfaceInfo parameter. This + * stores each Still Image interface's configuration and state information. + */ + typedef struct + { + struct + { + USB_Pipe_Table_t DataINPipe; /**< Data IN Pipe configuration table. */ + USB_Pipe_Table_t DataOUTPipe; /**< Data OUT Pipe configuration table. */ + USB_Pipe_Table_t EventsPipe; /**< Event notification IN Pipe configuration table. */ + } Config; /**< Config data for the USB class interface within the device. All elements in this section + * must be set or the interface will fail to enumerate and operate correctly. + */ + struct + { + bool IsActive; /**< Indicates if the current interface instance is connected to an attached device, valid + * after \ref SI_Host_ConfigurePipes() is called and the Host state machine is in the + * Configured state. + */ + uint8_t InterfaceNumber; /**< Interface index of the Still Image interface within the attached device. */ + + bool IsSessionOpen; /**< Indicates if a PIMA session is currently open with the attached device. */ + uint32_t TransactionID; /**< Transaction ID for the next transaction to send to the device. */ + } State; /**< State data for the USB class interface within the device. All elements in this section + * may be set to initial values, but may also be ignored to default to sane values when + * the interface is enumerated. + */ + } USB_ClassInfo_SI_Host_t; + + /* Enums: */ + /** Enum for the possible error codes returned by the \ref SI_Host_ConfigurePipes() function. */ + enum SI_Host_EnumerationFailure_ErrorCodes_t + { + SI_ENUMERROR_NoError = 0, /**< Configuration Descriptor was processed successfully. */ + SI_ENUMERROR_InvalidConfigDescriptor = 1, /**< The device returned an invalid Configuration Descriptor. */ + SI_ENUMERROR_NoCompatibleInterfaceFound = 2, /**< A compatible Still Image interface was not found in the device's + * Configuration Descriptor. + */ + SI_ENUMERROR_PipeConfigurationFailed = 3, /**< One or more pipes for the specified interface could not be configured correctly. */ + }; + + /* Function Prototypes: */ + /** Host interface configuration routine, to configure a given Still Image host interface instance using the + * Configuration Descriptor read from an attached USB device. This function automatically updates the given Still + * Image Host instance's state values and configures the pipes required to communicate with the interface if it is + * found within the device. This should be called once after the stack has enumerated the attached device, while + * the host state machine is in the Addressed state. + * + * \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state. + * \param[in] ConfigDescriptorSize Length of the attached device's Configuration Descriptor. + * \param[in] ConfigDescriptorData Pointer to a buffer containing the attached device's Configuration Descriptor. + * + * \return A value from the \ref SI_Host_EnumerationFailure_ErrorCodes_t enum. + */ + uint8_t SI_Host_ConfigurePipes(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo, + uint16_t ConfigDescriptorSize, + void* ConfigDescriptorData) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(3); + + /** Opens a new PIMA session with the attached device. This should be used before any session-orientated PIMA commands + * are issued to the device. Only one session can be open at the one time. + * + * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the + * call will fail. + * + * \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum, or \ref SI_ERROR_LOGICAL_CMD_FAILED if the device + * returned a logical command failure. + */ + uint8_t SI_Host_OpenSession(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + /** Closes an already opened PIMA session with the attached device. This should be used after all session-orientated + * PIMA commands have been issued to the device. + * + * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the + * call will fail. + * + * \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum, or \ref SI_ERROR_LOGICAL_CMD_FAILED if the device + * returned a logical command failure. + */ + uint8_t SI_Host_CloseSession(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + /** Sends a raw PIMA block header to the device, filling out the transaction ID automatically. This can be used to send + * arbitrary PIMA blocks to the device with or without parameters. + * + * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the + * call will fail. + * + * \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state. + * \param[in] PIMAHeader Pointer to a PIMA container structure that is to be sent. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. + */ + uint8_t SI_Host_SendBlockHeader(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo, + PIMA_Container_t* const PIMAHeader) ATTR_NON_NULL_PTR_ARG(1) + ATTR_NON_NULL_PTR_ARG(2); + + /** Receives a raw PIMA block header from the device. This can be used to receive arbitrary PIMA blocks from the device with + * or without parameters. + * + * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the + * call will fail. + * + * \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state. + * \param[out] PIMAHeader Pointer to a PIMA container structure where the received block is to be stored. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. + */ + uint8_t SI_Host_ReceiveBlockHeader(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo, + PIMA_Container_t* const PIMAHeader) ATTR_NON_NULL_PTR_ARG(1) + ATTR_NON_NULL_PTR_ARG(2); + + /** Sends a given PIMA command to the attached device, filling out the PIMA command header's Transaction ID automatically. + * + * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the + * call will fail. + * + * \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state. + * \param[in] Operation PIMA operation code to issue to the device. + * \param[in] TotalParams Total number of 32-bit parameters to send to the device in the issued command block. + * \param[in] Params Pointer to an array of 32-bit values containing the parameters to send in the command block. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum, or \ref SI_ERROR_LOGICAL_CMD_FAILED if the device + * returned a logical command failure. + */ + uint8_t SI_Host_SendCommand(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo, + const uint16_t Operation, + const uint8_t TotalParams, + uint32_t* const Params) ATTR_NON_NULL_PTR_ARG(1); + + /** Receives and checks a response block from the attached Still Image device, once a command has been issued and all data + * associated with the command has been transferred. + * + * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the + * call will fail. + * + * \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum, or \ref SI_ERROR_LOGICAL_CMD_FAILED if the device + * returned a logical command failure. + */ + uint8_t SI_Host_ReceiveResponse(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + /** Indicates if the device has issued a PIMA event block to the host via the asynchronous events pipe. + * + * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the + * call will fail. + * + * \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state. + * + * \return Boolean \c true if an event is waiting to be read, \c false otherwise. + */ + bool SI_Host_IsEventReceived(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1); + + /** Receives an asynchronous event block from the device via the asynchronous events pipe. + * + * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the + * call will fail. + * + * \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state. + * \param[out] PIMAHeader Pointer to a PIMA container structure where the event should be stored. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum, or \ref SI_ERROR_LOGICAL_CMD_FAILED if the device + * returned a logical command failure. + */ + uint8_t SI_Host_ReceiveEventHeader(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo, + PIMA_Container_t* const PIMAHeader) ATTR_NON_NULL_PTR_ARG(1) + ATTR_NON_NULL_PTR_ARG(2); + + /** Sends arbitrary data to the attached device, for use in the data phase of PIMA commands which require data + * transfer beyond the regular PIMA command block parameters. + * + * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the + * call will fail. + * + * \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state. + * \param[in] Buffer Pointer to a buffer where the data to send has been stored. + * \param[in] Bytes Length in bytes of the data in the buffer to send to the attached device. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. + */ + uint8_t SI_Host_SendData(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo, + void* Buffer, + const uint16_t Bytes) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); + + /** Receives arbitrary data from the attached device, for use in the data phase of PIMA commands which require data + * transfer beyond the regular PIMA command block parameters. + * + * \pre This function must only be called when the Host state machine is in the \ref HOST_STATE_Configured state or the + * call will fail. + * + * \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state. + * \param[out] Buffer Pointer to a buffer where the received data is to be stored. + * \param[in] Bytes Length in bytes of the data to read. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. + */ + uint8_t SI_Host_ReadData(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo, + void* Buffer, + const uint16_t Bytes) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); + + /* Inline Functions: */ + /** General management task for a given Still Image host class interface, required for the correct operation of the + * interface. This should be called frequently in the main program loop, before the master USB management task + * \ref USB_USBTask(). + * + * \param[in,out] SIInterfaceInfo Pointer to a structure containing a Still Image Class host configuration and state. + */ + static inline void SI_Host_USBTask(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo) ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE; + static inline void SI_Host_USBTask(USB_ClassInfo_SI_Host_t* const SIInterfaceInfo) + { + (void)SIInterfaceInfo; + } + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Macros: */ + #define SI_COMMAND_DATA_TIMEOUT_MS 10000 + + /* Function Prototypes: */ + #if defined(__INCLUDE_FROM_STILLIMAGE_HOST_C) + static uint8_t DCOMP_SI_Host_NextSIInterface(void* const CurrentDescriptor) + ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1); + static uint8_t DCOMP_SI_Host_NextSIInterfaceEndpoint(void* const CurrentDescriptor) + ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(1); + #endif + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/MIDIClass.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/MIDIClass.h new file mode 100644 index 00000000..e3b8e2f5 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/MIDIClass.h @@ -0,0 +1,83 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Master include file for the library USB MIDI Class driver. + * + * Master include file for the library USB MIDI Class driver, for both host and device modes, where available. + * + * This file should be included in all user projects making use of this optional class driver, instead of + * including any headers in the USB/ClassDriver/Device, USB/ClassDriver/Host or USB/ClassDriver/Common subdirectories. + */ + +/** \ingroup Group_USBClassDrivers + * \defgroup Group_USBClassMIDI MIDI Class Driver + * + * \section Sec_Dependencies Module Source Dependencies + * The following files must be built with any user project that uses this module: + * - LUFA/Drivers/USB/Class/Device/MIDIClassDevice.c (Makefile source module name: LUFA_SRC_USBCLASS) + * - LUFA/Drivers/USB/Class/Host/MIDIClassHost.c (Makefile source module name: LUFA_SRC_USBCLASS) + * + * \section Sec_ModDescription Module Description + * MIDI Class Driver module. This module contains an internal implementation of the USB MIDI Class, for both Device + * and Host USB modes. User applications can use this class driver instead of implementing the MIDI class manually + * via the low-level LUFA APIs. + * + * This module is designed to simplify the user code by exposing only the required interface needed to interface with + * Hosts or Devices using the USB MIDI Class. + * + * \note The USB MIDI class is actually a special case of the regular Audio class, thus this module depends on + * structure definitions from the \ref Group_USBClassAudioDevice class driver module. + * + * @{ + */ + +#ifndef _MIDI_CLASS_H_ +#define _MIDI_CLASS_H_ + + /* Macros: */ + #define __INCLUDE_FROM_USB_DRIVER + #define __INCLUDE_FROM_MIDI_DRIVER + + /* Includes: */ + #include "../Core/USBMode.h" + + #if defined(USB_CAN_BE_DEVICE) + #include "Device/MIDIClassDevice.h" + #endif + + #if defined(USB_CAN_BE_HOST) + #include "Host/MIDIClassHost.h" + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/MassStorageClass.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/MassStorageClass.h new file mode 100644 index 00000000..a5af1496 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/MassStorageClass.h @@ -0,0 +1,80 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Master include file for the library USB Mass Storage Class driver. + * + * Master include file for the library USB Mass Storage Class driver, for both host and device modes, where available. + * + * This file should be included in all user projects making use of this optional class driver, instead of + * including any headers in the USB/ClassDriver/Device, USB/ClassDriver/Host or USB/ClassDriver/Common subdirectories. + */ + +/** \ingroup Group_USBClassDrivers + * \defgroup Group_USBClassMS Mass Storage Class Driver + * + * \section Sec_Dependencies Module Source Dependencies + * The following files must be built with any user project that uses this module: + * - LUFA/Drivers/USB/Class/Device/MassStorageClassDevice.c (Makefile source module name: LUFA_SRC_USBCLASS) + * - LUFA/Drivers/USB/Class/Host/MassStorageClassHost.c (Makefile source module name: LUFA_SRC_USBCLASS) + * + * \section Sec_ModDescription Module Description + * Mass Storage Class Driver module. This module contains an internal implementation of the USB Mass Storage Class, for both + * Device and Host USB modes. User applications can use this class driver instead of implementing the Mass Storage class + * manually via the low-level LUFA APIs. + * + * This module is designed to simplify the user code by exposing only the required interface needed to interface with + * Hosts or Devices using the USB Mass Storage Class. + * + * @{ + */ + +#ifndef _MS_CLASS_H_ +#define _MS_CLASS_H_ + + /* Macros: */ + #define __INCLUDE_FROM_USB_DRIVER + #define __INCLUDE_FROM_MS_DRIVER + + /* Includes: */ + #include "../Core/USBMode.h" + + #if defined(USB_CAN_BE_DEVICE) + #include "Device/MassStorageClassDevice.h" + #endif + + #if defined(USB_CAN_BE_HOST) + #include "Host/MassStorageClassHost.h" + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/PrinterClass.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/PrinterClass.h new file mode 100644 index 00000000..181d6931 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/PrinterClass.h @@ -0,0 +1,77 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Master include file for the library USB Printer Class driver. + * + * Master include file for the library USB Printer Class driver, for both host and device modes, where available. + * + * This file should be included in all user projects making use of this optional class driver, instead of + * including any headers in the USB/ClassDriver/Device, USB/ClassDriver/Host or USB/ClassDriver/Common subdirectories. + */ + +/** \ingroup Group_USBClassDrivers + * \defgroup Group_USBClassPrinter Printer Class Driver + * + * \section Sec_Dependencies Module Source Dependencies + * The following files must be built with any user project that uses this module: + * - LUFA/Drivers/USB/Class/Host/PrinterClassHost.c (Makefile source module name: LUFA_SRC_USBCLASS) + * + * \section Sec_ModDescription Module Description + * Printer Class Driver module. This module contains an internal implementation of the USB Printer Class, for the base + * USB Printer transport layer for USB Host mode only. Note that printers are free to implement whatever printer language + * they choose on top of this (e.g. Postscript), and so this driver exposes low level data transport functions only rather + * than high level raster or text functions. User applications can use this class driver instead of implementing the Printer + * class manually via the low-level LUFA APIs. + * + * This module is designed to simplify the user code by exposing only the required interface needed to interface with + * Devices using the USB Printer Class. + * + * @{ + */ + +#ifndef _PRINTER_CLASS_H_ +#define _PRINTER_CLASS_H_ + + /* Macros: */ + #define __INCLUDE_FROM_USB_DRIVER + #define __INCLUDE_FROM_PRINTER_DRIVER + + /* Includes: */ + #include "../Core/USBMode.h" + + #if defined(USB_CAN_BE_HOST) + #include "Host/PrinterClassHost.h" + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/RNDISClass.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/RNDISClass.h new file mode 100644 index 00000000..e270629e --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/RNDISClass.h @@ -0,0 +1,80 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Master include file for the library USB RNDIS Class driver. + * + * Master include file for the library USB RNDIS Class driver, for both host and device modes, where available. + * + * This file should be included in all user projects making use of this optional class driver, instead of + * including any headers in the USB/ClassDriver/Device, USB/ClassDriver/Host or USB/ClassDriver/Common subdirectories. + */ + +/** \ingroup Group_USBClassDrivers + * \defgroup Group_USBClassRNDIS RNDIS (Networking) Class Driver + * + * \section Sec_Dependencies Module Source Dependencies + * The following files must be built with any user project that uses this module: + * - LUFA/Drivers/USB/Class/Device/RNDISClassDevice.c (Makefile source module name: LUFA_SRC_USBCLASS) + * - LUFA/Drivers/USB/Class/Host/RNDISClassHost.c (Makefile source module name: LUFA_SRC_USBCLASS) + * + * \section Sec_ModDescription Module Description + * RNDIS Class Driver module. This module contains an internal implementation of the Microsoft USB RNDIS Networking + * Class, for both Device and Host USB modes. User applications can use this class driver instead of implementing the + * RNDIS class manually via the low-level LUFA APIs. + * + * This module is designed to simplify the user code by exposing only the required interface needed to interface with + * Hosts using the USB RNDIS Class. + * + * @{ + */ + +#ifndef _RNDIS_CLASS_H_ +#define _RNDIS_CLASS_H_ + + /* Macros: */ + #define __INCLUDE_FROM_USB_DRIVER + #define __INCLUDE_FROM_RNDIS_DRIVER + + /* Includes: */ + #include "../Core/USBMode.h" + + #if defined(USB_CAN_BE_DEVICE) + #include "Device/RNDISClassDevice.h" + #endif + + #if defined(USB_CAN_BE_HOST) + #include "Host/RNDISClassHost.h" + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/StillImageClass.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/StillImageClass.h new file mode 100644 index 00000000..e8c28b44 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Class/StillImageClass.h @@ -0,0 +1,75 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Master include file for the library USB Still Image Class driver. + * + * Master include file for the library USB Still Image Class driver, for both host and device modes, where available. + * + * This file should be included in all user projects making use of this optional class driver, instead of + * including any headers in the USB/ClassDriver/Device, USB/ClassDriver/Host or USB/ClassDriver/Common subdirectories. + */ + +/** \ingroup Group_USBClassDrivers + * \defgroup Group_USBClassSI Still Image Class Driver + * + * \section Sec_Dependencies Module Source Dependencies + * The following files must be built with any user project that uses this module: + * - LUFA/Drivers/USB/Class/Host/StillImageClassHost.c (Makefile source module name: LUFA_SRC_USBCLASS) + * + * \section Sec_ModDescription Module Description + * Still Image Class Driver module. This module contains an internal implementation of the USB Still Image Class, + * for USB Host mode only. User applications can use this class driver instead of implementing the Still Image class + * manually via the low-level LUFA APIs. + * + * This module is designed to simplify the user code by exposing only the required interface needed to interface with + * Devices using the USB Still Image Class. + * + * @{ + */ + +#ifndef _SI_CLASS_H_ +#define _SI_CLASS_H_ + + /* Macros: */ + #define __INCLUDE_FROM_USB_DRIVER + #define __INCLUDE_FROM_SI_DRIVER + + /* Includes: */ + #include "../Core/USBMode.h" + + #if defined(USB_CAN_BE_HOST) + #include "Host/StillImageClassHost.h" + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/Device_AVR8.c b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/Device_AVR8.c new file mode 100644 index 00000000..09d6f377 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/Device_AVR8.c @@ -0,0 +1,57 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#include "../../../../Common/Common.h" +#if (ARCH == ARCH_AVR8) + +#define __INCLUDE_FROM_USB_DRIVER +#include "../USBMode.h" + +#if defined(USB_CAN_BE_DEVICE) + +#include "../Device.h" + +void USB_Device_SendRemoteWakeup(void) +{ + if (!(USB_Options & USB_OPT_MANUAL_PLL)) + { + USB_PLL_On(); + while (!(USB_PLL_IsReady())); + } + + USB_CLK_Unfreeze(); + + UDCON |= (1 << RMWKUP); + while (UDCON & (1 << RMWKUP)); +} + +#endif + +#endif diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/Device_AVR8.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/Device_AVR8.h new file mode 100644 index 00000000..318ff872 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/Device_AVR8.h @@ -0,0 +1,264 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief USB Device definitions for the AVR8 microcontrollers. + * \copydetails Group_Device_AVR8 + * + * \note This file should not be included directly. It is automatically included as needed by the USB driver + * dispatch header located in LUFA/Drivers/USB/USB.h. + */ + +/** \ingroup Group_Device + * \defgroup Group_Device_AVR8 Device Management (AVR8) + * \brief USB Device definitions for the AVR8 microcontrollers. + * + * Architecture specific USB Device definitions for the Atmel 8-bit AVR microcontrollers. + * + * @{ + */ + +#ifndef __USBDEVICE_AVR8_H__ +#define __USBDEVICE_AVR8_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + #include "../USBController.h" + #include "../StdDescriptors.h" + #include "../USBInterrupt.h" + #include "../Endpoint.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_USB_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB/USB.h instead. + #endif + + #if (defined(USE_RAM_DESCRIPTORS) && defined(USE_EEPROM_DESCRIPTORS)) + #error USE_RAM_DESCRIPTORS and USE_EEPROM_DESCRIPTORS are mutually exclusive. + #endif + + #if (defined(USE_FLASH_DESCRIPTORS) && defined(USE_EEPROM_DESCRIPTORS)) + #error USE_FLASH_DESCRIPTORS and USE_EEPROM_DESCRIPTORS are mutually exclusive. + #endif + + #if (defined(USE_FLASH_DESCRIPTORS) && defined(USE_RAM_DESCRIPTORS)) + #error USE_FLASH_DESCRIPTORS and USE_RAM_DESCRIPTORS are mutually exclusive. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** \name USB Device Mode Option Masks */ + //@{ + #if defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR) || defined(__DOXYGEN__) + /** Mask for the Options parameter of the \ref USB_Init() function. This indicates that the + * USB interface should be initialized in low speed (1.5Mb/s) mode. + * + * \note Low Speed mode is not available on all USB AVR models. + * \n + * + * \note Restrictions apply on the number, size and type of endpoints which can be used + * when running in low speed mode - please refer to the USB 2.0 specification. + */ + #define USB_DEVICE_OPT_LOWSPEED (1 << 0) + #endif + + /** Mask for the Options parameter of the \ref USB_Init() function. This indicates that the + * USB interface should be initialized in full speed (12Mb/s) mode. + */ + #define USB_DEVICE_OPT_FULLSPEED (0 << 0) + //@} + + #if (!defined(NO_INTERNAL_SERIAL) && \ + (defined(USB_SERIES_7_AVR) || defined(USB_SERIES_6_AVR) || \ + defined(USB_SERIES_4_AVR) || defined(USB_SERIES_2_AVR) || \ + defined(__DOXYGEN__))) + /** String descriptor index for the device's unique serial number string descriptor within the device. + * This unique serial number is used by the host to associate resources to the device (such as drivers or COM port + * number allocations) to a device regardless of the port it is plugged in to on the host. Some microcontrollers contain + * a unique serial number internally, and setting the device descriptors serial number string index to this value + * will cause it to use the internal serial number. + * + * On unsupported devices, this will evaluate to \ref NO_DESCRIPTOR and so will force the host to create a pseudo-serial + * number for the device. + */ + #define USE_INTERNAL_SERIAL 0xDC + + /** Length of the device's unique internal serial number, in bits, if present on the selected microcontroller + * model. + */ + #define INTERNAL_SERIAL_LENGTH_BITS 80 + + /** Start address of the internal serial number, in the appropriate address space, if present on the selected microcontroller + * model. + */ + #define INTERNAL_SERIAL_START_ADDRESS 0x0E + #else + #define USE_INTERNAL_SERIAL NO_DESCRIPTOR + + #define INTERNAL_SERIAL_LENGTH_BITS 0 + #define INTERNAL_SERIAL_START_ADDRESS 0 + #endif + + /* Function Prototypes: */ + /** Sends a Remote Wakeup request to the host. This signals to the host that the device should + * be taken out of suspended mode, and communications should resume. + * + * Typically, this is implemented so that HID devices (mice, keyboards, etc.) can wake up the + * host computer when the host has suspended all USB devices to enter a low power state. + * + * \attention This function should only be used if the device has indicated to the host that it + * supports the Remote Wakeup feature in the device descriptors, and should only be + * issued if the host is currently allowing remote wakeup events from the device (i.e., + * the \ref USB_Device_RemoteWakeupEnabled flag is set). When the \c NO_DEVICE_REMOTE_WAKEUP + * compile time option is used, this function is unavailable. + * \n\n + * + * \attention The USB clock must be running for this function to operate. If the stack is initialized with + * the \ref USB_OPT_MANUAL_PLL option enabled, the user must ensure that the PLL is running + * before attempting to call this function. + * + * \see \ref Group_StdDescriptors for more information on the RMWAKEUP feature and device descriptors. + */ + void USB_Device_SendRemoteWakeup(void); + + /* Inline Functions: */ + /** Returns the current USB frame number, when in device mode. Every millisecond the USB bus is active (i.e. enumerated to a host) + * the frame number is incremented by one. + * + * \return Current USB frame number from the USB controller. + */ + static inline uint16_t USB_Device_GetFrameNumber(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT; + static inline uint16_t USB_Device_GetFrameNumber(void) + { + return UDFNUM; + } + + #if !defined(NO_SOF_EVENTS) + /** Enables the device mode Start Of Frame events. When enabled, this causes the + * \ref EVENT_USB_Device_StartOfFrame() event to fire once per millisecond, synchronized to the USB bus, + * at the start of each USB frame when enumerated in device mode. + * + * \note This function is not available when the \c NO_SOF_EVENTS compile time token is defined. + */ + static inline void USB_Device_EnableSOFEvents(void) ATTR_ALWAYS_INLINE; + static inline void USB_Device_EnableSOFEvents(void) + { + USB_INT_Enable(USB_INT_SOFI); + } + + /** Disables the device mode Start Of Frame events. When disabled, this stops the firing of the + * \ref EVENT_USB_Device_StartOfFrame() event when enumerated in device mode. + * + * \note This function is not available when the \c NO_SOF_EVENTS compile time token is defined. + */ + static inline void USB_Device_DisableSOFEvents(void) ATTR_ALWAYS_INLINE; + static inline void USB_Device_DisableSOFEvents(void) + { + USB_INT_Disable(USB_INT_SOFI); + } + #endif + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Inline Functions: */ + #if defined(USB_DEVICE_OPT_LOWSPEED) + static inline void USB_Device_SetLowSpeed(void) ATTR_ALWAYS_INLINE; + static inline void USB_Device_SetLowSpeed(void) + { + UDCON |= (1 << LSM); + } + + static inline void USB_Device_SetFullSpeed(void) ATTR_ALWAYS_INLINE; + static inline void USB_Device_SetFullSpeed(void) + { + UDCON &= ~(1 << LSM); + } + #endif + + static inline void USB_Device_SetDeviceAddress(const uint8_t Address) ATTR_ALWAYS_INLINE; + static inline void USB_Device_SetDeviceAddress(const uint8_t Address) + { + uint8_t Temp = (UDADDR & (1 << ADDEN)) | (Address & 0x7F); + + UDADDR = Temp; + UDADDR = Temp | (1 << ADDEN); + } + + static inline bool USB_Device_IsAddressSet(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT; + static inline bool USB_Device_IsAddressSet(void) + { + return (UDADDR & (1 << ADDEN)); + } + + #if (USE_INTERNAL_SERIAL != NO_DESCRIPTOR) + static inline void USB_Device_GetSerialString(uint16_t* const UnicodeString) ATTR_NON_NULL_PTR_ARG(1); + static inline void USB_Device_GetSerialString(uint16_t* const UnicodeString) + { + uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask(); + GlobalInterruptDisable(); + + uint8_t SigReadAddress = INTERNAL_SERIAL_START_ADDRESS; + + for (uint8_t SerialCharNum = 0; SerialCharNum < (INTERNAL_SERIAL_LENGTH_BITS / 4); SerialCharNum++) + { + uint8_t SerialByte = boot_signature_byte_get(SigReadAddress); + + if (SerialCharNum & 0x01) + { + SerialByte >>= 4; + SigReadAddress++; + } + + SerialByte &= 0x0F; + + UnicodeString[SerialCharNum] = cpu_to_le16((SerialByte >= 10) ? + (('A' - 10) + SerialByte) : ('0' + SerialByte)); + } + + SetGlobalInterruptMask(CurrentGlobalInt); + } + #endif + + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/EndpointStream_AVR8.c b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/EndpointStream_AVR8.c new file mode 100644 index 00000000..7563ed35 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/EndpointStream_AVR8.c @@ -0,0 +1,275 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#include "../../../../Common/Common.h" +#if (ARCH == ARCH_AVR8) + +#define __INCLUDE_FROM_USB_DRIVER +#include "../USBMode.h" + +#if defined(USB_CAN_BE_DEVICE) + +#include "EndpointStream_AVR8.h" + +#if !defined(CONTROL_ONLY_DEVICE) +uint8_t Endpoint_Discard_Stream(uint16_t Length, + uint16_t* const BytesProcessed) +{ + uint8_t ErrorCode; + uint16_t BytesInTransfer = 0; + + if ((ErrorCode = Endpoint_WaitUntilReady())) + return ErrorCode; + + if (BytesProcessed != NULL) + Length -= *BytesProcessed; + + while (Length) + { + if (!(Endpoint_IsReadWriteAllowed())) + { + Endpoint_ClearOUT(); + + if (BytesProcessed != NULL) + { + *BytesProcessed += BytesInTransfer; + return ENDPOINT_RWSTREAM_IncompleteTransfer; + } + + if ((ErrorCode = Endpoint_WaitUntilReady())) + return ErrorCode; + } + else + { + Endpoint_Discard_8(); + + Length--; + BytesInTransfer++; + } + } + + return ENDPOINT_RWSTREAM_NoError; +} + +uint8_t Endpoint_Null_Stream(uint16_t Length, + uint16_t* const BytesProcessed) +{ + uint8_t ErrorCode; + uint16_t BytesInTransfer = 0; + + if ((ErrorCode = Endpoint_WaitUntilReady())) + return ErrorCode; + + if (BytesProcessed != NULL) + Length -= *BytesProcessed; + + while (Length) + { + if (!(Endpoint_IsReadWriteAllowed())) + { + Endpoint_ClearIN(); + + if (BytesProcessed != NULL) + { + *BytesProcessed += BytesInTransfer; + return ENDPOINT_RWSTREAM_IncompleteTransfer; + } + + if ((ErrorCode = Endpoint_WaitUntilReady())) + return ErrorCode; + } + else + { + Endpoint_Write_8(0); + + Length--; + BytesInTransfer++; + } + } + + return ENDPOINT_RWSTREAM_NoError; +} + +/* The following abuses the C preprocessor in order to copy-paste common code with slight alterations, + * so that the code needs to be written once. It is a crude form of templating to reduce code maintenance. */ + +#define TEMPLATE_FUNC_NAME Endpoint_Write_Stream_LE +#define TEMPLATE_BUFFER_TYPE const void* +#define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN() +#define TEMPLATE_BUFFER_OFFSET(Length) 0 +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(*BufferPtr) +#include "Template/Template_Endpoint_RW.c" + +#define TEMPLATE_FUNC_NAME Endpoint_Write_Stream_BE +#define TEMPLATE_BUFFER_TYPE const void* +#define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN() +#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(*BufferPtr) +#include "Template/Template_Endpoint_RW.c" + +#define TEMPLATE_FUNC_NAME Endpoint_Read_Stream_LE +#define TEMPLATE_BUFFER_TYPE void* +#define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearOUT() +#define TEMPLATE_BUFFER_OFFSET(Length) 0 +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *BufferPtr = Endpoint_Read_8() +#include "Template/Template_Endpoint_RW.c" + +#define TEMPLATE_FUNC_NAME Endpoint_Read_Stream_BE +#define TEMPLATE_BUFFER_TYPE void* +#define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearOUT() +#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *BufferPtr = Endpoint_Read_8() +#include "Template/Template_Endpoint_RW.c" + +#if defined(ARCH_HAS_FLASH_ADDRESS_SPACE) + #define TEMPLATE_FUNC_NAME Endpoint_Write_PStream_LE + #define TEMPLATE_BUFFER_TYPE const void* + #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN() + #define TEMPLATE_BUFFER_OFFSET(Length) 0 + #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount + #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(pgm_read_byte(BufferPtr)) + #include "Template/Template_Endpoint_RW.c" + + #define TEMPLATE_FUNC_NAME Endpoint_Write_PStream_BE + #define TEMPLATE_BUFFER_TYPE const void* + #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN() + #define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) + #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount + #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(pgm_read_byte(BufferPtr)) + #include "Template/Template_Endpoint_RW.c" +#endif + +#if defined(ARCH_HAS_EEPROM_ADDRESS_SPACE) + #define TEMPLATE_FUNC_NAME Endpoint_Write_EStream_LE + #define TEMPLATE_BUFFER_TYPE const void* + #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN() + #define TEMPLATE_BUFFER_OFFSET(Length) 0 + #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount + #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(eeprom_read_byte(BufferPtr)) + #include "Template/Template_Endpoint_RW.c" + + #define TEMPLATE_FUNC_NAME Endpoint_Write_EStream_BE + #define TEMPLATE_BUFFER_TYPE const void* + #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN() + #define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) + #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount + #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(eeprom_read_byte(BufferPtr)) + #include "Template/Template_Endpoint_RW.c" + + #define TEMPLATE_FUNC_NAME Endpoint_Read_EStream_LE + #define TEMPLATE_BUFFER_TYPE void* + #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearOUT() + #define TEMPLATE_BUFFER_OFFSET(Length) 0 + #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount + #define TEMPLATE_TRANSFER_BYTE(BufferPtr) eeprom_update_byte(BufferPtr, Endpoint_Read_8()) + #include "Template/Template_Endpoint_RW.c" + + #define TEMPLATE_FUNC_NAME Endpoint_Read_EStream_BE + #define TEMPLATE_BUFFER_TYPE void* + #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearOUT() + #define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) + #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount + #define TEMPLATE_TRANSFER_BYTE(BufferPtr) eeprom_update_byte(BufferPtr, Endpoint_Read_8()) + #include "Template/Template_Endpoint_RW.c" +#endif + +#endif + +#define TEMPLATE_FUNC_NAME Endpoint_Write_Control_Stream_LE +#define TEMPLATE_BUFFER_OFFSET(Length) 0 +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(*BufferPtr) +#include "Template/Template_Endpoint_Control_W.c" + +#define TEMPLATE_FUNC_NAME Endpoint_Write_Control_Stream_BE +#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(*BufferPtr) +#include "Template/Template_Endpoint_Control_W.c" + +#define TEMPLATE_FUNC_NAME Endpoint_Read_Control_Stream_LE +#define TEMPLATE_BUFFER_OFFSET(Length) 0 +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *BufferPtr = Endpoint_Read_8() +#include "Template/Template_Endpoint_Control_R.c" + +#define TEMPLATE_FUNC_NAME Endpoint_Read_Control_Stream_BE +#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *BufferPtr = Endpoint_Read_8() +#include "Template/Template_Endpoint_Control_R.c" + +#if defined(ARCH_HAS_FLASH_ADDRESS_SPACE) + #define TEMPLATE_FUNC_NAME Endpoint_Write_Control_PStream_LE + #define TEMPLATE_BUFFER_OFFSET(Length) 0 + #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount + #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(pgm_read_byte(BufferPtr)) + #include "Template/Template_Endpoint_Control_W.c" + + #define TEMPLATE_FUNC_NAME Endpoint_Write_Control_PStream_BE + #define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) + #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount + #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(pgm_read_byte(BufferPtr)) + #include "Template/Template_Endpoint_Control_W.c" +#endif + +#if defined(ARCH_HAS_EEPROM_ADDRESS_SPACE) + #define TEMPLATE_FUNC_NAME Endpoint_Write_Control_EStream_LE + #define TEMPLATE_BUFFER_OFFSET(Length) 0 + #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount + #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(eeprom_read_byte(BufferPtr)) + #include "Template/Template_Endpoint_Control_W.c" + + #define TEMPLATE_FUNC_NAME Endpoint_Write_Control_EStream_BE + #define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) + #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount + #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(eeprom_read_byte(BufferPtr)) + #include "Template/Template_Endpoint_Control_W.c" + + #define TEMPLATE_FUNC_NAME Endpoint_Read_Control_EStream_LE + #define TEMPLATE_BUFFER_OFFSET(Length) 0 + #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount + #define TEMPLATE_TRANSFER_BYTE(BufferPtr) eeprom_update_byte(BufferPtr, Endpoint_Read_8()) + #include "Template/Template_Endpoint_Control_R.c" + + #define TEMPLATE_FUNC_NAME Endpoint_Read_Control_EStream_BE + #define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) + #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount + #define TEMPLATE_TRANSFER_BYTE(BufferPtr) eeprom_update_byte(BufferPtr, Endpoint_Read_8()) + #include "Template/Template_Endpoint_Control_R.c" +#endif + +#endif + +#endif diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/EndpointStream_AVR8.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/EndpointStream_AVR8.h new file mode 100644 index 00000000..77c9c82f --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/EndpointStream_AVR8.h @@ -0,0 +1,648 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Endpoint data stream transmission and reception management for the AVR8 microcontrollers. + * \copydetails Group_EndpointStreamRW_AVR8 + * + * \note This file should not be included directly. It is automatically included as needed by the USB driver + * dispatch header located in LUFA/Drivers/USB/USB.h. + */ + +/** \ingroup Group_EndpointStreamRW + * \defgroup Group_EndpointStreamRW_AVR8 Read/Write of Multi-Byte Streams (AVR8) + * \brief Endpoint data stream transmission and reception management for the Atmel AVR8 architecture. + * + * Functions, macros, variables, enums and types related to data reading and writing of data streams from + * and to endpoints. + * + * @{ + */ + +#ifndef __ENDPOINT_STREAM_AVR8_H__ +#define __ENDPOINT_STREAM_AVR8_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + #include "../USBMode.h" + #include "../USBTask.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_USB_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB/USB.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Function Prototypes: */ + /** \name Stream functions for null data */ + //@{ + + /** Reads and discards the given number of bytes from the currently selected endpoint's bank, + * discarding fully read packets from the host as needed. The last packet is not automatically + * discarded once the remaining bytes has been read; the user is responsible for manually + * discarding the last packet from the host via the \ref Endpoint_ClearOUT() macro. + * + * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, + * failing or succeeding as a single unit. If the BytesProcessed parameter points to a valid + * storage location, the transfer will instead be performed as a series of chunks. Each time + * the endpoint bank becomes empty while there is still data to process (and after the current + * packet has been acknowledged) the BytesProcessed location will be updated with the total number + * of bytes processed in the stream, and the function will exit with an error code of + * \ref ENDPOINT_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed + * in the user code - to continue the transfer, call the function again with identical parameters + * and it will resume until the BytesProcessed value reaches the total transfer length. + * + * Single Stream Transfer Example: + * \code + * uint8_t ErrorCode; + * + * if ((ErrorCode = Endpoint_Discard_Stream(512, NULL)) != ENDPOINT_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * Partial Stream Transfers Example: + * \code + * uint8_t ErrorCode; + * uint16_t BytesProcessed; + * + * BytesProcessed = 0; + * while ((ErrorCode = Endpoint_Discard_Stream(512, &BytesProcessed)) == ENDPOINT_RWSTREAM_IncompleteTransfer) + * { + * // Stream not yet complete - do other actions here, abort if required + * } + * + * if (ErrorCode != ENDPOINT_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * \note This routine should not be used on CONTROL type endpoints. + * + * \param[in] Length Number of bytes to discard via the currently selected endpoint. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current + * transaction should be updated, \c NULL if the entire stream should be read at once. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Discard_Stream(uint16_t Length, + uint16_t* const BytesProcessed); + + /** Writes a given number of zeroed bytes to the currently selected endpoint's bank, sending + * full packets to the host as needed. The last packet is not automatically sent once the + * remaining bytes have been written; the user is responsible for manually sending the last + * packet to the host via the \ref Endpoint_ClearIN() macro. + * + * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, + * failing or succeeding as a single unit. If the BytesProcessed parameter points to a valid + * storage location, the transfer will instead be performed as a series of chunks. Each time + * the endpoint bank becomes full while there is still data to process (and after the current + * packet transmission has been initiated) the BytesProcessed location will be updated with the + * total number of bytes processed in the stream, and the function will exit with an error code of + * \ref ENDPOINT_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed + * in the user code - to continue the transfer, call the function again with identical parameters + * and it will resume until the BytesProcessed value reaches the total transfer length. + * + * Single Stream Transfer Example: + * \code + * uint8_t ErrorCode; + * + * if ((ErrorCode = Endpoint_Null_Stream(512, NULL)) != ENDPOINT_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * Partial Stream Transfers Example: + * \code + * uint8_t ErrorCode; + * uint16_t BytesProcessed; + * + * BytesProcessed = 0; + * while ((ErrorCode = Endpoint_Null_Stream(512, &BytesProcessed)) == ENDPOINT_RWSTREAM_IncompleteTransfer) + * { + * // Stream not yet complete - do other actions here, abort if required + * } + * + * if (ErrorCode != ENDPOINT_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * \note This routine should not be used on CONTROL type endpoints. + * + * \param[in] Length Number of zero bytes to send via the currently selected endpoint. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current + * transaction should be updated, \c NULL if the entire stream should be read at once. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Null_Stream(uint16_t Length, + uint16_t* const BytesProcessed); + + //@} + + /** \name Stream functions for RAM source/destination data */ + //@{ + + /** Writes the given number of bytes to the endpoint from the given buffer in little endian, + * sending full packets to the host as needed. The last packet filled is not automatically sent; + * the user is responsible for manually sending the last written packet to the host via the + * \ref Endpoint_ClearIN() macro. + * + * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, + * failing or succeeding as a single unit. If the BytesProcessed parameter points to a valid + * storage location, the transfer will instead be performed as a series of chunks. Each time + * the endpoint bank becomes full while there is still data to process (and after the current + * packet transmission has been initiated) the BytesProcessed location will be updated with the + * total number of bytes processed in the stream, and the function will exit with an error code of + * \ref ENDPOINT_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed + * in the user code - to continue the transfer, call the function again with identical parameters + * and it will resume until the BytesProcessed value reaches the total transfer length. + * + * Single Stream Transfer Example: + * \code + * uint8_t DataStream[512]; + * uint8_t ErrorCode; + * + * if ((ErrorCode = Endpoint_Write_Stream_LE(DataStream, sizeof(DataStream), + * NULL)) != ENDPOINT_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * Partial Stream Transfers Example: + * \code + * uint8_t DataStream[512]; + * uint8_t ErrorCode; + * uint16_t BytesProcessed; + * + * BytesProcessed = 0; + * while ((ErrorCode = Endpoint_Write_Stream_LE(DataStream, sizeof(DataStream), + * &BytesProcessed)) == ENDPOINT_RWSTREAM_IncompleteTransfer) + * { + * // Stream not yet complete - do other actions here, abort if required + * } + * + * if (ErrorCode != ENDPOINT_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * \note This routine should not be used on CONTROL type endpoints. + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current + * transaction should be updated, \c NULL if the entire stream should be written at once. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Write_Stream_LE(const void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** Writes the given number of bytes to the endpoint from the given buffer in big endian, + * sending full packets to the host as needed. The last packet filled is not automatically sent; + * the user is responsible for manually sending the last written packet to the host via the + * \ref Endpoint_ClearIN() macro. + * + * \note This routine should not be used on CONTROL type endpoints. + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current + * transaction should be updated, \c NULL if the entire stream should be written at once. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Write_Stream_BE(const void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** Reads the given number of bytes from the endpoint from the given buffer in little endian, + * discarding fully read packets from the host as needed. The last packet is not automatically + * discarded once the remaining bytes has been read; the user is responsible for manually + * discarding the last packet from the host via the \ref Endpoint_ClearOUT() macro. + * + * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, + * failing or succeeding as a single unit. If the BytesProcessed parameter points to a valid + * storage location, the transfer will instead be performed as a series of chunks. Each time + * the endpoint bank becomes empty while there is still data to process (and after the current + * packet has been acknowledged) the BytesProcessed location will be updated with the total number + * of bytes processed in the stream, and the function will exit with an error code of + * \ref ENDPOINT_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed + * in the user code - to continue the transfer, call the function again with identical parameters + * and it will resume until the BytesProcessed value reaches the total transfer length. + * + * Single Stream Transfer Example: + * \code + * uint8_t DataStream[512]; + * uint8_t ErrorCode; + * + * if ((ErrorCode = Endpoint_Read_Stream_LE(DataStream, sizeof(DataStream), + * NULL)) != ENDPOINT_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * Partial Stream Transfers Example: + * \code + * uint8_t DataStream[512]; + * uint8_t ErrorCode; + * uint16_t BytesProcessed; + * + * BytesProcessed = 0; + * while ((ErrorCode = Endpoint_Read_Stream_LE(DataStream, sizeof(DataStream), + * &BytesProcessed)) == ENDPOINT_RWSTREAM_IncompleteTransfer) + * { + * // Stream not yet complete - do other actions here, abort if required + * } + * + * if (ErrorCode != ENDPOINT_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * \note This routine should not be used on CONTROL type endpoints. + * + * \param[out] Buffer Pointer to the destination data buffer to write to. + * \param[in] Length Number of bytes to send via the currently selected endpoint. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current + * transaction should be updated, \c NULL if the entire stream should be read at once. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Read_Stream_LE(void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** Reads the given number of bytes from the endpoint from the given buffer in big endian, + * discarding fully read packets from the host as needed. The last packet is not automatically + * discarded once the remaining bytes has been read; the user is responsible for manually + * discarding the last packet from the host via the \ref Endpoint_ClearOUT() macro. + * + * \note This routine should not be used on CONTROL type endpoints. + * + * \param[out] Buffer Pointer to the destination data buffer to write to. + * \param[in] Length Number of bytes to send via the currently selected endpoint. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current + * transaction should be updated, \c NULL if the entire stream should be read at once. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Read_Stream_BE(void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** Writes the given number of bytes to the CONTROL type endpoint from the given buffer in little endian, + * sending full packets to the host as needed. The host OUT acknowledgement is not automatically cleared + * in both failure and success states; the user is responsible for manually clearing the status OUT packet + * to finalize the transfer's status stage via the \ref Endpoint_ClearOUT() macro. + * + * \note This function automatically clears the control transfer's status stage. Do not manually attempt + * to clear the status stage when using this routine in a control transaction. + * \n\n + * + * \note This routine should only be used on CONTROL type endpoints. + * + * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained + * together; i.e. the entire stream data must be read or written at the one time. + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. + * + * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Write_Control_Stream_LE(const void* const Buffer, + uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); + + /** Writes the given number of bytes to the CONTROL type endpoint from the given buffer in big endian, + * sending full packets to the host as needed. The host OUT acknowledgement is not automatically cleared + * in both failure and success states; the user is responsible for manually clearing the status OUT packet + * to finalize the transfer's status stage via the \ref Endpoint_ClearOUT() macro. + * + * \note This function automatically clears the control transfer's status stage. Do not manually attempt + * to clear the status stage when using this routine in a control transaction. + * \n\n + * + * \note This routine should only be used on CONTROL type endpoints. + * + * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained + * together; i.e. the entire stream data must be read or written at the one time. + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. + * + * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Write_Control_Stream_BE(const void* const Buffer, + uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); + + /** Reads the given number of bytes from the CONTROL endpoint from the given buffer in little endian, + * discarding fully read packets from the host as needed. The device IN acknowledgement is not + * automatically sent after success or failure states; the user is responsible for manually sending the + * status IN packet to finalize the transfer's status stage via the \ref Endpoint_ClearIN() macro. + * + * \note This function automatically clears the control transfer's status stage. Do not manually attempt + * to clear the status stage when using this routine in a control transaction. + * \n\n + * + * \note This routine should only be used on CONTROL type endpoints. + * + * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained + * together; i.e. the entire stream data must be read or written at the one time. + * + * \param[out] Buffer Pointer to the destination data buffer to write to. + * \param[in] Length Number of bytes to send via the currently selected endpoint. + * + * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Read_Control_Stream_LE(void* const Buffer, + uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); + + /** Reads the given number of bytes from the CONTROL endpoint from the given buffer in big endian, + * discarding fully read packets from the host as needed. The device IN acknowledgement is not + * automatically sent after success or failure states; the user is responsible for manually sending the + * status IN packet to finalize the transfer's status stage via the \ref Endpoint_ClearIN() macro. + * + * \note This function automatically clears the control transfer's status stage. Do not manually attempt + * to clear the status stage when using this routine in a control transaction. + * \n\n + * + * \note This routine should only be used on CONTROL type endpoints. + * + * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained + * together; i.e. the entire stream data must be read or written at the one time. + * + * \param[out] Buffer Pointer to the destination data buffer to write to. + * \param[in] Length Number of bytes to send via the currently selected endpoint. + * + * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Read_Control_Stream_BE(void* const Buffer, + uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); + //@} + + /** \name Stream functions for EEPROM source/destination data */ + //@{ + + /** EEPROM buffer source version of \ref Endpoint_Write_Stream_LE(). + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current + * transaction should be updated, \c NULL if the entire stream should be written at once. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Write_EStream_LE(const void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** EEPROM buffer source version of \ref Endpoint_Write_Stream_BE(). + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current + * transaction should be updated, \c NULL if the entire stream should be written at once. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Write_EStream_BE(const void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** EEPROM buffer destination version of \ref Endpoint_Read_Stream_LE(). + * + * \param[out] Buffer Pointer to the destination data buffer to write to, located in EEPROM memory space. + * \param[in] Length Number of bytes to send via the currently selected endpoint. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current + * transaction should be updated, \c NULL if the entire stream should be read at once. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Read_EStream_LE(void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** EEPROM buffer destination version of \ref Endpoint_Read_Stream_BE(). + * + * \param[out] Buffer Pointer to the destination data buffer to write to, located in EEPROM memory space. + * \param[in] Length Number of bytes to send via the currently selected endpoint. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current + * transaction should be updated, \c NULL if the entire stream should be read at once. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Read_EStream_BE(void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** EEPROM buffer source version of Endpoint_Write_Control_Stream_LE. + * + * \note This function automatically clears the control transfer's status stage. Do not manually attempt + * to clear the status stage when using this routine in a control transaction. + * \n\n + * + * \note This routine should only be used on CONTROL type endpoints. + * \n\n + * + * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained + * together; i.e. the entire stream data must be read or written at the one time. + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. + * + * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Write_Control_EStream_LE(const void* const Buffer, + uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); + + /** EEPROM buffer source version of \ref Endpoint_Write_Control_Stream_BE(). + * + * \note This function automatically clears the control transfer's status stage. Do not manually attempt + * to clear the status stage when using this routine in a control transaction. + * \n\n + * + * \note This routine should only be used on CONTROL type endpoints. + * \n\n + * + * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained + * together; i.e. the entire stream data must be read or written at the one time. + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. + * + * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Write_Control_EStream_BE(const void* const Buffer, + uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); + + /** EEPROM buffer source version of \ref Endpoint_Read_Control_Stream_LE(). + * + * \note This function automatically clears the control transfer's status stage. Do not manually attempt + * to clear the status stage when using this routine in a control transaction. + * \n\n + * + * \note This routine should only be used on CONTROL type endpoints. + * \n\n + * + * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained + * together; i.e. the entire stream data must be read or written at the one time. + * + * \param[out] Buffer Pointer to the destination data buffer to write to. + * \param[in] Length Number of bytes to send via the currently selected endpoint. + * + * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Read_Control_EStream_LE(void* const Buffer, + uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); + + /** EEPROM buffer source version of \ref Endpoint_Read_Control_Stream_BE(). + * + * \note This function automatically clears the control transfer's status stage. Do not manually attempt + * to clear the status stage when using this routine in a control transaction. + * \n\n + * + * \note This routine should only be used on CONTROL type endpoints. + * \n\n + * + * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained + * together; i.e. the entire stream data must be read or written at the one time. + * + * \param[out] Buffer Pointer to the destination data buffer to write to. + * \param[in] Length Number of bytes to send via the currently selected endpoint. + * + * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Read_Control_EStream_BE(void* const Buffer, + uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); + //@} + + /** \name Stream functions for PROGMEM source/destination data */ + //@{ + + /** FLASH buffer source version of \ref Endpoint_Write_Stream_LE(). + * + * \pre The FLASH data must be located in the first 64KB of FLASH for this function to work correctly. + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current + * transaction should be updated, \c NULL if the entire stream should be written at once. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Write_PStream_LE(const void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** FLASH buffer source version of \ref Endpoint_Write_Stream_BE(). + * + * \pre The FLASH data must be located in the first 64KB of FLASH for this function to work correctly. + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current + * transaction should be updated, \c NULL if the entire stream should be written at once. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Write_PStream_BE(const void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** FLASH buffer source version of \ref Endpoint_Write_Control_Stream_LE(). + * + * \pre The FLASH data must be located in the first 64KB of FLASH for this function to work correctly. + * + * \note This function automatically clears the control transfer's status stage. Do not manually attempt + * to clear the status stage when using this routine in a control transaction. + * \n\n + * + * \note This routine should only be used on CONTROL type endpoints. + * \n\n + * + * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained + * together; i.e. the entire stream data must be read or written at the one time. + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. + * + * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Write_Control_PStream_LE(const void* const Buffer, + uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); + + /** FLASH buffer source version of \ref Endpoint_Write_Control_Stream_BE(). + * + * \pre The FLASH data must be located in the first 64KB of FLASH for this function to work correctly. + * + * \note This function automatically clears the control transfer's status stage. Do not manually attempt + * to clear the status stage when using this routine in a control transaction. + * \n\n + * + * \note This routine should only be used on CONTROL type endpoints. + * \n\n + * + * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained + * together; i.e. the entire stream data must be read or written at the one time. + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. + * + * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Write_Control_PStream_BE(const void* const Buffer, + uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); + //@} + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/Endpoint_AVR8.c b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/Endpoint_AVR8.c new file mode 100644 index 00000000..0002a256 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/Endpoint_AVR8.c @@ -0,0 +1,201 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#include "../../../../Common/Common.h" +#if (ARCH == ARCH_AVR8) + +#define __INCLUDE_FROM_USB_DRIVER +#include "../USBMode.h" + +#if defined(USB_CAN_BE_DEVICE) + +#include "../Endpoint.h" + +#if !defined(FIXED_CONTROL_ENDPOINT_SIZE) +uint8_t USB_Device_ControlEndpointSize = ENDPOINT_CONTROLEP_DEFAULT_SIZE; +#endif + +bool Endpoint_ConfigureEndpointTable(const USB_Endpoint_Table_t* const Table, + const uint8_t Entries) +{ + for (uint8_t i = 0; i < Entries; i++) + { + if (!(Table[i].Address)) + continue; + + if (!(Endpoint_ConfigureEndpoint(Table[i].Address, Table[i].Type, Table[i].Size, Table[i].Banks))) + return false; + } + + return true; +} + +bool Endpoint_ConfigureEndpoint_Prv(const uint8_t Number, + const uint8_t UECFG0XData, + const uint8_t UECFG1XData) +{ +#if defined(CONTROL_ONLY_DEVICE) || defined(ORDERED_EP_CONFIG) + Endpoint_SelectEndpoint(Number); + Endpoint_EnableEndpoint(); + + UECFG1X = 0; + UECFG0X = UECFG0XData; + UECFG1X = UECFG1XData; + + return Endpoint_IsConfigured(); +#else + for (uint8_t EPNum = Number; EPNum < ENDPOINT_TOTAL_ENDPOINTS; EPNum++) + { + uint8_t UECFG0XTemp; + uint8_t UECFG1XTemp; + uint8_t UEIENXTemp; + + Endpoint_SelectEndpoint(EPNum); + + if (EPNum == Number) + { + UECFG0XTemp = UECFG0XData; + UECFG1XTemp = UECFG1XData; + UEIENXTemp = 0; + } + else + { + UECFG0XTemp = UECFG0X; + UECFG1XTemp = UECFG1X; + UEIENXTemp = UEIENX; + } + + if (!(UECFG1XTemp & (1 << ALLOC))) + continue; + + Endpoint_DisableEndpoint(); + UECFG1X &= ~(1 << ALLOC); + + Endpoint_EnableEndpoint(); + UECFG0X = UECFG0XTemp; + UECFG1X = UECFG1XTemp; + UEIENX = UEIENXTemp; + + if (!(Endpoint_IsConfigured())) + return false; + } + + Endpoint_SelectEndpoint(Number); + return true; +#endif +} + +void Endpoint_ClearEndpoints(void) +{ + UEINT = 0; + + for (uint8_t EPNum = 0; EPNum < ENDPOINT_TOTAL_ENDPOINTS; EPNum++) + { + Endpoint_SelectEndpoint(EPNum); + UEIENX = 0; + UEINTX = 0; + UECFG1X = 0; + Endpoint_DisableEndpoint(); + } +} + +void Endpoint_ClearStatusStage(void) +{ + if (USB_ControlRequest.bmRequestType & REQDIR_DEVICETOHOST) + { + while (!(Endpoint_IsOUTReceived())) + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return; + } + + Endpoint_ClearOUT(); + } + else + { + while (!(Endpoint_IsINReady())) + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return; + } + + Endpoint_ClearIN(); + } +} + +#if !defined(CONTROL_ONLY_DEVICE) +uint8_t Endpoint_WaitUntilReady(void) +{ + #if (USB_STREAM_TIMEOUT_MS < 0xFF) + uint8_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS; + #else + uint16_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS; + #endif + + uint16_t PreviousFrameNumber = USB_Device_GetFrameNumber(); + + for (;;) + { + if (Endpoint_GetEndpointDirection() == ENDPOINT_DIR_IN) + { + if (Endpoint_IsINReady()) + return ENDPOINT_READYWAIT_NoError; + } + else + { + if (Endpoint_IsOUTReceived()) + return ENDPOINT_READYWAIT_NoError; + } + + uint8_t USB_DeviceState_LCL = USB_DeviceState; + + if (USB_DeviceState_LCL == DEVICE_STATE_Unattached) + return ENDPOINT_READYWAIT_DeviceDisconnected; + else if (USB_DeviceState_LCL == DEVICE_STATE_Suspended) + return ENDPOINT_READYWAIT_BusSuspended; + else if (Endpoint_IsStalled()) + return ENDPOINT_READYWAIT_EndpointStalled; + + uint16_t CurrentFrameNumber = USB_Device_GetFrameNumber(); + + if (CurrentFrameNumber != PreviousFrameNumber) + { + PreviousFrameNumber = CurrentFrameNumber; + + if (!(TimeoutMSRem--)) + return ENDPOINT_READYWAIT_Timeout; + } + } +} +#endif + +#endif + +#endif diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/Endpoint_AVR8.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/Endpoint_AVR8.h new file mode 100644 index 00000000..08944bab --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/Endpoint_AVR8.h @@ -0,0 +1,819 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief USB Endpoint definitions for the AVR8 microcontrollers. + * \copydetails Group_EndpointManagement_AVR8 + * + * \note This file should not be included directly. It is automatically included as needed by the USB driver + * dispatch header located in LUFA/Drivers/USB/USB.h. + */ + +/** \ingroup Group_EndpointRW + * \defgroup Group_EndpointRW_AVR8 Endpoint Data Reading and Writing (AVR8) + * \brief Endpoint data read/write definitions for the Atmel AVR8 architecture. + * + * Functions, macros, variables, enums and types related to data reading and writing from and to endpoints. + */ + +/** \ingroup Group_EndpointPrimitiveRW + * \defgroup Group_EndpointPrimitiveRW_AVR8 Read/Write of Primitive Data Types (AVR8) + * \brief Endpoint primitive read/write definitions for the Atmel AVR8 architecture. + * + * Functions, macros, variables, enums and types related to data reading and writing of primitive data types + * from and to endpoints. + */ + +/** \ingroup Group_EndpointPacketManagement + * \defgroup Group_EndpointPacketManagement_AVR8 Endpoint Packet Management (AVR8) + * \brief Endpoint packet management definitions for the Atmel AVR8 architecture. + * + * Functions, macros, variables, enums and types related to packet management of endpoints. + */ + +/** \ingroup Group_EndpointManagement + * \defgroup Group_EndpointManagement_AVR8 Endpoint Management (AVR8) + * \brief Endpoint management definitions for the Atmel AVR8 architecture. + * + * Functions, macros and enums related to endpoint management when in USB Device mode. This + * module contains the endpoint management macros, as well as endpoint interrupt and data + * send/receive functions for various data types. + * + * @{ + */ + +#ifndef __ENDPOINT_AVR8_H__ +#define __ENDPOINT_AVR8_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + #include "../USBTask.h" + #include "../USBInterrupt.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_USB_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB/USB.h instead. + #endif + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Inline Functions: */ + static inline uint8_t Endpoint_BytesToEPSizeMask(const uint16_t Bytes) ATTR_WARN_UNUSED_RESULT ATTR_CONST + ATTR_ALWAYS_INLINE; + static inline uint8_t Endpoint_BytesToEPSizeMask(const uint16_t Bytes) + { + uint8_t MaskVal = 0; + uint16_t CheckBytes = 8; + + while (CheckBytes < Bytes) + { + MaskVal++; + CheckBytes <<= 1; + } + + return (MaskVal << EPSIZE0); + } + + /* Function Prototypes: */ + void Endpoint_ClearEndpoints(void); + bool Endpoint_ConfigureEndpoint_Prv(const uint8_t Number, + const uint8_t UECFG0XData, + const uint8_t UECFG1XData); + + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + #if (!defined(FIXED_CONTROL_ENDPOINT_SIZE) || defined(__DOXYGEN__)) + /** Default size of the default control endpoint's bank, until altered by the control endpoint bank size + * value in the device descriptor. Not available if the \c FIXED_CONTROL_ENDPOINT_SIZE token is defined. + */ + #define ENDPOINT_CONTROLEP_DEFAULT_SIZE 8 + #endif + + #if !defined(CONTROL_ONLY_DEVICE) || defined(__DOXYGEN__) + #if defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR) + #define ENDPOINT_TOTAL_ENDPOINTS 7 + #else + /** Total number of endpoints (including the default control endpoint at address 0) which may + * be used in the device. Different USB AVR models support different amounts of endpoints, + * this value reflects the maximum number of endpoints for the currently selected AVR model. + */ + #define ENDPOINT_TOTAL_ENDPOINTS 5 + #endif + #else + #define ENDPOINT_TOTAL_ENDPOINTS 1 + #endif + + /* Enums: */ + /** Enum for the possible error return codes of the \ref Endpoint_WaitUntilReady() function. + * + * \ingroup Group_EndpointRW_AVR8 + */ + enum Endpoint_WaitUntilReady_ErrorCodes_t + { + ENDPOINT_READYWAIT_NoError = 0, /**< Endpoint is ready for next packet, no error. */ + ENDPOINT_READYWAIT_EndpointStalled = 1, /**< The endpoint was stalled during the stream + * transfer by the host or device. + */ + ENDPOINT_READYWAIT_DeviceDisconnected = 2, /**< Device was disconnected from the host while + * waiting for the endpoint to become ready. + */ + ENDPOINT_READYWAIT_BusSuspended = 3, /**< The USB bus has been suspended by the host and + * no USB endpoint traffic can occur until the bus + * has resumed. + */ + ENDPOINT_READYWAIT_Timeout = 4, /**< The host failed to accept or send the next packet + * within the software timeout period set by the + * \ref USB_STREAM_TIMEOUT_MS macro. + */ + }; + + /* Inline Functions: */ + /** Configures the specified endpoint address with the given endpoint type, bank size and number of hardware + * banks. Once configured, the endpoint may be read from or written to, depending on its direction. + * + * \param[in] Address Endpoint address to configure. + * + * \param[in] Type Type of endpoint to configure, a \c EP_TYPE_* mask. Not all endpoint types + * are available on Low Speed USB devices - refer to the USB 2.0 specification. + * + * \param[in] Size Size of the endpoint's bank, where packets are stored before they are transmitted + * to the USB host, or after they have been received from the USB host (depending on + * the endpoint's data direction). The bank size must indicate the maximum packet size + * that the endpoint can handle. + * + * \param[in] Banks Number of banks to use for the endpoint being configured. + * + * \attention When the \c ORDERED_EP_CONFIG compile time option is used, Endpoints must be configured in + * ascending order, or bank corruption will occur. + * + * \note Different endpoints may have different maximum packet sizes based on the endpoint's index - please + * refer to the chosen microcontroller model's datasheet to determine the maximum bank size for each endpoint. + * \n\n + * + * \note The default control endpoint should not be manually configured by the user application, as + * it is automatically configured by the library internally. + * \n\n + * + * \note This routine will automatically select the specified endpoint upon success. Upon failure, the endpoint + * which failed to reconfigure correctly will be selected. + * + * \return Boolean \c true if the configuration succeeded, \c false otherwise. + */ + static inline bool Endpoint_ConfigureEndpoint(const uint8_t Address, + const uint8_t Type, + const uint16_t Size, + const uint8_t Banks) ATTR_ALWAYS_INLINE; + static inline bool Endpoint_ConfigureEndpoint(const uint8_t Address, + const uint8_t Type, + const uint16_t Size, + const uint8_t Banks) + { + uint8_t Number = (Address & ENDPOINT_EPNUM_MASK); + + if (Number >= ENDPOINT_TOTAL_ENDPOINTS) + return false; + + return Endpoint_ConfigureEndpoint_Prv(Number, + ((Type << EPTYPE0) | ((Address & ENDPOINT_DIR_IN) ? (1 << EPDIR) : 0)), + ((1 << ALLOC) | ((Banks > 1) ? (1 << EPBK0) : 0) | Endpoint_BytesToEPSizeMask(Size))); + } + + /** Indicates the number of bytes currently stored in the current endpoint's selected bank. + * + * \ingroup Group_EndpointRW_AVR8 + * + * \return Total number of bytes in the currently selected Endpoint's FIFO buffer. + */ + static inline uint16_t Endpoint_BytesInEndpoint(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint16_t Endpoint_BytesInEndpoint(void) + { + #if (defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR)) && !defined(__AVR_ATmega32U6__) + return UEBCX; + #elif defined(USB_SERIES_4_AVR) || defined(__AVR_ATmega32U6__) + return (((uint16_t)UEBCHX << 8) | UEBCLX); + #elif defined(USB_SERIES_2_AVR) + return UEBCLX; + #endif + } + + /** Determines the currently selected endpoint's direction. + * + * \return The currently selected endpoint's direction, as a \c ENDPOINT_DIR_* mask. + */ + static inline uint8_t Endpoint_GetEndpointDirection(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint8_t Endpoint_GetEndpointDirection(void) + { + return (UECFG0X & (1 << EPDIR)) ? ENDPOINT_DIR_IN : ENDPOINT_DIR_OUT; + } + + /** Get the endpoint address of the currently selected endpoint. This is typically used to save + * the currently selected endpoint so that it can be restored after another endpoint has been + * manipulated. + * + * \return Index of the currently selected endpoint. + */ + static inline uint8_t Endpoint_GetCurrentEndpoint(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint8_t Endpoint_GetCurrentEndpoint(void) + { + #if !defined(CONTROL_ONLY_DEVICE) + return ((UENUM & ENDPOINT_EPNUM_MASK) | Endpoint_GetEndpointDirection()); + #else + return ENDPOINT_CONTROLEP; + #endif + } + + /** Selects the given endpoint address. + * + * Any endpoint operations which do not require the endpoint address to be indicated will operate on + * the currently selected endpoint. + * + * \param[in] Address Endpoint address to select. + */ + static inline void Endpoint_SelectEndpoint(const uint8_t Address) ATTR_ALWAYS_INLINE; + static inline void Endpoint_SelectEndpoint(const uint8_t Address) + { + #if !defined(CONTROL_ONLY_DEVICE) + UENUM = (Address & ENDPOINT_EPNUM_MASK); + #endif + } + + /** Resets the endpoint bank FIFO. This clears all the endpoint banks and resets the USB controller's + * data In and Out pointers to the bank's contents. + * + * \param[in] Address Endpoint address whose FIFO buffers are to be reset. + */ + static inline void Endpoint_ResetEndpoint(const uint8_t Address) ATTR_ALWAYS_INLINE; + static inline void Endpoint_ResetEndpoint(const uint8_t Address) + { + UERST = (1 << (Address & ENDPOINT_EPNUM_MASK)); + UERST = 0; + } + + /** Enables the currently selected endpoint so that data can be sent and received through it to + * and from a host. + * + * \note Endpoints must first be configured properly via \ref Endpoint_ConfigureEndpoint(). + */ + static inline void Endpoint_EnableEndpoint(void) ATTR_ALWAYS_INLINE; + static inline void Endpoint_EnableEndpoint(void) + { + UECONX |= (1 << EPEN); + } + + /** Disables the currently selected endpoint so that data cannot be sent and received through it + * to and from a host. + */ + static inline void Endpoint_DisableEndpoint(void) ATTR_ALWAYS_INLINE; + static inline void Endpoint_DisableEndpoint(void) + { + UECONX &= ~(1 << EPEN); + } + + /** Determines if the currently selected endpoint is enabled, but not necessarily configured. + * + * \return Boolean \c true if the currently selected endpoint is enabled, \c false otherwise. + */ + static inline bool Endpoint_IsEnabled(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool Endpoint_IsEnabled(void) + { + return ((UECONX & (1 << EPEN)) ? true : false); + } + + /** Retrieves the number of busy banks in the currently selected endpoint, which have been queued for + * transmission via the \ref Endpoint_ClearIN() command, or are awaiting acknowledgement via the + * \ref Endpoint_ClearOUT() command. + * + * \ingroup Group_EndpointPacketManagement_AVR8 + * + * \return Total number of busy banks in the selected endpoint. + */ + static inline uint8_t Endpoint_GetBusyBanks(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT; + static inline uint8_t Endpoint_GetBusyBanks(void) + { + return (UESTA0X & (0x03 << NBUSYBK0)); + } + + /** Aborts all pending IN transactions on the currently selected endpoint, once the bank + * has been queued for transmission to the host via \ref Endpoint_ClearIN(). This function + * will terminate all queued transactions, resetting the endpoint banks ready for a new + * packet. + * + * \ingroup Group_EndpointPacketManagement_AVR8 + */ + static inline void Endpoint_AbortPendingIN(void) + { + while (Endpoint_GetBusyBanks() != 0) + { + UEINTX |= (1 << RXOUTI); + while (UEINTX & (1 << RXOUTI)); + } + } + + /** Determines if the currently selected endpoint may be read from (if data is waiting in the endpoint + * bank and the endpoint is an OUT direction, or if the bank is not yet full if the endpoint is an IN + * direction). This function will return false if an error has occurred in the endpoint, if the endpoint + * is an OUT direction and no packet (or an empty packet) has been received, or if the endpoint is an IN + * direction and the endpoint bank is full. + * + * \ingroup Group_EndpointPacketManagement_AVR8 + * + * \return Boolean \c true if the currently selected endpoint may be read from or written to, depending + * on its direction. + */ + static inline bool Endpoint_IsReadWriteAllowed(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool Endpoint_IsReadWriteAllowed(void) + { + return ((UEINTX & (1 << RWAL)) ? true : false); + } + + /** Determines if the currently selected endpoint is configured. + * + * \return Boolean \c true if the currently selected endpoint has been configured, \c false otherwise. + */ + static inline bool Endpoint_IsConfigured(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool Endpoint_IsConfigured(void) + { + return ((UESTA0X & (1 << CFGOK)) ? true : false); + } + + /** Returns a mask indicating which INTERRUPT type endpoints have interrupted - i.e. their + * interrupt duration has elapsed. Which endpoints have interrupted can be determined by + * masking the return value against (1 << {Endpoint Number}). + * + * \return Mask whose bits indicate which endpoints have interrupted. + */ + static inline uint8_t Endpoint_GetEndpointInterrupts(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint8_t Endpoint_GetEndpointInterrupts(void) + { + return UEINT; + } + + /** Determines if the specified endpoint number has interrupted (valid only for INTERRUPT type + * endpoints). + * + * \param[in] Address Address of the endpoint whose interrupt flag should be tested. + * + * \return Boolean \c true if the specified endpoint has interrupted, \c false otherwise. + */ + static inline bool Endpoint_HasEndpointInterrupted(const uint8_t Address) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool Endpoint_HasEndpointInterrupted(const uint8_t Address) + { + return ((Endpoint_GetEndpointInterrupts() & (1 << (Address & ENDPOINT_EPNUM_MASK))) ? true : false); + } + + /** Determines if the selected IN endpoint is ready for a new packet to be sent to the host. + * + * \ingroup Group_EndpointPacketManagement_AVR8 + * + * \return Boolean \c true if the current endpoint is ready for an IN packet, \c false otherwise. + */ + static inline bool Endpoint_IsINReady(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool Endpoint_IsINReady(void) + { + return ((UEINTX & (1 << TXINI)) ? true : false); + } + + /** Determines if the selected OUT endpoint has received new packet from the host. + * + * \ingroup Group_EndpointPacketManagement_AVR8 + * + * \return Boolean \c true if current endpoint is has received an OUT packet, \c false otherwise. + */ + static inline bool Endpoint_IsOUTReceived(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool Endpoint_IsOUTReceived(void) + { + return ((UEINTX & (1 << RXOUTI)) ? true : false); + } + + /** Determines if the current CONTROL type endpoint has received a SETUP packet. + * + * \ingroup Group_EndpointPacketManagement_AVR8 + * + * \return Boolean \c true if the selected endpoint has received a SETUP packet, \c false otherwise. + */ + static inline bool Endpoint_IsSETUPReceived(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool Endpoint_IsSETUPReceived(void) + { + return ((UEINTX & (1 << RXSTPI)) ? true : false); + } + + /** Clears a received SETUP packet on the currently selected CONTROL type endpoint, freeing up the + * endpoint for the next packet. + * + * \ingroup Group_EndpointPacketManagement_AVR8 + * + * \note This is not applicable for non CONTROL type endpoints. + */ + static inline void Endpoint_ClearSETUP(void) ATTR_ALWAYS_INLINE; + static inline void Endpoint_ClearSETUP(void) + { + UEINTX &= ~(1 << RXSTPI); + } + + /** Sends an IN packet to the host on the currently selected endpoint, freeing up the endpoint for the + * next packet and switching to the alternative endpoint bank if double banked. + * + * \ingroup Group_EndpointPacketManagement_AVR8 + */ + static inline void Endpoint_ClearIN(void) ATTR_ALWAYS_INLINE; + static inline void Endpoint_ClearIN(void) + { + #if !defined(CONTROL_ONLY_DEVICE) + UEINTX &= ~((1 << TXINI) | (1 << FIFOCON)); + #else + UEINTX &= ~(1 << TXINI); + #endif + } + + /** Acknowledges an OUT packet to the host on the currently selected endpoint, freeing up the endpoint + * for the next packet and switching to the alternative endpoint bank if double banked. + * + * \ingroup Group_EndpointPacketManagement_AVR8 + */ + static inline void Endpoint_ClearOUT(void) ATTR_ALWAYS_INLINE; + static inline void Endpoint_ClearOUT(void) + { + #if !defined(CONTROL_ONLY_DEVICE) + UEINTX &= ~((1 << RXOUTI) | (1 << FIFOCON)); + #else + UEINTX &= ~(1 << RXOUTI); + #endif + } + + /** Stalls the current endpoint, indicating to the host that a logical problem occurred with the + * indicated endpoint and that the current transfer sequence should be aborted. This provides a + * way for devices to indicate invalid commands to the host so that the current transfer can be + * aborted and the host can begin its own recovery sequence. + * + * The currently selected endpoint remains stalled until either the \ref Endpoint_ClearStall() macro + * is called, or the host issues a CLEAR FEATURE request to the device for the currently selected + * endpoint. + * + * \ingroup Group_EndpointPacketManagement_AVR8 + */ + static inline void Endpoint_StallTransaction(void) ATTR_ALWAYS_INLINE; + static inline void Endpoint_StallTransaction(void) + { + UECONX |= (1 << STALLRQ); + } + + /** Clears the STALL condition on the currently selected endpoint. + * + * \ingroup Group_EndpointPacketManagement_AVR8 + */ + static inline void Endpoint_ClearStall(void) ATTR_ALWAYS_INLINE; + static inline void Endpoint_ClearStall(void) + { + UECONX |= (1 << STALLRQC); + } + + /** Determines if the currently selected endpoint is stalled, false otherwise. + * + * \ingroup Group_EndpointPacketManagement_AVR8 + * + * \return Boolean \c true if the currently selected endpoint is stalled, \c false otherwise. + */ + static inline bool Endpoint_IsStalled(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool Endpoint_IsStalled(void) + { + return ((UECONX & (1 << STALLRQ)) ? true : false); + } + + /** Resets the data toggle of the currently selected endpoint. */ + static inline void Endpoint_ResetDataToggle(void) ATTR_ALWAYS_INLINE; + static inline void Endpoint_ResetDataToggle(void) + { + UECONX |= (1 << RSTDT); + } + + /** Sets the direction of the currently selected endpoint. + * + * \param[in] DirectionMask New endpoint direction, as a \c ENDPOINT_DIR_* mask. + */ + static inline void Endpoint_SetEndpointDirection(const uint8_t DirectionMask) ATTR_ALWAYS_INLINE; + static inline void Endpoint_SetEndpointDirection(const uint8_t DirectionMask) + { + UECFG0X = ((UECFG0X & ~(1 << EPDIR)) | (DirectionMask ? (1 << EPDIR) : 0)); + } + + /** Reads one byte from the currently selected endpoint's bank, for OUT direction endpoints. + * + * \ingroup Group_EndpointPrimitiveRW_AVR8 + * + * \return Next byte in the currently selected endpoint's FIFO buffer. + */ + static inline uint8_t Endpoint_Read_8(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint8_t Endpoint_Read_8(void) + { + return UEDATX; + } + + /** Writes one byte to the currently selected endpoint's bank, for IN direction endpoints. + * + * \ingroup Group_EndpointPrimitiveRW_AVR8 + * + * \param[in] Data Data to write into the the currently selected endpoint's FIFO buffer. + */ + static inline void Endpoint_Write_8(const uint8_t Data) ATTR_ALWAYS_INLINE; + static inline void Endpoint_Write_8(const uint8_t Data) + { + UEDATX = Data; + } + + /** Discards one byte from the currently selected endpoint's bank, for OUT direction endpoints. + * + * \ingroup Group_EndpointPrimitiveRW_AVR8 + */ + static inline void Endpoint_Discard_8(void) ATTR_ALWAYS_INLINE; + static inline void Endpoint_Discard_8(void) + { + uint8_t Dummy; + + Dummy = UEDATX; + + (void)Dummy; + } + + /** Reads two bytes from the currently selected endpoint's bank in little endian format, for OUT + * direction endpoints. + * + * \ingroup Group_EndpointPrimitiveRW_AVR8 + * + * \return Next two bytes in the currently selected endpoint's FIFO buffer. + */ + static inline uint16_t Endpoint_Read_16_LE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint16_t Endpoint_Read_16_LE(void) + { + union + { + uint16_t Value; + uint8_t Bytes[2]; + } Data; + + Data.Bytes[0] = UEDATX; + Data.Bytes[1] = UEDATX; + + return Data.Value; + } + + /** Reads two bytes from the currently selected endpoint's bank in big endian format, for OUT + * direction endpoints. + * + * \ingroup Group_EndpointPrimitiveRW_AVR8 + * + * \return Next two bytes in the currently selected endpoint's FIFO buffer. + */ + static inline uint16_t Endpoint_Read_16_BE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint16_t Endpoint_Read_16_BE(void) + { + union + { + uint16_t Value; + uint8_t Bytes[2]; + } Data; + + Data.Bytes[1] = UEDATX; + Data.Bytes[0] = UEDATX; + + return Data.Value; + } + + /** Writes two bytes to the currently selected endpoint's bank in little endian format, for IN + * direction endpoints. + * + * \ingroup Group_EndpointPrimitiveRW_AVR8 + * + * \param[in] Data Data to write to the currently selected endpoint's FIFO buffer. + */ + static inline void Endpoint_Write_16_LE(const uint16_t Data) ATTR_ALWAYS_INLINE; + static inline void Endpoint_Write_16_LE(const uint16_t Data) + { + UEDATX = (Data & 0xFF); + UEDATX = (Data >> 8); + } + + /** Writes two bytes to the currently selected endpoint's bank in big endian format, for IN + * direction endpoints. + * + * \ingroup Group_EndpointPrimitiveRW_AVR8 + * + * \param[in] Data Data to write to the currently selected endpoint's FIFO buffer. + */ + static inline void Endpoint_Write_16_BE(const uint16_t Data) ATTR_ALWAYS_INLINE; + static inline void Endpoint_Write_16_BE(const uint16_t Data) + { + UEDATX = (Data >> 8); + UEDATX = (Data & 0xFF); + } + + /** Discards two bytes from the currently selected endpoint's bank, for OUT direction endpoints. + * + * \ingroup Group_EndpointPrimitiveRW_AVR8 + */ + static inline void Endpoint_Discard_16(void) ATTR_ALWAYS_INLINE; + static inline void Endpoint_Discard_16(void) + { + uint8_t Dummy; + + Dummy = UEDATX; + Dummy = UEDATX; + + (void)Dummy; + } + + /** Reads four bytes from the currently selected endpoint's bank in little endian format, for OUT + * direction endpoints. + * + * \ingroup Group_EndpointPrimitiveRW_AVR8 + * + * \return Next four bytes in the currently selected endpoint's FIFO buffer. + */ + static inline uint32_t Endpoint_Read_32_LE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint32_t Endpoint_Read_32_LE(void) + { + union + { + uint32_t Value; + uint8_t Bytes[4]; + } Data; + + Data.Bytes[0] = UEDATX; + Data.Bytes[1] = UEDATX; + Data.Bytes[2] = UEDATX; + Data.Bytes[3] = UEDATX; + + return Data.Value; + } + + /** Reads four bytes from the currently selected endpoint's bank in big endian format, for OUT + * direction endpoints. + * + * \ingroup Group_EndpointPrimitiveRW_AVR8 + * + * \return Next four bytes in the currently selected endpoint's FIFO buffer. + */ + static inline uint32_t Endpoint_Read_32_BE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint32_t Endpoint_Read_32_BE(void) + { + union + { + uint32_t Value; + uint8_t Bytes[4]; + } Data; + + Data.Bytes[3] = UEDATX; + Data.Bytes[2] = UEDATX; + Data.Bytes[1] = UEDATX; + Data.Bytes[0] = UEDATX; + + return Data.Value; + } + + /** Writes four bytes to the currently selected endpoint's bank in little endian format, for IN + * direction endpoints. + * + * \ingroup Group_EndpointPrimitiveRW_AVR8 + * + * \param[in] Data Data to write to the currently selected endpoint's FIFO buffer. + */ + static inline void Endpoint_Write_32_LE(const uint32_t Data) ATTR_ALWAYS_INLINE; + static inline void Endpoint_Write_32_LE(const uint32_t Data) + { + UEDATX = (Data & 0xFF); + UEDATX = (Data >> 8); + UEDATX = (Data >> 16); + UEDATX = (Data >> 24); + } + + /** Writes four bytes to the currently selected endpoint's bank in big endian format, for IN + * direction endpoints. + * + * \ingroup Group_EndpointPrimitiveRW_AVR8 + * + * \param[in] Data Data to write to the currently selected endpoint's FIFO buffer. + */ + static inline void Endpoint_Write_32_BE(const uint32_t Data) ATTR_ALWAYS_INLINE; + static inline void Endpoint_Write_32_BE(const uint32_t Data) + { + UEDATX = (Data >> 24); + UEDATX = (Data >> 16); + UEDATX = (Data >> 8); + UEDATX = (Data & 0xFF); + } + + /** Discards four bytes from the currently selected endpoint's bank, for OUT direction endpoints. + * + * \ingroup Group_EndpointPrimitiveRW_AVR8 + */ + static inline void Endpoint_Discard_32(void) ATTR_ALWAYS_INLINE; + static inline void Endpoint_Discard_32(void) + { + uint8_t Dummy; + + Dummy = UEDATX; + Dummy = UEDATX; + Dummy = UEDATX; + Dummy = UEDATX; + + (void)Dummy; + } + + /* External Variables: */ + /** Global indicating the maximum packet size of the default control endpoint located at address + * 0 in the device. This value is set to the value indicated in the device descriptor in the user + * project once the USB interface is initialized into device mode. + * + * If space is an issue, it is possible to fix this to a static value by defining the control + * endpoint size in the \c FIXED_CONTROL_ENDPOINT_SIZE token passed to the compiler in the makefile + * via the -D switch. When a fixed control endpoint size is used, the size is no longer dynamically + * read from the descriptors at runtime and instead fixed to the given value. When used, it is + * important that the descriptor control endpoint size value matches the size given as the + * \c FIXED_CONTROL_ENDPOINT_SIZE token - it is recommended that the \c FIXED_CONTROL_ENDPOINT_SIZE token + * be used in the device descriptors to ensure this. + * + * \attention This variable should be treated as read-only in the user application, and never manually + * changed in value. + */ + #if (!defined(FIXED_CONTROL_ENDPOINT_SIZE) || defined(__DOXYGEN__)) + extern uint8_t USB_Device_ControlEndpointSize; + #else + #define USB_Device_ControlEndpointSize FIXED_CONTROL_ENDPOINT_SIZE + #endif + + /* Function Prototypes: */ + /** Configures a table of endpoint descriptions, in sequence. This function can be used to configure multiple + * endpoints at the same time. + * + * \note Endpoints with a zero address will be ignored, thus this function cannot be used to configure the + * control endpoint. + * + * \param[in] Table Pointer to a table of endpoint descriptions. + * \param[in] Entries Number of entries in the endpoint table to configure. + * + * \return Boolean \c true if all endpoints configured successfully, \c false otherwise. + */ + bool Endpoint_ConfigureEndpointTable(const USB_Endpoint_Table_t* const Table, + const uint8_t Entries); + + /** Completes the status stage of a control transfer on a CONTROL type endpoint automatically, + * with respect to the data direction. This is a convenience function which can be used to + * simplify user control request handling. + * + * \note This routine should not be called on non CONTROL type endpoints. + */ + void Endpoint_ClearStatusStage(void); + + /** Spin-loops until the currently selected non-control endpoint is ready for the next packet of data + * to be read or written to it. + * + * \note This routine should not be called on CONTROL type endpoints. + * + * \ingroup Group_EndpointRW_AVR8 + * + * \return A value from the \ref Endpoint_WaitUntilReady_ErrorCodes_t enum. + */ + uint8_t Endpoint_WaitUntilReady(void); + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/Host_AVR8.c b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/Host_AVR8.c new file mode 100644 index 00000000..d9326833 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/Host_AVR8.c @@ -0,0 +1,294 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#include "../../../../Common/Common.h" +#if (ARCH == ARCH_AVR8) + +#define __INCLUDE_FROM_USB_DRIVER +#include "../USBMode.h" + +#if defined(USB_CAN_BE_HOST) + +#define __INCLUDE_FROM_HOST_C +#include "../Host.h" + +void USB_Host_ProcessNextHostState(void) +{ + uint8_t ErrorCode = HOST_ENUMERROR_NoError; + uint8_t SubErrorCode = HOST_ENUMERROR_NoError; + + static uint16_t WaitMSRemaining; + static uint8_t PostWaitState; + + switch (USB_HostState) + { + case HOST_STATE_WaitForDevice: + if (WaitMSRemaining) + { + if ((SubErrorCode = USB_Host_WaitMS(1)) != HOST_WAITERROR_Successful) + { + USB_HostState = PostWaitState; + ErrorCode = HOST_ENUMERROR_WaitStage; + break; + } + + if (!(--WaitMSRemaining)) + USB_HostState = PostWaitState; + } + + break; + case HOST_STATE_Powered: + WaitMSRemaining = HOST_DEVICE_SETTLE_DELAY_MS; + + USB_HostState = HOST_STATE_Powered_WaitForDeviceSettle; + break; + case HOST_STATE_Powered_WaitForDeviceSettle: + if (WaitMSRemaining--) + { + Delay_MS(1); + break; + } + else + { + USB_Host_VBUS_Manual_Off(); + + USB_OTGPAD_On(); + USB_Host_VBUS_Auto_Enable(); + USB_Host_VBUS_Auto_On(); + + #if defined(NO_AUTO_VBUS_MANAGEMENT) + USB_Host_VBUS_Manual_Enable(); + USB_Host_VBUS_Manual_On(); + #endif + + USB_HostState = HOST_STATE_Powered_WaitForConnect; + } + + break; + case HOST_STATE_Powered_WaitForConnect: + if (USB_INT_HasOccurred(USB_INT_DCONNI)) + { + USB_INT_Clear(USB_INT_DCONNI); + USB_INT_Clear(USB_INT_DDISCI); + + USB_INT_Clear(USB_INT_VBERRI); + USB_INT_Enable(USB_INT_VBERRI); + + USB_Host_ResumeBus(); + Pipe_ClearPipes(); + + HOST_TASK_NONBLOCK_WAIT(100, HOST_STATE_Powered_DoReset); + } + + break; + case HOST_STATE_Powered_DoReset: + USB_Host_ResetDevice(); + + HOST_TASK_NONBLOCK_WAIT(200, HOST_STATE_Powered_ConfigPipe); + break; + case HOST_STATE_Powered_ConfigPipe: + if (!(Pipe_ConfigurePipe(PIPE_CONTROLPIPE, EP_TYPE_CONTROL, ENDPOINT_CONTROLEP, PIPE_CONTROLPIPE_DEFAULT_SIZE, 1))) + { + ErrorCode = HOST_ENUMERROR_PipeConfigError; + SubErrorCode = 0; + break; + } + + USB_HostState = HOST_STATE_Default; + break; + case HOST_STATE_Default: + USB_ControlRequest = (USB_Request_Header_t) + { + .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE), + .bRequest = REQ_GetDescriptor, + .wValue = (DTYPE_Device << 8), + .wIndex = 0, + .wLength = 8, + }; + + uint8_t DataBuffer[8]; + + Pipe_SelectPipe(PIPE_CONTROLPIPE); + if ((SubErrorCode = USB_Host_SendControlRequest(DataBuffer)) != HOST_SENDCONTROL_Successful) + { + ErrorCode = HOST_ENUMERROR_ControlError; + break; + } + + USB_Host_ControlPipeSize = DataBuffer[offsetof(USB_Descriptor_Device_t, Endpoint0Size)]; + + USB_Host_ResetDevice(); + + HOST_TASK_NONBLOCK_WAIT(200, HOST_STATE_Default_PostReset); + break; + case HOST_STATE_Default_PostReset: + if (!(Pipe_ConfigurePipe(PIPE_CONTROLPIPE, EP_TYPE_CONTROL, ENDPOINT_CONTROLEP, USB_Host_ControlPipeSize, 1))) + { + ErrorCode = HOST_ENUMERROR_PipeConfigError; + SubErrorCode = 0; + break; + } + + USB_ControlRequest = (USB_Request_Header_t) + { + .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE), + .bRequest = REQ_SetAddress, + .wValue = USB_HOST_DEVICEADDRESS, + .wIndex = 0, + .wLength = 0, + }; + + if ((SubErrorCode = USB_Host_SendControlRequest(NULL)) != HOST_SENDCONTROL_Successful) + { + ErrorCode = HOST_ENUMERROR_ControlError; + break; + } + + HOST_TASK_NONBLOCK_WAIT(100, HOST_STATE_Default_PostAddressSet); + break; + case HOST_STATE_Default_PostAddressSet: + USB_Host_SetDeviceAddress(USB_HOST_DEVICEADDRESS); + + USB_HostState = HOST_STATE_Addressed; + + EVENT_USB_Host_DeviceEnumerationComplete(); + break; + } + + if ((ErrorCode != HOST_ENUMERROR_NoError) && (USB_HostState != HOST_STATE_Unattached)) + { + EVENT_USB_Host_DeviceEnumerationFailed(ErrorCode, SubErrorCode); + + USB_Host_VBUS_Auto_Off(); + + EVENT_USB_Host_DeviceUnattached(); + + USB_ResetInterface(); + } +} + +uint8_t USB_Host_WaitMS(uint8_t MS) +{ + bool BusSuspended = USB_Host_IsBusSuspended(); + uint8_t ErrorCode = HOST_WAITERROR_Successful; + bool HSOFIEnabled = USB_INT_IsEnabled(USB_INT_HSOFI); + + USB_INT_Disable(USB_INT_HSOFI); + USB_INT_Clear(USB_INT_HSOFI); + + USB_Host_ResumeBus(); + + while (MS) + { + if (USB_INT_HasOccurred(USB_INT_HSOFI)) + { + USB_INT_Clear(USB_INT_HSOFI); + MS--; + } + + if ((USB_HostState == HOST_STATE_Unattached) || (USB_CurrentMode != USB_MODE_Host)) + { + ErrorCode = HOST_WAITERROR_DeviceDisconnect; + + break; + } + + if (Pipe_IsError()) + { + Pipe_ClearError(); + ErrorCode = HOST_WAITERROR_PipeError; + + break; + } + + if (Pipe_IsStalled()) + { + Pipe_ClearStall(); + ErrorCode = HOST_WAITERROR_SetupStalled; + + break; + } + } + + if (BusSuspended) + USB_Host_SuspendBus(); + + if (HSOFIEnabled) + USB_INT_Enable(USB_INT_HSOFI); + + return ErrorCode; +} + +static void USB_Host_ResetDevice(void) +{ + bool BusSuspended = USB_Host_IsBusSuspended(); + + USB_INT_Disable(USB_INT_DDISCI); + + USB_Host_ResetBus(); + while (!(USB_Host_IsBusResetComplete())); + USB_Host_ResumeBus(); + + USB_Host_ConfigurationNumber = 0; + + bool HSOFIEnabled = USB_INT_IsEnabled(USB_INT_HSOFI); + + USB_INT_Disable(USB_INT_HSOFI); + USB_INT_Clear(USB_INT_HSOFI); + + for (uint8_t MSRem = 10; MSRem != 0; MSRem--) + { + /* Workaround for powerless-pull-up devices. After a USB bus reset, + all disconnection interrupts are suppressed while a USB frame is + looked for - if it is found within 10ms, the device is still + present. */ + + if (USB_INT_HasOccurred(USB_INT_HSOFI)) + { + USB_INT_Clear(USB_INT_HSOFI); + USB_INT_Clear(USB_INT_DDISCI); + break; + } + + Delay_MS(1); + } + + if (HSOFIEnabled) + USB_INT_Enable(USB_INT_HSOFI); + + if (BusSuspended) + USB_Host_SuspendBus(); + + USB_INT_Enable(USB_INT_DDISCI); +} + +#endif + +#endif diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/Host_AVR8.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/Host_AVR8.h new file mode 100644 index 00000000..f8d92f81 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/Host_AVR8.h @@ -0,0 +1,372 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief USB Host definitions for the AVR8 microcontrollers. + * \copydetails Group_Host_AVR8 + * + * \note This file should not be included directly. It is automatically included as needed by the USB driver + * dispatch header located in LUFA/Drivers/USB/USB.h. + */ + +/** \ingroup Group_Host + * \defgroup Group_Host_AVR8 Host Management (AVR8) + * \brief USB Host definitions for the AVR8 microcontrollers. + * + * Architecture specific USB Host definitions for the Atmel 8-bit AVR microcontrollers. + * + * @{ + */ + +#ifndef __USBHOST_AVR8_H__ +#define __USBHOST_AVR8_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + #include "../StdDescriptors.h" + #include "../Pipe.h" + #include "../USBInterrupt.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_USB_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB/USB.h instead. + #endif + + #if defined(INVERTED_VBUS_ENABLE_LINE) && !defined(NO_AUTO_VBUS_MANAGEMENT) + #error The INVERTED_VBUS_ENABLE_LINE compile option requires NO_AUTO_VBUS_MANAGEMENT for the AVR8 architecture. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Indicates the fixed USB device address which any attached device is enumerated to when in + * host mode. As only one USB device may be attached to the AVR in host mode at any one time + * and that the address used is not important (other than the fact that it is non-zero), a + * fixed value is specified by the library. + */ + #define USB_HOST_DEVICEADDRESS 1 + + #if !defined(HOST_DEVICE_SETTLE_DELAY_MS) || defined(__DOXYGEN__) + /** Constant for the delay in milliseconds after a device is connected before the library + * will start the enumeration process. Some devices require a delay of up to 5 seconds + * after connection before the enumeration process can start or incorrect operation will + * occur. + * + * The default delay value may be overridden in the user project makefile by defining the + * \c HOST_DEVICE_SETTLE_DELAY_MS token to the required delay in milliseconds, and passed to the + * compiler using the -D switch. + */ + #define HOST_DEVICE_SETTLE_DELAY_MS 1000 + #endif + + /** Enum for the error codes for the \ref EVENT_USB_Host_HostError() event. + * + * \see \ref Group_Events for more information on this event. + */ + enum USB_Host_ErrorCodes_t + { + HOST_ERROR_VBusVoltageDip = 0, /**< VBUS voltage dipped to an unacceptable level. This + * error may be the result of an attached device drawing + * too much current from the VBUS line, or due to the + * AVR's power source being unable to supply sufficient + * current. + */ + }; + + /** Enum for the error codes for the \ref EVENT_USB_Host_DeviceEnumerationFailed() event. + * + * \see \ref Group_Events for more information on this event. + */ + enum USB_Host_EnumerationErrorCodes_t + { + HOST_ENUMERROR_NoError = 0, /**< No error occurred. Used internally, this is not a valid + * ErrorCode parameter value for the \ref EVENT_USB_Host_DeviceEnumerationFailed() + * event. + */ + HOST_ENUMERROR_WaitStage = 1, /**< One of the delays between enumeration steps failed + * to complete successfully, due to a timeout or other + * error. + */ + HOST_ENUMERROR_NoDeviceDetected = 2, /**< No device was detected, despite the USB data lines + * indicating the attachment of a device. + */ + HOST_ENUMERROR_ControlError = 3, /**< One of the enumeration control requests failed to + * complete successfully. + */ + HOST_ENUMERROR_PipeConfigError = 4, /**< The default control pipe (address 0) failed to + * configure correctly. + */ + }; + + /* Inline Functions: */ + /** Returns the current USB frame number, when in host mode. Every millisecond the USB bus is active (i.e. not suspended) + * the frame number is incremented by one. + * + * \return Current USB frame number from the USB controller. + */ + static inline uint16_t USB_Host_GetFrameNumber(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint16_t USB_Host_GetFrameNumber(void) + { + return UHFNUM; + } + + #if !defined(NO_SOF_EVENTS) + /** Enables the host mode Start Of Frame events. When enabled, this causes the + * \ref EVENT_USB_Host_StartOfFrame() event to fire once per millisecond, synchronized to the USB bus, + * at the start of each USB frame when a device is enumerated while in host mode. + * + * \note This function is not available when the \c NO_SOF_EVENTS compile time token is defined. + */ + static inline void USB_Host_EnableSOFEvents(void) ATTR_ALWAYS_INLINE; + static inline void USB_Host_EnableSOFEvents(void) + { + USB_INT_Enable(USB_INT_HSOFI); + } + + /** Disables the host mode Start Of Frame events. When disabled, this stops the firing of the + * \ref EVENT_USB_Host_StartOfFrame() event when enumerated in host mode. + * + * \note This function is not available when the \c NO_SOF_EVENTS compile time token is defined. + */ + static inline void USB_Host_DisableSOFEvents(void) ATTR_ALWAYS_INLINE; + static inline void USB_Host_DisableSOFEvents(void) + { + USB_INT_Disable(USB_INT_HSOFI); + } + #endif + + /** Resets the USB bus, including the endpoints in any attached device and pipes on the AVR host. + * USB bus resets leave the default control pipe configured (if already configured). + * + * If the USB bus has been suspended prior to issuing a bus reset, the attached device will be + * woken up automatically and the bus resumed after the reset has been correctly issued. + */ + static inline void USB_Host_ResetBus(void) ATTR_ALWAYS_INLINE; + static inline void USB_Host_ResetBus(void) + { + UHCON |= (1 << RESET); + } + + /** Determines if a previously issued bus reset (via the \ref USB_Host_ResetBus() macro) has + * completed. + * + * \return Boolean \c true if no bus reset is currently being sent, \c false otherwise. + */ + static inline bool USB_Host_IsBusResetComplete(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool USB_Host_IsBusResetComplete(void) + { + return ((UHCON & (1 << RESET)) ? false : true); + } + + /** Resumes USB communications with an attached and enumerated device, by resuming the transmission + * of the 1MS Start Of Frame messages to the device. When resumed, USB communications between the + * host and attached device may occur. + */ + static inline void USB_Host_ResumeBus(void) ATTR_ALWAYS_INLINE; + static inline void USB_Host_ResumeBus(void) + { + UHCON |= (1 << SOFEN); + } + + /** Suspends the USB bus, preventing any communications from occurring between the host and attached + * device until the bus has been resumed. This stops the transmission of the 1MS Start Of Frame + * messages to the device. + * + * \attention While the USB bus is suspended, all USB interrupt sources are also disabled; this means that + * some events (such as device disconnections) will not fire until the bus is resumed. + */ + static inline void USB_Host_SuspendBus(void) ATTR_ALWAYS_INLINE; + static inline void USB_Host_SuspendBus(void) + { + UHCON &= ~(1 << SOFEN); + } + + /** Determines if the USB bus has been suspended via the use of the \ref USB_Host_SuspendBus() macro, + * false otherwise. While suspended, no USB communications can occur until the bus is resumed, + * except for the Remote Wakeup event from the device if supported. + * + * \return Boolean \c true if the bus is currently suspended, \c false otherwise. + */ + static inline bool USB_Host_IsBusSuspended(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool USB_Host_IsBusSuspended(void) + { + return ((UHCON & (1 << SOFEN)) ? false : true); + } + + /** Determines if the attached device is currently enumerated in Full Speed mode (12Mb/s), or + * false if the attached device is enumerated in Low Speed mode (1.5Mb/s). + * + * \return Boolean \c true if the attached device is enumerated in Full Speed mode, \c false otherwise. + */ + static inline bool USB_Host_IsDeviceFullSpeed(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool USB_Host_IsDeviceFullSpeed(void) + { + return ((USBSTA & (1 << SPEED)) ? true : false); + } + + /** Determines if the attached device is currently issuing a Remote Wakeup request, requesting + * that the host resume the USB bus and wake up the device, false otherwise. + * + * \return Boolean \c true if the attached device has sent a Remote Wakeup request, \c false otherwise. + */ + static inline bool USB_Host_IsRemoteWakeupSent(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool USB_Host_IsRemoteWakeupSent(void) + { + return ((UHINT & (1 << RXRSMI)) ? true : false); + } + + /** Clears the flag indicating that a Remote Wakeup request has been issued by an attached device. */ + static inline void USB_Host_ClearRemoteWakeupSent(void) ATTR_ALWAYS_INLINE; + static inline void USB_Host_ClearRemoteWakeupSent(void) + { + UHINT &= ~(1 << RXRSMI); + } + + /** Accepts a Remote Wakeup request from an attached device. This must be issued in response to + * a device's Remote Wakeup request within 2ms for the request to be accepted and the bus to + * be resumed. + */ + static inline void USB_Host_ResumeFromWakeupRequest(void) ATTR_ALWAYS_INLINE; + static inline void USB_Host_ResumeFromWakeupRequest(void) + { + UHCON |= (1 << RESUME); + } + + /** Determines if a resume from Remote Wakeup request is currently being sent to an attached + * device. + * + * \return Boolean \c true if no resume request is currently being sent, \c false otherwise. + */ + static inline bool USB_Host_IsResumeFromWakeupRequestSent(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool USB_Host_IsResumeFromWakeupRequestSent(void) + { + return ((UHCON & (1 << RESUME)) ? false : true); + } + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Macros: */ + static inline void USB_Host_HostMode_On(void) ATTR_ALWAYS_INLINE; + static inline void USB_Host_HostMode_On(void) + { + USBCON |= (1 << HOST); + } + + static inline void USB_Host_HostMode_Off(void) ATTR_ALWAYS_INLINE; + static inline void USB_Host_HostMode_Off(void) + { + USBCON &= ~(1 << HOST); + } + + static inline void USB_Host_VBUS_Auto_Enable(void) ATTR_ALWAYS_INLINE; + static inline void USB_Host_VBUS_Auto_Enable(void) + { + OTGCON &= ~(1 << VBUSHWC); + UHWCON |= (1 << UVCONE); + } + + static inline void USB_Host_VBUS_Manual_Enable(void) ATTR_ALWAYS_INLINE; + static inline void USB_Host_VBUS_Manual_Enable(void) + { + OTGCON |= (1 << VBUSHWC); + UHWCON &= ~(1 << UVCONE); + + DDRE |= (1 << 7); + } + + static inline void USB_Host_VBUS_Auto_On(void) ATTR_ALWAYS_INLINE; + static inline void USB_Host_VBUS_Auto_On(void) + { + OTGCON |= (1 << VBUSREQ); + } + + static inline void USB_Host_VBUS_Manual_On(void) ATTR_ALWAYS_INLINE; + static inline void USB_Host_VBUS_Manual_On(void) + { + #if defined(INVERTED_VBUS_ENABLE_LINE) + PORTE &= ~(1 << 7); + #else + PORTE |= (1 << 7); + #endif + } + + static inline void USB_Host_VBUS_Auto_Off(void) ATTR_ALWAYS_INLINE; + static inline void USB_Host_VBUS_Auto_Off(void) + { + OTGCON |= (1 << VBUSRQC); + } + + static inline void USB_Host_VBUS_Manual_Off(void) ATTR_ALWAYS_INLINE; + static inline void USB_Host_VBUS_Manual_Off(void) + { + #if defined(INVERTED_VBUS_ENABLE_LINE) + PORTE |= (1 << 7); + #else + PORTE &= ~(1 << 7); + #endif + } + + static inline void USB_Host_SetDeviceAddress(const uint8_t Address) ATTR_ALWAYS_INLINE; + static inline void USB_Host_SetDeviceAddress(const uint8_t Address) + { + UHADDR = (Address & 0x7F); + } + + /* Enums: */ + enum USB_Host_WaitMSErrorCodes_t + { + HOST_WAITERROR_Successful = 0, + HOST_WAITERROR_DeviceDisconnect = 1, + HOST_WAITERROR_PipeError = 2, + HOST_WAITERROR_SetupStalled = 3, + }; + + /* Function Prototypes: */ + void USB_Host_ProcessNextHostState(void); + uint8_t USB_Host_WaitMS(uint8_t MS); + + #if defined(__INCLUDE_FROM_HOST_C) + static void USB_Host_ResetDevice(void); + #endif + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/OTG_AVR8.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/OTG_AVR8.h new file mode 100644 index 00000000..5296beb6 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/OTG_AVR8.h @@ -0,0 +1,159 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief USB OTG definitions for the AVR8 microcontrollers. + * \copydetails Group_OTG_AVR8 + * + * \note This file should not be included directly. It is automatically included as needed by the USB driver + * dispatch header located in LUFA/Drivers/USB/USB.h. + */ + +/** \ingroup Group_OTG + * \defgroup Group_OTG_AVR8 USB On The Go (OTG) Management (AVR8) + * \brief USB OTG definitions for the AVR8 microcontrollers. + * + * Architecture specific USB OTG definitions for the Atmel 8-bit AVR microcontrollers. + * + * @{ + */ + +#ifndef __USBOTG_AVR8_H__ +#define __USBOTG_AVR8_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_USB_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB/USB.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Mask for the VBUS pulsing method of SRP, supported by some OTG devices. + * + * \see \ref USB_OTG_Device_InitiateSRP(). + */ + #define USB_OTG_SRP_VBUS (1 << SRPSEL) + + /** Mask for the Data + pulsing method of SRP, supported by some OTG devices. + * + * \see \ref USB_OTG_Device_InitiateSRP(). + */ + #define USB_OTG_STP_DATA 0 + + /* Inline Functions: */ + /** Initiate a Host Negotiation Protocol request. This indicates to the other connected device + * that the device wishes to change device/host roles. + */ + static inline void USB_OTG_Device_RequestHNP(void) ATTR_ALWAYS_INLINE; + static inline void USB_OTG_Device_RequestHNP(void) + { + OTGCON |= (1 << HNPREQ); + } + + /** Cancel a Host Negotiation Protocol request. This stops a pending HNP request to the other + * connected device. + */ + static inline void USB_OTG_Device_CancelHNPRequest(void) ATTR_ALWAYS_INLINE; + static inline void USB_OTG_Device_CancelHNPRequest(void) + { + OTGCON &= ~(1 << HNPREQ); + } + + /** Determines if the device is currently sending a HNP to an attached host. + * + * \return Boolean \c true if currently sending a HNP to the other connected device, \c false otherwise + */ + static inline bool USB_OTG_Device_IsSendingHNP(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool USB_OTG_Device_IsSendingHNP(void) + { + return ((OTGCON & (1 << HNPREQ)) ? true : false); + } + + /** Initiates a Session Request Protocol request. Most OTG devices turn off VBUS when the USB + * interface is not in use, to conserve power. Sending a SRP to a USB OTG device running in + * host mode indicates that VBUS should be applied and a session started. + * + * There are two different methods of sending a SRP - either pulses on the VBUS line, or by + * pulsing the Data + line via the internal pull-up resistor. + * + * \param[in] SRPTypeMask Mask indicating the type of SRP to use, either \ref USB_OTG_SRP_VBUS or + * \ref USB_OTG_STP_DATA. + */ + static inline void USB_OTG_Device_InitiateSRP(const uint8_t SRPTypeMask) ATTR_ALWAYS_INLINE; + static inline void USB_OTG_Device_InitiateSRP(const uint8_t SRPTypeMask) + { + OTGCON = ((OTGCON & ~(1 << SRPSEL)) | (SRPTypeMask | (1 << SRPREQ))); + } + + /** Accepts a HNP from a connected device, indicating that both devices should exchange + * device/host roles. + */ + static inline void USB_OTG_Host_AcceptHNP(void) ATTR_ALWAYS_INLINE; + static inline void USB_OTG_Host_AcceptHNP(void) + { + OTGCON |= (1 << HNPREQ); + } + + /** Rejects a HNP from a connected device, indicating that both devices should remain in their + * current device/host roles. + */ + static inline void USB_OTG_Host_RejectHNP(void) ATTR_ALWAYS_INLINE; + static inline void USB_OTG_Host_RejectHNP(void) + { + OTGCON &= ~(1 << HNPREQ); + } + + /** Indicates if the connected device is currently sending a HNP request. + * + * \return Boolean \c true if a HNP is currently being issued by the connected device, \c false otherwise. + */ + static inline bool USB_OTG_Host_IsHNPReceived(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool USB_OTG_Host_IsHNPReceived(void) + { + return ((OTGCON & (1 << HNPREQ)) ? true : false); + } + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/PipeStream_AVR8.c b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/PipeStream_AVR8.c new file mode 100644 index 00000000..e71a7bd3 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/PipeStream_AVR8.c @@ -0,0 +1,221 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#include "../../../../Common/Common.h" +#if (ARCH == ARCH_AVR8) + +#define __INCLUDE_FROM_USB_DRIVER +#include "../USBMode.h" + +#if defined(USB_CAN_BE_HOST) + +#include "PipeStream_AVR8.h" + +uint8_t Pipe_Discard_Stream(uint16_t Length, + uint16_t* const BytesProcessed) +{ + uint8_t ErrorCode; + uint16_t BytesInTransfer = 0; + + Pipe_SetPipeToken(PIPE_TOKEN_IN); + + if ((ErrorCode = Pipe_WaitUntilReady())) + return ErrorCode; + + if (BytesProcessed != NULL) + Length -= *BytesProcessed; + + while (Length) + { + if (!(Pipe_IsReadWriteAllowed())) + { + Pipe_ClearIN(); + + if (BytesProcessed != NULL) + { + *BytesProcessed += BytesInTransfer; + return PIPE_RWSTREAM_IncompleteTransfer; + } + + if ((ErrorCode = Pipe_WaitUntilReady())) + return ErrorCode; + } + else + { + Pipe_Discard_8(); + + Length--; + BytesInTransfer++; + } + } + + return PIPE_RWSTREAM_NoError; +} + +uint8_t Pipe_Null_Stream(uint16_t Length, + uint16_t* const BytesProcessed) +{ + uint8_t ErrorCode; + uint16_t BytesInTransfer = 0; + + Pipe_SetPipeToken(PIPE_TOKEN_OUT); + + if ((ErrorCode = Pipe_WaitUntilReady())) + return ErrorCode; + + if (BytesProcessed != NULL) + Length -= *BytesProcessed; + + while (Length) + { + if (!(Pipe_IsReadWriteAllowed())) + { + Pipe_ClearOUT(); + + if (BytesProcessed != NULL) + { + *BytesProcessed += BytesInTransfer; + return PIPE_RWSTREAM_IncompleteTransfer; + } + + USB_USBTask(); + + if ((ErrorCode = Pipe_WaitUntilReady())) + return ErrorCode; + } + else + { + Pipe_Write_8(0); + + Length--; + BytesInTransfer++; + } + } + + return PIPE_RWSTREAM_NoError; +} + +/* The following abuses the C preprocessor in order to copy-paste common code with slight alterations, + * so that the code needs to be written once. It is a crude form of templating to reduce code maintenance. */ + +#define TEMPLATE_FUNC_NAME Pipe_Write_Stream_LE +#define TEMPLATE_BUFFER_TYPE const void* +#define TEMPLATE_TOKEN PIPE_TOKEN_OUT +#define TEMPLATE_CLEAR_PIPE() Pipe_ClearOUT() +#define TEMPLATE_BUFFER_OFFSET(Length) 0 +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) DataStream += Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Pipe_Write_8(*BufferPtr) +#include "Template/Template_Pipe_RW.c" + +#define TEMPLATE_FUNC_NAME Pipe_Write_Stream_BE +#define TEMPLATE_BUFFER_TYPE const void* +#define TEMPLATE_TOKEN PIPE_TOKEN_OUT +#define TEMPLATE_CLEAR_PIPE() Pipe_ClearOUT() +#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) DataStream -= Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Pipe_Write_8(*BufferPtr) +#include "Template/Template_Pipe_RW.c" + +#define TEMPLATE_FUNC_NAME Pipe_Read_Stream_LE +#define TEMPLATE_BUFFER_TYPE void* +#define TEMPLATE_TOKEN PIPE_TOKEN_IN +#define TEMPLATE_CLEAR_PIPE() Pipe_ClearIN() +#define TEMPLATE_BUFFER_OFFSET(Length) 0 +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) DataStream += Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *BufferPtr = Pipe_Read_8() +#include "Template/Template_Pipe_RW.c" + +#define TEMPLATE_FUNC_NAME Pipe_Read_Stream_BE +#define TEMPLATE_BUFFER_TYPE void* +#define TEMPLATE_TOKEN PIPE_TOKEN_IN +#define TEMPLATE_CLEAR_PIPE() Pipe_ClearIN() +#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) DataStream -= Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *BufferPtr = Pipe_Read_8() +#include "Template/Template_Pipe_RW.c" + +#define TEMPLATE_FUNC_NAME Pipe_Write_PStream_LE +#define TEMPLATE_BUFFER_TYPE const void* +#define TEMPLATE_TOKEN PIPE_TOKEN_OUT +#define TEMPLATE_CLEAR_PIPE() Pipe_ClearOUT() +#define TEMPLATE_BUFFER_OFFSET(Length) 0 +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) DataStream += Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Pipe_Write_8(pgm_read_byte(BufferPtr)) +#include "Template/Template_Pipe_RW.c" + +#define TEMPLATE_FUNC_NAME Pipe_Write_PStream_BE +#define TEMPLATE_BUFFER_TYPE const void* +#define TEMPLATE_TOKEN PIPE_TOKEN_OUT +#define TEMPLATE_CLEAR_PIPE() Pipe_ClearOUT() +#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) DataStream -= Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Pipe_Write_8(pgm_read_byte(BufferPtr)) +#include "Template/Template_Pipe_RW.c" + +#define TEMPLATE_FUNC_NAME Pipe_Write_EStream_LE +#define TEMPLATE_BUFFER_TYPE const void* +#define TEMPLATE_TOKEN PIPE_TOKEN_OUT +#define TEMPLATE_CLEAR_PIPE() Pipe_ClearOUT() +#define TEMPLATE_BUFFER_OFFSET(Length) 0 +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) DataStream += Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Pipe_Write_8(eeprom_read_byte(BufferPtr)) +#include "Template/Template_Pipe_RW.c" + +#define TEMPLATE_FUNC_NAME Pipe_Write_EStream_BE +#define TEMPLATE_BUFFER_TYPE const void* +#define TEMPLATE_TOKEN PIPE_TOKEN_OUT +#define TEMPLATE_CLEAR_PIPE() Pipe_ClearOUT() +#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) DataStream -= Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Pipe_Write_8(eeprom_read_byte(BufferPtr)) +#include "Template/Template_Pipe_RW.c" + +#define TEMPLATE_FUNC_NAME Pipe_Read_EStream_LE +#define TEMPLATE_BUFFER_TYPE void* +#define TEMPLATE_TOKEN PIPE_TOKEN_IN +#define TEMPLATE_CLEAR_PIPE() Pipe_ClearIN() +#define TEMPLATE_BUFFER_OFFSET(Length) 0 +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) DataStream += Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) eeprom_update_byte(BufferPtr, Pipe_Read_8()) +#include "Template/Template_Pipe_RW.c" + +#define TEMPLATE_FUNC_NAME Pipe_Read_EStream_BE +#define TEMPLATE_BUFFER_TYPE void* +#define TEMPLATE_TOKEN PIPE_TOKEN_IN +#define TEMPLATE_CLEAR_PIPE() Pipe_ClearIN() +#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) DataStream -= Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) eeprom_update_byte(BufferPtr, Pipe_Read_8()) +#include "Template/Template_Pipe_RW.c" + +#endif + +#endif + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/PipeStream_AVR8.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/PipeStream_AVR8.h new file mode 100644 index 00000000..8307ab49 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/PipeStream_AVR8.h @@ -0,0 +1,442 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Pipe data stream transmission and reception management for the AVR8 microcontrollers + * \copydetails Group_PipeStreamRW_AVR8 + * + * \note This file should not be included directly. It is automatically included as needed by the USB driver + * dispatch header located in LUFA/Drivers/USB/USB.h. + */ + +/** \ingroup Group_PipeStreamRW + * \defgroup Group_PipeStreamRW_AVR8 Read/Write of Multi-Byte Streams (AVR8) + * \brief Pipe data stream transmission and reception management for the Atmel AVR8 architecture. + * + * Functions, macros, variables, enums and types related to data reading and writing of data streams from + * and to pipes. + * + * @{ + */ + +#ifndef __PIPE_STREAM_AVR8_H__ +#define __PIPE_STREAM_AVR8_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + #include "../USBMode.h" + #include "../USBTask.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_USB_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB/USB.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Function Prototypes: */ + /** \name Stream functions for null data */ + //@{ + + /** Reads and discards the given number of bytes from the pipe, discarding fully read packets from the host + * as needed. The last packet is not automatically discarded once the remaining bytes has been read; the + * user is responsible for manually discarding the last packet from the device via the \ref Pipe_ClearIN() macro. + * + * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, failing or + * succeeding as a single unit. If the BytesProcessed parameter points to a valid storage location, the transfer + * will instead be performed as a series of chunks. Each time the pipe bank becomes empty while there is still data + * to process (and after the current packet has been acknowledged) the BytesProcessed location will be updated with + * the total number of bytes processed in the stream, and the function will exit with an error code of + * \ref PIPE_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed in the user code - to + * continue the transfer, call the function again with identical parameters and it will resume until the BytesProcessed + * value reaches the total transfer length. + * + * Single Stream Transfer Example: + * \code + * uint8_t ErrorCode; + * + * if ((ErrorCode = Pipe_Discard_Stream(512, NULL)) != PIPE_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * Partial Stream Transfers Example: + * \code + * uint8_t ErrorCode; + * uint16_t BytesProcessed; + * + * BytesProcessed = 0; + * while ((ErrorCode = Pipe_Discard_Stream(512, &BytesProcessed)) == PIPE_RWSTREAM_IncompleteTransfer) + * { + * // Stream not yet complete - do other actions here, abort if required + * } + * + * if (ErrorCode != PIPE_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * \note The pipe token is set automatically, thus this can be used on bi-directional pipes directly without + * having to explicitly change the data direction with a call to \ref Pipe_SetPipeToken(). + * + * \param[in] Length Number of bytes to discard via the currently selected pipe. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should + * updated, \c NULL if the entire stream should be processed at once. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Pipe_Discard_Stream(uint16_t Length, + uint16_t* const BytesProcessed); + + /** Writes a given number of zeroed bytes to the pipe, sending full pipe packets from the host to the device + * as needed. The last packet is not automatically sent once the remaining bytes has been written; the + * user is responsible for manually discarding the last packet from the device via the \ref Pipe_ClearOUT() macro. + * + * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, failing or + * succeeding as a single unit. If the BytesProcessed parameter points to a valid storage location, the transfer + * will instead be performed as a series of chunks. Each time the pipe bank becomes full while there is still data + * to process (and after the current packet transmission has been initiated) the BytesProcessed location will be + * updated with the total number of bytes processed in the stream, and the function will exit with an error code of + * \ref PIPE_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed in the user code - to + * continue the transfer, call the function again with identical parameters and it will resume until the BytesProcessed + * value reaches the total transfer length. + * + * Single Stream Transfer Example: + * \code + * uint8_t ErrorCode; + * + * if ((ErrorCode = Pipe_Null_Stream(512, NULL)) != PIPE_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * Partial Stream Transfers Example: + * \code + * uint8_t ErrorCode; + * uint16_t BytesProcessed; + * + * BytesProcessed = 0; + * while ((ErrorCode = Pipe_Null_Stream(512, &BytesProcessed)) == PIPE_RWSTREAM_IncompleteTransfer) + * { + * // Stream not yet complete - do other actions here, abort if required + * } + * + * if (ErrorCode != PIPE_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * \note The pipe token is set automatically, thus this can be used on bi-directional pipes directly without + * having to explicitly change the data direction with a call to \ref Pipe_SetPipeToken(). + * + * \param[in] Length Number of zero bytes to write via the currently selected pipe. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should + * updated, \c NULL if the entire stream should be processed at once. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Pipe_Null_Stream(uint16_t Length, + uint16_t* const BytesProcessed); + + //@} + + /** \name Stream functions for RAM source/destination data */ + //@{ + + /** Writes the given number of bytes to the pipe from the given buffer in little endian, + * sending full packets to the device as needed. The last packet filled is not automatically sent; + * the user is responsible for manually sending the last written packet to the host via the + * \ref Pipe_ClearOUT() macro. Between each USB packet, the given stream callback function is + * executed repeatedly until the next packet is ready, allowing for early aborts of stream transfers. + * + * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, + * failing or succeeding as a single unit. If the BytesProcessed parameter points to a valid + * storage location, the transfer will instead be performed as a series of chunks. Each time + * the pipe bank becomes full while there is still data to process (and after the current + * packet transmission has been initiated) the BytesProcessed location will be updated with the + * total number of bytes processed in the stream, and the function will exit with an error code of + * \ref PIPE_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed + * in the user code - to continue the transfer, call the function again with identical parameters + * and it will resume until the BytesProcessed value reaches the total transfer length. + * + * Single Stream Transfer Example: + * \code + * uint8_t DataStream[512]; + * uint8_t ErrorCode; + * + * if ((ErrorCode = Pipe_Write_Stream_LE(DataStream, sizeof(DataStream), + * NULL)) != PIPE_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * Partial Stream Transfers Example: + * \code + * uint8_t DataStream[512]; + * uint8_t ErrorCode; + * uint16_t BytesProcessed; + * + * BytesProcessed = 0; + * while ((ErrorCode = Pipe_Write_Stream_LE(DataStream, sizeof(DataStream), + * &BytesProcessed)) == PIPE_RWSTREAM_IncompleteTransfer) + * { + * // Stream not yet complete - do other actions here, abort if required + * } + * + * if (ErrorCode != PIPE_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * \note The pipe token is set automatically, thus this can be used on bi-directional pipes directly without + * having to explicitly change the data direction with a call to \ref Pipe_SetPipeToken(). + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected pipe into the buffer. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should + * updated, \c NULL if the entire stream should be written at once. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Pipe_Write_Stream_LE(const void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** Writes the given number of bytes to the pipe from the given buffer in big endian, + * sending full packets to the device as needed. The last packet filled is not automatically sent; + * the user is responsible for manually sending the last written packet to the host via the + * \ref Pipe_ClearOUT() macro. Between each USB packet, the given stream callback function is + * executed repeatedly until the next packet is ready, allowing for early aborts of stream transfers. + * + * \note The pipe token is set automatically, thus this can be used on bi-directional pipes directly without + * having to explicitly change the data direction with a call to \ref Pipe_SetPipeToken(). + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected pipe into the buffer. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should + * updated, \c NULL if the entire stream should be written at once. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Pipe_Write_Stream_BE(const void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** Reads the given number of bytes from the pipe into the given buffer in little endian, + * sending full packets to the device as needed. The last packet filled is not automatically sent; + * the user is responsible for manually sending the last written packet to the host via the + * \ref Pipe_ClearIN() macro. Between each USB packet, the given stream callback function is + * executed repeatedly until the next packet is ready, allowing for early aborts of stream transfers. + * + * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, + * failing or succeeding as a single unit. If the BytesProcessed parameter points to a valid + * storage location, the transfer will instead be performed as a series of chunks. Each time + * the pipe bank becomes empty while there is still data to process (and after the current + * packet has been acknowledged) the BytesProcessed location will be updated with the total number + * of bytes processed in the stream, and the function will exit with an error code of + * \ref PIPE_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed + * in the user code - to continue the transfer, call the function again with identical parameters + * and it will resume until the BytesProcessed value reaches the total transfer length. + * + * Single Stream Transfer Example: + * \code + * uint8_t DataStream[512]; + * uint8_t ErrorCode; + * + * if ((ErrorCode = Pipe_Read_Stream_LE(DataStream, sizeof(DataStream), + * NULL)) != PIPE_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * Partial Stream Transfers Example: + * \code + * uint8_t DataStream[512]; + * uint8_t ErrorCode; + * uint16_t BytesProcessed; + * + * BytesProcessed = 0; + * while ((ErrorCode = Pipe_Read_Stream_LE(DataStream, sizeof(DataStream), + * &BytesProcessed)) == PIPE_RWSTREAM_IncompleteTransfer) + * { + * // Stream not yet complete - do other actions here, abort if required + * } + * + * if (ErrorCode != PIPE_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * \note The pipe token is set automatically, thus this can be used on bi-directional pipes directly without + * having to explicitly change the data direction with a call to \ref Pipe_SetPipeToken(). + * + * \param[out] Buffer Pointer to the source data buffer to write to. + * \param[in] Length Number of bytes to read for the currently selected pipe to read from. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should + * updated, \c NULL if the entire stream should be read at once. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Pipe_Read_Stream_LE(void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** Reads the given number of bytes from the pipe into the given buffer in big endian, + * sending full packets to the device as needed. The last packet filled is not automatically sent; + * the user is responsible for manually sending the last written packet to the host via the + * \ref Pipe_ClearIN() macro. Between each USB packet, the given stream callback function is + * executed repeatedly until the next packet is ready, allowing for early aborts of stream transfers. + * + * \note The pipe token is set automatically, thus this can be used on bi-directional pipes directly without + * having to explicitly change the data direction with a call to \ref Pipe_SetPipeToken(). + * + * \param[out] Buffer Pointer to the source data buffer to write to. + * \param[in] Length Number of bytes to read for the currently selected pipe to read from. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should + * updated, \c NULL if the entire stream should be read at once. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Pipe_Read_Stream_BE(void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + //@} + + /** \name Stream functions for EEPROM source/destination data */ + //@{ + + /** EEPROM buffer source version of \ref Pipe_Write_Stream_LE(). + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected pipe into the buffer. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should + * updated, \c NULL if the entire stream should be written at once. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Pipe_Write_EStream_LE(const void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** EEPROM buffer source version of \ref Pipe_Write_Stream_BE(). + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected pipe into the buffer. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should + * updated, \c NULL if the entire stream should be written at once. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Pipe_Write_EStream_BE(const void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** EEPROM buffer source version of \ref Pipe_Read_Stream_LE(). + * + * \param[out] Buffer Pointer to the source data buffer to write to. + * \param[in] Length Number of bytes to read for the currently selected pipe to read from. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should + * updated, \c NULL if the entire stream should be read at once. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Pipe_Read_EStream_LE(void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** EEPROM buffer source version of \ref Pipe_Read_Stream_BE(). + * + * \param[out] Buffer Pointer to the source data buffer to write to. + * \param[in] Length Number of bytes to read for the currently selected pipe to read from. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should + * updated, \c NULL if the entire stream should be read at once. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Pipe_Read_EStream_BE(void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + //@} + + /** \name Stream functions for PROGMEM source/destination data */ + //@{ + + /** FLASH buffer source version of \ref Pipe_Write_Stream_LE(). + * + * \pre The FLASH data must be located in the first 64KB of FLASH for this function to work correctly. + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected pipe into the buffer. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should + * updated, \c NULL if the entire stream should be written at once. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Pipe_Write_PStream_LE(const void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** FLASH buffer source version of \ref Pipe_Write_Stream_BE(). + * + * \pre The FLASH data must be located in the first 64KB of FLASH for this function to work correctly. + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected pipe into the buffer. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should + * updated, \c NULL if the entire stream should be written at once. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Pipe_Write_PStream_BE(const void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + //@} + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/Pipe_AVR8.c b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/Pipe_AVR8.c new file mode 100644 index 00000000..bf3ff003 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/Pipe_AVR8.c @@ -0,0 +1,210 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#include "../../../../Common/Common.h" +#if (ARCH == ARCH_AVR8) + +#define __INCLUDE_FROM_USB_DRIVER +#include "../USBMode.h" + +#if defined(USB_CAN_BE_HOST) + +#include "../Pipe.h" + +uint8_t USB_Host_ControlPipeSize = PIPE_CONTROLPIPE_DEFAULT_SIZE; + +bool Pipe_ConfigurePipeTable(const USB_Pipe_Table_t* const Table, + const uint8_t Entries) +{ + for (uint8_t i = 0; i < Entries; i++) + { + if (!(Table[i].Address)) + continue; + + if (!(Pipe_ConfigurePipe(Table[i].Address, Table[i].Type, Table[i].EndpointAddress, Table[i].Size, Table[i].Banks))) + { + return false; + } + } + + return true; +} + +bool Pipe_ConfigurePipe(const uint8_t Address, + const uint8_t Type, + const uint8_t EndpointAddress, + const uint16_t Size, + const uint8_t Banks) +{ + uint8_t Number = (Address & PIPE_EPNUM_MASK); + uint8_t Token = (Address & PIPE_DIR_IN) ? PIPE_TOKEN_IN : PIPE_TOKEN_OUT; + + if (Number >= PIPE_TOTAL_PIPES) + return false; + + if (Type == EP_TYPE_CONTROL) + Token = PIPE_TOKEN_SETUP; + +#if defined(ORDERED_EP_CONFIG) + Pipe_SelectPipe(Number); + Pipe_EnablePipe(); + + UPCFG1X = 0; + + UPCFG0X = ((Type << EPTYPE0) | Token | ((EndpointAddress & PIPE_EPNUM_MASK) << PEPNUM0)); + UPCFG1X = ((1 << ALLOC) | ((Banks > 1) ? (1 << EPBK0) : 0) | Pipe_BytesToEPSizeMask(Size)); + + Pipe_SetInfiniteINRequests(); + + return Pipe_IsConfigured(); +#else + for (uint8_t PNum = Number; PNum < PIPE_TOTAL_PIPES; PNum++) + { + uint8_t UPCFG0XTemp; + uint8_t UPCFG1XTemp; + uint8_t UPCFG2XTemp; + uint8_t UPIENXTemp; + + Pipe_SelectPipe(PNum); + + if (PNum == Number) + { + UPCFG0XTemp = ((Type << EPTYPE0) | Token | ((EndpointAddress & PIPE_EPNUM_MASK) << PEPNUM0)); + UPCFG1XTemp = ((1 << ALLOC) | Banks | Pipe_BytesToEPSizeMask(Size)); + UPCFG2XTemp = 0; + UPIENXTemp = 0; + } + else + { + UPCFG0XTemp = UPCFG0X; + UPCFG1XTemp = UPCFG1X; + UPCFG2XTemp = UPCFG2X; + UPIENXTemp = UPIENX; + } + + if (!(UPCFG1XTemp & (1 << ALLOC))) + continue; + + Pipe_DisablePipe(); + UPCFG1X &= ~(1 << ALLOC); + + Pipe_EnablePipe(); + UPCFG0X = UPCFG0XTemp; + UPCFG1X = UPCFG1XTemp; + UPCFG2X = UPCFG2XTemp; + UPIENX = UPIENXTemp; + + Pipe_SetInfiniteINRequests(); + + if (!(Pipe_IsConfigured())) + return false; + } + + Pipe_SelectPipe(Number); + return true; +#endif +} + +void Pipe_ClearPipes(void) +{ + UPINT = 0; + + for (uint8_t PNum = 0; PNum < PIPE_TOTAL_PIPES; PNum++) + { + Pipe_SelectPipe(PNum); + UPIENX = 0; + UPINTX = 0; + UPCFG1X = 0; + Pipe_DisablePipe(); + } +} + +bool Pipe_IsEndpointBound(const uint8_t EndpointAddress) +{ + uint8_t PrevPipeNumber = Pipe_GetCurrentPipe(); + + for (uint8_t PNum = 0; PNum < PIPE_TOTAL_PIPES; PNum++) + { + Pipe_SelectPipe(PNum); + + if (!(Pipe_IsConfigured())) + continue; + + if (Pipe_GetBoundEndpointAddress() == EndpointAddress) + return true; + } + + Pipe_SelectPipe(PrevPipeNumber); + return false; +} + +uint8_t Pipe_WaitUntilReady(void) +{ + #if (USB_STREAM_TIMEOUT_MS < 0xFF) + uint8_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS; + #else + uint16_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS; + #endif + + uint16_t PreviousFrameNumber = USB_Host_GetFrameNumber(); + + for (;;) + { + if (Pipe_GetPipeToken() == PIPE_TOKEN_IN) + { + if (Pipe_IsINReceived()) + return PIPE_READYWAIT_NoError; + } + else + { + if (Pipe_IsOUTReady()) + return PIPE_READYWAIT_NoError; + } + + if (Pipe_IsStalled()) + return PIPE_READYWAIT_PipeStalled; + else if (USB_HostState == HOST_STATE_Unattached) + return PIPE_READYWAIT_DeviceDisconnected; + + uint16_t CurrentFrameNumber = USB_Host_GetFrameNumber(); + + if (CurrentFrameNumber != PreviousFrameNumber) + { + PreviousFrameNumber = CurrentFrameNumber; + + if (!(TimeoutMSRem--)) + return PIPE_READYWAIT_Timeout; + } + } +} + +#endif + +#endif diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/Pipe_AVR8.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/Pipe_AVR8.h new file mode 100644 index 00000000..24c7b36c --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/Pipe_AVR8.h @@ -0,0 +1,921 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief USB Pipe definitions for the AVR8 microcontrollers. + * \copydetails Group_PipeManagement_AVR8 + * + * \note This file should not be included directly. It is automatically included as needed by the USB driver + * dispatch header located in LUFA/Drivers/USB/USB.h. + */ + +/** \ingroup Group_PipeRW + * \defgroup Group_PipeRW_AVR8 Pipe Data Reading and Writing (AVR8) + * \brief Pipe data read/write definitions for the Atmel AVR8 architecture. + * + * Functions, macros, variables, enums and types related to data reading and writing from and to pipes. + */ + +/** \ingroup Group_PipePrimitiveRW + * \defgroup Group_PipePrimitiveRW_AVR8 Read/Write of Primitive Data Types (AVR8) + * \brief Pipe primitive data read/write definitions for the Atmel AVR8 architecture. + * + * Functions, macros, variables, enums and types related to data reading and writing of primitive data types + * from and to pipes. + */ + +/** \ingroup Group_PipePacketManagement + * \defgroup Group_PipePacketManagement_AVR8 Pipe Packet Management (AVR8) + * \brief Pipe packet management definitions for the Atmel AVR8 architecture. + * + * Functions, macros, variables, enums and types related to packet management of pipes. + */ + +/** \ingroup Group_PipeControlReq + * \defgroup Group_PipeControlReq_AVR8 Pipe Control Request Management (AVR8) + * \brief Pipe control request management definitions for the Atmel AVR8 architecture. + * + * Module for host mode request processing. This module allows for the transmission of standard, class and + * vendor control requests to the default control endpoint of an attached device while in host mode. + * + * \see Chapter 9 of the USB 2.0 specification. + */ + +/** \ingroup Group_PipeManagement + * \defgroup Group_PipeManagement_AVR8 Pipe Management (AVR8) + * \brief Pipe management definitions for the Atmel AVR8 architecture. + * + * This module contains functions, macros and enums related to pipe management when in USB Host mode. This + * module contains the pipe management macros, as well as pipe interrupt and data send/receive functions + * for various data types. + * + * @{ + */ + +#ifndef __PIPE_AVR8_H__ +#define __PIPE_AVR8_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + #include "../USBTask.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_USB_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB/USB.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** \name Pipe Error Flag Masks */ + //@{ + /** Mask for \ref Pipe_GetErrorFlags(), indicating that an overflow error occurred in the pipe on the received data. */ + #define PIPE_ERRORFLAG_OVERFLOW (1 << 6) + + /** Mask for \ref Pipe_GetErrorFlags(), indicating that an underflow error occurred in the pipe on the received data. */ + #define PIPE_ERRORFLAG_UNDERFLOW (1 << 5) + + /** Mask for \ref Pipe_GetErrorFlags(), indicating that a CRC error occurred in the pipe on the received data. */ + #define PIPE_ERRORFLAG_CRC16 (1 << 4) + + /** Mask for \ref Pipe_GetErrorFlags(), indicating that a hardware timeout error occurred in the pipe. */ + #define PIPE_ERRORFLAG_TIMEOUT (1 << 3) + + /** Mask for \ref Pipe_GetErrorFlags(), indicating that a hardware PID error occurred in the pipe. */ + #define PIPE_ERRORFLAG_PID (1 << 2) + + /** Mask for \ref Pipe_GetErrorFlags(), indicating that a hardware data PID error occurred in the pipe. */ + #define PIPE_ERRORFLAG_DATAPID (1 << 1) + + /** Mask for \ref Pipe_GetErrorFlags(), indicating that a hardware data toggle error occurred in the pipe. */ + #define PIPE_ERRORFLAG_DATATGL (1 << 0) + //@} + + /** \name Pipe Token Masks */ + //@{ + /** Token mask for \ref Pipe_SetPipeToken() and \ref Pipe_GetPipeToken(). This sets the pipe as a SETUP token (for CONTROL type pipes), + * which will trigger a control request on the attached device when data is written to the pipe. + */ + #define PIPE_TOKEN_SETUP (0 << PTOKEN0) + + /** Token mask for \ref Pipe_SetPipeToken() and \ref Pipe_GetPipeToken(). This sets the pipe as a IN token (for non-CONTROL type pipes), + * indicating that the pipe data will flow from device to host. + */ + #define PIPE_TOKEN_IN (1 << PTOKEN0) + + /** Token mask for \ref Pipe_SetPipeToken() and \ref Pipe_GetPipeToken(). This sets the pipe as a OUT token (for non-CONTROL type pipes), + * indicating that the pipe data will flow from host to device. + */ + #define PIPE_TOKEN_OUT (2 << PTOKEN0) + //@} + + /** Default size of the default control pipe's bank, until altered by the Endpoint0Size value + * in the device descriptor of the attached device. + */ + #define PIPE_CONTROLPIPE_DEFAULT_SIZE 64 + + /** Total number of pipes (including the default control pipe at address 0) which may be used in + * the device. Different USB AVR models support different amounts of pipes, this value reflects + * the maximum number of pipes for the currently selected AVR model. + */ + #define PIPE_TOTAL_PIPES 7 + + /** Size in bytes of the largest pipe bank size possible in the device. Not all banks on each AVR + * model supports the largest bank size possible on the device; different pipe numbers support + * different maximum bank sizes. This value reflects the largest possible bank of any pipe on the + * currently selected USB AVR model. + */ + #define PIPE_MAX_SIZE 256 + + /* Enums: */ + /** Enum for the possible error return codes of the \ref Pipe_WaitUntilReady() function. + * + * \ingroup Group_PipeRW_AVR8 + */ + enum Pipe_WaitUntilReady_ErrorCodes_t + { + PIPE_READYWAIT_NoError = 0, /**< Pipe ready for next packet, no error. */ + PIPE_READYWAIT_PipeStalled = 1, /**< The device stalled the pipe while waiting. */ + PIPE_READYWAIT_DeviceDisconnected = 2, /**< Device was disconnected from the host while waiting. */ + PIPE_READYWAIT_Timeout = 3, /**< The device failed to accept or send the next packet + * within the software timeout period set by the + * \ref USB_STREAM_TIMEOUT_MS macro. + */ + }; + + /* Inline Functions: */ + /** Indicates the number of bytes currently stored in the current pipes's selected bank. + * + * \ingroup Group_PipeRW_AVR8 + * + * \return Total number of bytes in the currently selected pipe's FIFO buffer. + */ + static inline uint16_t Pipe_BytesInPipe(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint16_t Pipe_BytesInPipe(void) + { + return UPBCX; + } + + /** Determines the currently selected pipe's direction. + * + * \return The currently selected pipe's direction, as a \c PIPE_DIR_* mask. + */ + static inline uint8_t Pipe_GetPipeDirection(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint8_t Pipe_GetPipeDirection(void) + { + return (UPCFG0X & (1 << EPDIR)) ? PIPE_DIR_IN : PIPE_DIR_OUT; + } + + /** Returns the pipe address of the currently selected pipe. This is typically used to save the + * currently selected pipe address so that it can be restored after another pipe has been manipulated. + * + * \return Index of the currently selected pipe. + */ + static inline uint8_t Pipe_GetCurrentPipe(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint8_t Pipe_GetCurrentPipe(void) + { + return ((UPNUM & PIPE_PIPENUM_MASK) | Pipe_GetPipeDirection()); + } + + /** Selects the given pipe address. Any pipe operations which do not require the pipe address to be + * indicated will operate on the currently selected pipe. + * + * \param[in] Address Address of the pipe to select. + */ + static inline void Pipe_SelectPipe(const uint8_t Address) ATTR_ALWAYS_INLINE; + static inline void Pipe_SelectPipe(const uint8_t Address) + { + UPNUM = (Address & PIPE_PIPENUM_MASK); + } + + /** Resets the desired pipe, including the pipe banks and flags. + * + * \param[in] Address Address of the pipe to reset. + */ + static inline void Pipe_ResetPipe(const uint8_t Address) ATTR_ALWAYS_INLINE; + static inline void Pipe_ResetPipe(const uint8_t Address) + { + UPRST = (1 << (Address & PIPE_PIPENUM_MASK)); + UPRST = 0; + } + + /** Enables the currently selected pipe so that data can be sent and received through it to and from + * an attached device. + * + * \pre The currently selected pipe must first be configured properly via \ref Pipe_ConfigurePipe(). + */ + static inline void Pipe_EnablePipe(void) ATTR_ALWAYS_INLINE; + static inline void Pipe_EnablePipe(void) + { + UPCONX |= (1 << PEN); + } + + /** Disables the currently selected pipe so that data cannot be sent and received through it to and + * from an attached device. + */ + static inline void Pipe_DisablePipe(void) ATTR_ALWAYS_INLINE; + static inline void Pipe_DisablePipe(void) + { + UPCONX &= ~(1 << PEN); + } + + /** Determines if the currently selected pipe is enabled, but not necessarily configured. + * + * \return Boolean \c true if the currently selected pipe is enabled, \c false otherwise. + */ + static inline bool Pipe_IsEnabled(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool Pipe_IsEnabled(void) + { + return ((UPCONX & (1 << PEN)) ? true : false); + } + + /** Gets the current pipe token, indicating the pipe's data direction and type. + * + * \return The current pipe token, as a \c PIPE_TOKEN_* mask. + */ + static inline uint8_t Pipe_GetPipeToken(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint8_t Pipe_GetPipeToken(void) + { + return (UPCFG0X & (0x03 << PTOKEN0)); + } + + /** Sets the token for the currently selected pipe to one of the tokens specified by the \c PIPE_TOKEN_* + * masks. This can be used on CONTROL type pipes, to allow for bidirectional transfer of data during + * control requests, or on regular pipes to allow for half-duplex bidirectional data transfer to devices + * which have two endpoints of opposite direction sharing the same endpoint address within the device. + * + * \param[in] Token New pipe token to set the selected pipe to, as a \c PIPE_TOKEN_* mask. + */ + static inline void Pipe_SetPipeToken(const uint8_t Token) ATTR_ALWAYS_INLINE; + static inline void Pipe_SetPipeToken(const uint8_t Token) + { + UPCFG0X = ((UPCFG0X & ~(0x03 << PTOKEN0)) | Token); + } + + /** Configures the currently selected pipe to allow for an unlimited number of IN requests. */ + static inline void Pipe_SetInfiniteINRequests(void) ATTR_ALWAYS_INLINE; + static inline void Pipe_SetInfiniteINRequests(void) + { + UPCONX |= (1 << INMODE); + } + + /** Configures the currently selected pipe to only allow the specified number of IN requests to be + * accepted by the pipe before it is automatically frozen. + * + * \param[in] TotalINRequests Total number of IN requests that the pipe may receive before freezing. + */ + static inline void Pipe_SetFiniteINRequests(const uint8_t TotalINRequests) ATTR_ALWAYS_INLINE; + static inline void Pipe_SetFiniteINRequests(const uint8_t TotalINRequests) + { + UPCONX &= ~(1 << INMODE); + UPINRQX = TotalINRequests; + } + + /** Determines if the currently selected pipe is configured. + * + * \return Boolean \c true if the selected pipe is configured, \c false otherwise. + */ + static inline bool Pipe_IsConfigured(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool Pipe_IsConfigured(void) + { + return ((UPSTAX & (1 << CFGOK)) ? true : false); + } + + /** Retrieves the endpoint address of the endpoint within the attached device that the currently selected + * pipe is bound to. + * + * \return Endpoint address the currently selected pipe is bound to. + */ + static inline uint8_t Pipe_GetBoundEndpointAddress(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint8_t Pipe_GetBoundEndpointAddress(void) + { + uint8_t UPCFG0X_Temp = UPCFG0X; + + return (((UPCFG0X_Temp >> PEPNUM0) & PIPE_EPNUM_MASK) | ((UPCFG0X_Temp & PEPNUM1) ? ENDPOINT_DIR_OUT : ENDPOINT_DIR_IN)); + } + + /** Sets the period between interrupts for an INTERRUPT type pipe to a specified number of milliseconds. + * + * \param[in] Milliseconds Number of milliseconds between each pipe poll. + */ + static inline void Pipe_SetInterruptPeriod(const uint8_t Milliseconds) ATTR_ALWAYS_INLINE; + static inline void Pipe_SetInterruptPeriod(const uint8_t Milliseconds) + { + UPCFG2X = Milliseconds; + } + + /** Returns a mask indicating which pipe's interrupt periods have elapsed, indicating that the pipe should + * be serviced. + * + * \return Mask whose bits indicate which pipes have interrupted. + */ + static inline uint8_t Pipe_GetPipeInterrupts(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint8_t Pipe_GetPipeInterrupts(void) + { + return UPINT; + } + + /** Determines if the specified pipe address has interrupted (valid only for INTERRUPT type + * pipes). + * + * \param[in] Address Address of the pipe whose interrupt flag should be tested. + * + * \return Boolean \c true if the specified pipe has interrupted, \c false otherwise. + */ + static inline bool Pipe_HasPipeInterrupted(const uint8_t Address) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool Pipe_HasPipeInterrupted(const uint8_t Address) + { + return ((UPINT & (1 << (Address & PIPE_PIPENUM_MASK))) ? true : false); + } + + /** Unfreezes the selected pipe, allowing it to communicate with an attached device. */ + static inline void Pipe_Unfreeze(void) ATTR_ALWAYS_INLINE; + static inline void Pipe_Unfreeze(void) + { + UPCONX &= ~(1 << PFREEZE); + } + + /** Freezes the selected pipe, preventing it from communicating with an attached device. */ + static inline void Pipe_Freeze(void) ATTR_ALWAYS_INLINE; + static inline void Pipe_Freeze(void) + { + UPCONX |= (1 << PFREEZE); + } + + /** Determines if the currently selected pipe is frozen, and not able to accept data. + * + * \return Boolean \c true if the currently selected pipe is frozen, \c false otherwise. + */ + static inline bool Pipe_IsFrozen(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool Pipe_IsFrozen(void) + { + return ((UPCONX & (1 << PFREEZE)) ? true : false); + } + + /** Clears the error flags for the currently selected pipe. */ + static inline void Pipe_ClearError(void) ATTR_ALWAYS_INLINE; + static inline void Pipe_ClearError(void) + { + UPERRX = 0; + UPINTX &= ~(1 << PERRI); + } + + /** Determines if the master pipe error flag is set for the currently selected pipe, indicating that + * some sort of hardware error has occurred on the pipe. + * + * \see \ref Pipe_GetErrorFlags() macro for information on retrieving the exact error flag. + * + * \return Boolean \c true if an error has occurred on the selected pipe, \c false otherwise. + */ + static inline bool Pipe_IsError(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool Pipe_IsError(void) + { + return ((UPINTX & (1 << PERRI)) ? true : false); + } + + /** Gets a mask of the hardware error flags which have occurred on the currently selected pipe. This + * value can then be masked against the \c PIPE_ERRORFLAG_* masks to determine what error has occurred. + * + * \return Mask comprising of \c PIPE_ERRORFLAG_* bits indicating what error has occurred on the selected pipe. + */ + static inline uint8_t Pipe_GetErrorFlags(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint8_t Pipe_GetErrorFlags(void) + { + return ((UPERRX & (PIPE_ERRORFLAG_CRC16 | PIPE_ERRORFLAG_TIMEOUT | + PIPE_ERRORFLAG_PID | PIPE_ERRORFLAG_DATAPID | + PIPE_ERRORFLAG_DATATGL)) | + (UPSTAX & (PIPE_ERRORFLAG_OVERFLOW | PIPE_ERRORFLAG_UNDERFLOW))); + } + + /** Retrieves the number of busy banks in the currently selected pipe, which have been queued for + * transmission via the \ref Pipe_ClearOUT() command, or are awaiting acknowledgement via the + * \ref Pipe_ClearIN() command. + * + * \ingroup Group_PipePacketManagement_AVR8 + * + * \return Total number of busy banks in the selected pipe. + */ + static inline uint8_t Pipe_GetBusyBanks(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint8_t Pipe_GetBusyBanks(void) + { + return (UPSTAX & (0x03 << NBUSYBK0)); + } + + /** Determines if the currently selected pipe may be read from (if data is waiting in the pipe + * bank and the pipe is an IN direction, or if the bank is not yet full if the pipe is an OUT + * direction). This function will return false if an error has occurred in the pipe, or if the pipe + * is an IN direction and no packet (or an empty packet) has been received, or if the pipe is an OUT + * direction and the pipe bank is full. + * + * \note This function is not valid on CONTROL type pipes. + * + * \ingroup Group_PipePacketManagement_AVR8 + * + * \return Boolean \c true if the currently selected pipe may be read from or written to, depending + * on its direction. + */ + static inline bool Pipe_IsReadWriteAllowed(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool Pipe_IsReadWriteAllowed(void) + { + return ((UPINTX & (1 << RWAL)) ? true : false); + } + + /** Determines if a packet has been received on the currently selected IN pipe from the attached device. + * + * \ingroup Group_PipePacketManagement_AVR8 + * + * \return Boolean \c true if the current pipe has received an IN packet, \c false otherwise. + */ + static inline bool Pipe_IsINReceived(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool Pipe_IsINReceived(void) + { + return ((UPINTX & (1 << RXINI)) ? true : false); + } + + /** Determines if the currently selected OUT pipe is ready to send an OUT packet to the attached device. + * + * \ingroup Group_PipePacketManagement_AVR8 + * + * \return Boolean \c true if the current pipe is ready for an OUT packet, \c false otherwise. + */ + static inline bool Pipe_IsOUTReady(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool Pipe_IsOUTReady(void) + { + return ((UPINTX & (1 << TXOUTI)) ? true : false); + } + + /** Determines if no SETUP request is currently being sent to the attached device on the selected + * CONTROL type pipe. + * + * \ingroup Group_PipePacketManagement_AVR8 + * + * \return Boolean \c true if the current pipe is ready for a SETUP packet, \c false otherwise. + */ + static inline bool Pipe_IsSETUPSent(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool Pipe_IsSETUPSent(void) + { + return ((UPINTX & (1 << TXSTPI)) ? true : false); + } + + /** Sends the currently selected CONTROL type pipe's contents to the device as a SETUP packet. + * + * \ingroup Group_PipePacketManagement_AVR8 + */ + static inline void Pipe_ClearSETUP(void) ATTR_ALWAYS_INLINE; + static inline void Pipe_ClearSETUP(void) + { + UPINTX &= ~((1 << TXSTPI) | (1 << FIFOCON)); + } + + /** Acknowledges the reception of a setup IN request from the attached device on the currently selected + * pipe, freeing the bank ready for the next packet. + * + * \ingroup Group_PipePacketManagement_AVR8 + */ + static inline void Pipe_ClearIN(void) ATTR_ALWAYS_INLINE; + static inline void Pipe_ClearIN(void) + { + UPINTX &= ~((1 << RXINI) | (1 << FIFOCON)); + } + + /** Sends the currently selected pipe's contents to the device as an OUT packet on the selected pipe, freeing + * the bank ready for the next packet. + * + * \ingroup Group_PipePacketManagement_AVR8 + */ + static inline void Pipe_ClearOUT(void) ATTR_ALWAYS_INLINE; + static inline void Pipe_ClearOUT(void) + { + UPINTX &= ~((1 << TXOUTI) | (1 << FIFOCON)); + } + + /** Determines if the device sent a NAK (Negative Acknowledge) in response to the last sent packet on + * the currently selected pipe. This occurs when the host sends a packet to the device, but the device + * is not currently ready to handle the packet (i.e. its endpoint banks are full). Once a NAK has been + * received, it must be cleared using \ref Pipe_ClearNAKReceived() before the previous (or any other) packet + * can be re-sent. + * + * \ingroup Group_PipePacketManagement_AVR8 + * + * \return Boolean \c true if an NAK has been received on the current pipe, \c false otherwise. + */ + static inline bool Pipe_IsNAKReceived(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool Pipe_IsNAKReceived(void) + { + return ((UPINTX & (1 << NAKEDI)) ? true : false); + } + + /** Clears the NAK condition on the currently selected pipe. + * + * \ingroup Group_PipePacketManagement_AVR8 + * + * \see \ref Pipe_IsNAKReceived() for more details. + */ + static inline void Pipe_ClearNAKReceived(void) ATTR_ALWAYS_INLINE; + static inline void Pipe_ClearNAKReceived(void) + { + UPINTX &= ~(1 << NAKEDI); + } + + /** Determines if the currently selected pipe has had the STALL condition set by the attached device. + * + * \ingroup Group_PipePacketManagement_AVR8 + * + * \return Boolean \c true if the current pipe has been stalled by the attached device, \c false otherwise. + */ + static inline bool Pipe_IsStalled(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool Pipe_IsStalled(void) + { + return ((UPINTX & (1 << RXSTALLI)) ? true : false); + } + + /** Clears the STALL condition detection flag on the currently selected pipe, but does not clear the + * STALL condition itself (this must be done via a ClearFeature control request to the device). + * + * \ingroup Group_PipePacketManagement_AVR8 + */ + static inline void Pipe_ClearStall(void) ATTR_ALWAYS_INLINE; + static inline void Pipe_ClearStall(void) + { + UPINTX &= ~(1 << RXSTALLI); + } + + /** Reads one byte from the currently selected pipe's bank, for OUT direction pipes. + * + * \ingroup Group_PipePrimitiveRW_AVR8 + * + * \return Next byte in the currently selected pipe's FIFO buffer. + */ + static inline uint8_t Pipe_Read_8(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint8_t Pipe_Read_8(void) + { + return UPDATX; + } + + /** Writes one byte to the currently selected pipe's bank, for IN direction pipes. + * + * \ingroup Group_PipePrimitiveRW_AVR8 + * + * \param[in] Data Data to write into the the currently selected pipe's FIFO buffer. + */ + static inline void Pipe_Write_8(const uint8_t Data) ATTR_ALWAYS_INLINE; + static inline void Pipe_Write_8(const uint8_t Data) + { + UPDATX = Data; + } + + /** Discards one byte from the currently selected pipe's bank, for OUT direction pipes. + * + * \ingroup Group_PipePrimitiveRW_AVR8 + */ + static inline void Pipe_Discard_8(void) ATTR_ALWAYS_INLINE; + static inline void Pipe_Discard_8(void) + { + uint8_t Dummy; + + Dummy = UPDATX; + + (void)Dummy; + } + + /** Reads two bytes from the currently selected pipe's bank in little endian format, for OUT + * direction pipes. + * + * \ingroup Group_PipePrimitiveRW_AVR8 + * + * \return Next two bytes in the currently selected pipe's FIFO buffer. + */ + static inline uint16_t Pipe_Read_16_LE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint16_t Pipe_Read_16_LE(void) + { + union + { + uint16_t Value; + uint8_t Bytes[2]; + } Data; + + Data.Bytes[0] = UPDATX; + Data.Bytes[1] = UPDATX; + + return Data.Value; + } + + /** Reads two bytes from the currently selected pipe's bank in big endian format, for OUT + * direction pipes. + * + * \ingroup Group_PipePrimitiveRW_AVR8 + * + * \return Next two bytes in the currently selected pipe's FIFO buffer. + */ + static inline uint16_t Pipe_Read_16_BE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint16_t Pipe_Read_16_BE(void) + { + union + { + uint16_t Value; + uint8_t Bytes[2]; + } Data; + + Data.Bytes[1] = UPDATX; + Data.Bytes[0] = UPDATX; + + return Data.Value; + } + + /** Writes two bytes to the currently selected pipe's bank in little endian format, for IN + * direction pipes. + * + * \ingroup Group_PipePrimitiveRW_AVR8 + * + * \param[in] Data Data to write to the currently selected pipe's FIFO buffer. + */ + static inline void Pipe_Write_16_LE(const uint16_t Data) ATTR_ALWAYS_INLINE; + static inline void Pipe_Write_16_LE(const uint16_t Data) + { + UPDATX = (Data & 0xFF); + UPDATX = (Data >> 8); + } + + /** Writes two bytes to the currently selected pipe's bank in big endian format, for IN + * direction pipes. + * + * \ingroup Group_PipePrimitiveRW_AVR8 + * + * \param[in] Data Data to write to the currently selected pipe's FIFO buffer. + */ + static inline void Pipe_Write_16_BE(const uint16_t Data) ATTR_ALWAYS_INLINE; + static inline void Pipe_Write_16_BE(const uint16_t Data) + { + UPDATX = (Data >> 8); + UPDATX = (Data & 0xFF); + } + + /** Discards two bytes from the currently selected pipe's bank, for OUT direction pipes. + * + * \ingroup Group_PipePrimitiveRW_AVR8 + */ + static inline void Pipe_Discard_16(void) ATTR_ALWAYS_INLINE; + static inline void Pipe_Discard_16(void) + { + uint8_t Dummy; + + Dummy = UPDATX; + Dummy = UPDATX; + + (void)Dummy; + } + + /** Reads four bytes from the currently selected pipe's bank in little endian format, for OUT + * direction pipes. + * + * \ingroup Group_PipePrimitiveRW_AVR8 + * + * \return Next four bytes in the currently selected pipe's FIFO buffer. + */ + static inline uint32_t Pipe_Read_32_LE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint32_t Pipe_Read_32_LE(void) + { + union + { + uint32_t Value; + uint8_t Bytes[4]; + } Data; + + Data.Bytes[0] = UPDATX; + Data.Bytes[1] = UPDATX; + Data.Bytes[2] = UPDATX; + Data.Bytes[3] = UPDATX; + + return Data.Value; + } + + /** Reads four bytes from the currently selected pipe's bank in big endian format, for OUT + * direction pipes. + * + * \ingroup Group_PipePrimitiveRW_AVR8 + * + * \return Next four bytes in the currently selected pipe's FIFO buffer. + */ + static inline uint32_t Pipe_Read_32_BE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint32_t Pipe_Read_32_BE(void) + { + union + { + uint32_t DWord; + uint8_t Bytes[4]; + } Data; + + Data.Bytes[3] = UPDATX; + Data.Bytes[2] = UPDATX; + Data.Bytes[1] = UPDATX; + Data.Bytes[0] = UPDATX; + + return Data.DWord; + } + + /** Writes four bytes to the currently selected pipe's bank in little endian format, for IN + * direction pipes. + * + * \ingroup Group_PipePrimitiveRW_AVR8 + * + * \param[in] Data Data to write to the currently selected pipe's FIFO buffer. + */ + static inline void Pipe_Write_32_LE(const uint32_t Data) ATTR_ALWAYS_INLINE; + static inline void Pipe_Write_32_LE(const uint32_t Data) + { + UPDATX = (Data & 0xFF); + UPDATX = (Data >> 8); + UPDATX = (Data >> 16); + UPDATX = (Data >> 24); + } + + /** Writes four bytes to the currently selected pipe's bank in big endian format, for IN + * direction pipes. + * + * \ingroup Group_PipePrimitiveRW_AVR8 + * + * \param[in] Data Data to write to the currently selected pipe's FIFO buffer. + */ + static inline void Pipe_Write_32_BE(const uint32_t Data) ATTR_ALWAYS_INLINE; + static inline void Pipe_Write_32_BE(const uint32_t Data) + { + UPDATX = (Data >> 24); + UPDATX = (Data >> 16); + UPDATX = (Data >> 8); + UPDATX = (Data & 0xFF); + } + + /** Discards four bytes from the currently selected pipe's bank, for OUT direction pipes. + * + * \ingroup Group_PipePrimitiveRW_AVR8 + */ + static inline void Pipe_Discard_32(void) ATTR_ALWAYS_INLINE; + static inline void Pipe_Discard_32(void) + { + uint8_t Dummy; + + Dummy = UPDATX; + Dummy = UPDATX; + Dummy = UPDATX; + Dummy = UPDATX; + + (void)Dummy; + } + + /* External Variables: */ + /** Global indicating the maximum packet size of the default control pipe located at address + * 0 in the device. This value is set to the value indicated in the attached device's device + * descriptor once the USB interface is initialized into host mode and a device is attached + * to the USB bus. + * + * \attention This variable should be treated as read-only in the user application, and never manually + * changed in value. + */ + extern uint8_t USB_Host_ControlPipeSize; + + /* Function Prototypes: */ + /** Configures a table of pipe descriptions, in sequence. This function can be used to configure multiple + * pipes at the same time. + * + * \note Pipe with a zero address will be ignored, thus this function cannot be used to configure the + * control pipe. + * + * \param[in] Table Pointer to a table of pipe descriptions. + * \param[in] Entries Number of entries in the pipe table to configure. + * + * \return Boolean \c true if all pipes configured successfully, \c false otherwise. + */ + bool Pipe_ConfigurePipeTable(const USB_Pipe_Table_t* const Table, + const uint8_t Entries); + + /** Configures the specified pipe address with the given pipe type, endpoint address within the attached device, bank size + * and number of hardware banks. + * + * A newly configured pipe is frozen by default, and must be unfrozen before use via the \ref Pipe_Unfreeze() + * before being used. Pipes should be kept frozen unless waiting for data from a device while in IN mode, or + * sending data to the device in OUT mode. IN type pipes are also automatically configured to accept infinite + * numbers of IN requests without automatic freezing - this can be overridden by a call to + * \ref Pipe_SetFiniteINRequests(). + * + * \param[in] Address Pipe address to configure. + * + * \param[in] Type Type of pipe to configure, an \c EP_TYPE_* mask. Not all pipe types are available on Low + * Speed USB devices - refer to the USB 2.0 specification. + * + * \param[in] EndpointAddress Endpoint address within the attached device that the pipe should interface to. + * + * \param[in] Size Size of the pipe's bank, where packets are stored before they are transmitted to + * the USB device, or after they have been received from the USB device (depending on + * the pipe's data direction). The bank size must indicate the maximum packet size that + * the pipe can handle. + * + * \param[in] Banks Number of banks to use for the pipe being configured. + * + * \attention When the \c ORDERED_EP_CONFIG compile time option is used, Pipes must be configured in ascending order, + * or bank corruption will occur. + * + * \note Certain microcontroller model's pipes may have different maximum packet sizes based on the pipe's + * index - refer to the chosen microcontroller's datasheet to determine the maximum bank size for each pipe. + * \n\n + * + * \note The default control pipe should not be manually configured by the user application, as it is + * automatically configured by the library internally. + * \n\n + * + * \note This routine will automatically select the specified pipe upon success. Upon failure, the pipe which + * failed to reconfigure correctly will be selected. + * + * \return Boolean \c true if the configuration succeeded, \c false otherwise. + */ + bool Pipe_ConfigurePipe(const uint8_t Address, + const uint8_t Type, + const uint8_t EndpointAddress, + const uint16_t Size, + const uint8_t Banks); + + /** Spin-loops until the currently selected non-control pipe is ready for the next packet of data to be read + * or written to it, aborting in the case of an error condition (such as a timeout or device disconnect). + * + * \ingroup Group_PipeRW_AVR8 + * + * \return A value from the \ref Pipe_WaitUntilReady_ErrorCodes_t enum. + */ + uint8_t Pipe_WaitUntilReady(void); + + /** Determines if a pipe has been bound to the given device endpoint address. If a pipe which is bound to the given + * endpoint is found, it is automatically selected. + * + * \param[in] EndpointAddress Address and direction mask of the endpoint within the attached device to check. + * + * \return Boolean \c true if a pipe bound to the given endpoint address of the specified direction is found, + * \c false otherwise. + */ + bool Pipe_IsEndpointBound(const uint8_t EndpointAddress) ATTR_WARN_UNUSED_RESULT; + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Macros: */ + #if !defined(ENDPOINT_CONTROLEP) + #define ENDPOINT_CONTROLEP 0 + #endif + + /* Inline Functions: */ + static inline uint8_t Pipe_BytesToEPSizeMask(const uint16_t Bytes) ATTR_WARN_UNUSED_RESULT ATTR_CONST ATTR_ALWAYS_INLINE; + static inline uint8_t Pipe_BytesToEPSizeMask(const uint16_t Bytes) + { + uint8_t MaskVal = 0; + uint16_t CheckBytes = 8; + + while ((CheckBytes < Bytes) && (CheckBytes < PIPE_MAX_SIZE)) + { + MaskVal++; + CheckBytes <<= 1; + } + + return (MaskVal << EPSIZE0); + } + + /* Function Prototypes: */ + void Pipe_ClearPipes(void); + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/Template/Template_Endpoint_Control_R.c b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/Template/Template_Endpoint_Control_R.c new file mode 100644 index 00000000..ab69536b --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/Template/Template_Endpoint_Control_R.c @@ -0,0 +1,85 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#if defined(TEMPLATE_FUNC_NAME) + +// cppcheck-suppress unusedFunction +uint8_t TEMPLATE_FUNC_NAME (void* const Buffer, + uint16_t Length) +{ + uint8_t* DataStream = ((uint8_t*)Buffer + TEMPLATE_BUFFER_OFFSET(Length)); + + if (!(Length)) + Endpoint_ClearOUT(); + + while (Length) + { + uint8_t USB_DeviceState_LCL = USB_DeviceState; + + if (USB_DeviceState_LCL == DEVICE_STATE_Unattached) + return ENDPOINT_RWCSTREAM_DeviceDisconnected; + else if (USB_DeviceState_LCL == DEVICE_STATE_Suspended) + return ENDPOINT_RWCSTREAM_BusSuspended; + else if (Endpoint_IsSETUPReceived()) + return ENDPOINT_RWCSTREAM_HostAborted; + + if (Endpoint_IsOUTReceived()) + { + while (Length && Endpoint_BytesInEndpoint()) + { + TEMPLATE_TRANSFER_BYTE(DataStream); + TEMPLATE_BUFFER_MOVE(DataStream, 1); + Length--; + } + + Endpoint_ClearOUT(); + } + } + + while (!(Endpoint_IsINReady())) + { + uint8_t USB_DeviceState_LCL = USB_DeviceState; + + if (USB_DeviceState_LCL == DEVICE_STATE_Unattached) + return ENDPOINT_RWCSTREAM_DeviceDisconnected; + else if (USB_DeviceState_LCL == DEVICE_STATE_Suspended) + return ENDPOINT_RWCSTREAM_BusSuspended; + } + + return ENDPOINT_RWCSTREAM_NoError; +} + +#undef TEMPLATE_BUFFER_OFFSET +#undef TEMPLATE_BUFFER_MOVE +#undef TEMPLATE_FUNC_NAME +#undef TEMPLATE_TRANSFER_BYTE + +#endif + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/Template/Template_Endpoint_Control_W.c b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/Template/Template_Endpoint_Control_W.c new file mode 100644 index 00000000..c2d171db --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/Template/Template_Endpoint_Control_W.c @@ -0,0 +1,94 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#if defined(TEMPLATE_FUNC_NAME) + +// cppcheck-suppress unusedFunction +uint8_t TEMPLATE_FUNC_NAME (const void* const Buffer, + uint16_t Length) +{ + uint8_t* DataStream = ((uint8_t*)Buffer + TEMPLATE_BUFFER_OFFSET(Length)); + bool LastPacketFull = false; + + if (Length > USB_ControlRequest.wLength) + Length = USB_ControlRequest.wLength; + else if (!(Length)) + Endpoint_ClearIN(); + + while (Length || LastPacketFull) + { + uint8_t USB_DeviceState_LCL = USB_DeviceState; + + if (USB_DeviceState_LCL == DEVICE_STATE_Unattached) + return ENDPOINT_RWCSTREAM_DeviceDisconnected; + else if (USB_DeviceState_LCL == DEVICE_STATE_Suspended) + return ENDPOINT_RWCSTREAM_BusSuspended; + else if (Endpoint_IsSETUPReceived()) + return ENDPOINT_RWCSTREAM_HostAborted; + else if (Endpoint_IsOUTReceived()) + break; + + if (Endpoint_IsINReady()) + { + uint16_t BytesInEndpoint = Endpoint_BytesInEndpoint(); + + while (Length && (BytesInEndpoint < USB_Device_ControlEndpointSize)) + { + TEMPLATE_TRANSFER_BYTE(DataStream); + TEMPLATE_BUFFER_MOVE(DataStream, 1); + Length--; + BytesInEndpoint++; + } + + LastPacketFull = (BytesInEndpoint == USB_Device_ControlEndpointSize); + Endpoint_ClearIN(); + } + } + + while (!(Endpoint_IsOUTReceived())) + { + uint8_t USB_DeviceState_LCL = USB_DeviceState; + + if (USB_DeviceState_LCL == DEVICE_STATE_Unattached) + return ENDPOINT_RWCSTREAM_DeviceDisconnected; + else if (USB_DeviceState_LCL == DEVICE_STATE_Suspended) + return ENDPOINT_RWCSTREAM_BusSuspended; + } + + return ENDPOINT_RWCSTREAM_NoError; +} + +#undef TEMPLATE_BUFFER_OFFSET +#undef TEMPLATE_BUFFER_MOVE +#undef TEMPLATE_FUNC_NAME +#undef TEMPLATE_TRANSFER_BYTE + +#endif + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/Template/Template_Endpoint_RW.c b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/Template/Template_Endpoint_RW.c new file mode 100644 index 00000000..02ad9786 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/Template/Template_Endpoint_RW.c @@ -0,0 +1,90 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#if defined(TEMPLATE_FUNC_NAME) + +// cppcheck-suppress unusedFunction +uint8_t TEMPLATE_FUNC_NAME (TEMPLATE_BUFFER_TYPE const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) +{ + uint8_t* DataStream = ((uint8_t*)Buffer + TEMPLATE_BUFFER_OFFSET(Length)); + uint16_t BytesInTransfer = 0; + uint8_t ErrorCode; + + if ((ErrorCode = Endpoint_WaitUntilReady())) + return ErrorCode; + + if (BytesProcessed != NULL) + { + Length -= *BytesProcessed; + TEMPLATE_BUFFER_MOVE(DataStream, *BytesProcessed); + } + + while (Length) + { + if (!(Endpoint_IsReadWriteAllowed())) + { + TEMPLATE_CLEAR_ENDPOINT(); + + #if !defined(INTERRUPT_CONTROL_ENDPOINT) + USB_USBTask(); + #endif + + if (BytesProcessed != NULL) + { + *BytesProcessed += BytesInTransfer; + return ENDPOINT_RWSTREAM_IncompleteTransfer; + } + + if ((ErrorCode = Endpoint_WaitUntilReady())) + return ErrorCode; + } + else + { + TEMPLATE_TRANSFER_BYTE(DataStream); + TEMPLATE_BUFFER_MOVE(DataStream, 1); + Length--; + BytesInTransfer++; + } + } + + return ENDPOINT_RWSTREAM_NoError; +} + +#undef TEMPLATE_FUNC_NAME +#undef TEMPLATE_BUFFER_TYPE +#undef TEMPLATE_TRANSFER_BYTE +#undef TEMPLATE_CLEAR_ENDPOINT +#undef TEMPLATE_BUFFER_OFFSET +#undef TEMPLATE_BUFFER_MOVE + +#endif + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/Template/Template_Pipe_RW.c b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/Template/Template_Pipe_RW.c new file mode 100644 index 00000000..05846bb6 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/Template/Template_Pipe_RW.c @@ -0,0 +1,89 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#if defined(TEMPLATE_FUNC_NAME) + +// cppcheck-suppress unusedFunction +uint8_t TEMPLATE_FUNC_NAME (TEMPLATE_BUFFER_TYPE const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) +{ + uint8_t* DataStream = ((uint8_t*)Buffer + TEMPLATE_BUFFER_OFFSET(Length)); + uint16_t BytesInTransfer = 0; + uint8_t ErrorCode; + + Pipe_SetPipeToken(TEMPLATE_TOKEN); + + if ((ErrorCode = Pipe_WaitUntilReady())) + return ErrorCode; + + if (BytesProcessed != NULL) + { + Length -= *BytesProcessed; + TEMPLATE_BUFFER_MOVE(DataStream, *BytesProcessed); + } + + while (Length) + { + if (!(Pipe_IsReadWriteAllowed())) + { + TEMPLATE_CLEAR_PIPE(); + + if (BytesProcessed != NULL) + { + *BytesProcessed += BytesInTransfer; + return PIPE_RWSTREAM_IncompleteTransfer; + } + + if ((ErrorCode = Pipe_WaitUntilReady())) + return ErrorCode; + } + else + { + TEMPLATE_TRANSFER_BYTE(DataStream); + TEMPLATE_BUFFER_MOVE(DataStream, 1); + Length--; + BytesInTransfer++; + } + } + + return PIPE_RWSTREAM_NoError; +} + +#undef TEMPLATE_FUNC_NAME +#undef TEMPLATE_BUFFER_TYPE +#undef TEMPLATE_TOKEN +#undef TEMPLATE_TRANSFER_BYTE +#undef TEMPLATE_CLEAR_PIPE +#undef TEMPLATE_BUFFER_OFFSET +#undef TEMPLATE_BUFFER_MOVE + +#endif + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/USBController_AVR8.c b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/USBController_AVR8.c new file mode 100644 index 00000000..37b106ab --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/USBController_AVR8.c @@ -0,0 +1,265 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#include "../../../../Common/Common.h" +#if (ARCH == ARCH_AVR8) + +#define __INCLUDE_FROM_USB_DRIVER +#define __INCLUDE_FROM_USB_CONTROLLER_C +#include "../USBController.h" + +#if (!defined(USB_HOST_ONLY) && !defined(USB_DEVICE_ONLY)) +volatile uint8_t USB_CurrentMode = USB_MODE_None; +#endif + +#if !defined(USE_STATIC_OPTIONS) +volatile uint8_t USB_Options; +#endif + +void USB_Init( + #if defined(USB_CAN_BE_BOTH) + const uint8_t Mode + #endif + + #if (defined(USB_CAN_BE_BOTH) && !defined(USE_STATIC_OPTIONS)) + , + #elif (!defined(USB_CAN_BE_BOTH) && defined(USE_STATIC_OPTIONS)) + void + #endif + + #if !defined(USE_STATIC_OPTIONS) + const uint8_t Options + #endif + ) +{ + #if !defined(USE_STATIC_OPTIONS) + USB_Options = Options; + #endif + + if (!(USB_Options & USB_OPT_REG_DISABLED)) + USB_REG_On(); + else + USB_REG_Off(); + + if (!(USB_Options & USB_OPT_MANUAL_PLL)) + { + #if defined(USB_SERIES_4_AVR) + PLLFRQ = (1 << PDIV2); + #endif + } + + #if defined(USB_CAN_BE_BOTH) + if (Mode == USB_MODE_UID) + { + UHWCON |= (1 << UIDE); + USB_INT_Enable(USB_INT_IDTI); + USB_CurrentMode = USB_GetUSBModeFromUID(); + } + else + { + UHWCON &= ~(1 << UIDE); + USB_CurrentMode = Mode; + } + #endif + + USB_IsInitialized = true; + + USB_ResetInterface(); +} + +void USB_Disable(void) +{ + USB_INT_DisableAllInterrupts(); + USB_INT_ClearAllInterrupts(); + + USB_Detach(); + USB_Controller_Disable(); + + if (!(USB_Options & USB_OPT_MANUAL_PLL)) + USB_PLL_Off(); + + USB_REG_Off(); + + #if defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR) + USB_OTGPAD_Off(); + #endif + + #if defined(USB_CAN_BE_BOTH) + USB_CurrentMode = USB_MODE_None; + #endif + + USB_IsInitialized = false; +} + +void USB_ResetInterface(void) +{ + #if defined(USB_CAN_BE_BOTH) + bool UIDModeSelectEnabled = ((UHWCON & (1 << UIDE)) != 0); + #endif + + USB_INT_DisableAllInterrupts(); + USB_INT_ClearAllInterrupts(); + + USB_Controller_Reset(); + + #if defined(USB_CAN_BE_BOTH) + if (UIDModeSelectEnabled) + USB_INT_Enable(USB_INT_IDTI); + #endif + + USB_CLK_Unfreeze(); + + if (USB_CurrentMode == USB_MODE_Device) + { + #if defined(USB_CAN_BE_DEVICE) + #if (defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR)) + UHWCON |= (1 << UIMOD); + #endif + + if (!(USB_Options & USB_OPT_MANUAL_PLL)) + { + #if defined(USB_SERIES_2_AVR) + USB_PLL_On(); + while (!(USB_PLL_IsReady())); + #else + USB_PLL_Off(); + #endif + } + + USB_Init_Device(); + #endif + } + else if (USB_CurrentMode == USB_MODE_Host) + { + #if defined(USB_CAN_BE_HOST) + UHWCON &= ~(1 << UIMOD); + + if (!(USB_Options & USB_OPT_MANUAL_PLL)) + { + #if defined(USB_CAN_BE_HOST) + USB_PLL_On(); + while (!(USB_PLL_IsReady())); + #endif + } + + USB_Init_Host(); + #endif + } + + #if (defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR)) + USB_OTGPAD_On(); + #endif +} + +#if defined(USB_CAN_BE_DEVICE) +static void USB_Init_Device(void) +{ + USB_DeviceState = DEVICE_STATE_Unattached; + USB_Device_ConfigurationNumber = 0; + + #if !defined(NO_DEVICE_REMOTE_WAKEUP) + USB_Device_RemoteWakeupEnabled = false; + #endif + + #if !defined(NO_DEVICE_SELF_POWER) + USB_Device_CurrentlySelfPowered = false; + #endif + + #if !defined(FIXED_CONTROL_ENDPOINT_SIZE) + USB_Descriptor_Device_t* DeviceDescriptorPtr; + + #if defined(ARCH_HAS_MULTI_ADDRESS_SPACE) && \ + !(defined(USE_FLASH_DESCRIPTORS) || defined(USE_EEPROM_DESCRIPTORS) || defined(USE_RAM_DESCRIPTORS)) + uint8_t DescriptorAddressSpace; + + if (CALLBACK_USB_GetDescriptor((DTYPE_Device << 8), 0, (void*)&DeviceDescriptorPtr, &DescriptorAddressSpace) != NO_DESCRIPTOR) + { + if (DescriptorAddressSpace == MEMSPACE_FLASH) + USB_Device_ControlEndpointSize = pgm_read_byte(&DeviceDescriptorPtr->Endpoint0Size); + else if (DescriptorAddressSpace == MEMSPACE_EEPROM) + USB_Device_ControlEndpointSize = eeprom_read_byte(&DeviceDescriptorPtr->Endpoint0Size); + else + USB_Device_ControlEndpointSize = DeviceDescriptorPtr->Endpoint0Size; + } + #else + if (CALLBACK_USB_GetDescriptor((DTYPE_Device << 8), 0, (void*)&DeviceDescriptorPtr) != NO_DESCRIPTOR) + { + #if defined(USE_RAM_DESCRIPTORS) + USB_Device_ControlEndpointSize = DeviceDescriptorPtr->Endpoint0Size; + #elif defined(USE_EEPROM_DESCRIPTORS) + USB_Device_ControlEndpointSize = eeprom_read_byte(&DeviceDescriptorPtr->Endpoint0Size); + #else + USB_Device_ControlEndpointSize = pgm_read_byte(&DeviceDescriptorPtr->Endpoint0Size); + #endif + } + #endif + #endif + + #if (defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR)) + if (USB_Options & USB_DEVICE_OPT_LOWSPEED) + USB_Device_SetLowSpeed(); + else + USB_Device_SetFullSpeed(); + + USB_INT_Enable(USB_INT_VBUSTI); + #endif + + Endpoint_ConfigureEndpoint(ENDPOINT_CONTROLEP, EP_TYPE_CONTROL, + USB_Device_ControlEndpointSize, 1); + + USB_INT_Clear(USB_INT_SUSPI); + USB_INT_Enable(USB_INT_SUSPI); + USB_INT_Enable(USB_INT_EORSTI); + + USB_Attach(); +} +#endif + +#if defined(USB_CAN_BE_HOST) +static void USB_Init_Host(void) +{ + USB_HostState = HOST_STATE_Unattached; + USB_Host_ConfigurationNumber = 0; + USB_Host_ControlPipeSize = PIPE_CONTROLPIPE_DEFAULT_SIZE; + + USB_Host_HostMode_On(); + + USB_Host_VBUS_Auto_Off(); + USB_Host_VBUS_Manual_Enable(); + USB_Host_VBUS_Manual_On(); + + USB_INT_Enable(USB_INT_SRPI); + USB_INT_Enable(USB_INT_BCERRI); + + USB_Attach(); +} +#endif + +#endif diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/USBController_AVR8.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/USBController_AVR8.h new file mode 100644 index 00000000..e479d7a1 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/USBController_AVR8.h @@ -0,0 +1,436 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief USB Controller definitions for the AVR8 microcontrollers. + * \copydetails Group_USBManagement_AVR8 + * + * \note This file should not be included directly. It is automatically included as needed by the USB driver + * dispatch header located in LUFA/Drivers/USB/USB.h. + */ + +/** \ingroup Group_USBManagement + * \defgroup Group_USBManagement_AVR8 USB Interface Management (AVR8) + * \brief USB Controller definitions for the AVR8 microcontrollers. + * + * Functions, macros, variables, enums and types related to the setup and management of the USB interface. + * + * @{ + */ + +#ifndef __USBCONTROLLER_AVR8_H__ +#define __USBCONTROLLER_AVR8_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + #include "../USBMode.h" + #include "../Events.h" + #include "../USBTask.h" + #include "../USBInterrupt.h" + + #if defined(USB_CAN_BE_HOST) || defined(__DOXYGEN__) + #include "../Host.h" + #include "../OTG.h" + #include "../Pipe.h" + #include "../HostStandardReq.h" + #include "../PipeStream.h" + #endif + + #if defined(USB_CAN_BE_DEVICE) || defined(__DOXYGEN__) + #include "../Device.h" + #include "../Endpoint.h" + #include "../DeviceStandardReq.h" + #include "../EndpointStream.h" + #endif + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks and Defines: */ + #if !defined(__INCLUDE_FROM_USB_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB/USB.h instead. + #endif + + #if !defined(F_USB) + #error F_USB is not defined. You must define F_USB to the frequency of the unprescaled USB controller clock in your project makefile. + #endif + + #if (F_USB == 8000000) + #if (defined(__AVR_AT90USB82__) || defined(__AVR_AT90USB162__) || \ + defined(__AVR_ATmega8U2__) || defined(__AVR_ATmega16U2__) || \ + defined(__AVR_ATmega32U2__)) + #define USB_PLL_PSC 0 + #elif (defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__)) + #define USB_PLL_PSC 0 + #elif (defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__) || defined(__AVR_ATmega32U6__)) + #define USB_PLL_PSC ((1 << PLLP1) | (1 << PLLP0)) + #elif (defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1287__)) + #define USB_PLL_PSC ((1 << PLLP1) | (1 << PLLP0)) + #endif + #elif (F_USB == 16000000) + #if (defined(__AVR_AT90USB82__) || defined(__AVR_AT90USB162__) || \ + defined(__AVR_ATmega8U2__) || defined(__AVR_ATmega16U2__) || \ + defined(__AVR_ATmega32U2__)) + #define USB_PLL_PSC (1 << PLLP0) + #elif (defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__)) + #define USB_PLL_PSC (1 << PINDIV) + #elif (defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || defined(__AVR_ATmega32U6__)) + #define USB_PLL_PSC ((1 << PLLP2) | (1 << PLLP1)) + #elif (defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__)) + #define USB_PLL_PSC ((1 << PLLP2) | (1 << PLLP0)) + #endif + #endif + + #if !defined(USB_PLL_PSC) + #error No PLL prescale value available for chosen F_USB value and AVR model. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** \name USB Controller Option Masks */ + //@{ + /** Regulator disable option mask for \ref USB_Init(). This indicates that the internal 3.3V USB data pad + * regulator should be disabled and the AVR's VCC level used for the data pads. + * + * \note See USB AVR data sheet for more information on the internal pad regulator. + */ + #define USB_OPT_REG_DISABLED (1 << 1) + + /** Regulator enable option mask for \ref USB_Init(). This indicates that the internal 3.3V USB data pad + * regulator should be enabled to regulate the data pin voltages from the VBUS level down to a level within + * the range allowable by the USB standard. + * + * \note See USB AVR data sheet for more information on the internal pad regulator. + */ + #define USB_OPT_REG_ENABLED (0 << 1) + + /** Manual PLL control option mask for \ref USB_Init(). This indicates to the library that the user application + * will take full responsibility for controlling the AVR's PLL (used to generate the high frequency clock + * that the USB controller requires) and ensuring that it is locked at the correct frequency for USB operations. + */ + #define USB_OPT_MANUAL_PLL (1 << 2) + + /** Automatic PLL control option mask for \ref USB_Init(). This indicates to the library that the library should + * take full responsibility for controlling the AVR's PLL (used to generate the high frequency clock + * that the USB controller requires) and ensuring that it is locked at the correct frequency for USB operations. + */ + #define USB_OPT_AUTO_PLL (0 << 2) + //@} + + #if !defined(USB_STREAM_TIMEOUT_MS) || defined(__DOXYGEN__) + /** Constant for the maximum software timeout period of the USB data stream transfer functions + * (both control and standard) when in either device or host mode. If the next packet of a stream + * is not received or acknowledged within this time period, the stream function will fail. + * + * This value may be overridden in the user project makefile as the value of the + * \ref USB_STREAM_TIMEOUT_MS token, and passed to the compiler using the -D switch. + */ + #define USB_STREAM_TIMEOUT_MS 100 + #endif + + /* Inline Functions: */ + #if defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR) || defined(__DOXYGEN__) + /** Determines if the VBUS line is currently high (i.e. the USB host is supplying power). + * + * \note This function is not available on some AVR models which do not support hardware VBUS monitoring. + * + * \return Boolean \c true if the VBUS line is currently detecting power from a host, \c false otherwise. + */ + static inline bool USB_VBUS_GetStatus(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool USB_VBUS_GetStatus(void) + { + return ((USBSTA & (1 << VBUS)) ? true : false); + } + #endif + + /** Detaches the device from the USB bus. This has the effect of removing the device from any + * attached host, ceasing USB communications. If no host is present, this prevents any host from + * enumerating the device once attached until \ref USB_Attach() is called. + */ + static inline void USB_Detach(void) ATTR_ALWAYS_INLINE; + static inline void USB_Detach(void) + { + UDCON |= (1 << DETACH); + } + + /** Attaches the device to the USB bus. This announces the device's presence to any attached + * USB host, starting the enumeration process. If no host is present, attaching the device + * will allow for enumeration once a host is connected to the device. + * + * This is inexplicably also required for proper operation while in host mode, to enable the + * attachment of a device to the host. This is despite the bit being located in the device-mode + * register and despite the datasheet making no mention of its requirement in host mode. + */ + static inline void USB_Attach(void) ATTR_ALWAYS_INLINE; + static inline void USB_Attach(void) + { + UDCON &= ~(1 << DETACH); + } + + /* Function Prototypes: */ + /** Main function to initialize and start the USB interface. Once active, the USB interface will + * allow for device connection to a host when in device mode, or for device enumeration while in + * host mode. + * + * As the USB library relies on interrupts for the device and host mode enumeration processes, + * the user must enable global interrupts before or shortly after this function is called. In + * device mode, interrupts must be enabled within 500ms of this function being called to ensure + * that the host does not time out whilst enumerating the device. In host mode, interrupts may be + * enabled at the application's leisure however enumeration will not begin of an attached device + * until after this has occurred. + * + * Calling this function when the USB interface is already initialized will cause a complete USB + * interface reset and re-enumeration. + * + * \param[in] Mode This is a mask indicating what mode the USB interface is to be initialized to, a value + * from the \ref USB_Modes_t enum. + * + * \param[in] Options Mask indicating the options which should be used when initializing the USB + * interface to control the USB interface's behavior. This should be comprised of + * a \c USB_OPT_REG_* mask to control the regulator, a \c USB_OPT_*_PLL mask to control the + * PLL, and a \c USB_DEVICE_OPT_* mask (when the device mode is enabled) to set the device + * mode speed. + * + * \note To reduce the FLASH requirements of the library if only device or host mode is required, + * the mode can be statically set in the project makefile by defining the token \c USB_DEVICE_ONLY + * (for device mode) or \c USB_HOST_ONLY (for host mode), passing the token to the compiler + * via the -D switch. If the mode is statically set, this parameter does not exist in the + * function prototype. + * \n\n + * + * \note To reduce the FLASH requirements of the library if only fixed settings are required, + * the options may be set statically in the same manner as the mode (see the Mode parameter of + * this function). To statically set the USB options, pass in the \c USE_STATIC_OPTIONS token, + * defined to the appropriate options masks. When the options are statically set, this + * parameter does not exist in the function prototype. + * \n\n + * + * \note The mode parameter does not exist on devices where only one mode is possible, such as USB + * AVR models which only implement the USB device mode in hardware. + * + * \see \ref Group_Device for the \c USB_DEVICE_OPT_* masks. + */ + void USB_Init( + #if defined(USB_CAN_BE_BOTH) || defined(__DOXYGEN__) + const uint8_t Mode + #endif + + #if (defined(USB_CAN_BE_BOTH) && !defined(USE_STATIC_OPTIONS)) || defined(__DOXYGEN__) + , + #elif (!defined(USB_CAN_BE_BOTH) && defined(USE_STATIC_OPTIONS)) + void + #endif + + #if !defined(USE_STATIC_OPTIONS) || defined(__DOXYGEN__) + const uint8_t Options + #endif + ); + + /** Shuts down the USB interface. This turns off the USB interface after deallocating all USB FIFO + * memory, endpoints and pipes. When turned off, no USB functionality can be used until the interface + * is restarted with the \ref USB_Init() function. + */ + void USB_Disable(void); + + /** Resets the interface, when already initialized. This will re-enumerate the device if already connected + * to a host, or re-enumerate an already attached device when in host mode. + */ + void USB_ResetInterface(void); + + /* Global Variables: */ + #if (!defined(USB_HOST_ONLY) && !defined(USB_DEVICE_ONLY)) || defined(__DOXYGEN__) + /** Indicates the mode that the USB interface is currently initialized to, a value from the + * \ref USB_Modes_t enum. + * + * \attention This variable should be treated as read-only in the user application, and never manually + * changed in value. + * + * \note When the controller is initialized into UID auto-detection mode, this variable will hold the + * currently selected USB mode (i.e. \ref USB_MODE_Device or \ref USB_MODE_Host). If the controller + * is fixed into a specific mode (either through the \c USB_DEVICE_ONLY or \c USB_HOST_ONLY compile time + * options, or a limitation of the USB controller in the chosen device model) this will evaluate to + * a constant of the appropriate value and will never evaluate to \ref USB_MODE_None even when the + * USB interface is not initialized. + */ + extern volatile uint8_t USB_CurrentMode; + #elif defined(USB_HOST_ONLY) + #define USB_CurrentMode USB_MODE_Host + #elif defined(USB_DEVICE_ONLY) + #define USB_CurrentMode USB_MODE_Device + #endif + + #if !defined(USE_STATIC_OPTIONS) || defined(__DOXYGEN__) + /** Indicates the current USB options that the USB interface was initialized with when \ref USB_Init() + * was called. This value will be one of the \c USB_MODE_* masks defined elsewhere in this module. + * + * \attention This variable should be treated as read-only in the user application, and never manually + * changed in value. + */ + extern volatile uint8_t USB_Options; + #elif defined(USE_STATIC_OPTIONS) + #define USB_Options USE_STATIC_OPTIONS + #endif + + /* Enums: */ + /** Enum for the possible USB controller modes, for initialization via \ref USB_Init() and indication back to the + * user application via \ref USB_CurrentMode. + */ + enum USB_Modes_t + { + USB_MODE_None = 0, /**< Indicates that the controller is currently not initialized in any specific USB mode. */ + USB_MODE_Device = 1, /**< Indicates that the controller is currently initialized in USB Device mode. */ + USB_MODE_Host = 2, /**< Indicates that the controller is currently initialized in USB Host mode. */ + USB_MODE_UID = 3, /**< Indicates that the controller should determine the USB mode from the UID pin of the + * USB connector. + */ + }; + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Function Prototypes: */ + #if defined(__INCLUDE_FROM_USB_CONTROLLER_C) + #if defined(USB_CAN_BE_DEVICE) + static void USB_Init_Device(void); + #endif + + #if defined(USB_CAN_BE_HOST) + static void USB_Init_Host(void); + #endif + #endif + + /* Inline Functions: */ + static inline void USB_PLL_On(void) ATTR_ALWAYS_INLINE; + static inline void USB_PLL_On(void) + { + PLLCSR = USB_PLL_PSC; + PLLCSR = (USB_PLL_PSC | (1 << PLLE)); + } + + static inline void USB_PLL_Off(void) ATTR_ALWAYS_INLINE; + static inline void USB_PLL_Off(void) + { + PLLCSR = 0; + } + + static inline bool USB_PLL_IsReady(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool USB_PLL_IsReady(void) + { + return ((PLLCSR & (1 << PLOCK)) ? true : false); + } + + static inline void USB_REG_On(void) ATTR_ALWAYS_INLINE; + static inline void USB_REG_On(void) + { + #if defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR) + UHWCON |= (1 << UVREGE); + #else + REGCR &= ~(1 << REGDIS); + #endif + } + + static inline void USB_REG_Off(void) ATTR_ALWAYS_INLINE; + static inline void USB_REG_Off(void) + { + #if defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR) + UHWCON &= ~(1 << UVREGE); + #else + REGCR |= (1 << REGDIS); + #endif + } + + #if defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR) + static inline void USB_OTGPAD_On(void) ATTR_ALWAYS_INLINE; + static inline void USB_OTGPAD_On(void) + { + USBCON |= (1 << OTGPADE); + } + + static inline void USB_OTGPAD_Off(void) ATTR_ALWAYS_INLINE; + static inline void USB_OTGPAD_Off(void) + { + USBCON &= ~(1 << OTGPADE); + } + #endif + + static inline void USB_CLK_Freeze(void) ATTR_ALWAYS_INLINE; + static inline void USB_CLK_Freeze(void) + { + USBCON |= (1 << FRZCLK); + } + + static inline void USB_CLK_Unfreeze(void) ATTR_ALWAYS_INLINE; + static inline void USB_CLK_Unfreeze(void) + { + USBCON &= ~(1 << FRZCLK); + } + + static inline void USB_Controller_Enable(void) ATTR_ALWAYS_INLINE; + static inline void USB_Controller_Enable(void) + { + USBCON |= (1 << USBE); + } + + static inline void USB_Controller_Disable(void) ATTR_ALWAYS_INLINE; + static inline void USB_Controller_Disable(void) + { + USBCON &= ~(1 << USBE); + } + + static inline void USB_Controller_Reset(void) ATTR_ALWAYS_INLINE; + static inline void USB_Controller_Reset(void) + { + USBCON &= ~(1 << USBE); + USBCON |= (1 << USBE); + } + + #if defined(USB_CAN_BE_BOTH) + static inline uint8_t USB_GetUSBModeFromUID(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint8_t USB_GetUSBModeFromUID(void) + { + if (USBSTA & (1 << ID)) + return USB_MODE_Device; + else + return USB_MODE_Host; + } + #endif + + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/USBInterrupt_AVR8.c b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/USBInterrupt_AVR8.c new file mode 100644 index 00000000..3bff19f2 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/USBInterrupt_AVR8.c @@ -0,0 +1,279 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#include "../../../../Common/Common.h" +#if (ARCH == ARCH_AVR8) + +#define __INCLUDE_FROM_USB_DRIVER +#include "../USBInterrupt.h" + +void USB_INT_DisableAllInterrupts(void) +{ + #if defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR) + USBCON &= ~((1 << VBUSTE) | (1 << IDTE)); + #elif defined(USB_SERIES_4_AVR) + USBCON &= ~(1 << VBUSTE); + #endif + + #if defined(USB_CAN_BE_BOTH) + OTGIEN = 0; + #endif + + #if defined(USB_CAN_BE_HOST) + UHIEN = 0; + #endif + + #if defined(USB_CAN_BE_DEVICE) + UDIEN = 0; + #endif +} + +void USB_INT_ClearAllInterrupts(void) +{ + #if defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR) + USBINT = 0; + #endif + + #if defined(USB_CAN_BE_BOTH) + OTGINT = 0; + #endif + + #if defined(USB_CAN_BE_HOST) + UHINT = 0; + #endif + + #if defined(USB_CAN_BE_DEVICE) + UDINT = 0; + #endif +} + +ISR(USB_GEN_vect, ISR_BLOCK) +{ + #if defined(USB_CAN_BE_DEVICE) + #if !defined(NO_SOF_EVENTS) + if (USB_INT_HasOccurred(USB_INT_SOFI) && USB_INT_IsEnabled(USB_INT_SOFI)) + { + USB_INT_Clear(USB_INT_SOFI); + + EVENT_USB_Device_StartOfFrame(); + } + #endif + + #if defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR) + if (USB_INT_HasOccurred(USB_INT_VBUSTI) && USB_INT_IsEnabled(USB_INT_VBUSTI)) + { + USB_INT_Clear(USB_INT_VBUSTI); + + if (USB_VBUS_GetStatus()) + { + if (!(USB_Options & USB_OPT_MANUAL_PLL)) + { + USB_PLL_On(); + while (!(USB_PLL_IsReady())); + } + + USB_DeviceState = DEVICE_STATE_Powered; + EVENT_USB_Device_Connect(); + } + else + { + if (!(USB_Options & USB_OPT_MANUAL_PLL)) + USB_PLL_Off(); + + USB_DeviceState = DEVICE_STATE_Unattached; + EVENT_USB_Device_Disconnect(); + } + } + #endif + + if (USB_INT_HasOccurred(USB_INT_SUSPI) && USB_INT_IsEnabled(USB_INT_SUSPI)) + { + USB_INT_Disable(USB_INT_SUSPI); + USB_INT_Enable(USB_INT_WAKEUPI); + + USB_CLK_Freeze(); + + if (!(USB_Options & USB_OPT_MANUAL_PLL)) + USB_PLL_Off(); + + #if defined(USB_SERIES_2_AVR) && !defined(NO_LIMITED_CONTROLLER_CONNECT) + USB_DeviceState = DEVICE_STATE_Unattached; + EVENT_USB_Device_Disconnect(); + #else + USB_DeviceState = DEVICE_STATE_Suspended; + EVENT_USB_Device_Suspend(); + #endif + } + + if (USB_INT_HasOccurred(USB_INT_WAKEUPI) && USB_INT_IsEnabled(USB_INT_WAKEUPI)) + { + if (!(USB_Options & USB_OPT_MANUAL_PLL)) + { + USB_PLL_On(); + while (!(USB_PLL_IsReady())); + } + + USB_CLK_Unfreeze(); + + USB_INT_Clear(USB_INT_WAKEUPI); + + USB_INT_Disable(USB_INT_WAKEUPI); + USB_INT_Enable(USB_INT_SUSPI); + + if (USB_Device_ConfigurationNumber) + USB_DeviceState = DEVICE_STATE_Configured; + else + USB_DeviceState = (USB_Device_IsAddressSet()) ? DEVICE_STATE_Configured : DEVICE_STATE_Powered; + + #if defined(USB_SERIES_2_AVR) && !defined(NO_LIMITED_CONTROLLER_CONNECT) + EVENT_USB_Device_Connect(); + #else + EVENT_USB_Device_WakeUp(); + #endif + } + + if (USB_INT_HasOccurred(USB_INT_EORSTI) && USB_INT_IsEnabled(USB_INT_EORSTI)) + { + USB_INT_Clear(USB_INT_EORSTI); + + USB_DeviceState = DEVICE_STATE_Default; + USB_Device_ConfigurationNumber = 0; + + USB_INT_Clear(USB_INT_SUSPI); + USB_INT_Disable(USB_INT_SUSPI); + USB_INT_Enable(USB_INT_WAKEUPI); + + Endpoint_ConfigureEndpoint(ENDPOINT_CONTROLEP, EP_TYPE_CONTROL, + USB_Device_ControlEndpointSize, 1); + + #if defined(INTERRUPT_CONTROL_ENDPOINT) + USB_INT_Enable(USB_INT_RXSTPI); + #endif + + EVENT_USB_Device_Reset(); + } + #endif + + #if defined(USB_CAN_BE_HOST) + #if !defined(NO_SOF_EVENTS) + if (USB_INT_HasOccurred(USB_INT_HSOFI) && USB_INT_IsEnabled(USB_INT_HSOFI)) + { + USB_INT_Clear(USB_INT_HSOFI); + + EVENT_USB_Host_StartOfFrame(); + } + #endif + + if (USB_INT_HasOccurred(USB_INT_DDISCI) && USB_INT_IsEnabled(USB_INT_DDISCI)) + { + USB_INT_Clear(USB_INT_DDISCI); + USB_INT_Clear(USB_INT_DCONNI); + USB_INT_Disable(USB_INT_DDISCI); + + EVENT_USB_Host_DeviceUnattached(); + + USB_ResetInterface(); + } + + if (USB_INT_HasOccurred(USB_INT_VBERRI) && USB_INT_IsEnabled(USB_INT_VBERRI)) + { + USB_INT_Clear(USB_INT_VBERRI); + + USB_Host_VBUS_Manual_Off(); + USB_Host_VBUS_Auto_Off(); + + EVENT_USB_Host_HostError(HOST_ERROR_VBusVoltageDip); + EVENT_USB_Host_DeviceUnattached(); + + USB_HostState = HOST_STATE_Unattached; + } + + if (USB_INT_HasOccurred(USB_INT_SRPI) && USB_INT_IsEnabled(USB_INT_SRPI)) + { + USB_INT_Clear(USB_INT_SRPI); + USB_INT_Disable(USB_INT_SRPI); + + EVENT_USB_Host_DeviceAttached(); + + USB_INT_Enable(USB_INT_DDISCI); + + USB_HostState = HOST_STATE_Powered; + } + + if (USB_INT_HasOccurred(USB_INT_BCERRI) && USB_INT_IsEnabled(USB_INT_BCERRI)) + { + USB_INT_Clear(USB_INT_BCERRI); + + EVENT_USB_Host_DeviceEnumerationFailed(HOST_ENUMERROR_NoDeviceDetected, 0); + EVENT_USB_Host_DeviceUnattached(); + + USB_ResetInterface(); + } + #endif + + #if defined(USB_CAN_BE_BOTH) + if (USB_INT_HasOccurred(USB_INT_IDTI) && USB_INT_IsEnabled(USB_INT_IDTI)) + { + USB_INT_Clear(USB_INT_IDTI); + + if (USB_DeviceState != DEVICE_STATE_Unattached) + EVENT_USB_Device_Disconnect(); + + if (USB_HostState != HOST_STATE_Unattached) + EVENT_USB_Host_DeviceUnattached(); + + USB_CurrentMode = USB_GetUSBModeFromUID(); + USB_ResetInterface(); + + EVENT_USB_UIDChange(); + } + #endif +} + +#if defined(INTERRUPT_CONTROL_ENDPOINT) && defined(USB_CAN_BE_DEVICE) +ISR(USB_COM_vect, ISR_BLOCK) +{ + uint8_t PrevSelectedEndpoint = Endpoint_GetCurrentEndpoint(); + + Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP); + USB_INT_Disable(USB_INT_RXSTPI); + + GlobalInterruptEnable(); + + USB_Device_ProcessControlRequest(); + + Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP); + USB_INT_Enable(USB_INT_RXSTPI); + Endpoint_SelectEndpoint(PrevSelectedEndpoint); +} +#endif + +#endif + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/USBInterrupt_AVR8.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/USBInterrupt_AVR8.h new file mode 100644 index 00000000..9e9210ec --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/AVR8/USBInterrupt_AVR8.h @@ -0,0 +1,369 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief USB Controller Interrupt definitions for the AVR8 microcontrollers. + * + * This file contains definitions required for the correct handling of low level USB service routine interrupts + * from the USB controller. + * + * \note This file should not be included directly. It is automatically included as needed by the USB driver + * dispatch header located in LUFA/Drivers/USB/USB.h. + */ + +#ifndef __USBINTERRUPT_AVR8_H__ +#define __USBINTERRUPT_AVR8_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_USB_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB/USB.h instead. + #endif + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Enums: */ + enum USB_Interrupts_t + { + #if (defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR) || defined(__DOXYGEN__)) + USB_INT_VBUSTI = 0, + #endif + #if (defined(USB_CAN_BE_BOTH) || defined(__DOXYGEN__)) + USB_INT_IDTI = 1, + #endif + #if (defined(USB_CAN_BE_DEVICE) || defined(__DOXYGEN__)) + USB_INT_WAKEUPI = 2, + USB_INT_SUSPI = 3, + USB_INT_EORSTI = 4, + USB_INT_SOFI = 5, + USB_INT_RXSTPI = 6, + #endif + #if (defined(USB_CAN_BE_HOST) || defined(__DOXYGEN__)) + USB_INT_HSOFI = 7, + USB_INT_DCONNI = 8, + USB_INT_DDISCI = 9, + USB_INT_RSTI = 10, + USB_INT_BCERRI = 11, + USB_INT_VBERRI = 12, + USB_INT_SRPI = 13, + #endif + }; + + /* Inline Functions: */ + static inline void USB_INT_Enable(const uint8_t Interrupt) ATTR_ALWAYS_INLINE; + static inline void USB_INT_Enable(const uint8_t Interrupt) + { + switch (Interrupt) + { + #if (defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR)) + case USB_INT_VBUSTI: + USBCON |= (1 << VBUSTE); + break; + #endif + #if defined(USB_CAN_BE_BOTH) + case USB_INT_IDTI: + USBCON |= (1 << IDTE); + break; + #endif + #if defined(USB_CAN_BE_DEVICE) + case USB_INT_WAKEUPI: + UDIEN |= (1 << WAKEUPE); + break; + case USB_INT_SUSPI: + UDIEN |= (1 << SUSPE); + break; + case USB_INT_EORSTI: + UDIEN |= (1 << EORSTE); + break; + case USB_INT_SOFI: + UDIEN |= (1 << SOFE); + break; + case USB_INT_RXSTPI: + UEIENX |= (1 << RXSTPE); + break; + #endif + #if defined(USB_CAN_BE_HOST) + case USB_INT_HSOFI: + UHIEN |= (1 << HSOFE); + break; + case USB_INT_DCONNI: + UHIEN |= (1 << DCONNE); + break; + case USB_INT_DDISCI: + UHIEN |= (1 << DDISCE); + break; + case USB_INT_RSTI: + UHIEN |= (1 << RSTE); + break; + case USB_INT_BCERRI: + OTGIEN |= (1 << BCERRE); + break; + case USB_INT_VBERRI: + OTGIEN |= (1 << VBERRE); + break; + case USB_INT_SRPI: + OTGIEN |= (1 << SRPE); + break; + #endif + } + } + + static inline void USB_INT_Disable(const uint8_t Interrupt) ATTR_ALWAYS_INLINE; + static inline void USB_INT_Disable(const uint8_t Interrupt) + { + switch (Interrupt) + { + #if (defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR)) + case USB_INT_VBUSTI: + USBCON &= ~(1 << VBUSTE); + break; + #endif + #if defined(USB_CAN_BE_BOTH) + case USB_INT_IDTI: + USBCON &= ~(1 << IDTE); + break; + #endif + #if defined(USB_CAN_BE_DEVICE) + case USB_INT_WAKEUPI: + UDIEN &= ~(1 << WAKEUPE); + break; + case USB_INT_SUSPI: + UDIEN &= ~(1 << SUSPE); + break; + case USB_INT_EORSTI: + UDIEN &= ~(1 << EORSTE); + break; + case USB_INT_SOFI: + UDIEN &= ~(1 << SOFE); + break; + case USB_INT_RXSTPI: + UEIENX &= ~(1 << RXSTPE); + break; + #endif + #if defined(USB_CAN_BE_HOST) + case USB_INT_HSOFI: + UHIEN &= ~(1 << HSOFE); + break; + case USB_INT_DCONNI: + UHIEN &= ~(1 << DCONNE); + break; + case USB_INT_DDISCI: + UHIEN &= ~(1 << DDISCE); + break; + case USB_INT_RSTI: + UHIEN &= ~(1 << RSTE); + break; + case USB_INT_BCERRI: + OTGIEN &= ~(1 << BCERRE); + break; + case USB_INT_VBERRI: + OTGIEN &= ~(1 << VBERRE); + break; + case USB_INT_SRPI: + OTGIEN &= ~(1 << SRPE); + break; + #endif + } + } + + static inline void USB_INT_Clear(const uint8_t Interrupt) ATTR_ALWAYS_INLINE; + static inline void USB_INT_Clear(const uint8_t Interrupt) + { + switch (Interrupt) + { + #if (defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR)) + case USB_INT_VBUSTI: + USBINT &= ~(1 << VBUSTI); + break; + #endif + #if defined(USB_CAN_BE_BOTH) + case USB_INT_IDTI: + USBINT &= ~(1 << IDTI); + break; + #endif + #if defined(USB_CAN_BE_DEVICE) + case USB_INT_WAKEUPI: + UDINT &= ~(1 << WAKEUPI); + break; + case USB_INT_SUSPI: + UDINT &= ~(1 << SUSPI); + break; + case USB_INT_EORSTI: + UDINT &= ~(1 << EORSTI); + break; + case USB_INT_SOFI: + UDINT &= ~(1 << SOFI); + break; + case USB_INT_RXSTPI: + UEINTX &= ~(1 << RXSTPI); + break; + #endif + #if defined(USB_CAN_BE_HOST) + case USB_INT_HSOFI: + UHINT &= ~(1 << HSOFI); + break; + case USB_INT_DCONNI: + UHINT &= ~(1 << DCONNI); + break; + case USB_INT_DDISCI: + UHINT &= ~(1 << DDISCI); + break; + case USB_INT_RSTI: + UHINT &= ~(1 << RSTI); + break; + case USB_INT_BCERRI: + OTGINT &= ~(1 << BCERRI); + break; + case USB_INT_VBERRI: + OTGINT &= ~(1 << VBERRI); + break; + case USB_INT_SRPI: + OTGINT &= ~(1 << SRPI); + break; + #endif + } + } + + static inline bool USB_INT_IsEnabled(const uint8_t Interrupt) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT; + static inline bool USB_INT_IsEnabled(const uint8_t Interrupt) + { + switch (Interrupt) + { + #if (defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR)) + case USB_INT_VBUSTI: + return (USBCON & (1 << VBUSTE)); + #endif + #if defined(USB_CAN_BE_BOTH) + case USB_INT_IDTI: + return (USBCON & (1 << IDTE)); + #endif + #if defined(USB_CAN_BE_DEVICE) + case USB_INT_WAKEUPI: + return (UDIEN & (1 << WAKEUPE)); + case USB_INT_SUSPI: + return (UDIEN & (1 << SUSPE)); + case USB_INT_EORSTI: + return (UDIEN & (1 << EORSTE)); + case USB_INT_SOFI: + return (UDIEN & (1 << SOFE)); + case USB_INT_RXSTPI: + return (UEIENX & (1 << RXSTPE)); + #endif + #if defined(USB_CAN_BE_HOST) + case USB_INT_HSOFI: + return (UHIEN & (1 << HSOFE)); + case USB_INT_DCONNI: + return (UHIEN & (1 << DCONNE)); + case USB_INT_DDISCI: + return (UHIEN & (1 << DDISCE)); + case USB_INT_RSTI: + return (UHIEN & (1 << RSTE)); + case USB_INT_BCERRI: + return (OTGIEN & (1 << BCERRE)); + case USB_INT_VBERRI: + return (OTGIEN & (1 << VBERRE)); + case USB_INT_SRPI: + return (OTGIEN & (1 << SRPE)); + #endif + } + + return false; + } + + static inline bool USB_INT_HasOccurred(const uint8_t Interrupt) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT; + static inline bool USB_INT_HasOccurred(const uint8_t Interrupt) + { + switch (Interrupt) + { + #if (defined(USB_SERIES_4_AVR) || defined(USB_SERIES_6_AVR) || defined(USB_SERIES_7_AVR)) + case USB_INT_VBUSTI: + return (USBINT & (1 << VBUSTI)); + #endif + #if defined(USB_CAN_BE_BOTH) + case USB_INT_IDTI: + return (USBINT & (1 << IDTI)); + #endif + #if defined(USB_CAN_BE_DEVICE) + case USB_INT_WAKEUPI: + return (UDINT & (1 << WAKEUPI)); + case USB_INT_SUSPI: + return (UDINT & (1 << SUSPI)); + case USB_INT_EORSTI: + return (UDINT & (1 << EORSTI)); + case USB_INT_SOFI: + return (UDINT & (1 << SOFI)); + case USB_INT_RXSTPI: + return (UEINTX & (1 << RXSTPI)); + #endif + #if defined(USB_CAN_BE_HOST) + case USB_INT_HSOFI: + return (UHINT & (1 << HSOFI)); + case USB_INT_DCONNI: + return (UHINT & (1 << DCONNI)); + case USB_INT_DDISCI: + return (UHINT & (1 << DDISCI)); + case USB_INT_RSTI: + return (UHINT & (1 << RSTI)); + case USB_INT_BCERRI: + return (OTGINT & (1 << BCERRI)); + case USB_INT_VBERRI: + return (OTGINT & (1 << VBERRI)); + case USB_INT_SRPI: + return (OTGINT & (1 << SRPI)); + #endif + } + + return false; + } + + /* Includes: */ + #include "../USBMode.h" + #include "../Events.h" + #include "../USBController.h" + + /* Function Prototypes: */ + void USB_INT_ClearAllInterrupts(void); + void USB_INT_DisableAllInterrupts(void); + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/ConfigDescriptors.c b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/ConfigDescriptors.c new file mode 100644 index 00000000..71cced87 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/ConfigDescriptors.c @@ -0,0 +1,146 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#define __INCLUDE_FROM_USB_DRIVER +#include "ConfigDescriptors.h" + +#if defined(USB_CAN_BE_HOST) +uint8_t USB_Host_GetDeviceConfigDescriptor(const uint8_t ConfigNumber, + uint16_t* const ConfigSizePtr, + void* const BufferPtr, + const uint16_t BufferSize) +{ + uint8_t ErrorCode; + uint8_t ConfigHeader[sizeof(USB_Descriptor_Configuration_Header_t)]; + + USB_ControlRequest = (USB_Request_Header_t) + { + .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE), + .bRequest = REQ_GetDescriptor, + .wValue = ((DTYPE_Configuration << 8) | (ConfigNumber - 1)), + .wIndex = 0, + .wLength = sizeof(USB_Descriptor_Configuration_Header_t), + }; + + Pipe_SelectPipe(PIPE_CONTROLPIPE); + + if ((ErrorCode = USB_Host_SendControlRequest(ConfigHeader)) != HOST_SENDCONTROL_Successful) + return ErrorCode; + + *ConfigSizePtr = le16_to_cpu(DESCRIPTOR_PCAST(ConfigHeader, USB_Descriptor_Configuration_Header_t)->TotalConfigurationSize); + + if (*ConfigSizePtr > BufferSize) + return HOST_GETCONFIG_BuffOverflow; + + USB_ControlRequest.wLength = *ConfigSizePtr; + + if ((ErrorCode = USB_Host_SendControlRequest(BufferPtr)) != HOST_SENDCONTROL_Successful) + return ErrorCode; + + if (DESCRIPTOR_TYPE(BufferPtr) != DTYPE_Configuration) + return HOST_GETCONFIG_InvalidData; + + return HOST_GETCONFIG_Successful; +} +#endif + +void USB_GetNextDescriptorOfType(uint16_t* const BytesRem, + void** const CurrConfigLoc, + const uint8_t Type) +{ + while (*BytesRem) + { + USB_GetNextDescriptor(BytesRem, CurrConfigLoc); + + if (DESCRIPTOR_TYPE(*CurrConfigLoc) == Type) + return; + } +} + +void USB_GetNextDescriptorOfTypeBefore(uint16_t* const BytesRem, + void** const CurrConfigLoc, + const uint8_t Type, + const uint8_t BeforeType) +{ + while (*BytesRem) + { + USB_GetNextDescriptor(BytesRem, CurrConfigLoc); + + if (DESCRIPTOR_TYPE(*CurrConfigLoc) == Type) + { + return; + } + else if (DESCRIPTOR_TYPE(*CurrConfigLoc) == BeforeType) + { + *BytesRem = 0; + return; + } + } +} + +void USB_GetNextDescriptorOfTypeAfter(uint16_t* const BytesRem, + void** const CurrConfigLoc, + const uint8_t Type, + const uint8_t AfterType) +{ + USB_GetNextDescriptorOfType(BytesRem, CurrConfigLoc, AfterType); + + if (*BytesRem) + USB_GetNextDescriptorOfType(BytesRem, CurrConfigLoc, Type); +} + +uint8_t USB_GetNextDescriptorComp(uint16_t* const BytesRem, + void** const CurrConfigLoc, + ConfigComparatorPtr_t const ComparatorRoutine) +{ + uint8_t ErrorCode; + + while (*BytesRem) + { + uint8_t* PrevDescLoc = *CurrConfigLoc; + uint16_t PrevBytesRem = *BytesRem; + + USB_GetNextDescriptor(BytesRem, CurrConfigLoc); + + if ((ErrorCode = ComparatorRoutine(*CurrConfigLoc)) != DESCRIPTOR_SEARCH_NotFound) + { + if (ErrorCode == DESCRIPTOR_SEARCH_Fail) + { + *CurrConfigLoc = PrevDescLoc; + *BytesRem = PrevBytesRem; + } + + return ErrorCode; + } + } + + return DESCRIPTOR_SEARCH_COMP_EndOfDescriptor; +} + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/ConfigDescriptors.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/ConfigDescriptors.h new file mode 100644 index 00000000..0de59823 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/ConfigDescriptors.h @@ -0,0 +1,286 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief USB Configuration Descriptor definitions. + * \copydetails Group_ConfigDescriptorParser + * + * \note This file should not be included directly. It is automatically included as needed by the USB driver + * dispatch header located in LUFA/Drivers/USB/USB.h. + */ + +/** \ingroup Group_StdDescriptors + * \defgroup Group_ConfigDescriptorParser Configuration Descriptor Parser + * \brief USB Configuration Descriptor definitions. + * + * This section of the library gives a friendly API which can be used in host applications to easily + * parse an attached device's configuration descriptor so that endpoint, interface and other descriptor + * data can be extracted and used as needed. + * + * @{ + */ + +#ifndef __CONFIGDESCRIPTOR_H__ +#define __CONFIGDESCRIPTOR_H__ + + /* Includes: */ + #include "../../../Common/Common.h" + #include "USBMode.h" + #include "HostStandardReq.h" + #include "StdDescriptors.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_USB_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB/USB.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Casts a pointer to a descriptor inside the configuration descriptor into a pointer to the given + * descriptor type. + * + * Usage Example: + * \code + * uint8_t* CurrDescriptor = &ConfigDescriptor[0]; // Pointing to the configuration header + * USB_Descriptor_Configuration_Header_t* ConfigHeaderPtr = DESCRIPTOR_PCAST(CurrDescriptor, + * USB_Descriptor_Configuration_Header_t); + * + * // Can now access elements of the configuration header struct using the -> indirection operator + * \endcode + */ + #define DESCRIPTOR_PCAST(DescriptorPtr, Type) ((Type*)(DescriptorPtr)) + + /** Casts a pointer to a descriptor inside the configuration descriptor into the given descriptor + * type (as an actual struct instance rather than a pointer to a struct). + * + * Usage Example: + * \code + * uint8_t* CurrDescriptor = &ConfigDescriptor[0]; // Pointing to the configuration header + * USB_Descriptor_Configuration_Header_t ConfigHeader = DESCRIPTOR_CAST(CurrDescriptor, + * USB_Descriptor_Configuration_Header_t); + * + * // Can now access elements of the configuration header struct using the . operator + * \endcode + */ + #define DESCRIPTOR_CAST(DescriptorPtr, Type) (*DESCRIPTOR_PCAST(DescriptorPtr, Type)) + + /** Returns the descriptor's type, expressed as the 8-bit type value in the header of the descriptor. + * This value's meaning depends on the descriptor's placement in the descriptor, but standard type + * values can be accessed in the \ref USB_DescriptorTypes_t enum. + */ + #define DESCRIPTOR_TYPE(DescriptorPtr) DESCRIPTOR_PCAST(DescriptorPtr, USB_Descriptor_Header_t)->Type + + /** Returns the descriptor's size, expressed as the 8-bit value indicating the number of bytes. */ + #define DESCRIPTOR_SIZE(DescriptorPtr) DESCRIPTOR_PCAST(DescriptorPtr, USB_Descriptor_Header_t)->Size + + /* Type Defines: */ + /** Type define for a Configuration Descriptor comparator function (function taking a pointer to an array + * of type void, returning a uint8_t value). + * + * \see \ref USB_GetNextDescriptorComp function for more details. + */ + typedef uint8_t (* ConfigComparatorPtr_t)(void*); + + /* Enums: */ + /** Enum for the possible return codes of the \ref USB_Host_GetDeviceConfigDescriptor() function. */ + enum USB_Host_GetConfigDescriptor_ErrorCodes_t + { + HOST_GETCONFIG_Successful = 0, /**< No error occurred while retrieving the configuration descriptor. */ + HOST_GETCONFIG_DeviceDisconnect = 1, /**< The attached device was disconnected while retrieving the configuration + * descriptor. + */ + HOST_GETCONFIG_PipeError = 2, /**< An error occurred in the pipe while sending the request. */ + HOST_GETCONFIG_SetupStalled = 3, /**< The attached device stalled the request to retrieve the configuration + * descriptor. + */ + HOST_GETCONFIG_SoftwareTimeOut = 4, /**< The request or data transfer timed out. */ + HOST_GETCONFIG_BuffOverflow = 5, /**< The device's configuration descriptor is too large to fit into the allocated + * buffer. + */ + HOST_GETCONFIG_InvalidData = 6, /**< The device returned invalid configuration descriptor data. */ + }; + + /** Enum for return values of a descriptor comparator function. */ + enum DSearch_Return_ErrorCodes_t + { + DESCRIPTOR_SEARCH_Found = 0, /**< Current descriptor matches comparator criteria. */ + DESCRIPTOR_SEARCH_Fail = 1, /**< No further descriptor could possibly match criteria, fail the search. */ + DESCRIPTOR_SEARCH_NotFound = 2, /**< Current descriptor does not match comparator criteria. */ + }; + + /** Enum for return values of \ref USB_GetNextDescriptorComp(). */ + enum DSearch_Comp_Return_ErrorCodes_t + { + DESCRIPTOR_SEARCH_COMP_Found = 0, /**< Configuration descriptor now points to descriptor which matches + * search criteria of the given comparator function. */ + DESCRIPTOR_SEARCH_COMP_Fail = 1, /**< Comparator function returned \ref DESCRIPTOR_SEARCH_Fail. */ + DESCRIPTOR_SEARCH_COMP_EndOfDescriptor = 2, /**< End of configuration descriptor reached before match found. */ + }; + + /* Function Prototypes: */ + /** Retrieves the configuration descriptor data from an attached device via a standard request into a buffer, + * including validity and size checking to prevent a buffer overflow. + * + * \param[in] ConfigNumber Device configuration descriptor number to fetch from the device (usually set to 1 for + * single configuration devices). + * \param[in,out] ConfigSizePtr Pointer to a location for storing the retrieved configuration descriptor size. + * \param[out] BufferPtr Pointer to the buffer for storing the configuration descriptor data. + * \param[out] BufferSize Size of the allocated buffer where the configuration descriptor is to be stored. + * + * \return A value from the \ref USB_Host_GetConfigDescriptor_ErrorCodes_t enum. + */ + uint8_t USB_Host_GetDeviceConfigDescriptor(const uint8_t ConfigNumber, + uint16_t* const ConfigSizePtr, + void* const BufferPtr, + const uint16_t BufferSize) ATTR_NON_NULL_PTR_ARG(2) ATTR_NON_NULL_PTR_ARG(3); + + /** Skips to the next sub-descriptor inside the configuration descriptor of the specified type value. + * The bytes remaining value is automatically decremented. + * + * \param[in,out] BytesRem Pointer to the number of bytes remaining of the configuration descriptor. + * \param[in,out] CurrConfigLoc Pointer to the current descriptor inside the configuration descriptor. + * \param[in] Type Descriptor type value to search for. + */ + void USB_GetNextDescriptorOfType(uint16_t* const BytesRem, + void** const CurrConfigLoc, + const uint8_t Type) + ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); + + /** Skips to the next sub-descriptor inside the configuration descriptor of the specified type value, + * which must come before a descriptor of the second given type value. If the BeforeType type + * descriptor is reached first, the number of bytes remaining to process is set to zero and the + * function exits. The bytes remaining value is automatically decremented. + * + * \param[in,out] BytesRem Pointer to the number of bytes remaining of the configuration descriptor. + * \param[in,out] CurrConfigLoc Pointer to the current descriptor inside the configuration descriptor. + * \param[in] Type Descriptor type value to search for. + * \param[in] BeforeType Descriptor type value which must not be reached before the given Type descriptor. + */ + void USB_GetNextDescriptorOfTypeBefore(uint16_t* const BytesRem, + void** const CurrConfigLoc, + const uint8_t Type, + const uint8_t BeforeType) + ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); + + /** Skips to the next sub-descriptor inside the configuration descriptor of the specified type value, + * which must come after a descriptor of the second given type value. The bytes remaining value is + * automatically decremented. + * + * \param[in,out] BytesRem Pointer to the number of bytes remaining of the configuration descriptor. + * \param[in,out] CurrConfigLoc Pointer to the current descriptor inside the configuration descriptor. + * \param[in] Type Descriptor type value to search for. + * \param[in] AfterType Descriptor type value which must be reached before the given Type descriptor. + */ + void USB_GetNextDescriptorOfTypeAfter(uint16_t* const BytesRem, + void** const CurrConfigLoc, + const uint8_t Type, + const uint8_t AfterType) + ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); + + /** Searches for the next descriptor in the given configuration descriptor using a pre-made comparator + * function. The routine updates the position and remaining configuration descriptor bytes values + * automatically. If a comparator routine fails a search, the descriptor pointer is retreated back + * so that the next descriptor search invocation will start from the descriptor which first caused the + * original search to fail. This behavior allows for one comparator to be used immediately after another + * has failed, starting the second search from the descriptor which failed the first. + * + * Comparator functions should be standard functions which accept a pointer to the header of the current + * descriptor inside the configuration descriptor which is being compared, and should return a value from + * the \ref DSearch_Return_ErrorCodes_t enum as a uint8_t value. + * + * \note This function is available in USB Host mode only. + * + * \param[in,out] BytesRem Pointer to an int storing the remaining bytes in the configuration descriptor. + * \param[in,out] CurrConfigLoc Pointer to the current position in the configuration descriptor. + * \param[in] ComparatorRoutine Name of the comparator search function to use on the configuration descriptor. + * + * \return Value of one of the members of the \ref DSearch_Comp_Return_ErrorCodes_t enum. + * + * Usage Example: + * \code + * uint8_t EndpointSearcher(void* CurrentDescriptor); // Comparator Prototype + * + * uint8_t EndpointSearcher(void* CurrentDescriptor) + * { + * if (DESCRIPTOR_TYPE(CurrentDescriptor) == DTYPE_Endpoint) + * return DESCRIPTOR_SEARCH_Found; + * else + * return DESCRIPTOR_SEARCH_NotFound; + * } + * + * //... + * + * // After retrieving configuration descriptor: + * if (USB_Host_GetNextDescriptorComp(&BytesRemaining, &CurrentConfigLoc, EndpointSearcher) == + * Descriptor_Search_Comp_Found) + * { + * // Do something with the endpoint descriptor + * } + * \endcode + */ + uint8_t USB_GetNextDescriptorComp(uint16_t* const BytesRem, + void** const CurrConfigLoc, + ConfigComparatorPtr_t const ComparatorRoutine); + + /* Inline Functions: */ + /** Skips over the current sub-descriptor inside the configuration descriptor, so that the pointer then + points to the next sub-descriptor. The bytes remaining value is automatically decremented. + * + * \param[in,out] BytesRem Pointer to the number of bytes remaining of the configuration descriptor. + * \param[in,out] CurrConfigLoc Pointer to the current descriptor inside the configuration descriptor. + */ + static inline void USB_GetNextDescriptor(uint16_t* const BytesRem, + void** CurrConfigLoc) ATTR_NON_NULL_PTR_ARG(1) ATTR_NON_NULL_PTR_ARG(2); + static inline void USB_GetNextDescriptor(uint16_t* const BytesRem, + void** CurrConfigLoc) + { + uint16_t CurrDescriptorSize = DESCRIPTOR_CAST(*CurrConfigLoc, USB_Descriptor_Header_t).Size; + + if (*BytesRem < CurrDescriptorSize) + CurrDescriptorSize = *BytesRem; + + *CurrConfigLoc = (void*)((uintptr_t)*CurrConfigLoc + CurrDescriptorSize); + *BytesRem -= CurrDescriptorSize; + } + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/Device.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/Device.h new file mode 100644 index 00000000..995b9208 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/Device.h @@ -0,0 +1,159 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Common USB Device definitions for all architectures. + * \copydetails Group_Device + * + * \note This file should not be included directly. It is automatically included as needed by the USB driver + * dispatch header located in LUFA/Drivers/USB/USB.h. + */ + +/** \ingroup Group_USB + * \defgroup Group_Device Device Management + * \brief USB Device management definitions for USB device mode. + * + * USB Device mode related definitions common to all architectures. This module contains definitions which + * are used when the USB controller is initialized in device mode. + * + * @{ + */ + +#ifndef __USBDEVICE_H__ +#define __USBDEVICE_H__ + + /* Includes: */ + #include "../../../Common/Common.h" + #include "USBMode.h" + #include "StdDescriptors.h" + #include "USBInterrupt.h" + #include "Endpoint.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_USB_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB/USB.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Enums: */ + /** Enum for the various states of the USB Device state machine. Only some states are + * implemented in the LUFA library - other states are left to the user to implement. + * + * For information on each possible USB device state, refer to the USB 2.0 specification. + * + * \see \ref USB_DeviceState, which stores the current device state machine state. + */ + enum USB_Device_States_t + { + DEVICE_STATE_Unattached = 0, /**< Internally implemented by the library. This state indicates + * that the device is not currently connected to a host. + */ + DEVICE_STATE_Powered = 1, /**< Internally implemented by the library. This state indicates + * that the device is connected to a host, but enumeration has not + * yet begun. + */ + DEVICE_STATE_Default = 2, /**< Internally implemented by the library. This state indicates + * that the device's USB bus has been reset by the host and it is + * now waiting for the host to begin the enumeration process. + */ + DEVICE_STATE_Addressed = 3, /**< Internally implemented by the library. This state indicates + * that the device has been addressed by the USB Host, but is not + * yet configured. + */ + DEVICE_STATE_Configured = 4, /**< May be implemented by the user project. This state indicates + * that the device has been enumerated by the host and is ready + * for USB communications to begin. + */ + DEVICE_STATE_Suspended = 5, /**< May be implemented by the user project. This state indicates + * that the USB bus has been suspended by the host, and the device + * should power down to a minimal power level until the bus is + * resumed. + */ + }; + + /* Function Prototypes: */ + /** Function to retrieve a given descriptor's size and memory location from the given descriptor type value, + * index and language ID. This function MUST be overridden in the user application (added with full, identical + * prototype and name so that the library can call it to retrieve descriptor data. + * + * \param[in] wValue The type of the descriptor to retrieve in the upper byte, and the index in the + * lower byte (when more than one descriptor of the given type exists, such as the + * case of string descriptors). The type may be one of the standard types defined + * in the DescriptorTypes_t enum, or may be a class-specific descriptor type value. + * \param[in] wIndex The language ID of the string to return if the \c wValue type indicates + * \ref DTYPE_String, otherwise zero for standard descriptors, or as defined in a + * class-specific standards. + * \param[out] DescriptorAddress Pointer to the descriptor in memory. This should be set by the routine to + * the address of the descriptor. + * \param[out] DescriptorMemorySpace A value from the \ref USB_DescriptorMemorySpaces_t enum to indicate the memory + * space in which the descriptor is stored. This parameter does not exist when one + * of the \c USE_*_DESCRIPTORS compile time options is used, or on architectures which + * use a unified address space. + * + * \note By default, the library expects all descriptors to be located in flash memory via the \c PROGMEM attribute. + * If descriptors should be located in RAM or EEPROM instead (to speed up access in the case of RAM, or to + * allow the descriptors to be changed dynamically at runtime) either the \c USE_RAM_DESCRIPTORS or the + * \c USE_EEPROM_DESCRIPTORS tokens may be defined in the project makefile and passed to the compiler by the -D + * switch. + * + * \return Size in bytes of the descriptor if it exists, zero or \ref NO_DESCRIPTOR otherwise. + */ + uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue, + const uint8_t wIndex, + const void** const DescriptorAddress + #if (defined(ARCH_HAS_MULTI_ADDRESS_SPACE) || defined(__DOXYGEN__)) && \ + !(defined(USE_FLASH_DESCRIPTORS) || defined(USE_EEPROM_DESCRIPTORS) || defined(USE_RAM_DESCRIPTORS)) + , uint8_t* const DescriptorMemorySpace + #endif + ) ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3); + + /* Architecture Includes: */ + #if (ARCH == ARCH_AVR8) + #include "AVR8/Device_AVR8.h" + #elif (ARCH == ARCH_UC3) + #include "UC3/Device_UC3.h" + #elif (ARCH == ARCH_XMEGA) + #include "XMEGA/Device_XMEGA.h" + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/DeviceStandardReq.c b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/DeviceStandardReq.c new file mode 100644 index 00000000..c4ae6471 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/DeviceStandardReq.c @@ -0,0 +1,378 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#define __INCLUDE_FROM_USB_DRIVER +#include "USBMode.h" + +#if defined(USB_CAN_BE_DEVICE) + +#define __INCLUDE_FROM_DEVICESTDREQ_C +#include "DeviceStandardReq.h" + +uint8_t USB_Device_ConfigurationNumber; + +#if !defined(NO_DEVICE_SELF_POWER) +bool USB_Device_CurrentlySelfPowered; +#endif + +#if !defined(NO_DEVICE_REMOTE_WAKEUP) +bool USB_Device_RemoteWakeupEnabled; +#endif + +void USB_Device_ProcessControlRequest(void) +{ + #if defined(ARCH_BIG_ENDIAN) + USB_ControlRequest.bmRequestType = Endpoint_Read_8(); + USB_ControlRequest.bRequest = Endpoint_Read_8(); + USB_ControlRequest.wValue = Endpoint_Read_16_LE(); + USB_ControlRequest.wIndex = Endpoint_Read_16_LE(); + USB_ControlRequest.wLength = Endpoint_Read_16_LE(); + #else + uint8_t* RequestHeader = (uint8_t*)&USB_ControlRequest; + + for (uint8_t RequestHeaderByte = 0; RequestHeaderByte < sizeof(USB_Request_Header_t); RequestHeaderByte++) + *(RequestHeader++) = Endpoint_Read_8(); + #endif + + EVENT_USB_Device_ControlRequest(); + + if (Endpoint_IsSETUPReceived()) + { + uint8_t bmRequestType = USB_ControlRequest.bmRequestType; + + switch (USB_ControlRequest.bRequest) + { + case REQ_GetStatus: + if ((bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE)) || + (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_ENDPOINT))) + { + USB_Device_GetStatus(); + } + + break; + case REQ_ClearFeature: + case REQ_SetFeature: + if ((bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE)) || + (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_ENDPOINT))) + { + USB_Device_ClearSetFeature(); + } + + break; + case REQ_SetAddress: + if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE)) + USB_Device_SetAddress(); + + break; + case REQ_GetDescriptor: + if ((bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE)) || + (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_INTERFACE))) + { + USB_Device_GetDescriptor(); + } + + break; + case REQ_GetConfiguration: + if (bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE)) + USB_Device_GetConfiguration(); + + break; + case REQ_SetConfiguration: + if (bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE)) + USB_Device_SetConfiguration(); + + break; + } + } + + if (Endpoint_IsSETUPReceived()) + { + Endpoint_StallTransaction(); + Endpoint_ClearSETUP(); + } +} + +static void USB_Device_SetAddress(void) +{ + uint8_t DeviceAddress = (USB_ControlRequest.wValue & 0x7F); + uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask(); + GlobalInterruptDisable(); + + Endpoint_ClearSETUP(); + + Endpoint_ClearStatusStage(); + + while (!(Endpoint_IsINReady())); + + USB_Device_SetDeviceAddress(DeviceAddress); + USB_DeviceState = (DeviceAddress) ? DEVICE_STATE_Addressed : DEVICE_STATE_Default; + + SetGlobalInterruptMask(CurrentGlobalInt); +} + +static void USB_Device_SetConfiguration(void) +{ + #if defined(FIXED_NUM_CONFIGURATIONS) + if ((uint8_t)USB_ControlRequest.wValue > FIXED_NUM_CONFIGURATIONS) + return; + #else + USB_Descriptor_Device_t* DevDescriptorPtr; + + #if defined(ARCH_HAS_MULTI_ADDRESS_SPACE) + #if defined(USE_FLASH_DESCRIPTORS) + #define MemoryAddressSpace MEMSPACE_FLASH + #elif defined(USE_EEPROM_DESCRIPTORS) + #define MemoryAddressSpace MEMSPACE_EEPROM + #elif defined(USE_SRAM_DESCRIPTORS) + #define MemoryAddressSpace MEMSPACE_SRAM + #else + uint8_t MemoryAddressSpace; + #endif + #endif + + if (CALLBACK_USB_GetDescriptor((DTYPE_Device << 8), 0, (void*)&DevDescriptorPtr + #if defined(ARCH_HAS_MULTI_ADDRESS_SPACE) && \ + !(defined(USE_FLASH_DESCRIPTORS) || defined(USE_EEPROM_DESCRIPTORS) || defined(USE_RAM_DESCRIPTORS)) + , &MemoryAddressSpace + #endif + ) == NO_DESCRIPTOR) + { + return; + } + + #if defined(ARCH_HAS_MULTI_ADDRESS_SPACE) + if (MemoryAddressSpace == MEMSPACE_FLASH) + { + if (((uint8_t)USB_ControlRequest.wValue > pgm_read_byte(&DevDescriptorPtr->NumberOfConfigurations))) + return; + } + else if (MemoryAddressSpace == MEMSPACE_EEPROM) + { + if (((uint8_t)USB_ControlRequest.wValue > eeprom_read_byte(&DevDescriptorPtr->NumberOfConfigurations))) + return; + } + else + { + if ((uint8_t)USB_ControlRequest.wValue > DevDescriptorPtr->NumberOfConfigurations) + return; + } + #else + if ((uint8_t)USB_ControlRequest.wValue > DevDescriptorPtr->NumberOfConfigurations) + return; + #endif + #endif + + Endpoint_ClearSETUP(); + + USB_Device_ConfigurationNumber = (uint8_t)USB_ControlRequest.wValue; + + Endpoint_ClearStatusStage(); + + if (USB_Device_ConfigurationNumber) + USB_DeviceState = DEVICE_STATE_Configured; + else + USB_DeviceState = (USB_Device_IsAddressSet()) ? DEVICE_STATE_Configured : DEVICE_STATE_Powered; + + EVENT_USB_Device_ConfigurationChanged(); +} + +static void USB_Device_GetConfiguration(void) +{ + Endpoint_ClearSETUP(); + + Endpoint_Write_8(USB_Device_ConfigurationNumber); + Endpoint_ClearIN(); + + Endpoint_ClearStatusStage(); +} + +#if !defined(NO_INTERNAL_SERIAL) && (USE_INTERNAL_SERIAL != NO_DESCRIPTOR) +static void USB_Device_GetInternalSerialDescriptor(void) +{ + struct + { + USB_Descriptor_Header_t Header; + uint16_t UnicodeString[INTERNAL_SERIAL_LENGTH_BITS / 4]; + } SignatureDescriptor; + + SignatureDescriptor.Header.Type = DTYPE_String; + SignatureDescriptor.Header.Size = USB_STRING_LEN(INTERNAL_SERIAL_LENGTH_BITS / 4); + + USB_Device_GetSerialString(SignatureDescriptor.UnicodeString); + + Endpoint_ClearSETUP(); + + Endpoint_Write_Control_Stream_LE(&SignatureDescriptor, sizeof(SignatureDescriptor)); + Endpoint_ClearOUT(); +} +#endif + +static void USB_Device_GetDescriptor(void) +{ + const void* DescriptorPointer; + uint16_t DescriptorSize; + + #if defined(ARCH_HAS_MULTI_ADDRESS_SPACE) && \ + !(defined(USE_FLASH_DESCRIPTORS) || defined(USE_EEPROM_DESCRIPTORS) || defined(USE_RAM_DESCRIPTORS)) + uint8_t DescriptorAddressSpace; + #endif + + #if !defined(NO_INTERNAL_SERIAL) && (USE_INTERNAL_SERIAL != NO_DESCRIPTOR) + if (USB_ControlRequest.wValue == ((DTYPE_String << 8) | USE_INTERNAL_SERIAL)) + { + USB_Device_GetInternalSerialDescriptor(); + return; + } + #endif + + if ((DescriptorSize = CALLBACK_USB_GetDescriptor(USB_ControlRequest.wValue, USB_ControlRequest.wIndex, + &DescriptorPointer + #if defined(ARCH_HAS_MULTI_ADDRESS_SPACE) && \ + !(defined(USE_FLASH_DESCRIPTORS) || defined(USE_EEPROM_DESCRIPTORS) || defined(USE_RAM_DESCRIPTORS)) + , &DescriptorAddressSpace + #endif + )) == NO_DESCRIPTOR) + { + return; + } + + Endpoint_ClearSETUP(); + + #if defined(USE_RAM_DESCRIPTORS) || !defined(ARCH_HAS_MULTI_ADDRESS_SPACE) + Endpoint_Write_Control_Stream_LE(DescriptorPointer, DescriptorSize); + #elif defined(USE_EEPROM_DESCRIPTORS) + Endpoint_Write_Control_EStream_LE(DescriptorPointer, DescriptorSize); + #elif defined(USE_FLASH_DESCRIPTORS) + Endpoint_Write_Control_PStream_LE(DescriptorPointer, DescriptorSize); + #else + if (DescriptorAddressSpace == MEMSPACE_FLASH) + Endpoint_Write_Control_PStream_LE(DescriptorPointer, DescriptorSize); + else if (DescriptorAddressSpace == MEMSPACE_EEPROM) + Endpoint_Write_Control_EStream_LE(DescriptorPointer, DescriptorSize); + else + Endpoint_Write_Control_Stream_LE(DescriptorPointer, DescriptorSize); + #endif + + Endpoint_ClearOUT(); +} + +static void USB_Device_GetStatus(void) +{ + uint8_t CurrentStatus = 0; + + switch (USB_ControlRequest.bmRequestType) + { + case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE): + #if !defined(NO_DEVICE_SELF_POWER) + if (USB_Device_CurrentlySelfPowered) + CurrentStatus |= FEATURE_SELFPOWERED_ENABLED; + #endif + + #if !defined(NO_DEVICE_REMOTE_WAKEUP) + if (USB_Device_RemoteWakeupEnabled) + CurrentStatus |= FEATURE_REMOTE_WAKEUP_ENABLED; + #endif + break; + case (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_ENDPOINT): + #if !defined(CONTROL_ONLY_DEVICE) + Endpoint_SelectEndpoint((uint8_t)USB_ControlRequest.wIndex & ENDPOINT_EPNUM_MASK); + + CurrentStatus = Endpoint_IsStalled(); + + Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP); + #endif + + break; + default: + return; + } + + Endpoint_ClearSETUP(); + + Endpoint_Write_16_LE(CurrentStatus); + Endpoint_ClearIN(); + + Endpoint_ClearStatusStage(); +} + +static void USB_Device_ClearSetFeature(void) +{ + switch (USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_RECIPIENT) + { + #if !defined(NO_DEVICE_REMOTE_WAKEUP) + case REQREC_DEVICE: + if ((uint8_t)USB_ControlRequest.wValue == FEATURE_SEL_DeviceRemoteWakeup) + USB_Device_RemoteWakeupEnabled = (USB_ControlRequest.bRequest == REQ_SetFeature); + else + return; + + break; + #endif + #if !defined(CONTROL_ONLY_DEVICE) + case REQREC_ENDPOINT: + if ((uint8_t)USB_ControlRequest.wValue == FEATURE_SEL_EndpointHalt) + { + uint8_t EndpointIndex = ((uint8_t)USB_ControlRequest.wIndex & ENDPOINT_EPNUM_MASK); + + if (EndpointIndex == ENDPOINT_CONTROLEP) + return; + + Endpoint_SelectEndpoint(EndpointIndex); + + if (Endpoint_IsEnabled()) + { + if (USB_ControlRequest.bRequest == REQ_SetFeature) + { + Endpoint_StallTransaction(); + } + else + { + Endpoint_ClearStall(); + Endpoint_ResetEndpoint(EndpointIndex); + Endpoint_ResetDataToggle(); + } + } + } + + break; + #endif + default: + return; + } + + Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP); + + Endpoint_ClearSETUP(); + + Endpoint_ClearStatusStage(); +} + +#endif + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/DeviceStandardReq.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/DeviceStandardReq.h new file mode 100644 index 00000000..dfaa1662 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/DeviceStandardReq.h @@ -0,0 +1,158 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief USB device standard request management. + * + * This file contains the function prototypes necessary for the processing of incoming standard control requests + * when the library is in USB device mode. + * + * \note This file should not be included directly. It is automatically included as needed by the USB driver + * dispatch header located in LUFA/Drivers/USB/USB.h. + */ + +#ifndef __DEVICESTDREQ_H__ +#define __DEVICESTDREQ_H__ + + /* Includes: */ + #include "../../../Common/Common.h" + #include "USBMode.h" + #include "StdDescriptors.h" + #include "Events.h" + #include "StdRequestType.h" + #include "USBTask.h" + #include "USBController.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_USB_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB/USB.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Enums: */ + #if defined(ARCH_HAS_MULTI_ADDRESS_SPACE) || defined(__DOXYGEN__) + /** Enum for the possible descriptor memory spaces, for the \c MemoryAddressSpace parameter of the + * \ref CALLBACK_USB_GetDescriptor() function. This can be used when none of the \c USE_*_DESCRIPTORS + * compile time options are used, to indicate in which memory space the descriptor is stored. + * + * \ingroup Group_Device + */ + enum USB_DescriptorMemorySpaces_t + { + #if defined(ARCH_HAS_FLASH_ADDRESS_SPACE) || defined(__DOXYGEN__) + MEMSPACE_FLASH = 0, /**< Indicates the requested descriptor is located in FLASH memory. */ + #endif + #if defined(ARCH_HAS_EEPROM_ADDRESS_SPACE) || defined(__DOXYGEN__) + MEMSPACE_EEPROM = 1, /**< Indicates the requested descriptor is located in EEPROM memory. */ + #endif + MEMSPACE_RAM = 2, /**< Indicates the requested descriptor is located in RAM memory. */ + }; + #endif + + /* Global Variables: */ + /** Indicates the currently set configuration number of the device. USB devices may have several + * different configurations which the host can select between; this indicates the currently selected + * value, or 0 if no configuration has been selected. + * + * \attention This variable should be treated as read-only in the user application, and never manually + * changed in value. + * + * \ingroup Group_Device + */ + extern uint8_t USB_Device_ConfigurationNumber; + + #if !defined(NO_DEVICE_REMOTE_WAKEUP) + /** Indicates if the host is currently allowing the device to issue remote wakeup events. If this + * flag is cleared, the device should not issue remote wakeup events to the host. + * + * \attention This variable should be treated as read-only in the user application, and never manually + * changed in value. + * + * \note To reduce FLASH usage of the compiled applications where Remote Wakeup is not supported, + * this global and the underlying management code can be disabled by defining the + * \c NO_DEVICE_REMOTE_WAKEUP token in the project makefile and passing it to the compiler via + * the -D switch. + * + * \ingroup Group_Device + */ + extern bool USB_Device_RemoteWakeupEnabled; + #endif + + #if !defined(NO_DEVICE_SELF_POWER) + /** Indicates if the device is currently being powered by its own power supply, rather than being + * powered by the host's USB supply. This flag should remain cleared if the device does not + * support self powered mode, as indicated in the device descriptors. + * + * \ingroup Group_Device + */ + extern bool USB_Device_CurrentlySelfPowered; + #endif + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + #if defined(USE_RAM_DESCRIPTORS) && defined(USE_EEPROM_DESCRIPTORS) + #error USE_RAM_DESCRIPTORS and USE_EEPROM_DESCRIPTORS are mutually exclusive. + #elif defined(USE_RAM_DESCRIPTORS) && defined(USE_FLASH_DESCRIPTORS) + #error USE_RAM_DESCRIPTORS and USE_FLASH_DESCRIPTORS are mutually exclusive. + #elif defined(USE_FLASH_DESCRIPTORS) && defined(USE_EEPROM_DESCRIPTORS) + #error USE_FLASH_DESCRIPTORS and USE_EEPROM_DESCRIPTORS are mutually exclusive. + #elif defined(USE_FLASH_DESCRIPTORS) && defined(USE_EEPROM_DESCRIPTORS) && defined(USE_RAM_DESCRIPTORS) + #error Only one of the USE_*_DESCRIPTORS modes should be selected. + #endif + + /* Function Prototypes: */ + void USB_Device_ProcessControlRequest(void); + + #if defined(__INCLUDE_FROM_DEVICESTDREQ_C) + static void USB_Device_SetAddress(void); + static void USB_Device_SetConfiguration(void); + static void USB_Device_GetConfiguration(void); + static void USB_Device_GetDescriptor(void); + static void USB_Device_GetStatus(void); + static void USB_Device_ClearSetFeature(void); + + #if !defined(NO_INTERNAL_SERIAL) && (USE_INTERNAL_SERIAL != NO_DESCRIPTOR) + static void USB_Device_GetInternalSerialDescriptor(void); + #endif + #endif + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/Endpoint.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/Endpoint.h new file mode 100644 index 00000000..a6ca64dd --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/Endpoint.h @@ -0,0 +1,130 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief USB Endpoint definitions for all architectures. + * \copydetails Group_EndpointManagement + * + * \note This file should not be included directly. It is automatically included as needed by the USB driver + * dispatch header located in LUFA/Drivers/USB/USB.h. + */ + +/** \ingroup Group_EndpointManagement + * \defgroup Group_EndpointRW Endpoint Data Reading and Writing + * \brief Endpoint data read/write definitions. + * + * Functions, macros, variables, enums and types related to data reading and writing from and to endpoints. + */ + +/** \ingroup Group_EndpointRW + * \defgroup Group_EndpointPrimitiveRW Read/Write of Primitive Data Types + * \brief Endpoint data primitive read/write definitions. + * + * Functions, macros, variables, enums and types related to data reading and writing of primitive data types + * from and to endpoints. + */ + +/** \ingroup Group_EndpointManagement + * \defgroup Group_EndpointPacketManagement Endpoint Packet Management + * \brief USB Endpoint package management definitions. + * + * Functions, macros, variables, enums and types related to packet management of endpoints. + */ + +/** \ingroup Group_USB + * \defgroup Group_EndpointManagement Endpoint Management + * \brief Endpoint management definitions. + * + * Functions, macros and enums related to endpoint management when in USB Device mode. This + * module contains the endpoint management macros, as well as endpoint interrupt and data + * send/receive functions for various data types. + * + * @{ + */ + +#ifndef __ENDPOINT_H__ +#define __ENDPOINT_H__ + + /* Includes: */ + #include "../../../Common/Common.h" + #include "USBMode.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_USB_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB/USB.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Type Defines: */ + /** Type define for a endpoint table entry, used to configure endpoints in groups via + * \ref Endpoint_ConfigureEndpointTable(). + */ + typedef struct + { + uint8_t Address; /**< Address of the endpoint to configure, or zero if the table entry is to be unused. */ + uint16_t Size; /**< Size of the endpoint bank, in bytes. */ + uint8_t Type; /**< Type of the endpoint, a \c EP_TYPE_* mask. */ + uint8_t Banks; /**< Number of hardware banks to use for the endpoint. */ + } USB_Endpoint_Table_t; + + /* Macros: */ + /** Endpoint number mask, for masking against endpoint addresses to retrieve the endpoint's + * numerical address in the device. + */ + #define ENDPOINT_EPNUM_MASK 0x0F + + /** Endpoint address for the default control endpoint, which always resides in address 0. This is + * defined for convenience to give more readable code when used with the endpoint macros. + */ + #define ENDPOINT_CONTROLEP 0 + + /* Architecture Includes: */ + #if (ARCH == ARCH_AVR8) + #include "AVR8/Endpoint_AVR8.h" + #elif (ARCH == ARCH_UC3) + #include "UC3/Endpoint_UC3.h" + #elif (ARCH == ARCH_XMEGA) + #include "XMEGA/Endpoint_XMEGA.h" + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/EndpointStream.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/EndpointStream.h new file mode 100644 index 00000000..89df381a --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/EndpointStream.h @@ -0,0 +1,124 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Endpoint data stream transmission and reception management. + * \copydetails Group_EndpointStreamRW + * + * \note This file should not be included directly. It is automatically included as needed by the USB driver + * dispatch header located in LUFA/Drivers/USB/USB.h. + */ + +/** \ingroup Group_EndpointRW + * \defgroup Group_EndpointStreamRW Read/Write of Multi-Byte Streams + * \brief Endpoint data stream transmission and reception management. + * + * Functions, macros, variables, enums and types related to data reading and writing of data streams from + * and to endpoints. + * + * @{ + */ + +#ifndef __ENDPOINT_STREAM_H__ +#define __ENDPOINT_STREAM_H__ + + /* Includes: */ + #include "../../../Common/Common.h" + #include "USBMode.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_USB_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB/USB.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Enums: */ + /** Enum for the possible error return codes of the \c Endpoint_*_Stream_* functions. */ + enum Endpoint_Stream_RW_ErrorCodes_t + { + ENDPOINT_RWSTREAM_NoError = 0, /**< Command completed successfully, no error. */ + ENDPOINT_RWSTREAM_EndpointStalled = 1, /**< The endpoint was stalled during the stream + * transfer by the host or device. + */ + ENDPOINT_RWSTREAM_DeviceDisconnected = 2, /**< Device was disconnected from the host during + * the transfer. + */ + ENDPOINT_RWSTREAM_BusSuspended = 3, /**< The USB bus has been suspended by the host and + * no USB endpoint traffic can occur until the bus + * has resumed. + */ + ENDPOINT_RWSTREAM_Timeout = 4, /**< The host failed to accept or send the next packet + * within the software timeout period set by the + * \ref USB_STREAM_TIMEOUT_MS macro. + */ + ENDPOINT_RWSTREAM_IncompleteTransfer = 5, /**< Indicates that the endpoint bank became full or empty before + * the complete contents of the current stream could be + * transferred. The endpoint stream function should be called + * again to process the next chunk of data in the transfer. + */ + }; + + /** Enum for the possible error return codes of the \c Endpoint_*_Control_Stream_* functions. */ + enum Endpoint_ControlStream_RW_ErrorCodes_t + { + ENDPOINT_RWCSTREAM_NoError = 0, /**< Command completed successfully, no error. */ + ENDPOINT_RWCSTREAM_HostAborted = 1, /**< The aborted the transfer prematurely. */ + ENDPOINT_RWCSTREAM_DeviceDisconnected = 2, /**< Device was disconnected from the host during + * the transfer. + */ + ENDPOINT_RWCSTREAM_BusSuspended = 3, /**< The USB bus has been suspended by the host and + * no USB endpoint traffic can occur until the bus + * has resumed. + */ + }; + + /* Architecture Includes: */ + #if (ARCH == ARCH_AVR8) + #include "AVR8/EndpointStream_AVR8.h" + #elif (ARCH == ARCH_UC3) + #include "UC3/EndpointStream_UC3.h" + #elif (ARCH == ARCH_XMEGA) + #include "XMEGA/EndpointStream_XMEGA.h" + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/Events.c b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/Events.c new file mode 100644 index 00000000..5f504306 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/Events.c @@ -0,0 +1,40 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#define __INCLUDE_FROM_EVENTS_C +#define __INCLUDE_FROM_USB_DRIVER +#include "Events.h" + +// cppcheck-suppress unusedFunction +void USB_Event_Stub(void) +{ + +} + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/Events.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/Events.h new file mode 100644 index 00000000..33db543d --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/Events.h @@ -0,0 +1,366 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief USB Event management definitions. + * \copydetails Group_Events + * + * \note This file should not be included directly. It is automatically included as needed by the USB driver + * dispatch header located in LUFA/Drivers/USB/USB.h. + */ + +/** \ingroup Group_USB + * \defgroup Group_Events USB Events + * \brief USB Event management definitions. + * + * This module contains macros and functions relating to the management of library events, which are small + * pieces of code similar to ISRs which are run when a given condition is met. Each event can be fired from + * multiple places in the user or library code, which may or may not be inside an ISR, thus each handler + * should be written to be as small and fast as possible to prevent possible problems. + * + * Events can be hooked by the user application by declaring a handler function with the same name and parameters + * listed here. If an event with no user-associated handler is fired within the library, it by default maps to an + * internal empty stub function. + * + * Each event must only have one associated event handler, but can be raised by multiple sources by calling the + * event handler function (with any required event parameters). + * + * @{ + */ + +#ifndef __USBEVENTS_H__ +#define __USBEVENTS_H__ + + /* Includes: */ + #include "../../../Common/Common.h" + #include "USBMode.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_USB_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB/USB.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Pseudo-Functions for Doxygen: */ + #if !defined(__INCLUDE_FROM_EVENTS_C) || defined(__DOXYGEN__) + /** Event for USB mode pin level change. This event fires when the USB interface is set to dual role + * mode, and the UID pin level has changed to indicate a new mode (device or host). This event fires + * before the mode is switched to the newly indicated mode but after the \ref EVENT_USB_Device_Disconnect + * event has fired (if disconnected before the role change). + * + * \note This event only exists on microcontrollers that support dual role USB modes. + * \n\n + * + * \note This event does not exist if the \c USB_DEVICE_ONLY or \c USB_HOST_ONLY tokens have been supplied + * to the compiler (see \ref Group_USBManagement documentation). + */ + void EVENT_USB_UIDChange(void); + + /** Event for USB host error. This event fires when a hardware fault has occurred whilst the USB + * interface is in host mode. + * + * \param[in] ErrorCode Error code indicating the failure reason, a value in \ref USB_Host_ErrorCodes_t. + * + * \note This event only exists on microcontrollers that supports USB host mode. + * \n\n + * + * \note This event does not exist if the \c USB_DEVICE_ONLY token is supplied to the compiler (see + * \ref Group_USBManagement documentation). + */ + void EVENT_USB_Host_HostError(const uint8_t ErrorCode); + + /** Event for USB device attachment. This event fires when a the USB interface is in host mode, and + * a USB device has been connected to the USB interface. This is interrupt driven, thus fires before + * the standard \ref EVENT_USB_Device_Connect() event and so can be used to programmatically start the USB + * management task to reduce CPU consumption. + * + * \note This event only exists on microcontrollers that supports USB host mode. + * \n\n + * + * \note This event does not exist if the \c USB_DEVICE_ONLY token is supplied to the compiler (see + * \ref Group_USBManagement documentation). + * + * \see \ref USB_USBTask() for more information on the USB management task and reducing CPU usage. + */ + void EVENT_USB_Host_DeviceAttached(void); + + /** Event for USB device removal. This event fires when a the USB interface is in host mode, and + * a USB device has been removed the USB interface whether or not it has been enumerated. This + * can be used to programmatically stop the USB management task to reduce CPU consumption. + * + * \note This event only exists on microcontrollers that supports USB host mode. + * \n\n + * + * \note This event does not exist if the \c USB_DEVICE_ONLY token is supplied to the compiler (see + * \ref Group_USBManagement documentation). + * + * \see \ref USB_USBTask() for more information on the USB management task and reducing CPU usage. + */ + void EVENT_USB_Host_DeviceUnattached(void); + + /** Event for USB device enumeration failure. This event fires when a the USB interface is + * in host mode, and an attached USB device has failed to enumerate completely. + * + * \param[in] ErrorCode Error code indicating the failure reason, a value in + * \ref USB_Host_EnumerationErrorCodes_t. + * + * \param[in] SubErrorCode Sub error code indicating the reason for failure - for example, if the + * ErrorCode parameter indicates a control error, this will give the error + * code returned by the \ref USB_Host_SendControlRequest() function. + * + * \note This event only exists on microcontrollers that supports USB host mode. + * \n\n + * + * \note This event does not exist if the \c USB_DEVICE_ONLY token is supplied to the compiler (see + * \ref Group_USBManagement documentation). + */ + void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode, + const uint8_t SubErrorCode); + + /** Event for USB device enumeration completion. This event fires when a the USB interface is + * in host mode and an attached USB device has been completely enumerated and is ready to be + * controlled by the user application. + * + * This event is time-critical; exceeding OS-specific delays within this event handler (typically of around + * 1 second) when a transaction is waiting to be processed by the device will prevent break communications + * and cause the host to reset the USB bus. + */ + void EVENT_USB_Host_DeviceEnumerationComplete(void); + + /** Event for USB Start Of Frame detection, when enabled. This event fires at the start of each USB + * frame, once per millisecond, and is synchronized to the USB bus. This can be used as an accurate + * millisecond timer source when the USB bus is not suspended while in host mode. + * + * This event is time-critical; it is run once per millisecond and thus long handlers will significantly + * degrade device performance. This event should only be enabled when needed to reduce device wake-ups. + * + * \note This event is not normally active - it must be manually enabled and disabled via the + * \ref USB_Host_EnableSOFEvents() and \ref USB_Host_DisableSOFEvents() commands after enumeration of + * a USB device. + * \n\n + * + * \note This event does not exist if the \c USB_DEVICE_ONLY token is supplied to the compiler (see + * \ref Group_USBManagement documentation). + */ + void EVENT_USB_Host_StartOfFrame(void); + + /** Event for USB device connection. This event fires when the microcontroller is in USB Device mode + * and the device is connected to a USB host, beginning the enumeration process measured by a rising + * level on the microcontroller's VBUS sense pin. + * + * This event is time-critical; exceeding OS-specific delays within this event handler (typically of around + * two seconds) will prevent the device from enumerating correctly. + * + * \attention This event may fire multiple times during device enumeration on the microcontrollers with limited USB controllers + * if \c NO_LIMITED_CONTROLLER_CONNECT is not defined. + * + * \note For the microcontrollers with limited USB controller functionality, VBUS sensing is not available. + * this means that the current connection state is derived from the bus suspension and wake up events by default, + * which is not always accurate (host may suspend the bus while still connected). If the actual connection state + * needs to be determined, VBUS should be routed to an external pin, and the auto-detect behavior turned off by + * passing the \c NO_LIMITED_CONTROLLER_CONNECT token to the compiler via the -D switch at compile time. The connection + * and disconnection events may be manually fired, and the \ref USB_DeviceState global changed manually. + * \n\n + * + * \see \ref Group_USBManagement for more information on the USB management task and reducing CPU usage. + */ + void EVENT_USB_Device_Connect(void); + + /** Event for USB device disconnection. This event fires when the microcontroller is in USB Device mode and the device is + * disconnected from a host, measured by a falling level on the microcontroller's VBUS sense pin. + * + * \attention This event may fire multiple times during device enumeration on the microcontrollers with limited USB controllers + * if \c NO_LIMITED_CONTROLLER_CONNECT is not defined. + * + * \note For the microcontrollers with limited USB controllers, VBUS sense is not available to the USB controller. + * this means that the current connection state is derived from the bus suspension and wake up events by default, + * which is not always accurate (host may suspend the bus while still connected). If the actual connection state + * needs to be determined, VBUS should be routed to an external pin, and the auto-detect behavior turned off by + * passing the \c NO_LIMITED_CONTROLLER_CONNECT token to the compiler via the -D switch at compile time. The connection + * and disconnection events may be manually fired, and the \ref USB_DeviceState global changed manually. + * \n\n + * + * \see \ref Group_USBManagement for more information on the USB management task and reducing CPU usage. + */ + void EVENT_USB_Device_Disconnect(void); + + /** Event for control requests. This event fires when a the USB host issues a control request + * to the mandatory device control endpoint (of address 0). This may either be a standard + * request that the library may have a handler code for internally, or a class specific request + * issued to the device which must be handled appropriately. If a request is not processed in the + * user application via this event, it will be passed to the library for processing internally + * if a suitable handler exists. + * + * This event is time-critical; each packet within the request transaction must be acknowledged or + * sent within 50ms or the host will abort the transfer. + * + * The library internally handles all standard control requests with the exceptions of SYNC FRAME, + * SET DESCRIPTOR and SET INTERFACE. These and all other non-standard control requests will be left + * for the user to process via this event if desired. If not handled in the user application or by + * the library internally, unknown requests are automatically STALLed. + * + * \note This event does not exist if the \c USB_HOST_ONLY token is supplied to the compiler (see + * \ref Group_USBManagement documentation). + * \n\n + * + * \note Requests should be handled in the same manner as described in the USB 2.0 Specification, + * or appropriate class specification. In all instances, the library has already read the + * request SETUP parameters into the \ref USB_ControlRequest structure which should then be used + * by the application to determine how to handle the issued request. + */ + void EVENT_USB_Device_ControlRequest(void); + + /** Event for USB configuration number changed. This event fires when a the USB host changes the + * selected configuration number while in device mode. This event should be hooked in device + * applications to create the endpoints and configure the device for the selected configuration. + * + * This event is time-critical; exceeding OS-specific delays within this event handler (typically of around + * one second) will prevent the device from enumerating correctly. + * + * This event fires after the value of \ref USB_Device_ConfigurationNumber has been changed. + * + * \note This event does not exist if the \c USB_HOST_ONLY token is supplied to the compiler (see + * \ref Group_USBManagement documentation). + */ + void EVENT_USB_Device_ConfigurationChanged(void); + + /** Event for USB suspend. This event fires when a the USB host suspends the device by halting its + * transmission of Start Of Frame pulses to the device. This is generally hooked in order to move + * the device over to a low power state until the host wakes up the device. If the USB interface is + * enumerated with the \ref USB_OPT_AUTO_PLL option set, the library will automatically suspend the + * USB PLL before the event is fired to save power. + * + * \note This event does not exist if the \c USB_HOST_ONLY token is supplied to the compiler (see + * \ref Group_USBManagement documentation). + * \n\n + * + * \note This event does not exist on the microcontrollers with limited USB VBUS sensing abilities + * when the \c NO_LIMITED_CONTROLLER_CONNECT compile time token is not set - see + * \ref EVENT_USB_Device_Disconnect. + * + * \see \ref EVENT_USB_Device_WakeUp() event for accompanying Wake Up event. + */ + void EVENT_USB_Device_Suspend(void); + + /** Event for USB wake up. This event fires when a the USB interface is suspended while in device + * mode, and the host wakes up the device by supplying Start Of Frame pulses. This is generally + * hooked to pull the user application out of a low power state and back into normal operating + * mode. If the USB interface is enumerated with the \ref USB_OPT_AUTO_PLL option set, the library + * will automatically restart the USB PLL before the event is fired. + * + * \note This event does not exist if the \c USB_HOST_ONLY token is supplied to the compiler (see + * \ref Group_USBManagement documentation). + * \n\n + * + * \note This event does not exist on the microcontrollers with limited USB VBUS sensing abilities + * when the \c NO_LIMITED_CONTROLLER_CONNECT compile time token is not set - see + * \ref EVENT_USB_Device_Disconnect. + * + * \see \ref EVENT_USB_Device_Suspend() event for accompanying Suspend event. + */ + void EVENT_USB_Device_WakeUp(void); + + /** Event for USB interface reset. This event fires when the USB interface is in device mode, and + * a the USB host requests that the device reset its interface. This event fires after the control + * endpoint has been automatically configured by the library. + * + * This event is time-critical; exceeding OS-specific delays within this event handler (typically of around + * two seconds) will prevent the device from enumerating correctly. + * + * \note This event does not exist if the \c USB_HOST_ONLY token is supplied to the compiler (see + * \ref Group_USBManagement documentation). + */ + void EVENT_USB_Device_Reset(void); + + /** Event for USB Start Of Frame detection, when enabled. This event fires at the start of each USB + * frame, once per millisecond, and is synchronized to the USB bus. This can be used as an accurate + * millisecond timer source when the USB bus is enumerated in device mode to a USB host. + * + * This event is time-critical; it is run once per millisecond and thus long handlers will significantly + * degrade device performance. This event should only be enabled when needed to reduce device wake-ups. + * + * \pre This event is not normally active - it must be manually enabled and disabled via the + * \ref USB_Device_EnableSOFEvents() and \ref USB_Device_DisableSOFEvents() commands after enumeration. + * \n\n + * + * \note This event does not exist if the \c USB_HOST_ONLY token is supplied to the compiler (see + * \ref Group_USBManagement documentation). + */ + void EVENT_USB_Device_StartOfFrame(void); + #endif + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Function Prototypes: */ + #if defined(__INCLUDE_FROM_EVENTS_C) + void USB_Event_Stub(void) ATTR_CONST; + + #if defined(USB_CAN_BE_BOTH) + void EVENT_USB_UIDChange(void) ATTR_WEAK ATTR_ALIAS(USB_Event_Stub); + #endif + + #if defined(USB_CAN_BE_HOST) + void EVENT_USB_Host_HostError(const uint8_t ErrorCode) ATTR_WEAK ATTR_ALIAS(USB_Event_Stub); + void EVENT_USB_Host_DeviceAttached(void) ATTR_WEAK ATTR_ALIAS(USB_Event_Stub); + void EVENT_USB_Host_DeviceUnattached(void) ATTR_WEAK ATTR_ALIAS(USB_Event_Stub); + void EVENT_USB_Host_DeviceEnumerationComplete(void) ATTR_WEAK ATTR_ALIAS(USB_Event_Stub); + void EVENT_USB_Host_DeviceEnumerationFailed(const uint8_t ErrorCode, + const uint8_t SubErrorCode) + ATTR_WEAK ATTR_ALIAS(USB_Event_Stub); + void EVENT_USB_Host_StartOfFrame(void) ATTR_WEAK ATTR_ALIAS(USB_Event_Stub); + #endif + + #if defined(USB_CAN_BE_DEVICE) + void EVENT_USB_Device_Connect(void) ATTR_WEAK ATTR_ALIAS(USB_Event_Stub); + void EVENT_USB_Device_Disconnect(void) ATTR_WEAK ATTR_ALIAS(USB_Event_Stub); + void EVENT_USB_Device_ControlRequest(void) ATTR_WEAK ATTR_ALIAS(USB_Event_Stub); + void EVENT_USB_Device_ConfigurationChanged(void) ATTR_WEAK ATTR_ALIAS(USB_Event_Stub); + void EVENT_USB_Device_Suspend(void) ATTR_WEAK ATTR_ALIAS(USB_Event_Stub); + void EVENT_USB_Device_WakeUp(void) ATTR_WEAK ATTR_ALIAS(USB_Event_Stub); + void EVENT_USB_Device_Reset(void) ATTR_WEAK ATTR_ALIAS(USB_Event_Stub); + void EVENT_USB_Device_StartOfFrame(void) ATTR_WEAK ATTR_ALIAS(USB_Event_Stub); + #endif + #endif + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/Host.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/Host.h new file mode 100644 index 00000000..bf2225f3 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/Host.h @@ -0,0 +1,139 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Common USB Host definitions for all architectures. + * \copydetails Group_Host + * + * \note This file should not be included directly. It is automatically included as needed by the USB driver + * dispatch header located in LUFA/Drivers/USB/USB.h. + */ + +/** \ingroup Group_USB + * \defgroup Group_Host Host Management + * \brief USB Host management definitions for USB host mode. + * + * USB Host mode related macros and enums. This module contains macros and enums which are used when + * the USB controller is initialized in host mode. + * + * @{ + */ + +#ifndef __USBHOST_H__ +#define __USBHOST_H__ + + /* Includes: */ + #include "../../../Common/Common.h" + #include "USBMode.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_USB_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB/USB.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Enums: */ + /** Enum for the various states of the USB Host state machine. + * + * For information on each possible USB host state, refer to the USB 2.0 specification. + * Several of the USB host states are broken up further into multiple smaller sub-states, + * so that they can be internally implemented inside the library in an efficient manner. + * + * \see \ref USB_HostState, which stores the current host state machine state. + */ + enum USB_Host_States_t + { + HOST_STATE_WaitForDevice = 0, /**< This state indicates that the stack is waiting for an interval + * to elapse before continuing with the next step of the device + * enumeration process. + */ + HOST_STATE_Unattached = 1, /**< This state indicates that the host state machine is waiting for + * a device to be attached so that it can start the enumeration process. + */ + HOST_STATE_Powered = 2, /**< This state indicates that a device has been attached, and the + * library's internals are being configured to begin the enumeration + * process. + */ + HOST_STATE_Powered_WaitForDeviceSettle = 3, /**< This state indicates that the stack is waiting for the initial + * settling period to elapse before beginning the enumeration process. + */ + HOST_STATE_Powered_WaitForConnect = 4, /**< This state indicates that the stack is waiting for a connection event + * from the USB controller to indicate a valid USB device has been attached + * to the bus and is ready to be enumerated. + */ + HOST_STATE_Powered_DoReset = 5, /**< This state indicates that a valid USB device has been attached, and that + * it will now be reset to ensure it is ready for enumeration. + */ + HOST_STATE_Powered_ConfigPipe = 6, /**< This state indicates that the attached device is currently powered and + * reset, and that the control pipe is now being configured by the stack. + */ + HOST_STATE_Default = 7, /**< This state indicates that the stack is currently retrieving the control + * endpoint's size from the device, so that the control pipe can be altered + * to match. + */ + HOST_STATE_Default_PostReset = 8, /**< This state indicates that the control pipe is being reconfigured to match + * the retrieved control endpoint size from the device, and the device's USB + * bus address is being set. + */ + HOST_STATE_Default_PostAddressSet = 9, /**< This state indicates that the device's address has now been set, and the + * stack is has now completed the device enumeration process. This state causes + * the stack to change the current USB device address to that set for the + * connected device, before progressing to the \ref HOST_STATE_Addressed state + * ready for use in the user application. + */ + HOST_STATE_Addressed = 10, /**< Indicates that the device has been enumerated and addressed, and is now waiting + * for the user application to configure the device ready for use. + */ + HOST_STATE_Configured = 11, /**< Indicates that the device has been configured into a valid device configuration, + * ready for general use by the user application. + */ + }; + + /* Architecture Includes: */ + #if (ARCH == ARCH_AVR8) + #include "AVR8/Host_AVR8.h" + #elif (ARCH == ARCH_UC3) + #include "UC3/Host_UC3.h" + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/HostStandardReq.c b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/HostStandardReq.c new file mode 100644 index 00000000..3242822f --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/HostStandardReq.c @@ -0,0 +1,322 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#define __INCLUDE_FROM_USB_DRIVER +#include "USBMode.h" + +#if defined(USB_CAN_BE_HOST) + +#define __INCLUDE_FROM_HOSTSTDREQ_C +#include "HostStandardReq.h" + +uint8_t USB_Host_ConfigurationNumber; + +static uint8_t USB_Host_SendControlRequest_PRV(void* const BufferPtr) +{ + uint8_t* DataStream = (uint8_t*)BufferPtr; + uint8_t ReturnStatus = HOST_SENDCONTROL_Successful; + uint16_t DataLen = USB_ControlRequest.wLength; + + USB_Host_ResumeBus(); + + if ((ReturnStatus = USB_Host_WaitMS(1)) != HOST_WAITERROR_Successful) + return ReturnStatus; + + Pipe_SetPipeToken(PIPE_TOKEN_SETUP); + Pipe_ClearError(); + + Pipe_Unfreeze(); + + #if defined(ARCH_BIG_ENDIAN) + Pipe_Write_8(USB_ControlRequest.bmRequestType); + Pipe_Write_8(USB_ControlRequest.bRequest); + Pipe_Write_16_LE(USB_ControlRequest.wValue); + Pipe_Write_16_LE(USB_ControlRequest.wIndex); + Pipe_Write_16_LE(USB_ControlRequest.wLength); + #else + uint8_t* HeaderStream = (uint8_t*)&USB_ControlRequest; + + for (uint8_t HeaderByte = 0; HeaderByte < sizeof(USB_Request_Header_t); HeaderByte++) + Pipe_Write_8(*(HeaderStream++)); + #endif + + Pipe_ClearSETUP(); + + if ((ReturnStatus = USB_Host_WaitForIOS(USB_HOST_WAITFOR_SetupSent)) != HOST_SENDCONTROL_Successful) + return ReturnStatus; + + Pipe_Freeze(); + + if ((ReturnStatus = USB_Host_WaitMS(1)) != HOST_WAITERROR_Successful) + return ReturnStatus; + + if ((USB_ControlRequest.bmRequestType & CONTROL_REQTYPE_DIRECTION) == REQDIR_DEVICETOHOST) + { + Pipe_SetPipeToken(PIPE_TOKEN_IN); + + if (DataStream != NULL) + { + while (DataLen) + { + Pipe_Unfreeze(); + + if ((ReturnStatus = USB_Host_WaitForIOS(USB_HOST_WAITFOR_InReceived)) != HOST_SENDCONTROL_Successful) + return ReturnStatus; + + if (!(Pipe_BytesInPipe())) + DataLen = 0; + + while (Pipe_BytesInPipe() && DataLen) + { + *(DataStream++) = Pipe_Read_8(); + DataLen--; + } + + Pipe_Freeze(); + Pipe_ClearIN(); + } + } + + Pipe_SetPipeToken(PIPE_TOKEN_OUT); + Pipe_Unfreeze(); + + if ((ReturnStatus = USB_Host_WaitForIOS(USB_HOST_WAITFOR_OutReady)) != HOST_SENDCONTROL_Successful) + return ReturnStatus; + + Pipe_ClearOUT(); + + if ((ReturnStatus = USB_Host_WaitForIOS(USB_HOST_WAITFOR_OutReady)) != HOST_SENDCONTROL_Successful) + return ReturnStatus; + } + else + { + if (DataStream != NULL) + { + Pipe_SetPipeToken(PIPE_TOKEN_OUT); + Pipe_Unfreeze(); + + while (DataLen) + { + if ((ReturnStatus = USB_Host_WaitForIOS(USB_HOST_WAITFOR_OutReady)) != HOST_SENDCONTROL_Successful) + return ReturnStatus; + + while (DataLen && (Pipe_BytesInPipe() < USB_Host_ControlPipeSize)) + { + Pipe_Write_8(*(DataStream++)); + DataLen--; + } + + Pipe_ClearOUT(); + } + + if ((ReturnStatus = USB_Host_WaitForIOS(USB_HOST_WAITFOR_OutReady)) != HOST_SENDCONTROL_Successful) + return ReturnStatus; + + Pipe_Freeze(); + } + + Pipe_SetPipeToken(PIPE_TOKEN_IN); + Pipe_Unfreeze(); + + if ((ReturnStatus = USB_Host_WaitForIOS(USB_HOST_WAITFOR_InReceived)) != HOST_SENDCONTROL_Successful) + return ReturnStatus; + + Pipe_ClearIN(); + } + + return ReturnStatus; +} + +static uint8_t USB_Host_WaitForIOS(const uint8_t WaitType) +{ + #if (USB_HOST_TIMEOUT_MS < 0xFF) + uint8_t TimeoutCounter = USB_HOST_TIMEOUT_MS; + #else + uint16_t TimeoutCounter = USB_HOST_TIMEOUT_MS; + #endif + + while (!(((WaitType == USB_HOST_WAITFOR_SetupSent) && Pipe_IsSETUPSent()) || + ((WaitType == USB_HOST_WAITFOR_InReceived) && Pipe_IsINReceived()) || + ((WaitType == USB_HOST_WAITFOR_OutReady) && Pipe_IsOUTReady()))) + { + uint8_t ErrorCode; + + if ((ErrorCode = USB_Host_WaitMS(1)) != HOST_WAITERROR_Successful) + return ErrorCode; + + if (!(TimeoutCounter--)) + return HOST_SENDCONTROL_SoftwareTimeOut; + } + + return HOST_SENDCONTROL_Successful; +} + +uint8_t USB_Host_SendControlRequest(void* const BufferPtr) +{ + bool BusSuspended = USB_Host_IsBusSuspended(); + uint8_t ReturnStatus = USB_Host_SendControlRequest_PRV(BufferPtr); + + Pipe_Freeze(); + + if (BusSuspended) + USB_Host_SuspendBus(); + + Pipe_ResetPipe(PIPE_CONTROLPIPE); + + return ReturnStatus; +} + +uint8_t USB_Host_SetDeviceConfiguration(const uint8_t ConfigNumber) +{ + uint8_t ErrorCode; + + USB_ControlRequest = (USB_Request_Header_t) + { + .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE), + .bRequest = REQ_SetConfiguration, + .wValue = ConfigNumber, + .wIndex = 0, + .wLength = 0, + }; + + Pipe_SelectPipe(PIPE_CONTROLPIPE); + + if ((ErrorCode = USB_Host_SendControlRequest(NULL)) == HOST_SENDCONTROL_Successful) + { + USB_Host_ConfigurationNumber = ConfigNumber; + USB_HostState = (ConfigNumber) ? HOST_STATE_Configured : HOST_STATE_Addressed; + } + + return ErrorCode; +} + +uint8_t USB_Host_GetDeviceConfiguration(uint8_t* const ConfigNumber) +{ + USB_ControlRequest = (USB_Request_Header_t) + { + .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE), + .bRequest = REQ_GetConfiguration, + .wValue = 0, + .wIndex = 0, + .wLength = sizeof(uint8_t), + }; + + Pipe_SelectPipe(PIPE_CONTROLPIPE); + + return USB_Host_SendControlRequest(ConfigNumber); +} + +uint8_t USB_Host_GetDescriptor(const uint8_t Type, + const uint8_t Index, + void* const Buffer, + const uint8_t BufferLength) +{ + USB_ControlRequest = (USB_Request_Header_t) + { + .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE), + .bRequest = REQ_GetDescriptor, + .wValue = (((uint16_t)Type << 8) | Index), + .wIndex = 0, + .wLength = BufferLength, + }; + + Pipe_SelectPipe(PIPE_CONTROLPIPE); + + return USB_Host_SendControlRequest(Buffer); +} + +uint8_t USB_Host_GetDeviceStatus(uint8_t* const FeatureStatus) +{ + USB_ControlRequest = (USB_Request_Header_t) + { + .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE), + .bRequest = REQ_GetStatus, + .wValue = 0, + .wIndex = 0, + .wLength = 0, + }; + + Pipe_SelectPipe(PIPE_CONTROLPIPE); + + return USB_Host_SendControlRequest(FeatureStatus); +} + +uint8_t USB_Host_ClearEndpointStall(const uint8_t EndpointAddress) +{ + USB_ControlRequest = (USB_Request_Header_t) + { + .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_ENDPOINT), + .bRequest = REQ_ClearFeature, + .wValue = FEATURE_SEL_EndpointHalt, + .wIndex = EndpointAddress, + .wLength = 0, + }; + + Pipe_SelectPipe(PIPE_CONTROLPIPE); + + return USB_Host_SendControlRequest(NULL); +} + +uint8_t USB_Host_SetInterfaceAltSetting(const uint8_t InterfaceIndex, + const uint8_t AltSetting) +{ + USB_ControlRequest = (USB_Request_Header_t) + { + .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_INTERFACE), + .bRequest = REQ_SetInterface, + .wValue = AltSetting, + .wIndex = InterfaceIndex, + .wLength = 0, + }; + + Pipe_SelectPipe(PIPE_CONTROLPIPE); + + return USB_Host_SendControlRequest(NULL); +} + +uint8_t USB_Host_GetInterfaceAltSetting(const uint8_t InterfaceIndex, + uint8_t* const AltSetting) +{ + USB_ControlRequest = (USB_Request_Header_t) + { + .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_INTERFACE), + .bRequest = REQ_GetInterface, + .wValue = 0, + .wIndex = InterfaceIndex, + .wLength = sizeof(uint8_t), + }; + + Pipe_SelectPipe(PIPE_CONTROLPIPE); + + return USB_Host_SendControlRequest(AltSetting); +} + +#endif + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/HostStandardReq.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/HostStandardReq.h new file mode 100644 index 00000000..cdfb3547 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/HostStandardReq.h @@ -0,0 +1,292 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief USB host standard request management. + * + * This file contains the function prototypes necessary for the issuing of outgoing standard control requests + * when the library is in USB host mode. + * + * \note This file should not be included directly. It is automatically included as needed by the USB driver + * dispatch header located in LUFA/Drivers/USB/USB.h. + */ + +#ifndef __HOSTSTDREQ_H__ +#define __HOSTSTDREQ_H__ + + /* Includes: */ + #include "../../../Common/Common.h" + #include "USBMode.h" + #include "StdRequestType.h" + #include "USBController.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_USB_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB/USB.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + #if !defined(USB_HOST_TIMEOUT_MS) || defined(__DOXYGEN__) + /** Constant for the maximum software timeout period of sent USB control transactions to an attached + * device. If a device fails to respond to a sent control request within this period, the + * library will return a timeout error code. + * + * This value may be overridden in the user project makefile as the value of the + * \ref USB_HOST_TIMEOUT_MS token, and passed to the compiler using the -D switch. + */ + #define USB_HOST_TIMEOUT_MS 1000 + #endif + + /* Enums: */ + /** Enum for the \ref USB_Host_SendControlRequest() return code, indicating the reason for the error + * if the transfer of the request is unsuccessful. + * + * \ingroup Group_PipeControlReq + */ + enum USB_Host_SendControlErrorCodes_t + { + HOST_SENDCONTROL_Successful = 0, /**< No error occurred in the request transfer. */ + HOST_SENDCONTROL_DeviceDisconnected = 1, /**< The attached device was disconnected during the + * request transfer. + */ + HOST_SENDCONTROL_PipeError = 2, /**< An error occurred in the pipe while sending the request. */ + HOST_SENDCONTROL_SetupStalled = 3, /**< The attached device stalled the request, usually + * indicating that the request is unsupported on the device. + */ + HOST_SENDCONTROL_SoftwareTimeOut = 4, /**< The request or data transfer timed out. */ + }; + + /* Global Variables: */ + /** Indicates the currently set configuration number of the attached device. This indicates the currently + * selected configuration value if one has been set successfully, or 0 if no configuration has been selected. + * + * To set a device configuration, call the \ref USB_Host_SetDeviceConfiguration() function. + * + * \attention This variable should be treated as read-only in the user application, and never manually + * changed in value. + * + * \ingroup Group_Host + */ + extern uint8_t USB_Host_ConfigurationNumber; + + /* Function Prototypes: */ + /** Sends the request stored in the \ref USB_ControlRequest global structure to the attached device, + * and transfers the data stored in the buffer to the device, or from the device to the buffer + * as requested. The transfer is made on the currently selected pipe. + * + * \ingroup Group_PipeControlReq + * + * \param[in] BufferPtr Pointer to the start of the data buffer if the request has a data stage, or + * \c NULL if the request transfers no data to or from the device. + * + * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result. + */ + uint8_t USB_Host_SendControlRequest(void* const BufferPtr); + + /** Sends a SET CONFIGURATION standard request to the attached device, with the given configuration index. + * + * This routine will automatically update the \ref USB_HostState and \ref USB_Host_ConfigurationNumber + * state variables according to the given function parameters and the result of the request. + * + * \note After this routine returns, the control pipe will be selected. + * + * \ingroup Group_PipeControlReq + * + * \param[in] ConfigNumber Configuration index to send to the device. + * + * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result. + */ + uint8_t USB_Host_SetDeviceConfiguration(const uint8_t ConfigNumber); + + /** Sends a GET CONFIGURATION standard request to the attached device, to retrieve the currently selected + * device configuration index. + * + * \note After this routine returns, the control pipe will be selected. + * + * \ingroup Group_PipeControlReq + * + * \param[out] ConfigNumber Pointer to a location where the retrieved configuration index should be stored. + * + * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result. + */ + uint8_t USB_Host_GetDeviceConfiguration(uint8_t* const ConfigNumber) ATTR_NON_NULL_PTR_ARG(1); + + /** Sends a GET DESCRIPTOR standard request to the attached device, requesting the descriptor of the + * specified type and index. + * + * \note After this routine returns, the control pipe will be selected. + * + * \ingroup Group_PipeControlReq + * + * \param[in] Type Type of descriptor to retrieve, a value from the \ref USB_DescriptorTypes_t enum. + * \param[in] Index Index of the descriptor to retrieve. + * \param[out] Buffer Pointer to the destination buffer where the retrieved string descriptor is to be stored. + * \param[in] BufferLength Maximum size of the string descriptor which can be stored into the buffer. + * + * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result. + */ + uint8_t USB_Host_GetDescriptor(const uint8_t Type, + const uint8_t Index, + void* const Buffer, + const uint8_t BufferLength) ATTR_NON_NULL_PTR_ARG(3); + + /** Retrieves the current feature status of the attached device, via a GET STATUS standard request. The + * retrieved feature status can then be examined by masking the retrieved value with the various + * \c FEATURE_* masks for bus/self power information and remote wakeup support. + * + * \note After this routine returns, the control pipe will be selected. + * + * \ingroup Group_PipeControlReq + * + * \param[out] FeatureStatus Location where the retrieved feature status should be stored. + * + * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result. + */ + uint8_t USB_Host_GetDeviceStatus(uint8_t* const FeatureStatus) ATTR_NON_NULL_PTR_ARG(1); + + /** Clears a stall condition on the given pipe, via a CLEAR FEATURE standard request to the attached device. + * + * \note After this routine returns, the control pipe will be selected. + * + * \ingroup Group_PipeControlReq + * + * \param[in] EndpointAddress Address of the endpoint to clear, including the endpoint's direction. + * + * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result. + */ + uint8_t USB_Host_ClearEndpointStall(const uint8_t EndpointAddress); + + /** Selects a given alternative setting for the specified interface, via a SET INTERFACE standard request to + * the attached device. + * + * \note After this routine returns, the control pipe will be selected. + * + * \ingroup Group_PipeControlReq + * + * \param[in] InterfaceIndex Index of the interface whose alternative setting is to be altered. + * \param[in] AltSetting Index of the interface's alternative setting which is to be selected. + * + * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result. + */ + uint8_t USB_Host_SetInterfaceAltSetting(const uint8_t InterfaceIndex, + const uint8_t AltSetting); + + + /** Retrieves the current alternative setting for the specified interface, via a GET INTERFACE standard request to + * the attached device. + * + * \note After this routine returns, the control pipe will be selected. + * + * \ingroup Group_PipeControlReq + * + * \param[in] InterfaceIndex Index of the interface whose alternative setting is to be altered. + * \param[out] AltSetting Pointer to a location where the retrieved alternative setting value should be stored. + * + * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result. + */ + uint8_t USB_Host_GetInterfaceAltSetting(const uint8_t InterfaceIndex, + uint8_t* const AltSetting) ATTR_NON_NULL_PTR_ARG(2); + + /* Inline Functions: */ + /** Sends a GET DESCRIPTOR standard request to the attached device, requesting the device descriptor. + * This can be used to easily retrieve information about the device such as its VID, PID and power + * requirements. This is a convenience wrapper for \ref USB_Host_GetDescriptor(). + * + * \note After this routine returns, the control pipe will be selected. + * + * \ingroup Group_PipeControlReq + * + * \param[out] DeviceDescriptorPtr Pointer to the destination device descriptor structure where + * the read data is to be stored. + * + * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result. + */ + static inline uint8_t USB_Host_GetDeviceDescriptor(USB_Descriptor_Device_t* const DeviceDescriptorPtr) ATTR_NON_NULL_PTR_ARG(1); + static inline uint8_t USB_Host_GetDeviceDescriptor(USB_Descriptor_Device_t* const DeviceDescriptorPtr) + { + return USB_Host_GetDescriptor(DTYPE_Device, 0, DeviceDescriptorPtr, sizeof(USB_Descriptor_Device_t)); + } + + /** Sends a GET DESCRIPTOR standard request to the attached device, requesting the string descriptor + * of the specified index. This can be used to easily retrieve string descriptors from the device by + * index, after the index is obtained from the Device or Configuration descriptors. This is a convenience + * wrapper for \ref USB_Host_GetDescriptor(). + * + * \note After this routine returns, the control pipe will be selected. + * + * \ingroup Group_PipeControlReq + * + * \param[in] Index Index of the string descriptor to retrieve. + * \param[out] Buffer Pointer to the destination buffer where the retrieved string descriptor is + * to be stored. + * \param[in] BufferLength Maximum size of the string descriptor which can be stored into the buffer. + * + * \return A value from the \ref USB_Host_SendControlErrorCodes_t enum to indicate the result. + */ + static inline uint8_t USB_Host_GetDeviceStringDescriptor(const uint8_t Index, + void* const Buffer, + const uint8_t BufferLength) ATTR_NON_NULL_PTR_ARG(2); + static inline uint8_t USB_Host_GetDeviceStringDescriptor(const uint8_t Index, + void* const Buffer, + const uint8_t BufferLength) + { + return USB_Host_GetDescriptor(DTYPE_String, Index, Buffer, BufferLength); + } + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Enums: */ + enum USB_WaitForTypes_t + { + USB_HOST_WAITFOR_SetupSent, + USB_HOST_WAITFOR_InReceived, + USB_HOST_WAITFOR_OutReady, + }; + + /* Function Prototypes: */ + #if defined(__INCLUDE_FROM_HOSTSTDREQ_C) + static uint8_t USB_Host_SendControlRequest_PRV(void* const BufferPtr); + static uint8_t USB_Host_WaitForIOS(const uint8_t WaitType); + #endif + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/OTG.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/OTG.h new file mode 100644 index 00000000..ccd7cc1b --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/OTG.h @@ -0,0 +1,80 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Common USB OTG definitions for all architectures. + * \copydetails Group_OTG + * + * \note This file should not be included directly. It is automatically included as needed by the USB driver + * dispatch header located in LUFA/Drivers/USB/USB.h. + */ + +/** \ingroup Group_USB + * \defgroup Group_OTG USB On The Go (OTG) Management + * \brief USB OTG management definitions. + * + * This module contains macros for embedded USB hosts with dual role On The Go capabilities, for managing role + * exchange. OTG is a way for two USB dual role devices to talk to one another directly without fixed device/host + * roles. + * + * @{ + */ + +#ifndef __USBOTG_H__ +#define __USBOTG_H__ + + /* Includes: */ + #include "../../../Common/Common.h" + #include "USBMode.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_USB_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB/USB.h instead. + #endif + + /* Architecture Includes: */ + #if (ARCH == ARCH_AVR8) + #include "AVR8/OTG_AVR8.h" + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/Pipe.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/Pipe.h new file mode 100644 index 00000000..ce2be549 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/Pipe.h @@ -0,0 +1,144 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Common USB Pipe definitions for all architectures. + * \copydetails Group_PipeManagement + * + * \note This file should not be included directly. It is automatically included as needed by the USB driver + * dispatch header located in LUFA/Drivers/USB/USB.h. + */ + +/** \ingroup Group_PipeManagement + * \defgroup Group_PipeRW Pipe Data Reading and Writing + * \brief Pipe data read/write definitions. + * + * Functions, macros, variables, enums and types related to data reading and writing from and to pipes. + */ + +/** \ingroup Group_PipeRW + * \defgroup Group_PipePrimitiveRW Read/Write of Primitive Data Types + * \brief Pipe data primitive read/write definitions. + * + * Functions, macros, variables, enums and types related to data reading and writing of primitive data types + * from and to pipes. + */ + +/** \ingroup Group_PipeManagement + * \defgroup Group_PipePacketManagement Pipe Packet Management + * \brief Pipe packet management definitions. + * + * Functions, macros, variables, enums and types related to packet management of pipes. + */ + +/** \ingroup Group_PipeManagement + * \defgroup Group_PipeControlReq Pipe Control Request Management + * \brief Pipe control request definitions. + * + * Module for host mode request processing. This module allows for the transmission of standard, class and + * vendor control requests to the default control endpoint of an attached device while in host mode. + * + * \see Chapter 9 of the USB 2.0 specification. + */ + +/** \ingroup Group_USB + * \defgroup Group_PipeManagement Pipe Management + * \brief Pipe management definitions. + * + * This module contains functions, macros and enums related to pipe management when in USB Host mode. This + * module contains the pipe management macros, as well as pipe interrupt and data send/receive functions + * for various data types. + * + * @{ + */ + +#ifndef __PIPE_H__ +#define __PIPE_H__ + + /* Includes: */ + #include "../../../Common/Common.h" + #include "USBMode.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_USB_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB/USB.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Type Defines: */ + /** Type define for a pipe table entry, used to configure pipes in groups via + * \ref Pipe_ConfigurePipeTable(). + */ + typedef struct + { + uint8_t Address; /**< Address of the pipe to configure, or zero if the table entry is to be unused. */ + uint16_t Size; /**< Size of the pipe bank, in bytes. */ + uint8_t EndpointAddress; /** Address of the endpoint in the connected device. */ + uint8_t Type; /**< Type of the endpoint, a \c EP_TYPE_* mask. */ + uint8_t Banks; /**< Number of hardware banks to use for the pipe. */ + } USB_Pipe_Table_t; + + /* Macros: */ + /** Pipe address for the default control pipe, which always resides in address 0. This is + * defined for convenience to give more readable code when used with the pipe macros. + */ + #define PIPE_CONTROLPIPE 0 + + /** Pipe number mask, for masking against pipe addresses to retrieve the pipe's numerical address + * in the device. + */ + #define PIPE_PIPENUM_MASK 0x0F + + /** Endpoint number mask, for masking against endpoint addresses to retrieve the endpoint's + * numerical address in the attached device. + */ + #define PIPE_EPNUM_MASK 0x0F + + /* Architecture Includes: */ + #if (ARCH == ARCH_AVR8) + #include "AVR8/Pipe_AVR8.h" + #elif (ARCH == ARCH_UC3) + #include "UC3/Pipe_UC3.h" + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/PipeStream.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/PipeStream.h new file mode 100644 index 00000000..002d6ff1 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/PipeStream.h @@ -0,0 +1,100 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Pipe data stream transmission and reception management. + * \copydetails Group_PipeStreamRW + * + * \note This file should not be included directly. It is automatically included as needed by the USB driver + * dispatch header located in LUFA/Drivers/USB/USB.h. + */ + +/** \ingroup Group_PipeRW + * \defgroup Group_PipeStreamRW Read/Write of Multi-Byte Streams + * \brief Pipe data stream transmission and reception management. + * + * Functions, macros, variables, enums and types related to data reading and writing of data streams from + * and to pipes. + * + * @{ + */ + +#ifndef __PIPE_STREAM_H__ +#define __PIPE_STREAM_H__ + + /* Includes: */ + #include "../../../Common/Common.h" + #include "USBMode.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_USB_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB/USB.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Enums: */ + /** Enum for the possible error return codes of the Pipe_*_Stream_* functions. */ + enum Pipe_Stream_RW_ErrorCodes_t + { + PIPE_RWSTREAM_NoError = 0, /**< Command completed successfully, no error. */ + PIPE_RWSTREAM_PipeStalled = 1, /**< The device stalled the pipe during the transfer. */ + PIPE_RWSTREAM_DeviceDisconnected = 2, /**< Device was disconnected from the host during + * the transfer. + */ + PIPE_RWSTREAM_Timeout = 3, /**< The device failed to accept or send the next packet + * within the software timeout period set by the + * \ref USB_STREAM_TIMEOUT_MS macro. + */ + PIPE_RWSTREAM_IncompleteTransfer = 4, /**< Indicates that the pipe bank became full/empty before the + * complete contents of the stream could be transferred. + */ + }; + + /* Architecture Includes: */ + #if (ARCH == ARCH_AVR8) + #include "AVR8/PipeStream_AVR8.h" + #elif (ARCH == ARCH_UC3) + #include "UC3/PipeStream_UC3.h" + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/StdDescriptors.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/StdDescriptors.h new file mode 100644 index 00000000..012399e9 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/StdDescriptors.h @@ -0,0 +1,739 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Common standard USB Descriptor definitions for all architectures. + * \copydetails Group_StdDescriptors + * + * \note This file should not be included directly. It is automatically included as needed by the USB driver + * dispatch header located in LUFA/Drivers/USB/USB.h. + */ + +/** \ingroup Group_USB + * \defgroup Group_StdDescriptors USB Descriptors + * \brief Standard USB Descriptor definitions. + * + * Standard USB device descriptor defines and retrieval routines, for USB devices. This module contains + * structures and macros for the easy creation of standard USB descriptors in USB device projects. + * + * @{ + */ + +#ifndef __USBDESCRIPTORS_H__ +#define __USBDESCRIPTORS_H__ + + /* Includes: */ + #include "../../../Common/Common.h" + #include "USBMode.h" + #include "Events.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_USB_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB/USB.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Indicates that a given descriptor does not exist in the device. This can be used inside descriptors + * for string descriptor indexes, or may be use as a return value for GetDescriptor when the specified + * descriptor does not exist. + */ + #define NO_DESCRIPTOR 0 + + /** Macro to calculate the power value for the configuration descriptor, from a given number of milliamperes. + * + * \param[in] mA Maximum number of milliamps the device consumes when the given configuration is selected. + */ + #define USB_CONFIG_POWER_MA(mA) ((mA) >> 1) + + /** Macro to calculate the Unicode length of a string with a given number of Unicode characters. + * Should be used in string descriptor's headers for giving the string descriptor's byte length. + * + * \param[in] UnicodeChars Number of Unicode characters in the string text. + */ + #define USB_STRING_LEN(UnicodeChars) (sizeof(USB_Descriptor_Header_t) + ((UnicodeChars) << 1)) + + /** Macro to encode a given four digit floating point version number (e.g. 01.23) into Binary Coded + * Decimal format for descriptor fields requiring BCD encoding, such as the USB version number in the + * standard device descriptor. + * + * \note This value is automatically converted into Little Endian, suitable for direct use inside device + * descriptors on all architectures without endianness conversion macros. + * + * \param[in] x Version number to encode as a 16-bit little-endian number, as a floating point number. + */ + #define VERSION_BCD(x) CPU_TO_LE16((VERSION_TENS(x) << 12) | (VERSION_ONES(x) << 8) | \ + (VERSION_TENTHS(x) << 4) | (VERSION_HUNDREDTHS(x) << 0) ) + + /** String language ID for the English language. Should be used in \ref USB_Descriptor_String_t descriptors + * to indicate that the English language is supported by the device in its string descriptors. + */ + #define LANGUAGE_ID_ENG 0x0409 + + /** \name USB Configuration Descriptor Attribute Masks */ + //@{ + /** Mask for the reserved bit in the Configuration Descriptor's \c ConfigAttributes field, which must be set on all + * devices for historical purposes. + */ + #define USB_CONFIG_ATTR_RESERVED 0x80 + + /** Can be masked with other configuration descriptor attributes for a \ref USB_Descriptor_Configuration_Header_t + * descriptor's \c ConfigAttributes value to indicate that the specified configuration can draw its power + * from the device's own power source. + */ + #define USB_CONFIG_ATTR_SELFPOWERED 0x40 + + /** Can be masked with other configuration descriptor attributes for a \ref USB_Descriptor_Configuration_Header_t + * descriptor's \c ConfigAttributes value to indicate that the specified configuration supports the + * remote wakeup feature of the USB standard, allowing a suspended USB device to wake up the host upon + * request. + */ + #define USB_CONFIG_ATTR_REMOTEWAKEUP 0x20 + //@} + + /** \name Endpoint Descriptor Attribute Masks */ + //@{ + /** Can be masked with other endpoint descriptor attributes for a \ref USB_Descriptor_Endpoint_t descriptor's + * \c Attributes value to indicate that the specified endpoint is not synchronized. + * + * \see The USB specification for more details on the possible Endpoint attributes. + */ + #define ENDPOINT_ATTR_NO_SYNC (0 << 2) + + /** Can be masked with other endpoint descriptor attributes for a \ref USB_Descriptor_Endpoint_t descriptor's + * \c Attributes value to indicate that the specified endpoint is asynchronous. + * + * \see The USB specification for more details on the possible Endpoint attributes. + */ + #define ENDPOINT_ATTR_ASYNC (1 << 2) + + /** Can be masked with other endpoint descriptor attributes for a \ref USB_Descriptor_Endpoint_t descriptor's + * \c Attributes value to indicate that the specified endpoint is adaptive. + * + * \see The USB specification for more details on the possible Endpoint attributes. + */ + #define ENDPOINT_ATTR_ADAPTIVE (2 << 2) + + /** Can be masked with other endpoint descriptor attributes for a \ref USB_Descriptor_Endpoint_t descriptor's + * \c Attributes value to indicate that the specified endpoint is synchronized. + * + * \see The USB specification for more details on the possible Endpoint attributes. + */ + #define ENDPOINT_ATTR_SYNC (3 << 2) + //@} + + /** \name Endpoint Descriptor Usage Masks */ + //@{ + /** Can be masked with other endpoint descriptor attributes for a \ref USB_Descriptor_Endpoint_t descriptor's + * \c Attributes value to indicate that the specified endpoint is used for data transfers. + * + * \see The USB specification for more details on the possible Endpoint usage attributes. + */ + #define ENDPOINT_USAGE_DATA (0 << 4) + + /** Can be masked with other endpoint descriptor attributes for a \ref USB_Descriptor_Endpoint_t descriptor's + * \c Attributes value to indicate that the specified endpoint is used for feedback. + * + * \see The USB specification for more details on the possible Endpoint usage attributes. + */ + #define ENDPOINT_USAGE_FEEDBACK (1 << 4) + + /** Can be masked with other endpoint descriptor attributes for a \ref USB_Descriptor_Endpoint_t descriptor's + * \c Attributes value to indicate that the specified endpoint is used for implicit feedback. + * + * \see The USB specification for more details on the possible Endpoint usage attributes. + */ + #define ENDPOINT_USAGE_IMPLICIT_FEEDBACK (2 << 4) + //@} + + /* Enums: */ + /** Enum for the possible standard descriptor types, as given in each descriptor's header. */ + enum USB_DescriptorTypes_t + { + DTYPE_Device = 0x01, /**< Indicates that the descriptor is a device descriptor. */ + DTYPE_Configuration = 0x02, /**< Indicates that the descriptor is a configuration descriptor. */ + DTYPE_String = 0x03, /**< Indicates that the descriptor is a string descriptor. */ + DTYPE_Interface = 0x04, /**< Indicates that the descriptor is an interface descriptor. */ + DTYPE_Endpoint = 0x05, /**< Indicates that the descriptor is an endpoint descriptor. */ + DTYPE_DeviceQualifier = 0x06, /**< Indicates that the descriptor is a device qualifier descriptor. */ + DTYPE_Other = 0x07, /**< Indicates that the descriptor is of other type. */ + DTYPE_InterfacePower = 0x08, /**< Indicates that the descriptor is an interface power descriptor. */ + DTYPE_InterfaceAssociation = 0x0B, /**< Indicates that the descriptor is an interface association descriptor. */ + DTYPE_CSInterface = 0x24, /**< Indicates that the descriptor is a class specific interface descriptor. */ + DTYPE_CSEndpoint = 0x25, /**< Indicates that the descriptor is a class specific endpoint descriptor. */ + }; + + /** Enum for possible Class, Subclass and Protocol values of device and interface descriptors. */ + enum USB_Descriptor_ClassSubclassProtocol_t + { + USB_CSCP_NoDeviceClass = 0x00, /**< Descriptor Class value indicating that the device does not belong + * to a particular class at the device level. + */ + USB_CSCP_NoDeviceSubclass = 0x00, /**< Descriptor Subclass value indicating that the device does not belong + * to a particular subclass at the device level. + */ + USB_CSCP_NoDeviceProtocol = 0x00, /**< Descriptor Protocol value indicating that the device does not belong + * to a particular protocol at the device level. + */ + USB_CSCP_VendorSpecificClass = 0xFF, /**< Descriptor Class value indicating that the device/interface belongs + * to a vendor specific class. + */ + USB_CSCP_VendorSpecificSubclass = 0xFF, /**< Descriptor Subclass value indicating that the device/interface belongs + * to a vendor specific subclass. + */ + USB_CSCP_VendorSpecificProtocol = 0xFF, /**< Descriptor Protocol value indicating that the device/interface belongs + * to a vendor specific protocol. + */ + USB_CSCP_IADDeviceClass = 0xEF, /**< Descriptor Class value indicating that the device belongs to the + * Interface Association Descriptor class. + */ + USB_CSCP_IADDeviceSubclass = 0x02, /**< Descriptor Subclass value indicating that the device belongs to the + * Interface Association Descriptor subclass. + */ + USB_CSCP_IADDeviceProtocol = 0x01, /**< Descriptor Protocol value indicating that the device belongs to the + * Interface Association Descriptor protocol. + */ + }; + + /* Type Defines: */ + /** \brief Standard USB Descriptor Header (LUFA naming conventions). + * + * Type define for all descriptors' standard header, indicating the descriptor's length and type. This structure + * uses LUFA-specific element names to make each element's purpose clearer. + * + * \see \ref USB_StdDescriptor_Header_t for the version of this type with standard element names. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + uint8_t Size; /**< Size of the descriptor, in bytes. */ + uint8_t Type; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value + * given by the specific class. + */ + } ATTR_PACKED USB_Descriptor_Header_t; + + /** \brief Standard USB Descriptor Header (USB-IF naming conventions). + * + * Type define for all descriptors' standard header, indicating the descriptor's length and type. This structure + * uses the relevant standard's given element names to ensure compatibility with the standard. + * + * \see \ref USB_Descriptor_Header_t for the version of this type with non-standard LUFA specific element names. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + uint8_t bLength; /**< Size of the descriptor, in bytes. */ + uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value + * given by the specific class. + */ + } ATTR_PACKED USB_StdDescriptor_Header_t; + + /** \brief Standard USB Device Descriptor (LUFA naming conventions). + * + * Type define for a standard Device Descriptor. This structure uses LUFA-specific element names to make each + * element's purpose clearer. + * + * \see \ref USB_StdDescriptor_Device_t for the version of this type with standard element names. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + USB_Descriptor_Header_t Header; /**< Descriptor header, including type and size. */ + + uint16_t USBSpecification; /**< BCD of the supported USB specification. */ + uint8_t Class; /**< USB device class. */ + uint8_t SubClass; /**< USB device subclass. */ + uint8_t Protocol; /**< USB device protocol. */ + + uint8_t Endpoint0Size; /**< Size of the control (address 0) endpoint's bank in bytes. */ + + uint16_t VendorID; /**< Vendor ID for the USB product. */ + uint16_t ProductID; /**< Unique product ID for the USB product. */ + uint16_t ReleaseNumber; /**< Product release (version) number. */ + + uint8_t ManufacturerStrIndex; /**< String index for the manufacturer's name. The + * host will request this string via a separate + * control request for the string descriptor. + * + * \note If no string supplied, use \ref NO_DESCRIPTOR. + */ + uint8_t ProductStrIndex; /**< String index for the product name/details. + * + * \see ManufacturerStrIndex structure entry. + */ + uint8_t SerialNumStrIndex; /**< String index for the product's globally unique hexadecimal + * serial number, in uppercase Unicode ASCII. + * + * \note On some microcontroller models, there is an embedded serial number + * in the chip which can be used for the device serial number. + * To use this serial number, set this to USE_INTERNAL_SERIAL. + * On unsupported devices, this will evaluate to 0 and will cause + * the host to generate a pseudo-unique value for the device upon + * insertion. + * + * \see ManufacturerStrIndex structure entry. + */ + uint8_t NumberOfConfigurations; /**< Total number of configurations supported by + * the device. + */ + } ATTR_PACKED USB_Descriptor_Device_t; + + /** \brief Standard USB Device Descriptor (USB-IF naming conventions). + * + * Type define for a standard Device Descriptor. This structure uses the relevant standard's given element names + * to ensure compatibility with the standard. + * + * \see \ref USB_Descriptor_Device_t for the version of this type with non-standard LUFA specific element names. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + uint8_t bLength; /**< Size of the descriptor, in bytes. */ + uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value + * given by the specific class. + */ + uint16_t bcdUSB; /**< BCD of the supported USB specification. */ + 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. */ + uint8_t iManufacturer; /**< String index for the manufacturer's name. The + * host will request this string via a separate + * control request for the string descriptor. + * + * \note If no string supplied, use \ref NO_DESCRIPTOR. + */ + uint8_t iProduct; /**< String index for the product name/details. + * + * \see ManufacturerStrIndex structure entry. + */ + uint8_t iSerialNumber; /**< String index for the product's globally unique hexadecimal + * serial number, in uppercase Unicode ASCII. + * + * \note On some microcontroller models, there is an embedded serial number + * in the chip which can be used for the device serial number. + * To use this serial number, set this to USE_INTERNAL_SERIAL. + * On unsupported devices, this will evaluate to 0 and will cause + * the host to generate a pseudo-unique value for the device upon + * insertion. + * + * \see ManufacturerStrIndex structure entry. + */ + uint8_t bNumConfigurations; /**< Total number of configurations supported by + * the device. + */ + } ATTR_PACKED USB_StdDescriptor_Device_t; + + /** \brief Standard USB Device Qualifier Descriptor (LUFA naming conventions). + * + * Type define for a standard Device Qualifier Descriptor. This structure uses LUFA-specific element names + * to make each element's purpose clearer. + * + * \see \ref USB_StdDescriptor_DeviceQualifier_t for the version of this type with standard element names. + */ + typedef struct + { + USB_Descriptor_Header_t Header; /**< Descriptor header, including type and size. */ + + uint16_t USBSpecification; /**< BCD of the supported USB specification. */ + uint8_t Class; /**< USB device class. */ + uint8_t SubClass; /**< USB device subclass. */ + uint8_t Protocol; /**< USB device protocol. */ + + uint8_t Endpoint0Size; /**< Size of the control (address 0) endpoint's bank in bytes. */ + uint8_t NumberOfConfigurations; /**< Total number of configurations supported by + * the device. + */ + uint8_t Reserved; /**< Reserved for future use, must be 0. */ + } ATTR_PACKED USB_Descriptor_DeviceQualifier_t; + + /** \brief Standard USB Device Qualifier Descriptor (USB-IF naming conventions). + * + * Type define for a standard Device Qualifier Descriptor. This structure uses the relevant standard's given element names + * to ensure compatibility with the standard. + * + * \see \ref USB_Descriptor_DeviceQualifier_t for the version of this type with non-standard LUFA specific element names. + */ + typedef struct + { + uint8_t bLength; /**< Size of the descriptor, in bytes. */ + uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value + * given by the specific class. + */ + uint16_t bcdUSB; /**< BCD of the supported USB specification. */ + 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. */ + } ATTR_PACKED USB_StdDescriptor_DeviceQualifier_t; + + /** \brief Standard USB Configuration Descriptor (LUFA naming conventions). + * + * Type define for a standard Configuration Descriptor header. This structure uses LUFA-specific element names + * to make each element's purpose clearer. + * + * \see \ref USB_StdDescriptor_Configuration_Header_t for the version of this type with standard element names. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + USB_Descriptor_Header_t Header; /**< Descriptor header, including type and size. */ + + uint16_t TotalConfigurationSize; /**< Size of the configuration descriptor header, + * and all sub descriptors inside the configuration. + */ + uint8_t TotalInterfaces; /**< Total number of interfaces in the configuration. */ + + uint8_t ConfigurationNumber; /**< Configuration index of the current configuration. */ + uint8_t ConfigurationStrIndex; /**< Index of a string descriptor describing the configuration. */ + + uint8_t ConfigAttributes; /**< 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 MaxPowerConsumption; /**< Maximum power consumption of the device while in the + * current configuration, calculated by the \ref USB_CONFIG_POWER_MA() + * macro. + */ + } ATTR_PACKED USB_Descriptor_Configuration_Header_t; + + /** \brief Standard USB Configuration Descriptor (USB-IF naming conventions). + * + * Type define for a standard Configuration Descriptor header. This structure uses the relevant standard's given element names + * to ensure compatibility with the standard. + * + * \see \ref USB_Descriptor_Device_t for the version of this type with non-standard LUFA specific element names. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + uint8_t bLength; /**< Size of the descriptor, in bytes. */ + uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value + * given by the specific class. + */ + 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_CONFIG_POWER_MA() + * macro. + */ + } ATTR_PACKED USB_StdDescriptor_Configuration_Header_t; + + /** \brief Standard USB Interface Descriptor (LUFA naming conventions). + * + * Type define for a standard Interface Descriptor. This structure uses LUFA-specific element names + * to make each element's purpose clearer. + * + * \see \ref USB_StdDescriptor_Interface_t for the version of this type with standard element names. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + USB_Descriptor_Header_t Header; /**< Descriptor header, including type and size. */ + + uint8_t InterfaceNumber; /**< Index of the interface in the current configuration. */ + uint8_t AlternateSetting; /**< Alternate setting for the interface number. The same + * interface number can have multiple alternate settings + * with different endpoint configurations, which can be + * selected by the host. + */ + uint8_t TotalEndpoints; /**< Total number of endpoints in the interface. */ + + uint8_t Class; /**< Interface class ID. */ + uint8_t SubClass; /**< Interface subclass ID. */ + uint8_t Protocol; /**< Interface protocol ID. */ + + uint8_t InterfaceStrIndex; /**< Index of the string descriptor describing the interface. */ + } ATTR_PACKED USB_Descriptor_Interface_t; + + /** \brief Standard USB Interface Descriptor (USB-IF naming conventions). + * + * Type define for a standard Interface Descriptor. This structure uses the relevant standard's given element names + * to ensure compatibility with the standard. + * + * \see \ref USB_Descriptor_Interface_t for the version of this type with non-standard LUFA specific element names. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + uint8_t bLength; /**< Size of the descriptor, in bytes. */ + uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value + * given by the specific class. + */ + uint8_t bInterfaceNumber; /**< Index of the interface in the current configuration. */ + uint8_t bAlternateSetting; /**< Alternate setting for the interface number. The same + * interface number can have multiple alternate settings + * with different endpoint configurations, which can be + * selected by the host. + */ + 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. + */ + } ATTR_PACKED USB_StdDescriptor_Interface_t; + + /** \brief Standard USB Interface Association Descriptor (LUFA naming conventions). + * + * Type define for a standard Interface Association Descriptor. This structure uses LUFA-specific element names + * to make each element's purpose clearer. + * + * This descriptor has been added as a supplement to the USB2.0 standard, in the ECN located at + * http://www.usb.org/developers/docs/InterfaceAssociationDescriptor_ecn.pdf. It allows composite + * devices with multiple interfaces related to the same function to have the multiple interfaces bound + * together at the point of enumeration, loading one generic driver for all the interfaces in the single + * function. Read the ECN for more information. + * + * \see \ref USB_StdDescriptor_Interface_Association_t for the version of this type with standard element names. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + USB_Descriptor_Header_t Header; /**< Descriptor header, including type and size. */ + + uint8_t FirstInterfaceIndex; /**< Index of the first associated interface. */ + uint8_t TotalInterfaces; /**< Total number of associated interfaces. */ + + uint8_t Class; /**< Interface class ID. */ + uint8_t SubClass; /**< Interface subclass ID. */ + uint8_t Protocol; /**< Interface protocol ID. */ + + uint8_t IADStrIndex; /**< Index of the string descriptor describing the + * interface association. + */ + } ATTR_PACKED USB_Descriptor_Interface_Association_t; + + /** \brief Standard USB Interface Association Descriptor (USB-IF naming conventions). + * + * Type define for a standard Interface Association Descriptor. This structure uses the relevant standard's given + * element names to ensure compatibility with the standard. + * + * This descriptor has been added as a supplement to the USB2.0 standard, in the ECN located at + * http://www.usb.org/developers/docs/InterfaceAssociationDescriptor_ecn.pdf. It allows composite + * devices with multiple interfaces related to the same function to have the multiple interfaces bound + * together at the point of enumeration, loading one generic driver for all the interfaces in the single + * function. Read the ECN for more information. + * + * \see \ref USB_Descriptor_Interface_Association_t for the version of this type with non-standard LUFA specific + * element names. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + uint8_t bLength; /**< Size of the descriptor, in bytes. */ + uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a value + * given by the specific class. + */ + 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. + */ + } ATTR_PACKED USB_StdDescriptor_Interface_Association_t; + + /** \brief Standard USB Endpoint Descriptor (LUFA naming conventions). + * + * Type define for a standard Endpoint Descriptor. This structure uses LUFA-specific element names + * to make each element's purpose clearer. + * + * \see \ref USB_StdDescriptor_Endpoint_t for the version of this type with standard element names. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + USB_Descriptor_Header_t Header; /**< Descriptor header, including type and size. */ + + uint8_t EndpointAddress; /**< Logical address of the endpoint within the device for the current + * configuration, including direction mask. + */ + uint8_t Attributes; /**< Endpoint attributes, comprised of a mask of the endpoint type (EP_TYPE_*) + * and attributes (ENDPOINT_ATTR_*) masks. + */ + uint16_t EndpointSize; /**< Size of the endpoint bank, in bytes. This indicates the maximum packet + * size that the endpoint can receive at a time. + */ + uint8_t PollingIntervalMS; /**< Polling interval in milliseconds for the endpoint if it is an INTERRUPT + * or ISOCHRONOUS type. + */ + } ATTR_PACKED USB_Descriptor_Endpoint_t; + + /** \brief Standard USB Endpoint Descriptor (USB-IF naming conventions). + * + * Type define for a standard Endpoint Descriptor. This structure uses the relevant standard's given + * element names to ensure compatibility with the standard. + * + * \see \ref USB_Descriptor_Endpoint_t for the version of this type with non-standard LUFA specific + * element names. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + uint8_t bLength; /**< Size of the descriptor, in bytes. */ + uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t or a + * value given by the specific class. + */ + uint8_t bEndpointAddress; /**< Logical address of the endpoint within the device for the current + * configuration, including direction mask. + */ + uint8_t bmAttributes; /**< Endpoint attributes, comprised of a mask of the endpoint type (EP_TYPE_*) + * and attributes (ENDPOINT_ATTR_*) masks. + */ + 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. + */ + } ATTR_PACKED USB_StdDescriptor_Endpoint_t; + + /** \brief Standard USB String Descriptor (LUFA naming conventions). + * + * Type define for a standard string descriptor. Unlike other standard descriptors, the length + * of the descriptor for placement in the descriptor header must be determined by the \ref USB_STRING_LEN() + * macro rather than by the size of the descriptor structure, as the length is not fixed. + * + * This structure should also be used for string index 0, which contains the supported language IDs for + * the device as an array. + * + * This structure uses LUFA-specific element names to make each element's purpose clearer. + * + * \see \ref USB_StdDescriptor_String_t for the version of this type with standard element names. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + USB_Descriptor_Header_t Header; /**< Descriptor header, including type and size. */ + + #if (((ARCH == ARCH_AVR8) || (ARCH == ARCH_XMEGA)) && !defined(__DOXYGEN__)) + wchar_t UnicodeString[]; + #else + uint16_t UnicodeString[]; /**< String data, as unicode characters (alternatively, + * string language IDs). If normal ASCII characters are + * to be used, they must be added as an array of characters + * rather than a normal C string so that they are widened to + * Unicode size. + * + * Under GCC, strings prefixed with the "L" character (before + * the opening string quotation mark) are considered to be + * Unicode strings, and may be used instead of an explicit + * array of ASCII characters on little endian devices with + * UTF-16-LE \c wchar_t encoding. + */ + #endif + } ATTR_PACKED USB_Descriptor_String_t; + + /** \brief Standard USB String Descriptor (USB-IF naming conventions). + * + * Type define for a standard string descriptor. Unlike other standard descriptors, the length + * of the descriptor for placement in the descriptor header must be determined by the \ref USB_STRING_LEN() + * macro rather than by the size of the descriptor structure, as the length is not fixed. + * + * This structure should also be used for string index 0, which contains the supported language IDs for + * the device as an array. + * + * This structure uses the relevant standard's given element names to ensure compatibility with the standard. + * + * \see \ref USB_Descriptor_String_t for the version of this type with with non-standard LUFA specific + * element names. + * + * \note Regardless of CPU architecture, these values should be stored as little endian. + */ + typedef struct + { + uint8_t bLength; /**< Size of the descriptor, in bytes. */ + uint8_t bDescriptorType; /**< Type of the descriptor, either a value in \ref USB_DescriptorTypes_t + * or a value given by the specific class. + */ + uint16_t bString[]; /**< String data, as unicode characters (alternatively, string language IDs). + * If normal ASCII characters are to be used, they must be added as an array + * of characters rather than a normal C string so that they are widened to + * Unicode size. + * + * Under GCC, strings prefixed with the "L" character (before the opening string + * quotation mark) are considered to be Unicode strings, and may be used instead + * of an explicit array of ASCII characters. + */ + } ATTR_PACKED USB_StdDescriptor_String_t; + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Macros: */ + #define VERSION_TENS(x) (int)((int)(x) / 10) + #define VERSION_ONES(x) (int)((int)(x) % 10) + #define VERSION_TENTHS(x) (int)(((x * 1) - ((int)(x * 1))) * 10) + #define VERSION_HUNDREDTHS(x) (int)(((x * 10) - ((int)(x * 10))) * 10) + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/StdRequestType.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/StdRequestType.h new file mode 100644 index 00000000..a841f8f3 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/StdRequestType.h @@ -0,0 +1,258 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief USB control endpoint request definitions. + * \copydetails Group_StdRequest + * + * \note This file should not be included directly. It is automatically included as needed by the USB driver + * dispatch header located in LUFA/Drivers/USB/USB.h. + */ + +/** \ingroup Group_USB + * \defgroup Group_StdRequest Standard USB Requests + * \brief USB control endpoint request definitions. + * + * This module contains definitions for the various control request parameters, so that the request + * details (such as data direction, request recipient, etc.) can be extracted via masking. + * + * @{ + */ + +#ifndef __STDREQTYPE_H__ +#define __STDREQTYPE_H__ + + /* Includes: */ + #include "../../../Common/Common.h" + #include "USBMode.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_USB_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB/USB.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Mask for the request type parameter, to indicate the direction of the request data (Host to Device + * or Device to Host). The result of this mask should then be compared to the request direction masks. + * + * \see \c REQDIR_* macros for masks indicating the request data direction. + */ + #define CONTROL_REQTYPE_DIRECTION 0x80 + + /** Mask for the request type parameter, to indicate the type of request (Device, Class or Vendor + * Specific). The result of this mask should then be compared to the request type masks. + * + * \see \c REQTYPE_* macros for masks indicating the request type. + */ + #define CONTROL_REQTYPE_TYPE 0x60 + + /** Mask for the request type parameter, to indicate the recipient of the request (Device, Interface + * Endpoint or Other). The result of this mask should then be compared to the request recipient + * masks. + * + * \see \c REQREC_* macros for masks indicating the request recipient. + */ + #define CONTROL_REQTYPE_RECIPIENT 0x1F + + /** \name Control Request Data Direction Masks */ + //@{ + /** Request data direction mask, indicating that the request data will flow from host to device. + * + * \see \ref CONTROL_REQTYPE_DIRECTION macro. + */ + #define REQDIR_HOSTTODEVICE (0 << 7) + + /** Request data direction mask, indicating that the request data will flow from device to host. + * + * \see \ref CONTROL_REQTYPE_DIRECTION macro. + */ + #define REQDIR_DEVICETOHOST (1 << 7) + //@} + + /** \name Control Request Type Masks */ + //@{ + /** Request type mask, indicating that the request is a standard request. + * + * \see \ref CONTROL_REQTYPE_TYPE macro. + */ + #define REQTYPE_STANDARD (0 << 5) + + /** Request type mask, indicating that the request is a class-specific request. + * + * \see \ref CONTROL_REQTYPE_TYPE macro. + */ + #define REQTYPE_CLASS (1 << 5) + + /** Request type mask, indicating that the request is a vendor specific request. + * + * \see \ref CONTROL_REQTYPE_TYPE macro. + */ + #define REQTYPE_VENDOR (2 << 5) + //@} + + /** \name Control Request Recipient Masks */ + //@{ + /** Request recipient mask, indicating that the request is to be issued to the device as a whole. + * + * \see \ref CONTROL_REQTYPE_RECIPIENT macro. + */ + #define REQREC_DEVICE (0 << 0) + + /** Request recipient mask, indicating that the request is to be issued to an interface in the + * currently selected configuration. + * + * \see \ref CONTROL_REQTYPE_RECIPIENT macro. + */ + #define REQREC_INTERFACE (1 << 0) + + /** Request recipient mask, indicating that the request is to be issued to an endpoint in the + * currently selected configuration. + * + * \see \ref CONTROL_REQTYPE_RECIPIENT macro. + */ + #define REQREC_ENDPOINT (2 << 0) + + /** Request recipient mask, indicating that the request is to be issued to an unspecified element + * in the currently selected configuration. + * + * \see \ref CONTROL_REQTYPE_RECIPIENT macro. + */ + #define REQREC_OTHER (3 << 0) + //@} + + /* Type Defines: */ + /** \brief Standard USB Control Request + * + * Type define for a standard USB control request. + * + * \see The USB 2.0 specification for more information on standard control requests. + */ + typedef struct + { + uint8_t bmRequestType; /**< Type of the request. */ + uint8_t bRequest; /**< Request command code. */ + uint16_t wValue; /**< wValue parameter of the request. */ + uint16_t wIndex; /**< wIndex parameter of the request. */ + uint16_t wLength; /**< Length of the data to transfer in bytes. */ + } ATTR_PACKED USB_Request_Header_t; + + /* Enums: */ + /** Enumeration for the various standard request commands. These commands are applicable when the + * request type is \ref REQTYPE_STANDARD (with the exception of \ref REQ_GetDescriptor, which is always + * handled regardless of the request type value). + * + * \see Chapter 9 of the USB 2.0 Specification. + */ + enum USB_Control_Request_t + { + REQ_GetStatus = 0, /**< Implemented in the library for device and endpoint recipients. Passed + * to the user application for other recipients via the + * \ref EVENT_USB_Device_ControlRequest() event when received in + * device mode. */ + REQ_ClearFeature = 1, /**< Implemented in the library for device and endpoint recipients. Passed + * to the user application for other recipients via the + * \ref EVENT_USB_Device_ControlRequest() event when received in + * device mode. */ + REQ_SetFeature = 3, /**< Implemented in the library for device and endpoint recipients. Passed + * to the user application for other recipients via the + * \ref EVENT_USB_Device_ControlRequest() event when received in + * device mode. */ + REQ_SetAddress = 5, /**< Implemented in the library for the device recipient. Passed + * to the user application for other recipients via the + * \ref EVENT_USB_Device_ControlRequest() event when received in + * device mode. */ + REQ_GetDescriptor = 6, /**< Implemented in the library for device and interface recipients. Passed to the + * user application for other recipients via the + * \ref EVENT_USB_Device_ControlRequest() event when received in + * device mode. */ + REQ_SetDescriptor = 7, /**< Not implemented in the library, passed to the user application + * via the \ref EVENT_USB_Device_ControlRequest() event when received in + * device mode. */ + REQ_GetConfiguration = 8, /**< Implemented in the library for the device recipient. Passed + * to the user application for other recipients via the + * \ref EVENT_USB_Device_ControlRequest() event when received in + * device mode. */ + REQ_SetConfiguration = 9, /**< Implemented in the library for the device recipient. Passed + * to the user application for other recipients via the + * \ref EVENT_USB_Device_ControlRequest() event when received in + * device mode. */ + REQ_GetInterface = 10, /**< Not implemented in the library, passed to the user application + * via the \ref EVENT_USB_Device_ControlRequest() event when received in + * device mode. */ + REQ_SetInterface = 11, /**< Not implemented in the library, passed to the user application + * via the \ref EVENT_USB_Device_ControlRequest() event when received in + * device mode. */ + REQ_SynchFrame = 12, /**< Not implemented in the library, passed to the user application + * via the \ref EVENT_USB_Device_ControlRequest() event when received in + * device mode. */ + }; + + /** Feature Selector values for Set Feature and Clear Feature standard control requests directed to the device, interface + * and endpoint recipients. + */ + enum USB_Feature_Selectors_t + { + FEATURE_SEL_EndpointHalt = 0x00, /**< Feature selector for Clear Feature or Set Feature commands. When + * used in a Set Feature or Clear Feature request this indicates that an + * endpoint (whose address is given elsewhere in the request) should have + * its stall condition changed. + */ + FEATURE_SEL_DeviceRemoteWakeup = 0x01, /**< Feature selector for Device level Remote Wakeup enable set or clear. + * This feature can be controlled by the host on devices which indicate + * remote wakeup support in their descriptors to selectively disable or + * enable remote wakeup. + */ + FEATURE_SEL_TestMode = 0x02, /**< Feature selector for Test Mode features, used to test the USB controller + * to check for incorrect operation. + */ + }; + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Macros: */ + #define FEATURE_SELFPOWERED_ENABLED (1 << 0) + #define FEATURE_REMOTE_WAKEUP_ENABLED (1 << 1) + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/Device_UC3.c b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/Device_UC3.c new file mode 100644 index 00000000..b7c186e8 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/Device_UC3.c @@ -0,0 +1,51 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#include "../../../../Common/Common.h" +#if (ARCH == ARCH_UC3) + +#define __INCLUDE_FROM_USB_DRIVER +#include "../USBMode.h" + +#if defined(USB_CAN_BE_DEVICE) + +#include "../Device.h" + +void USB_Device_SendRemoteWakeup(void) +{ + USB_CLK_Unfreeze(); + + AVR32_USBB.UDCON.rmwkup = true; + while (AVR32_USBB.UDCON.rmwkup); +} + +#endif + +#endif diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/Device_UC3.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/Device_UC3.h new file mode 100644 index 00000000..7139d51f --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/Device_UC3.h @@ -0,0 +1,260 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief USB Device definitions for the AVR32 UC3 microcontrollers. + * \copydetails Group_Device_UC3 + * + * \note This file should not be included directly. It is automatically included as needed by the USB driver + * dispatch header located in LUFA/Drivers/USB/USB.h. + */ + +/** \ingroup Group_Device + * \defgroup Group_Device_UC3 Device Management (UC3) + * \brief USB Device definitions for the AVR32 UC3 microcontrollers. + * + * Architecture specific USB Device definitions for the Atmel 32-bit UC3 AVR microcontrollers. + * + * @{ + */ + +#ifndef __USBDEVICE_UC3_H__ +#define __USBDEVICE_UC3_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + #include "../USBController.h" + #include "../StdDescriptors.h" + #include "../USBInterrupt.h" + #include "../Endpoint.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_USB_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB/USB.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** \name USB Device Mode Option Masks */ + //@{ + /** Mask for the Options parameter of the \ref USB_Init() function. This indicates that the + * USB interface should be initialized in low speed (1.5Mb/s) mode. + * + * \note Restrictions apply on the number, size and type of endpoints which can be used + * when running in low speed mode - please refer to the USB 2.0 specification. + */ + #define USB_DEVICE_OPT_LOWSPEED (1 << 0) + + /** Mask for the Options parameter of the \ref USB_Init() function. This indicates that the + * USB interface should be initialized in full speed (12Mb/s) mode. + */ + #define USB_DEVICE_OPT_FULLSPEED (0 << 0) + + #if defined(USB_SERIES_UC3A3_AVR32) || defined(USB_SERIES_UC3A4_AVR32) || defined(__DOXYGEN__) + /** Mask for the Options parameter of the \ref USB_Init() function. This indicates that the + * USB interface should be initialized in high speed (480Mb/s) mode. + */ + #define USB_DEVICE_OPT_HIGHSPEED (1 << 1) + #endif + //@} + + #if (!defined(NO_INTERNAL_SERIAL) && \ + (defined(USB_SERIES_UC3A3_AVR32) || defined(USB_SERIES_UC3A4_AVR32) || \ + defined(__DOXYGEN__))) + /** String descriptor index for the device's unique serial number string descriptor within the device. + * This unique serial number is used by the host to associate resources to the device (such as drivers or COM port + * number allocations) to a device regardless of the port it is plugged in to on the host. Some microcontrollers contain + * a unique serial number internally, and setting the device descriptors serial number string index to this value + * will cause it to use the internal serial number. + * + * On unsupported devices, this will evaluate to \ref NO_DESCRIPTOR and so will force the host to create a pseudo-serial + * number for the device. + */ + #define USE_INTERNAL_SERIAL 0xDC + + /** Length of the device's unique internal serial number, in bits, if present on the selected microcontroller + * model. + */ + #define INTERNAL_SERIAL_LENGTH_BITS 120 + + /** Start address of the internal serial number, in the appropriate address space, if present on the selected microcontroller + * model. + */ + #define INTERNAL_SERIAL_START_ADDRESS 0x80800204 + #else + #define USE_INTERNAL_SERIAL NO_DESCRIPTOR + + #define INTERNAL_SERIAL_LENGTH_BITS 0 + #define INTERNAL_SERIAL_START_ADDRESS 0 + #endif + + /* Function Prototypes: */ + /** Sends a Remote Wakeup request to the host. This signals to the host that the device should + * be taken out of suspended mode, and communications should resume. + * + * Typically, this is implemented so that HID devices (mice, keyboards, etc.) can wake up the + * host computer when the host has suspended all USB devices to enter a low power state. + * + * \note This function should only be used if the device has indicated to the host that it + * supports the Remote Wakeup feature in the device descriptors, and should only be + * issued if the host is currently allowing remote wakeup events from the device (i.e., + * the \ref USB_Device_RemoteWakeupEnabled flag is set). When the \c NO_DEVICE_REMOTE_WAKEUP + * compile time option is used, this function is unavailable. + * + * \note The USB clock must be running for this function to operate. If the stack is initialized with + * the \ref USB_OPT_MANUAL_PLL option enabled, the user must ensure that the PLL is running + * before attempting to call this function. + * + * \see \ref Group_StdDescriptors for more information on the RMWAKEUP feature and device descriptors. + */ + void USB_Device_SendRemoteWakeup(void); + + /* Inline Functions: */ + /** Returns the current USB frame number, when in device mode. Every millisecond the USB bus is active (i.e. enumerated to a host) + * the frame number is incremented by one. + * + * \return Current USB frame number from the USB controller. + */ + static inline uint16_t USB_Device_GetFrameNumber(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT; + static inline uint16_t USB_Device_GetFrameNumber(void) + { + return AVR32_USBB.UDFNUM.fnum; + } + + #if !defined(NO_SOF_EVENTS) + /** Enables the device mode Start Of Frame events. When enabled, this causes the + * \ref EVENT_USB_Device_StartOfFrame() event to fire once per millisecond, synchronized to the USB bus, + * at the start of each USB frame when enumerated in device mode. + * + * \note Not available when the \c NO_SOF_EVENTS compile time token is defined. + */ + static inline void USB_Device_EnableSOFEvents(void) ATTR_ALWAYS_INLINE; + static inline void USB_Device_EnableSOFEvents(void) + { + USB_INT_Enable(USB_INT_SOFI); + } + + /** Disables the device mode Start Of Frame events. When disabled, this stops the firing of the + * \ref EVENT_USB_Device_StartOfFrame() event when enumerated in device mode. + * + * \note Not available when the \c NO_SOF_EVENTS compile time token is defined. + */ + static inline void USB_Device_DisableSOFEvents(void) ATTR_ALWAYS_INLINE; + static inline void USB_Device_DisableSOFEvents(void) + { + USB_INT_Disable(USB_INT_SOFI); + } + #endif + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Inline Functions: */ + static inline void USB_Device_SetLowSpeed(void) ATTR_ALWAYS_INLINE; + static inline void USB_Device_SetLowSpeed(void) + { + AVR32_USBB.UDCON.ls = true; + } + + static inline void USB_Device_SetFullSpeed(void) ATTR_ALWAYS_INLINE; + static inline void USB_Device_SetFullSpeed(void) + { + AVR32_USBB.UDCON.ls = false; + #if defined(USB_DEVICE_OPT_HIGHSPEED) + AVR32_USBB.UDCON.spdconf = 3; + #endif + } + + #if defined(USB_DEVICE_OPT_HIGHSPEED) + static inline void USB_Device_SetHighSpeed(void) ATTR_ALWAYS_INLINE; + static inline void USB_Device_SetHighSpeed(void) + { + AVR32_USBB.UDCON.ls = false; + AVR32_USBB.UDCON.spdconf = 0; + } + #endif + + static inline void USB_Device_SetDeviceAddress(const uint8_t Address) ATTR_ALWAYS_INLINE; + static inline void USB_Device_SetDeviceAddress(const uint8_t Address) + { + AVR32_USBB.UDCON.uadd = Address; + AVR32_USBB.UDCON.adden = (Address ? true : false); + } + + static inline bool USB_Device_IsAddressSet(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT; + static inline bool USB_Device_IsAddressSet(void) + { + return AVR32_USBB.UDCON.adden; + } + + #if (USE_INTERNAL_SERIAL != NO_DESCRIPTOR) + static inline void USB_Device_GetSerialString(uint16_t* const UnicodeString) ATTR_NON_NULL_PTR_ARG(1); + static inline void USB_Device_GetSerialString(uint16_t* const UnicodeString) + { + uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask(); + GlobalInterruptDisable(); + + uint8_t* SigReadAddress = (uint8_t*)INTERNAL_SERIAL_START_ADDRESS; + + for (uint8_t SerialCharNum = 0; SerialCharNum < (INTERNAL_SERIAL_LENGTH_BITS / 4); SerialCharNum++) + { + uint8_t SerialByte = *SigReadAddress; + + if (SerialCharNum & 0x01) + { + SerialByte >>= 4; + SigReadAddress++; + } + + SerialByte &= 0x0F; + + UnicodeString[SerialCharNum] = cpu_to_le16((SerialByte >= 10) ? + (('A' - 10) + SerialByte) : ('0' + SerialByte)); + } + + SetGlobalInterruptMask(CurrentGlobalInt); + } + #endif + + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/EndpointStream_UC3.c b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/EndpointStream_UC3.c new file mode 100644 index 00000000..cc4206ca --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/EndpointStream_UC3.c @@ -0,0 +1,235 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#include "../../../../Common/Common.h" +#if (ARCH == ARCH_UC3) + +#define __INCLUDE_FROM_USB_DRIVER +#include "../USBMode.h" + +#if defined(USB_CAN_BE_DEVICE) + +#include "EndpointStream_UC3.h" + +#if !defined(CONTROL_ONLY_DEVICE) +uint8_t Endpoint_Discard_Stream(uint16_t Length, + uint16_t* const BytesProcessed) +{ + uint8_t ErrorCode; + uint16_t BytesInTransfer = 0; + + if ((ErrorCode = Endpoint_WaitUntilReady())) + return ErrorCode; + + if (BytesProcessed != NULL) + Length -= *BytesProcessed; + + while (Length) + { + if (!(Endpoint_IsReadWriteAllowed())) + { + Endpoint_ClearOUT(); + + if (BytesProcessed != NULL) + { + *BytesProcessed += BytesInTransfer; + return ENDPOINT_RWSTREAM_IncompleteTransfer; + } + + if ((ErrorCode = Endpoint_WaitUntilReady())) + return ErrorCode; + } + else + { + Endpoint_Discard_8(); + + Length--; + BytesInTransfer++; + } + } + + return ENDPOINT_RWSTREAM_NoError; +} + +uint8_t Endpoint_Null_Stream(uint16_t Length, + uint16_t* const BytesProcessed) +{ + uint8_t ErrorCode; + uint16_t BytesInTransfer = 0; + + if ((ErrorCode = Endpoint_WaitUntilReady())) + return ErrorCode; + + if (BytesProcessed != NULL) + Length -= *BytesProcessed; + + while (Length) + { + if (!(Endpoint_IsReadWriteAllowed())) + { + Endpoint_ClearIN(); + + if (BytesProcessed != NULL) + { + *BytesProcessed += BytesInTransfer; + return ENDPOINT_RWSTREAM_IncompleteTransfer; + } + + if ((ErrorCode = Endpoint_WaitUntilReady())) + return ErrorCode; + } + else + { + Endpoint_Write_8(0); + + Length--; + BytesInTransfer++; + } + } + + return ENDPOINT_RWSTREAM_NoError; +} + +/* The following abuses the C preprocessor in order to copy-paste common code with slight alterations, + * so that the code needs to be written once. It is a crude form of templating to reduce code maintenance. */ + +#define TEMPLATE_FUNC_NAME Endpoint_Write_Stream_LE +#define TEMPLATE_BUFFER_TYPE const void* +#define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN() +#define TEMPLATE_BUFFER_OFFSET(Length) 0 +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(*BufferPtr) +#include "Template/Template_Endpoint_RW.c" + +#define TEMPLATE_FUNC_NAME Endpoint_Write_Stream_BE +#define TEMPLATE_BUFFER_TYPE const void* +#define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN() +#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(*BufferPtr) +#include "Template/Template_Endpoint_RW.c" + +#define TEMPLATE_FUNC_NAME Endpoint_Read_Stream_LE +#define TEMPLATE_BUFFER_TYPE void* +#define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearOUT() +#define TEMPLATE_BUFFER_OFFSET(Length) 0 +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *BufferPtr = Endpoint_Read_8() +#include "Template/Template_Endpoint_RW.c" + +#define TEMPLATE_FUNC_NAME Endpoint_Read_Stream_BE +#define TEMPLATE_BUFFER_TYPE void* +#define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearOUT() +#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *BufferPtr = Endpoint_Read_8() +#include "Template/Template_Endpoint_RW.c" + +#if defined(ARCH_HAS_FLASH_ADDRESS_SPACE) + #define TEMPLATE_FUNC_NAME Endpoint_Write_PStream_LE + #define TEMPLATE_BUFFER_TYPE const void* + #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN() + #define TEMPLATE_BUFFER_OFFSET(Length) 0 + #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount + #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(pgm_read_byte(BufferPtr)) + #include "Template/Template_Endpoint_RW.c" + + #define TEMPLATE_FUNC_NAME Endpoint_Write_PStream_BE + #define TEMPLATE_BUFFER_TYPE const void* + #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN() + #define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) + #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount + #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(pgm_read_byte(BufferPtr)) + #include "Template/Template_Endpoint_RW.c" +#endif + +#if defined(ARCH_HAS_EEPROM_ADDRESS_SPACE) + #define TEMPLATE_FUNC_NAME Endpoint_Write_EStream_LE + #define TEMPLATE_BUFFER_TYPE const void* + #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN() + #define TEMPLATE_BUFFER_OFFSET(Length) 0 + #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount + #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(eeprom_read_byte(BufferPtr)) + #include "Template/Template_Endpoint_RW.c" + + #define TEMPLATE_FUNC_NAME Endpoint_Write_EStream_BE + #define TEMPLATE_BUFFER_TYPE const void* + #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN() + #define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) + #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount + #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(eeprom_read_byte(BufferPtr)) + #include "Template/Template_Endpoint_RW.c" + + #define TEMPLATE_FUNC_NAME Endpoint_Read_EStream_LE + #define TEMPLATE_BUFFER_TYPE void* + #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearOUT() + #define TEMPLATE_BUFFER_OFFSET(Length) 0 + #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount + #define TEMPLATE_TRANSFER_BYTE(BufferPtr) eeprom_update_byte(BufferPtr, Endpoint_Read_8()) + #include "Template/Template_Endpoint_RW.c" + + #define TEMPLATE_FUNC_NAME Endpoint_Read_EStream_BE + #define TEMPLATE_BUFFER_TYPE void* + #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearOUT() + #define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) + #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount + #define TEMPLATE_TRANSFER_BYTE(BufferPtr) eeprom_update_byte(BufferPtr, Endpoint_Read_8()) + #include "Template/Template_Endpoint_RW.c" +#endif + +#endif + +#define TEMPLATE_FUNC_NAME Endpoint_Write_Control_Stream_LE +#define TEMPLATE_BUFFER_OFFSET(Length) 0 +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(*BufferPtr) +#include "Template/Template_Endpoint_Control_W.c" + +#define TEMPLATE_FUNC_NAME Endpoint_Write_Control_Stream_BE +#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(*BufferPtr) +#include "Template/Template_Endpoint_Control_W.c" + +#define TEMPLATE_FUNC_NAME Endpoint_Read_Control_Stream_LE +#define TEMPLATE_BUFFER_OFFSET(Length) 0 +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *BufferPtr = Endpoint_Read_8() +#include "Template/Template_Endpoint_Control_R.c" + +#define TEMPLATE_FUNC_NAME Endpoint_Read_Control_Stream_BE +#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *BufferPtr = Endpoint_Read_8() +#include "Template/Template_Endpoint_Control_R.c" + +#endif + +#endif diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/EndpointStream_UC3.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/EndpointStream_UC3.h new file mode 100644 index 00000000..b360b4da --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/EndpointStream_UC3.h @@ -0,0 +1,434 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Endpoint data stream transmission and reception management for the AVR32 UC3 microcontrollers. + * \copydetails Group_EndpointStreamRW_UC3 + * + * \note This file should not be included directly. It is automatically included as needed by the USB driver + * dispatch header located in LUFA/Drivers/USB/USB.h. + */ + +/** \ingroup Group_EndpointStreamRW + * \defgroup Group_EndpointStreamRW_UC3 Read/Write of Multi-Byte Streams (UC3) + * \brief Endpoint data stream transmission and reception management for the Atmel AVR32 UC3 architecture. + * + * Functions, macros, variables, enums and types related to data reading and writing of data streams from + * and to endpoints. + * + * @{ + */ + +#ifndef __ENDPOINT_STREAM_UC3_H__ +#define __ENDPOINT_STREAM_UC3_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + #include "../USBMode.h" + #include "../USBTask.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_USB_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB/USB.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Function Prototypes: */ + /** \name Stream functions for null data */ + //@{ + + /** Reads and discards the given number of bytes from the currently selected endpoint's bank, + * discarding fully read packets from the host as needed. The last packet is not automatically + * discarded once the remaining bytes has been read; the user is responsible for manually + * discarding the last packet from the host via the \ref Endpoint_ClearOUT() macro. + * + * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, + * failing or succeeding as a single unit. If the BytesProcessed parameter points to a valid + * storage location, the transfer will instead be performed as a series of chunks. Each time + * the endpoint bank becomes empty while there is still data to process (and after the current + * packet has been acknowledged) the BytesProcessed location will be updated with the total number + * of bytes processed in the stream, and the function will exit with an error code of + * \ref ENDPOINT_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed + * in the user code - to continue the transfer, call the function again with identical parameters + * and it will resume until the BytesProcessed value reaches the total transfer length. + * + * Single Stream Transfer Example: + * \code + * uint8_t ErrorCode; + * + * if ((ErrorCode = Endpoint_Discard_Stream(512, NULL)) != ENDPOINT_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * Partial Stream Transfers Example: + * \code + * uint8_t ErrorCode; + * uint16_t BytesProcessed; + * + * BytesProcessed = 0; + * while ((ErrorCode = Endpoint_Discard_Stream(512, &BytesProcessed)) == ENDPOINT_RWSTREAM_IncompleteTransfer) + * { + * // Stream not yet complete - do other actions here, abort if required + * } + * + * if (ErrorCode != ENDPOINT_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * \note This routine should not be used on CONTROL type endpoints. + * + * \param[in] Length Number of bytes to discard via the currently selected endpoint. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current + * transaction should be updated, \c NULL if the entire stream should be read at once. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Discard_Stream(uint16_t Length, + uint16_t* const BytesProcessed); + + /** Writes a given number of zeroed bytes to the currently selected endpoint's bank, sending + * full packets to the host as needed. The last packet is not automatically sent once the + * remaining bytes have been written; the user is responsible for manually sending the last + * packet to the host via the \ref Endpoint_ClearIN() macro. + * + * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, + * failing or succeeding as a single unit. If the BytesProcessed parameter points to a valid + * storage location, the transfer will instead be performed as a series of chunks. Each time + * the endpoint bank becomes full while there is still data to process (and after the current + * packet transmission has been initiated) the BytesProcessed location will be updated with the + * total number of bytes processed in the stream, and the function will exit with an error code of + * \ref ENDPOINT_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed + * in the user code - to continue the transfer, call the function again with identical parameters + * and it will resume until the BytesProcessed value reaches the total transfer length. + * + * Single Stream Transfer Example: + * \code + * uint8_t ErrorCode; + * + * if ((ErrorCode = Endpoint_Null_Stream(512, NULL)) != ENDPOINT_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * Partial Stream Transfers Example: + * \code + * uint8_t ErrorCode; + * uint16_t BytesProcessed; + * + * BytesProcessed = 0; + * while ((ErrorCode = Endpoint_Null_Stream(512, &BytesProcessed)) == ENDPOINT_RWSTREAM_IncompleteTransfer) + * { + * // Stream not yet complete - do other actions here, abort if required + * } + * + * if (ErrorCode != ENDPOINT_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * \note This routine should not be used on CONTROL type endpoints. + * + * \param[in] Length Number of zero bytes to send via the currently selected endpoint. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current + * transaction should be updated, \c NULL if the entire stream should be read at once. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Null_Stream(uint16_t Length, + uint16_t* const BytesProcessed); + + //@} + + /** \name Stream functions for RAM source/destination data */ + //@{ + + /** Writes the given number of bytes to the endpoint from the given buffer in little endian, + * sending full packets to the host as needed. The last packet filled is not automatically sent; + * the user is responsible for manually sending the last written packet to the host via the + * \ref Endpoint_ClearIN() macro. + * + * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, + * failing or succeeding as a single unit. If the BytesProcessed parameter points to a valid + * storage location, the transfer will instead be performed as a series of chunks. Each time + * the endpoint bank becomes full while there is still data to process (and after the current + * packet transmission has been initiated) the BytesProcessed location will be updated with the + * total number of bytes processed in the stream, and the function will exit with an error code of + * \ref ENDPOINT_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed + * in the user code - to continue the transfer, call the function again with identical parameters + * and it will resume until the BytesProcessed value reaches the total transfer length. + * + * Single Stream Transfer Example: + * \code + * uint8_t DataStream[512]; + * uint8_t ErrorCode; + * + * if ((ErrorCode = Endpoint_Write_Stream_LE(DataStream, sizeof(DataStream), + * NULL)) != ENDPOINT_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * Partial Stream Transfers Example: + * \code + * uint8_t DataStream[512]; + * uint8_t ErrorCode; + * uint16_t BytesProcessed; + * + * BytesProcessed = 0; + * while ((ErrorCode = Endpoint_Write_Stream_LE(DataStream, sizeof(DataStream), + * &BytesProcessed)) == ENDPOINT_RWSTREAM_IncompleteTransfer) + * { + * // Stream not yet complete - do other actions here, abort if required + * } + * + * if (ErrorCode != ENDPOINT_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * \note This routine should not be used on CONTROL type endpoints. + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current + * transaction should be updated, \c NULL if the entire stream should be written at once. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Write_Stream_LE(const void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** Writes the given number of bytes to the endpoint from the given buffer in big endian, + * sending full packets to the host as needed. The last packet filled is not automatically sent; + * the user is responsible for manually sending the last written packet to the host via the + * \ref Endpoint_ClearIN() macro. + * + * \note This routine should not be used on CONTROL type endpoints. + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current + * transaction should be updated, \c NULL if the entire stream should be written at once. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Write_Stream_BE(const void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** Reads the given number of bytes from the endpoint from the given buffer in little endian, + * discarding fully read packets from the host as needed. The last packet is not automatically + * discarded once the remaining bytes has been read; the user is responsible for manually + * discarding the last packet from the host via the \ref Endpoint_ClearOUT() macro. + * + * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, + * failing or succeeding as a single unit. If the BytesProcessed parameter points to a valid + * storage location, the transfer will instead be performed as a series of chunks. Each time + * the endpoint bank becomes empty while there is still data to process (and after the current + * packet has been acknowledged) the BytesProcessed location will be updated with the total number + * of bytes processed in the stream, and the function will exit with an error code of + * \ref ENDPOINT_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed + * in the user code - to continue the transfer, call the function again with identical parameters + * and it will resume until the BytesProcessed value reaches the total transfer length. + * + * Single Stream Transfer Example: + * \code + * uint8_t DataStream[512]; + * uint8_t ErrorCode; + * + * if ((ErrorCode = Endpoint_Read_Stream_LE(DataStream, sizeof(DataStream), + * NULL)) != ENDPOINT_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * Partial Stream Transfers Example: + * \code + * uint8_t DataStream[512]; + * uint8_t ErrorCode; + * uint16_t BytesProcessed; + * + * BytesProcessed = 0; + * while ((ErrorCode = Endpoint_Read_Stream_LE(DataStream, sizeof(DataStream), + * &BytesProcessed)) == ENDPOINT_RWSTREAM_IncompleteTransfer) + * { + * // Stream not yet complete - do other actions here, abort if required + * } + * + * if (ErrorCode != ENDPOINT_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * \note This routine should not be used on CONTROL type endpoints. + * + * \param[out] Buffer Pointer to the destination data buffer to write to. + * \param[in] Length Number of bytes to send via the currently selected endpoint. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current + * transaction should be updated, \c NULL if the entire stream should be read at once. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Read_Stream_LE(void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** Reads the given number of bytes from the endpoint from the given buffer in big endian, + * discarding fully read packets from the host as needed. The last packet is not automatically + * discarded once the remaining bytes has been read; the user is responsible for manually + * discarding the last packet from the host via the \ref Endpoint_ClearOUT() macro. + * + * \note This routine should not be used on CONTROL type endpoints. + * + * \param[out] Buffer Pointer to the destination data buffer to write to. + * \param[in] Length Number of bytes to send via the currently selected endpoint. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current + * transaction should be updated, \c NULL if the entire stream should be read at once. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Read_Stream_BE(void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** Writes the given number of bytes to the CONTROL type endpoint from the given buffer in little endian, + * sending full packets to the host as needed. The host OUT acknowledgement is not automatically cleared + * in both failure and success states; the user is responsible for manually clearing the status OUT packet + * to finalize the transfer's status stage via the \ref Endpoint_ClearOUT() macro. + * + * \note This function automatically clears the control transfer's status stage. Do not manually attempt + * to clear the status stage when using this routine in a control transaction. + * \n\n + * + * \note This routine should only be used on CONTROL type endpoints. + * + * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained + * together; i.e. the entire stream data must be read or written at the one time. + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. + * + * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Write_Control_Stream_LE(const void* const Buffer, + uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); + + /** Writes the given number of bytes to the CONTROL type endpoint from the given buffer in big endian, + * sending full packets to the host as needed. The host OUT acknowledgement is not automatically cleared + * in both failure and success states; the user is responsible for manually clearing the status OUT packet + * to finalize the transfer's status stage via the \ref Endpoint_ClearOUT() macro. + * + * \note This function automatically clears the control transfer's status stage. Do not manually attempt + * to clear the status stage when using this routine in a control transaction. + * \n\n + * + * \note This routine should only be used on CONTROL type endpoints. + * + * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained + * together; i.e. the entire stream data must be read or written at the one time. + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. + * + * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Write_Control_Stream_BE(const void* const Buffer, + uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); + + /** Reads the given number of bytes from the CONTROL endpoint from the given buffer in little endian, + * discarding fully read packets from the host as needed. The device IN acknowledgement is not + * automatically sent after success or failure states; the user is responsible for manually sending the + * status IN packet to finalize the transfer's status stage via the \ref Endpoint_ClearIN() macro. + * + * \note This function automatically clears the control transfer's status stage. Do not manually attempt + * to clear the status stage when using this routine in a control transaction. + * \n\n + * + * \note This routine should only be used on CONTROL type endpoints. + * + * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained + * together; i.e. the entire stream data must be read or written at the one time. + * + * \param[out] Buffer Pointer to the destination data buffer to write to. + * \param[in] Length Number of bytes to send via the currently selected endpoint. + * + * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Read_Control_Stream_LE(void* const Buffer, + uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); + + /** Reads the given number of bytes from the CONTROL endpoint from the given buffer in big endian, + * discarding fully read packets from the host as needed. The device IN acknowledgement is not + * automatically sent after success or failure states; the user is responsible for manually sending the + * status IN packet to finalize the transfer's status stage via the \ref Endpoint_ClearIN() macro. + * + * \note This function automatically clears the control transfer's status stage. Do not manually attempt + * to clear the status stage when using this routine in a control transaction. + * \n\n + * + * \note This routine should only be used on CONTROL type endpoints. + * + * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained + * together; i.e. the entire stream data must be read or written at the one time. + * + * \param[out] Buffer Pointer to the destination data buffer to write to. + * \param[in] Length Number of bytes to send via the currently selected endpoint. + * + * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Read_Control_Stream_BE(void* const Buffer, + uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); + //@} + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/Endpoint_UC3.c b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/Endpoint_UC3.c new file mode 100644 index 00000000..235ddde5 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/Endpoint_UC3.c @@ -0,0 +1,196 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#include "../../../../Common/Common.h" +#if (ARCH == ARCH_UC3) + +#define __INCLUDE_FROM_USB_DRIVER +#include "../USBMode.h" + +#if defined(USB_CAN_BE_DEVICE) + +#include "../Endpoint.h" + +#if !defined(FIXED_CONTROL_ENDPOINT_SIZE) +uint8_t USB_Device_ControlEndpointSize = ENDPOINT_CONTROLEP_DEFAULT_SIZE; +#endif + +volatile uint32_t USB_Endpoint_SelectedEndpoint = ENDPOINT_CONTROLEP; +volatile uint8_t* USB_Endpoint_FIFOPos[ENDPOINT_TOTAL_ENDPOINTS]; + +bool Endpoint_ConfigureEndpointTable(const USB_Endpoint_Table_t* const Table, + const uint8_t Entries) +{ + for (uint8_t i = 0; i < Entries; i++) + { + if (!(Table[i].Address)) + continue; + + if (!(Endpoint_ConfigureEndpoint(Table[i].Address, Table[i].Type, Table[i].Size, Table[i].Banks))) + { + return false; + } + } + + return true; +} + +bool Endpoint_ConfigureEndpoint_Prv(const uint8_t Number, + const uint32_t UECFG0Data) +{ + USB_Endpoint_FIFOPos[Number] = &AVR32_USBB_SLAVE[Number * ENDPOINT_HSB_ADDRESS_SPACE_SIZE]; + +#if defined(CONTROL_ONLY_DEVICE) || defined(ORDERED_EP_CONFIG) + Endpoint_SelectEndpoint(Number); + Endpoint_EnableEndpoint(); + + (&AVR32_USBB.uecfg0)[Number] = 0; + (&AVR32_USBB.uecfg0)[Number] = UECFG0Data; + + return Endpoint_IsConfigured(); +#else + for (uint8_t EPNum = Number; EPNum < ENDPOINT_TOTAL_ENDPOINTS; EPNum++) + { + uint32_t UECFG0Temp; + + Endpoint_SelectEndpoint(EPNum); + + if (EPNum == Number) + { + UECFG0Temp = UECFG0Data; + } + else + { + UECFG0Temp = (&AVR32_USBB.uecfg0)[EPNum]; + } + + if (!(UECFG0Temp & AVR32_USBB_ALLOC_MASK)) + continue; + + Endpoint_DisableEndpoint(); + (&AVR32_USBB.uecfg0)[EPNum] &= ~AVR32_USBB_ALLOC_MASK; + + Endpoint_EnableEndpoint(); + (&AVR32_USBB.uecfg0)[EPNum] = UECFG0Temp; + + if (!(Endpoint_IsConfigured())) + return false; + } + + Endpoint_SelectEndpoint(Number); + return true; +#endif +} + +void Endpoint_ClearEndpoints(void) +{ + for (uint8_t EPNum = 0; EPNum < ENDPOINT_TOTAL_ENDPOINTS; EPNum++) + { + Endpoint_SelectEndpoint(EPNum); + (&AVR32_USBB.uecfg0)[EPNum] = 0; + (&AVR32_USBB.uecon0clr)[EPNum] = -1; + USB_Endpoint_FIFOPos[EPNum] = &AVR32_USBB_SLAVE[EPNum * 0x10000]; + Endpoint_DisableEndpoint(); + } +} + +void Endpoint_ClearStatusStage(void) +{ + if (USB_ControlRequest.bmRequestType & REQDIR_DEVICETOHOST) + { + while (!(Endpoint_IsOUTReceived())) + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return; + } + + Endpoint_ClearOUT(); + } + else + { + while (!(Endpoint_IsINReady())) + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return; + } + + Endpoint_ClearIN(); + } +} + +#if !defined(CONTROL_ONLY_DEVICE) +uint8_t Endpoint_WaitUntilReady(void) +{ + #if (USB_STREAM_TIMEOUT_MS < 0xFF) + uint8_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS; + #else + uint16_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS; + #endif + + uint16_t PreviousFrameNumber = USB_Device_GetFrameNumber(); + + for (;;) + { + if (Endpoint_GetEndpointDirection() == ENDPOINT_DIR_IN) + { + if (Endpoint_IsINReady()) + return ENDPOINT_READYWAIT_NoError; + } + else + { + if (Endpoint_IsOUTReceived()) + return ENDPOINT_READYWAIT_NoError; + } + + uint8_t USB_DeviceState_LCL = USB_DeviceState; + + if (USB_DeviceState_LCL == DEVICE_STATE_Unattached) + return ENDPOINT_READYWAIT_DeviceDisconnected; + else if (USB_DeviceState_LCL == DEVICE_STATE_Suspended) + return ENDPOINT_READYWAIT_BusSuspended; + else if (Endpoint_IsStalled()) + return ENDPOINT_READYWAIT_EndpointStalled; + + uint16_t CurrentFrameNumber = USB_Device_GetFrameNumber(); + + if (CurrentFrameNumber != PreviousFrameNumber) + { + PreviousFrameNumber = CurrentFrameNumber; + + if (!(TimeoutMSRem--)) + return ENDPOINT_READYWAIT_Timeout; + } + } +} +#endif + +#endif + +#endif diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/Endpoint_UC3.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/Endpoint_UC3.h new file mode 100644 index 00000000..356c9c3c --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/Endpoint_UC3.h @@ -0,0 +1,795 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief USB Endpoint definitions for the AVR32 UC3 microcontrollers. + * \copydetails Group_EndpointManagement_UC3 + * + * \note This file should not be included directly. It is automatically included as needed by the USB driver + * dispatch header located in LUFA/Drivers/USB/USB.h. + */ + +/** \ingroup Group_EndpointRW + * \defgroup Group_EndpointRW_UC3 Endpoint Data Reading and Writing (UC3) + * \brief Endpoint data read/write definitions for the Atmel AVR32 UC3 architecture. + * + * Functions, macros, variables, enums and types related to data reading and writing from and to endpoints. + */ + +/** \ingroup Group_EndpointPrimitiveRW + * \defgroup Group_EndpointPrimitiveRW_UC3 Read/Write of Primitive Data Types (UC3) + * \brief Endpoint primitive read/write definitions for the Atmel AVR32 UC3 architecture. + * + * Functions, macros, variables, enums and types related to data reading and writing of primitive data types + * from and to endpoints. + */ + +/** \ingroup Group_EndpointPacketManagement + * \defgroup Group_EndpointPacketManagement_UC3 Endpoint Packet Management (UC3) + * \brief Endpoint packet management definitions for the Atmel AVR32 UC3 architecture. + * + * Functions, macros, variables, enums and types related to packet management of endpoints. + */ + +/** \ingroup Group_EndpointManagement + * \defgroup Group_EndpointManagement_UC3 Endpoint Management (UC3) + * \brief Endpoint management definitions for the Atmel AVR32 UC3 architecture. + * + * Functions, macros and enums related to endpoint management when in USB Device mode. This + * module contains the endpoint management macros, as well as endpoint interrupt and data + * send/receive functions for various data types. + * + * @{ + */ + +#ifndef __ENDPOINT_UC3_H__ +#define __ENDPOINT_UC3_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + #include "../USBTask.h" + #include "../USBInterrupt.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_USB_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB/USB.h instead. + #endif + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Macros: */ + #define ENDPOINT_HSB_ADDRESS_SPACE_SIZE (64 * 1024UL) + + /* Inline Functions: */ + static inline uint32_t Endpoint_BytesToEPSizeMask(const uint16_t Bytes) ATTR_WARN_UNUSED_RESULT ATTR_CONST + ATTR_ALWAYS_INLINE; + static inline uint32_t Endpoint_BytesToEPSizeMask(const uint16_t Bytes) + { + uint8_t MaskVal = 0; + uint16_t CheckBytes = 8; + + while (CheckBytes < Bytes) + { + MaskVal++; + CheckBytes <<= 1; + } + + return (MaskVal << AVR32_USBB_EPSIZE_OFFSET); + } + + /* Function Prototypes: */ + void Endpoint_ClearEndpoints(void); + bool Endpoint_ConfigureEndpoint_Prv(const uint8_t Number, + const uint32_t UECFGXData); + + /* External Variables: */ + extern volatile uint32_t USB_Endpoint_SelectedEndpoint; + extern volatile uint8_t* USB_Endpoint_FIFOPos[]; + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + #if (!defined(FIXED_CONTROL_ENDPOINT_SIZE) || defined(__DOXYGEN__)) + /** Default size of the default control endpoint's bank, until altered by the control endpoint bank size + * value in the device descriptor. Not available if the \c FIXED_CONTROL_ENDPOINT_SIZE token is defined. + */ + #define ENDPOINT_CONTROLEP_DEFAULT_SIZE 8 + #endif + + #if !defined(CONTROL_ONLY_DEVICE) || defined(__DOXYGEN__) + #if defined(USB_SERIES_UC3A3_AVR32) || defined(USB_SERIES_UC3A4_AVR32) + #define ENDPOINT_TOTAL_ENDPOINTS 8 + #else + /** Total number of endpoints (including the default control endpoint at address 0) which may + * be used in the device. Different AVR models support different amounts of endpoints, + * this value reflects the maximum number of endpoints for the currently selected AVR model. + */ + #define ENDPOINT_TOTAL_ENDPOINTS 7 + #endif + #else + #define ENDPOINT_TOTAL_ENDPOINTS 1 + #endif + + /* Enums: */ + /** Enum for the possible error return codes of the \ref Endpoint_WaitUntilReady() function. + * + * \ingroup Group_EndpointRW_UC3 + */ + enum Endpoint_WaitUntilReady_ErrorCodes_t + { + ENDPOINT_READYWAIT_NoError = 0, /**< Endpoint is ready for next packet, no error. */ + ENDPOINT_READYWAIT_EndpointStalled = 1, /**< The endpoint was stalled during the stream + * transfer by the host or device. + */ + ENDPOINT_READYWAIT_DeviceDisconnected = 2, /**< Device was disconnected from the host while + * waiting for the endpoint to become ready. + */ + ENDPOINT_READYWAIT_BusSuspended = 3, /**< The USB bus has been suspended by the host and + * no USB endpoint traffic can occur until the bus + * has resumed. + */ + ENDPOINT_READYWAIT_Timeout = 4, /**< The host failed to accept or send the next packet + * within the software timeout period set by the + * \ref USB_STREAM_TIMEOUT_MS macro. + */ + }; + + /* Inline Functions: */ + /** Configures the specified endpoint address with the given endpoint type, direction, bank size + * and banking mode. Once configured, the endpoint may be read from or written to, depending + * on its direction. + * + * \param[in] Address Endpoint address to configure. + * + * \param[in] Type Type of endpoint to configure, a \c EP_TYPE_* mask. Not all endpoint types + * are available on Low Speed USB devices - refer to the USB 2.0 specification. + * + * \param[in] Size Size of the endpoint's bank, where packets are stored before they are transmitted + * to the USB host, or after they have been received from the USB host (depending on + * the endpoint's data direction). The bank size must indicate the maximum packet size + * that the endpoint can handle. + * + * \param[in] Banks Number of hardware banks to use for the endpoint being configured. + * + * \attention When the \c ORDERED_EP_CONFIG compile time option is used, Endpoints must be configured in + * ascending order, or bank corruption will occur. + * + * \note Different endpoints may have different maximum packet sizes based on the endpoint's index - refer to + * the chosen microcontroller model's datasheet to determine the maximum bank size for each endpoint. + * \n\n + * + * \note The default control endpoint should not be manually configured by the user application, as + * it is automatically configured by the library internally. + * \n\n + * + * \note This routine will automatically select the specified endpoint upon success. Upon failure, the endpoint + * which failed to reconfigure correctly will be selected. + * + * \return Boolean \c true if the configuration succeeded, \c false otherwise. + */ + static inline bool Endpoint_ConfigureEndpoint(const uint8_t Address, + const uint8_t Type, + const uint16_t Size, + const uint8_t Banks) ATTR_ALWAYS_INLINE; + static inline bool Endpoint_ConfigureEndpoint(const uint8_t Address, + const uint8_t Type, + const uint16_t Size, + const uint8_t Banks) + { + uint8_t Number = (Address & ENDPOINT_EPNUM_MASK); + + if (Number >= ENDPOINT_TOTAL_ENDPOINTS) + return false; + + return Endpoint_ConfigureEndpoint_Prv(Number, + (AVR32_USBB_ALLOC_MASK | + ((uint32_t)Type << AVR32_USBB_EPTYPE_OFFSET) | + ((Address & ENDPOINT_DIR_IN) ? AVR32_USBB_UECFG0_EPDIR_MASK : 0) | + ((Banks > 1) ? AVR32_USBB_UECFG0_EPBK_SINGLE : AVR32_USBB_UECFG0_EPBK_DOUBLE) | + Endpoint_BytesToEPSizeMask(Size))); + } + + /** Indicates the number of bytes currently stored in the current endpoint's selected bank. + * + * \ingroup Group_EndpointRW_UC3 + * + * \return Total number of bytes in the currently selected Endpoint's FIFO buffer. + */ + static inline uint16_t Endpoint_BytesInEndpoint(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint16_t Endpoint_BytesInEndpoint(void) + { + return (&AVR32_USBB.UESTA0)[USB_Endpoint_SelectedEndpoint].byct; + } + + /** Determines the currently selected endpoint's direction. + * + * \return The currently selected endpoint's direction, as a \c ENDPOINT_DIR_* mask. + */ + static inline uint32_t Endpoint_GetEndpointDirection(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint32_t Endpoint_GetEndpointDirection(void) + { + return ((&AVR32_USBB.UECFG0)[USB_Endpoint_SelectedEndpoint].epdir ? ENDPOINT_DIR_IN : ENDPOINT_DIR_OUT); + } + + /** Get the endpoint address of the currently selected endpoint. This is typically used to save + * the currently selected endpoint so that it can be restored after another endpoint has been + * manipulated. + * + * \return Index of the currently selected endpoint. + */ + static inline uint8_t Endpoint_GetCurrentEndpoint(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint8_t Endpoint_GetCurrentEndpoint(void) + { + return (USB_Endpoint_SelectedEndpoint | Endpoint_GetEndpointDirection()); + } + + /** Selects the given endpoint address. + * + * Any endpoint operations which do not require the endpoint address to be indicated will operate on + * the currently selected endpoint. + * + * \param[in] Address Endpoint address to select. + */ + static inline void Endpoint_SelectEndpoint(const uint8_t Address) ATTR_ALWAYS_INLINE; + static inline void Endpoint_SelectEndpoint(const uint8_t Address) + { + USB_Endpoint_SelectedEndpoint = (Address & ENDPOINT_EPNUM_MASK); + } + + /** Resets the endpoint bank FIFO. This clears all the endpoint banks and resets the USB controller's + * data In and Out pointers to the bank's contents. + * + * \param[in] Address Endpoint number whose FIFO buffers are to be reset. + */ + static inline void Endpoint_ResetEndpoint(const uint8_t Address) ATTR_ALWAYS_INLINE; + static inline void Endpoint_ResetEndpoint(const uint8_t Address) + { + uint32_t EndpointNumber = (Address & ENDPOINT_EPNUM_MASK); + + AVR32_USBB.uerst |= (AVR32_USBB_EPRST0_MASK << EndpointNumber); + AVR32_USBB.uerst &= ~(AVR32_USBB_EPRST0_MASK << EndpointNumber); + USB_Endpoint_FIFOPos[EndpointNumber] = &AVR32_USBB_SLAVE[EndpointNumber * ENDPOINT_HSB_ADDRESS_SPACE_SIZE]; + } + + /** Enables the currently selected endpoint so that data can be sent and received through it to + * and from a host. + * + * \note Endpoints must first be configured properly via \ref Endpoint_ConfigureEndpoint(). + */ + static inline void Endpoint_EnableEndpoint(void) ATTR_ALWAYS_INLINE; + static inline void Endpoint_EnableEndpoint(void) + { + AVR32_USBB.uerst |= (AVR32_USBB_EPEN0_MASK << USB_Endpoint_SelectedEndpoint); + } + + /** Disables the currently selected endpoint so that data cannot be sent and received through it + * to and from a host. + */ + static inline void Endpoint_DisableEndpoint(void) ATTR_ALWAYS_INLINE; + static inline void Endpoint_DisableEndpoint(void) + { + AVR32_USBB.uerst &= ~(AVR32_USBB_EPEN0_MASK << USB_Endpoint_SelectedEndpoint); + } + + /** Determines if the currently selected endpoint is enabled, but not necessarily configured. + * + * \return Boolean \c true if the currently selected endpoint is enabled, \c false otherwise. + */ + static inline bool Endpoint_IsEnabled(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool Endpoint_IsEnabled(void) + { + return ((AVR32_USBB.uerst & (AVR32_USBB_EPEN0_MASK << USB_Endpoint_SelectedEndpoint)) ? true : false); + } + + /** Retrieves the number of busy banks in the currently selected endpoint, which have been queued for + * transmission via the \ref Endpoint_ClearIN() command, or are awaiting acknowledgement via the + * \ref Endpoint_ClearOUT() command. + * + * \ingroup Group_EndpointPacketManagement_UC3 + * + * \return Total number of busy banks in the selected endpoint. + */ + static inline uint8_t Endpoint_GetBusyBanks(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT; + static inline uint8_t Endpoint_GetBusyBanks(void) + { + return (&AVR32_USBB.UESTA0)[USB_Endpoint_SelectedEndpoint].nbusybk; + } + + /** Aborts all pending IN transactions on the currently selected endpoint, once the bank + * has been queued for transmission to the host via \ref Endpoint_ClearIN(). This function + * will terminate all queued transactions, resetting the endpoint banks ready for a new + * packet. + * + * \ingroup Group_EndpointPacketManagement_UC3 + */ + static inline void Endpoint_AbortPendingIN(void) + { + while (Endpoint_GetBusyBanks() != 0) + { + (&AVR32_USBB.UECON0SET)[USB_Endpoint_SelectedEndpoint].killbks = true; + while ((&AVR32_USBB.UECON0)[USB_Endpoint_SelectedEndpoint].killbk); + } + } + + /** Determines if the currently selected endpoint may be read from (if data is waiting in the endpoint + * bank and the endpoint is an OUT direction, or if the bank is not yet full if the endpoint is an IN + * direction). This function will return false if an error has occurred in the endpoint, if the endpoint + * is an OUT direction and no packet (or an empty packet) has been received, or if the endpoint is an IN + * direction and the endpoint bank is full. + * + * \ingroup Group_EndpointPacketManagement_UC3 + * + * \return Boolean \c true if the currently selected endpoint may be read from or written to, depending + * on its direction. + */ + static inline bool Endpoint_IsReadWriteAllowed(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool Endpoint_IsReadWriteAllowed(void) + { + return (&AVR32_USBB.UESTA0)[USB_Endpoint_SelectedEndpoint].rwall; + } + + /** Determines if the currently selected endpoint is configured. + * + * \return Boolean \c true if the currently selected endpoint has been configured, \c false otherwise. + */ + static inline bool Endpoint_IsConfigured(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool Endpoint_IsConfigured(void) + { + return (&AVR32_USBB.UESTA0)[USB_Endpoint_SelectedEndpoint].cfgok; + } + + /** Returns a mask indicating which INTERRUPT type endpoints have interrupted - i.e. their + * interrupt duration has elapsed. Which endpoints have interrupted can be determined by + * masking the return value against (1 << {Endpoint Number}). + * + * \return Mask whose bits indicate which endpoints have interrupted. + */ + static inline uint32_t Endpoint_GetEndpointInterrupts(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint32_t Endpoint_GetEndpointInterrupts(void) + { + return ((AVR32_USBB.udint & (AVR32_USBB_EP6INT_MASK | AVR32_USBB_EP5INT_MASK | + AVR32_USBB_EP4INT_MASK | AVR32_USBB_EP3INT_MASK | + AVR32_USBB_EP2INT_MASK | AVR32_USBB_EP1INT_MASK | + AVR32_USBB_EP0INT_MASK)) >> AVR32_USBB_EP0INT_OFFSET); + } + + /** Determines if the specified endpoint number has interrupted (valid only for INTERRUPT type + * endpoints). + * + * \param[in] Address Address of the endpoint whose interrupt flag should be tested. + * + * \return Boolean \c true if the specified endpoint has interrupted, \c false otherwise. + */ + static inline bool Endpoint_HasEndpointInterrupted(const uint8_t Address) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool Endpoint_HasEndpointInterrupted(const uint8_t Address) + { + return ((Endpoint_GetEndpointInterrupts() & (AVR32_USBB_EP0INT_MASK << (Address & ENDPOINT_EPNUM_MASK))) ? true : false); + } + + /** Determines if the selected IN endpoint is ready for a new packet to be sent to the host. + * + * \ingroup Group_EndpointPacketManagement_UC3 + * + * \return Boolean \c true if the current endpoint is ready for an IN packet, \c false otherwise. + */ + static inline bool Endpoint_IsINReady(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool Endpoint_IsINReady(void) + { + return (&AVR32_USBB.UESTA0)[USB_Endpoint_SelectedEndpoint].txini; + } + + /** Determines if the selected OUT endpoint has received new packet from the host. + * + * \ingroup Group_EndpointPacketManagement_UC3 + * + * \return Boolean \c true if current endpoint is has received an OUT packet, \c false otherwise. + */ + static inline bool Endpoint_IsOUTReceived(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool Endpoint_IsOUTReceived(void) + { + return (&AVR32_USBB.UESTA0)[USB_Endpoint_SelectedEndpoint].rxouti; + } + + /** Determines if the current CONTROL type endpoint has received a SETUP packet. + * + * \ingroup Group_EndpointPacketManagement_UC3 + * + * \return Boolean \c true if the selected endpoint has received a SETUP packet, \c false otherwise. + */ + static inline bool Endpoint_IsSETUPReceived(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool Endpoint_IsSETUPReceived(void) + { + return (&AVR32_USBB.UESTA0)[USB_Endpoint_SelectedEndpoint].rxstpi; + } + + /** Clears a received SETUP packet on the currently selected CONTROL type endpoint, freeing up the + * endpoint for the next packet. + * + * \ingroup Group_EndpointPacketManagement_UC3 + * + * \note This is not applicable for non CONTROL type endpoints. + */ + static inline void Endpoint_ClearSETUP(void) ATTR_ALWAYS_INLINE; + static inline void Endpoint_ClearSETUP(void) + { + (&AVR32_USBB.UESTA0CLR)[USB_Endpoint_SelectedEndpoint].rxstpic = true; + USB_Endpoint_FIFOPos[USB_Endpoint_SelectedEndpoint] = &AVR32_USBB_SLAVE[USB_Endpoint_SelectedEndpoint * ENDPOINT_HSB_ADDRESS_SPACE_SIZE]; + } + + /** Sends an IN packet to the host on the currently selected endpoint, freeing up the endpoint for the + * next packet and switching to the alternative endpoint bank if double banked. + * + * \ingroup Group_EndpointPacketManagement_UC3 + */ + static inline void Endpoint_ClearIN(void) ATTR_ALWAYS_INLINE; + static inline void Endpoint_ClearIN(void) + { + (&AVR32_USBB.UESTA0CLR)[USB_Endpoint_SelectedEndpoint].txinic = true; + (&AVR32_USBB.UECON0CLR)[USB_Endpoint_SelectedEndpoint].fifoconc = true; + USB_Endpoint_FIFOPos[USB_Endpoint_SelectedEndpoint] = &AVR32_USBB_SLAVE[USB_Endpoint_SelectedEndpoint * ENDPOINT_HSB_ADDRESS_SPACE_SIZE]; + } + + /** Acknowledges an OUT packet to the host on the currently selected endpoint, freeing up the endpoint + * for the next packet and switching to the alternative endpoint bank if double banked. + * + * \ingroup Group_EndpointPacketManagement_UC3 + */ + static inline void Endpoint_ClearOUT(void) ATTR_ALWAYS_INLINE; + static inline void Endpoint_ClearOUT(void) + { + (&AVR32_USBB.UESTA0CLR)[USB_Endpoint_SelectedEndpoint].rxoutic = true; + (&AVR32_USBB.UECON0CLR)[USB_Endpoint_SelectedEndpoint].fifoconc = true; + USB_Endpoint_FIFOPos[USB_Endpoint_SelectedEndpoint] = &AVR32_USBB_SLAVE[USB_Endpoint_SelectedEndpoint * ENDPOINT_HSB_ADDRESS_SPACE_SIZE]; + } + + /** Stalls the current endpoint, indicating to the host that a logical problem occurred with the + * indicated endpoint and that the current transfer sequence should be aborted. This provides a + * way for devices to indicate invalid commands to the host so that the current transfer can be + * aborted and the host can begin its own recovery sequence. + * + * The currently selected endpoint remains stalled until either the \ref Endpoint_ClearStall() macro + * is called, or the host issues a CLEAR FEATURE request to the device for the currently selected + * endpoint. + * + * \ingroup Group_EndpointPacketManagement_UC3 + */ + static inline void Endpoint_StallTransaction(void) ATTR_ALWAYS_INLINE; + static inline void Endpoint_StallTransaction(void) + { + (&AVR32_USBB.UECON0SET)[USB_Endpoint_SelectedEndpoint].stallrqs = true; + } + + /** Clears the STALL condition on the currently selected endpoint. + * + * \ingroup Group_EndpointPacketManagement_UC3 + */ + static inline void Endpoint_ClearStall(void) ATTR_ALWAYS_INLINE; + static inline void Endpoint_ClearStall(void) + { + (&AVR32_USBB.UECON0CLR)[USB_Endpoint_SelectedEndpoint].stallrqc = true; + } + + /** Determines if the currently selected endpoint is stalled, false otherwise. + * + * \ingroup Group_EndpointPacketManagement_UC3 + * + * \return Boolean \c true if the currently selected endpoint is stalled, \c false otherwise. + */ + static inline bool Endpoint_IsStalled(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool Endpoint_IsStalled(void) + { + return (&AVR32_USBB.UECON0)[USB_Endpoint_SelectedEndpoint].stallrq; + } + + /** Resets the data toggle of the currently selected endpoint. */ + static inline void Endpoint_ResetDataToggle(void) ATTR_ALWAYS_INLINE; + static inline void Endpoint_ResetDataToggle(void) + { + (&AVR32_USBB.UECON0SET)[USB_Endpoint_SelectedEndpoint].rstdts = true; + } + + /** Sets the direction of the currently selected endpoint. + * + * \param[in] DirectionMask New endpoint direction, as a \c ENDPOINT_DIR_* mask. + */ + static inline void Endpoint_SetEndpointDirection(const uint32_t DirectionMask) ATTR_ALWAYS_INLINE; + static inline void Endpoint_SetEndpointDirection(const uint32_t DirectionMask) + { + (&AVR32_USBB.UECFG0)[USB_Endpoint_SelectedEndpoint].epdir = (DirectionMask == ENDPOINT_DIR_IN); + } + + /** Reads one byte from the currently selected endpoint's bank, for OUT direction endpoints. + * + * \ingroup Group_EndpointPrimitiveRW_UC3 + * + * \return Next byte in the currently selected endpoint's FIFO buffer. + */ + static inline uint8_t Endpoint_Read_8(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint8_t Endpoint_Read_8(void) + { + return *(USB_Endpoint_FIFOPos[USB_Endpoint_SelectedEndpoint]++); + } + + /** Writes one byte to the currently selected endpoint's bank, for IN direction endpoints. + * + * \ingroup Group_EndpointPrimitiveRW_UC3 + * + * \param[in] Data Data to write into the the currently selected endpoint's FIFO buffer. + */ + static inline void Endpoint_Write_8(const uint8_t Data) ATTR_ALWAYS_INLINE; + static inline void Endpoint_Write_8(const uint8_t Data) + { + *(USB_Endpoint_FIFOPos[USB_Endpoint_SelectedEndpoint]++) = Data; + } + + /** Discards one byte from the currently selected endpoint's bank, for OUT direction endpoints. + * + * \ingroup Group_EndpointPrimitiveRW_UC3 + */ + static inline void Endpoint_Discard_8(void) ATTR_ALWAYS_INLINE; + static inline void Endpoint_Discard_8(void) + { + uint8_t Dummy; + + Dummy = *(USB_Endpoint_FIFOPos[USB_Endpoint_SelectedEndpoint]++); + + (void)Dummy; + } + + /** Reads two bytes from the currently selected endpoint's bank in little endian format, for OUT + * direction endpoints. + * + * \ingroup Group_EndpointPrimitiveRW_UC3 + * + * \return Next two bytes in the currently selected endpoint's FIFO buffer. + */ + static inline uint16_t Endpoint_Read_16_LE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint16_t Endpoint_Read_16_LE(void) + { + uint16_t Byte0 = *(USB_Endpoint_FIFOPos[USB_Endpoint_SelectedEndpoint]++); + uint16_t Byte1 = *(USB_Endpoint_FIFOPos[USB_Endpoint_SelectedEndpoint]++); + + return ((Byte1 << 8) | Byte0); + } + + /** Reads two bytes from the currently selected endpoint's bank in big endian format, for OUT + * direction endpoints. + * + * \ingroup Group_EndpointPrimitiveRW_UC3 + * + * \return Next two bytes in the currently selected endpoint's FIFO buffer. + */ + static inline uint16_t Endpoint_Read_16_BE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint16_t Endpoint_Read_16_BE(void) + { + uint16_t Byte0 = *(USB_Endpoint_FIFOPos[USB_Endpoint_SelectedEndpoint]++); + uint16_t Byte1 = *(USB_Endpoint_FIFOPos[USB_Endpoint_SelectedEndpoint]++); + + return ((Byte0 << 8) | Byte1); + } + + /** Writes two bytes to the currently selected endpoint's bank in little endian format, for IN + * direction endpoints. + * + * \ingroup Group_EndpointPrimitiveRW_UC3 + * + * \param[in] Data Data to write to the currently selected endpoint's FIFO buffer. + */ + static inline void Endpoint_Write_16_LE(const uint16_t Data) ATTR_ALWAYS_INLINE; + static inline void Endpoint_Write_16_LE(const uint16_t Data) + { + *(USB_Endpoint_FIFOPos[USB_Endpoint_SelectedEndpoint]++) = (Data & 0xFF); + *(USB_Endpoint_FIFOPos[USB_Endpoint_SelectedEndpoint]++) = (Data >> 8); + } + + /** Writes two bytes to the currently selected endpoint's bank in big endian format, for IN + * direction endpoints. + * + * \ingroup Group_EndpointPrimitiveRW_UC3 + * + * \param[in] Data Data to write to the currently selected endpoint's FIFO buffer. + */ + static inline void Endpoint_Write_16_BE(const uint16_t Data) ATTR_ALWAYS_INLINE; + static inline void Endpoint_Write_16_BE(const uint16_t Data) + { + *(USB_Endpoint_FIFOPos[USB_Endpoint_SelectedEndpoint]++) = (Data >> 8); + *(USB_Endpoint_FIFOPos[USB_Endpoint_SelectedEndpoint]++) = (Data & 0xFF); + } + + /** Discards two bytes from the currently selected endpoint's bank, for OUT direction endpoints. + * + * \ingroup Group_EndpointPrimitiveRW_UC3 + */ + static inline void Endpoint_Discard_16(void) ATTR_ALWAYS_INLINE; + static inline void Endpoint_Discard_16(void) + { + uint8_t Dummy; + + Dummy = *(USB_Endpoint_FIFOPos[USB_Endpoint_SelectedEndpoint]++); + Dummy = *(USB_Endpoint_FIFOPos[USB_Endpoint_SelectedEndpoint]++); + + (void)Dummy; + } + + /** Reads four bytes from the currently selected endpoint's bank in little endian format, for OUT + * direction endpoints. + * + * \ingroup Group_EndpointPrimitiveRW_UC3 + * + * \return Next four bytes in the currently selected endpoint's FIFO buffer. + */ + static inline uint32_t Endpoint_Read_32_LE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint32_t Endpoint_Read_32_LE(void) + { + uint32_t Byte0 = *(USB_Endpoint_FIFOPos[USB_Endpoint_SelectedEndpoint]++); + uint32_t Byte1 = *(USB_Endpoint_FIFOPos[USB_Endpoint_SelectedEndpoint]++); + uint32_t Byte2 = *(USB_Endpoint_FIFOPos[USB_Endpoint_SelectedEndpoint]++); + uint32_t Byte3 = *(USB_Endpoint_FIFOPos[USB_Endpoint_SelectedEndpoint]++); + + return ((Byte3 << 24) | (Byte2 << 16) | (Byte1 << 8) | Byte0); + } + + /** Reads four bytes from the currently selected endpoint's bank in big endian format, for OUT + * direction endpoints. + * + * \ingroup Group_EndpointPrimitiveRW_UC3 + * + * \return Next four bytes in the currently selected endpoint's FIFO buffer. + */ + static inline uint32_t Endpoint_Read_32_BE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint32_t Endpoint_Read_32_BE(void) + { + uint32_t Byte0 = *(USB_Endpoint_FIFOPos[USB_Endpoint_SelectedEndpoint]++); + uint32_t Byte1 = *(USB_Endpoint_FIFOPos[USB_Endpoint_SelectedEndpoint]++); + uint32_t Byte2 = *(USB_Endpoint_FIFOPos[USB_Endpoint_SelectedEndpoint]++); + uint32_t Byte3 = *(USB_Endpoint_FIFOPos[USB_Endpoint_SelectedEndpoint]++); + + return ((Byte0 << 24) | (Byte1 << 16) | (Byte2 << 8) | Byte3); + } + + /** Writes four bytes to the currently selected endpoint's bank in little endian format, for IN + * direction endpoints. + * + * \ingroup Group_EndpointPrimitiveRW_UC3 + * + * \param[in] Data Data to write to the currently selected endpoint's FIFO buffer. + */ + static inline void Endpoint_Write_32_LE(const uint32_t Data) ATTR_ALWAYS_INLINE; + static inline void Endpoint_Write_32_LE(const uint32_t Data) + { + *(USB_Endpoint_FIFOPos[USB_Endpoint_SelectedEndpoint]++) = (Data & 0xFF); + *(USB_Endpoint_FIFOPos[USB_Endpoint_SelectedEndpoint]++) = (Data >> 8); + *(USB_Endpoint_FIFOPos[USB_Endpoint_SelectedEndpoint]++) = (Data >> 16); + *(USB_Endpoint_FIFOPos[USB_Endpoint_SelectedEndpoint]++) = (Data >> 24); + } + + /** Writes four bytes to the currently selected endpoint's bank in big endian format, for IN + * direction endpoints. + * + * \ingroup Group_EndpointPrimitiveRW_UC3 + * + * \param[in] Data Data to write to the currently selected endpoint's FIFO buffer. + */ + static inline void Endpoint_Write_32_BE(const uint32_t Data) ATTR_ALWAYS_INLINE; + static inline void Endpoint_Write_32_BE(const uint32_t Data) + { + *(USB_Endpoint_FIFOPos[USB_Endpoint_SelectedEndpoint]++) = (Data >> 24); + *(USB_Endpoint_FIFOPos[USB_Endpoint_SelectedEndpoint]++) = (Data >> 16); + *(USB_Endpoint_FIFOPos[USB_Endpoint_SelectedEndpoint]++) = (Data >> 8); + *(USB_Endpoint_FIFOPos[USB_Endpoint_SelectedEndpoint]++) = (Data & 0xFF); + } + + /** Discards four bytes from the currently selected endpoint's bank, for OUT direction endpoints. + * + * \ingroup Group_EndpointPrimitiveRW_UC3 + */ + static inline void Endpoint_Discard_32(void) ATTR_ALWAYS_INLINE; + static inline void Endpoint_Discard_32(void) + { + uint8_t Dummy; + + Dummy = *(USB_Endpoint_FIFOPos[USB_Endpoint_SelectedEndpoint]++); + Dummy = *(USB_Endpoint_FIFOPos[USB_Endpoint_SelectedEndpoint]++); + Dummy = *(USB_Endpoint_FIFOPos[USB_Endpoint_SelectedEndpoint]++); + Dummy = *(USB_Endpoint_FIFOPos[USB_Endpoint_SelectedEndpoint]++); + + (void)Dummy; + } + + /* External Variables: */ + /** Global indicating the maximum packet size of the default control endpoint located at address + * 0 in the device. This value is set to the value indicated in the device descriptor in the user + * project once the USB interface is initialized into device mode. + * + * If space is an issue, it is possible to fix this to a static value by defining the control + * endpoint size in the \c FIXED_CONTROL_ENDPOINT_SIZE token passed to the compiler in the makefile + * via the -D switch. When a fixed control endpoint size is used, the size is no longer dynamically + * read from the descriptors at runtime and instead fixed to the given value. When used, it is + * important that the descriptor control endpoint size value matches the size given as the + * \c FIXED_CONTROL_ENDPOINT_SIZE token - it is recommended that the \c FIXED_CONTROL_ENDPOINT_SIZE token + * be used in the device descriptors to ensure this. + * + * \attention This variable should be treated as read-only in the user application, and never manually + * changed in value. + */ + #if (!defined(FIXED_CONTROL_ENDPOINT_SIZE) || defined(__DOXYGEN__)) + extern uint8_t USB_Device_ControlEndpointSize; + #else + #define USB_Device_ControlEndpointSize FIXED_CONTROL_ENDPOINT_SIZE + #endif + + /* Function Prototypes: */ + /** Configures a table of endpoint descriptions, in sequence. This function can be used to configure multiple + * endpoints at the same time. + * + * \note Endpoints with a zero address will be ignored, thus this function cannot be used to configure the + * control endpoint. + * + * \param[in] Table Pointer to a table of endpoint descriptions. + * \param[in] Entries Number of entries in the endpoint table to configure. + * + * \return Boolean \c true if all endpoints configured successfully, \c false otherwise. + */ + bool Endpoint_ConfigureEndpointTable(const USB_Endpoint_Table_t* const Table, + const uint8_t Entries); + + /** Completes the status stage of a control transfer on a CONTROL type endpoint automatically, + * with respect to the data direction. This is a convenience function which can be used to + * simplify user control request handling. + * + * \note This routine should not be called on non CONTROL type endpoints. + */ + void Endpoint_ClearStatusStage(void); + + /** Spin-loops until the currently selected non-control endpoint is ready for the next packet of data + * to be read or written to it. + * + * \note This routine should not be called on CONTROL type endpoints. + * + * \ingroup Group_EndpointRW_UC3 + * + * \return A value from the \ref Endpoint_WaitUntilReady_ErrorCodes_t enum. + */ + uint8_t Endpoint_WaitUntilReady(void); + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/Host_UC3.c b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/Host_UC3.c new file mode 100644 index 00000000..24e2136e --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/Host_UC3.c @@ -0,0 +1,294 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#include "../../../../Common/Common.h" +#if (ARCH == ARCH_UC3) + +#define __INCLUDE_FROM_USB_DRIVER +#include "../USBMode.h" + +#if defined(USB_CAN_BE_HOST) + +#define __INCLUDE_FROM_HOST_C +#include "../Host.h" + +void USB_Host_ProcessNextHostState(void) +{ + uint8_t ErrorCode = HOST_ENUMERROR_NoError; + uint8_t SubErrorCode = HOST_ENUMERROR_NoError; + + static uint16_t WaitMSRemaining; + static uint8_t PostWaitState; + + switch (USB_HostState) + { + case HOST_STATE_WaitForDevice: + if (WaitMSRemaining) + { + if ((SubErrorCode = USB_Host_WaitMS(1)) != HOST_WAITERROR_Successful) + { + USB_HostState = PostWaitState; + ErrorCode = HOST_ENUMERROR_WaitStage; + break; + } + + if (!(--WaitMSRemaining)) + USB_HostState = PostWaitState; + } + + break; + case HOST_STATE_Powered: + WaitMSRemaining = HOST_DEVICE_SETTLE_DELAY_MS; + + USB_HostState = HOST_STATE_Powered_WaitForDeviceSettle; + break; + case HOST_STATE_Powered_WaitForDeviceSettle: + if (WaitMSRemaining--) + { + Delay_MS(1); + break; + } + else + { + USB_Host_VBUS_Manual_Off(); + + USB_OTGPAD_On(); + USB_Host_VBUS_Auto_Enable(); + USB_Host_VBUS_Auto_On(); + + #if defined(NO_AUTO_VBUS_MANAGEMENT) + USB_Host_VBUS_Manual_Enable(); + USB_Host_VBUS_Manual_On(); + #endif + + USB_HostState = HOST_STATE_Powered_WaitForConnect; + } + + break; + case HOST_STATE_Powered_WaitForConnect: + if (USB_INT_HasOccurred(USB_INT_DCONNI)) + { + USB_INT_Clear(USB_INT_DCONNI); + USB_INT_Clear(USB_INT_DDISCI); + + USB_INT_Clear(USB_INT_VBERRI); + USB_INT_Enable(USB_INT_VBERRI); + + USB_Host_ResumeBus(); + Pipe_ClearPipes(); + + HOST_TASK_NONBLOCK_WAIT(100, HOST_STATE_Powered_DoReset); + } + + break; + case HOST_STATE_Powered_DoReset: + USB_Host_ResetDevice(); + + HOST_TASK_NONBLOCK_WAIT(200, HOST_STATE_Powered_ConfigPipe); + break; + case HOST_STATE_Powered_ConfigPipe: + if (!(Pipe_ConfigurePipe(PIPE_CONTROLPIPE, EP_TYPE_CONTROL, ENDPOINT_CONTROLEP, PIPE_CONTROLPIPE_DEFAULT_SIZE, 1))) + { + ErrorCode = HOST_ENUMERROR_PipeConfigError; + SubErrorCode = 0; + break; + } + + USB_HostState = HOST_STATE_Default; + break; + case HOST_STATE_Default: + USB_ControlRequest = (USB_Request_Header_t) + { + .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_STANDARD | REQREC_DEVICE), + .bRequest = REQ_GetDescriptor, + .wValue = (DTYPE_Device << 8), + .wIndex = 0, + .wLength = 8, + }; + + uint8_t DataBuffer[8]; + + Pipe_SelectPipe(PIPE_CONTROLPIPE); + if ((SubErrorCode = USB_Host_SendControlRequest(DataBuffer)) != HOST_SENDCONTROL_Successful) + { + ErrorCode = HOST_ENUMERROR_ControlError; + break; + } + + USB_Host_ControlPipeSize = DataBuffer[offsetof(USB_Descriptor_Device_t, Endpoint0Size)]; + + USB_Host_ResetDevice(); + + HOST_TASK_NONBLOCK_WAIT(200, HOST_STATE_Default_PostReset); + break; + case HOST_STATE_Default_PostReset: + if (!(Pipe_ConfigurePipe(PIPE_CONTROLPIPE, EP_TYPE_CONTROL, ENDPOINT_CONTROLEP, USB_Host_ControlPipeSize, 1))) + { + ErrorCode = HOST_ENUMERROR_PipeConfigError; + SubErrorCode = 0; + break; + } + + USB_ControlRequest = (USB_Request_Header_t) + { + .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_DEVICE), + .bRequest = REQ_SetAddress, + .wValue = USB_HOST_DEVICEADDRESS, + .wIndex = 0, + .wLength = 0, + }; + + if ((SubErrorCode = USB_Host_SendControlRequest(NULL)) != HOST_SENDCONTROL_Successful) + { + ErrorCode = HOST_ENUMERROR_ControlError; + break; + } + + HOST_TASK_NONBLOCK_WAIT(100, HOST_STATE_Default_PostAddressSet); + break; + case HOST_STATE_Default_PostAddressSet: + USB_Host_SetDeviceAddress(USB_HOST_DEVICEADDRESS); + + USB_HostState = HOST_STATE_Addressed; + + EVENT_USB_Host_DeviceEnumerationComplete(); + break; + } + + if ((ErrorCode != HOST_ENUMERROR_NoError) && (USB_HostState != HOST_STATE_Unattached)) + { + EVENT_USB_Host_DeviceEnumerationFailed(ErrorCode, SubErrorCode); + + USB_Host_VBUS_Auto_Off(); + + EVENT_USB_Host_DeviceUnattached(); + + USB_ResetInterface(); + } +} + +uint8_t USB_Host_WaitMS(uint8_t MS) +{ + bool BusSuspended = USB_Host_IsBusSuspended(); + uint8_t ErrorCode = HOST_WAITERROR_Successful; + bool HSOFIEnabled = USB_INT_IsEnabled(USB_INT_HSOFI); + + USB_INT_Disable(USB_INT_HSOFI); + USB_INT_Clear(USB_INT_HSOFI); + + USB_Host_ResumeBus(); + + while (MS) + { + if (USB_INT_HasOccurred(USB_INT_HSOFI)) + { + USB_INT_Clear(USB_INT_HSOFI); + MS--; + } + + if ((USB_HostState == HOST_STATE_Unattached) || (USB_CurrentMode != USB_MODE_Host)) + { + ErrorCode = HOST_WAITERROR_DeviceDisconnect; + + break; + } + + if (Pipe_IsError()) + { + Pipe_ClearError(); + ErrorCode = HOST_WAITERROR_PipeError; + + break; + } + + if (Pipe_IsStalled()) + { + Pipe_ClearStall(); + ErrorCode = HOST_WAITERROR_SetupStalled; + + break; + } + } + + if (BusSuspended) + USB_Host_SuspendBus(); + + if (HSOFIEnabled) + USB_INT_Enable(USB_INT_HSOFI); + + return ErrorCode; +} + +static void USB_Host_ResetDevice(void) +{ + bool BusSuspended = USB_Host_IsBusSuspended(); + + USB_INT_Disable(USB_INT_DDISCI); + + USB_Host_ResetBus(); + while (!(USB_Host_IsBusResetComplete())); + USB_Host_ResumeBus(); + + USB_Host_ConfigurationNumber = 0; + + bool HSOFIEnabled = USB_INT_IsEnabled(USB_INT_HSOFI); + + USB_INT_Disable(USB_INT_HSOFI); + USB_INT_Clear(USB_INT_HSOFI); + + for (uint8_t MSRem = 10; MSRem != 0; MSRem--) + { + /* Workaround for powerless-pull-up devices. After a USB bus reset, + all disconnection interrupts are suppressed while a USB frame is + looked for - if it is found within 10ms, the device is still + present. */ + + if (USB_INT_HasOccurred(USB_INT_HSOFI)) + { + USB_INT_Clear(USB_INT_HSOFI); + USB_INT_Clear(USB_INT_DDISCI); + break; + } + + Delay_MS(1); + } + + if (HSOFIEnabled) + USB_INT_Enable(USB_INT_HSOFI); + + if (BusSuspended) + USB_Host_SuspendBus(); + + USB_INT_Enable(USB_INT_DDISCI); +} + +#endif + +#endif diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/Host_UC3.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/Host_UC3.h new file mode 100644 index 00000000..07559cd3 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/Host_UC3.h @@ -0,0 +1,363 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief USB Host definitions for the AVR32 UC3B microcontrollers. + * \copydetails Group_Host_UC3B + * + * \note This file should not be included directly. It is automatically included as needed by the USB driver + * dispatch header located in LUFA/Drivers/USB/USB.h. + */ + +/** \ingroup Group_Host + * \defgroup Group_Host_UC3B Host Management (UC3B) + * \brief USB Host definitions for the AVR32 UC3B microcontrollers. + * + * Architecture specific USB Host definitions for the Atmel 32-bit AVR UC3B microcontrollers. + * + * @{ + */ + +#ifndef __USBHOST_UC3B_H__ +#define __USBHOST_UC3B_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + #include "../StdDescriptors.h" + #include "../Pipe.h" + #include "../USBInterrupt.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_USB_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB/USB.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Indicates the fixed USB device address which any attached device is enumerated to when in + * host mode. As only one USB device may be attached to the AVR in host mode at any one time + * and that the address used is not important (other than the fact that it is non-zero), a + * fixed value is specified by the library. + */ + #define USB_HOST_DEVICEADDRESS 1 + + #if !defined(HOST_DEVICE_SETTLE_DELAY_MS) || defined(__DOXYGEN__) + /** Constant for the delay in milliseconds after a device is connected before the library + * will start the enumeration process. Some devices require a delay of up to 5 seconds + * after connection before the enumeration process can start or incorrect operation will + * occur. + * + * The default delay value may be overridden in the user project makefile by defining the + * \c HOST_DEVICE_SETTLE_DELAY_MS token to the required delay in milliseconds, and passed to the + * compiler using the -D switch. + */ + #define HOST_DEVICE_SETTLE_DELAY_MS 1000 + #endif + + /* Enums: */ + /** Enum for the error codes for the \ref EVENT_USB_Host_HostError() event. + * + * \see \ref Group_Events for more information on this event. + */ + enum USB_Host_ErrorCodes_t + { + HOST_ERROR_VBusVoltageDip = 0, /**< VBUS voltage dipped to an unacceptable level. This + * error may be the result of an attached device drawing + * too much current from the VBUS line, or due to the + * AVR's power source being unable to supply sufficient + * current. + */ + }; + + /** Enum for the error codes for the \ref EVENT_USB_Host_DeviceEnumerationFailed() event. + * + * \see \ref Group_Events for more information on this event. + */ + enum USB_Host_EnumerationErrorCodes_t + { + HOST_ENUMERROR_NoError = 0, /**< No error occurred. Used internally, this is not a valid + * ErrorCode parameter value for the \ref EVENT_USB_Host_DeviceEnumerationFailed() + * event. + */ + HOST_ENUMERROR_WaitStage = 1, /**< One of the delays between enumeration steps failed + * to complete successfully, due to a timeout or other + * error. + */ + HOST_ENUMERROR_NoDeviceDetected = 2, /**< No device was detected, despite the USB data lines + * indicating the attachment of a device. + */ + HOST_ENUMERROR_ControlError = 3, /**< One of the enumeration control requests failed to + * complete successfully. + */ + HOST_ENUMERROR_PipeConfigError = 4, /**< The default control pipe (address 0) failed to + * configure correctly. + */ + }; + + /* Inline Functions: */ + /** Returns the current USB frame number, when in host mode. Every millisecond the USB bus is active (i.e. not suspended) + * the frame number is incremented by one. + * + * \return Current USB frame number from the USB controller. + */ + static inline uint16_t USB_Host_GetFrameNumber(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint16_t USB_Host_GetFrameNumber(void) + { + return AVR32_USBB_UHFNUM; + } + + #if !defined(NO_SOF_EVENTS) + /** Enables the host mode Start Of Frame events. When enabled, this causes the + * \ref EVENT_USB_Host_StartOfFrame() event to fire once per millisecond, synchronized to the USB bus, + * at the start of each USB frame when a device is enumerated while in host mode. + * + * \note This function is not available when the \c NO_SOF_EVENTS compile time token is defined. + */ + static inline void USB_Host_EnableSOFEvents(void) ATTR_ALWAYS_INLINE; + static inline void USB_Host_EnableSOFEvents(void) + { + USB_INT_Enable(USB_INT_HSOFI); + } + + /** Disables the host mode Start Of Frame events. When disabled, this stops the firing of the + * \ref EVENT_USB_Host_StartOfFrame() event when enumerated in host mode. + * + * \note This function is not available when the \c NO_SOF_EVENTS compile time token is defined. + */ + static inline void USB_Host_DisableSOFEvents(void) ATTR_ALWAYS_INLINE; + static inline void USB_Host_DisableSOFEvents(void) + { + USB_INT_Disable(USB_INT_HSOFI); + } + #endif + + /** Resets the USB bus, including the endpoints in any attached device and pipes on the AVR host. + * USB bus resets leave the default control pipe configured (if already configured). + * + * If the USB bus has been suspended prior to issuing a bus reset, the attached device will be + * woken up automatically and the bus resumed after the reset has been correctly issued. + */ + static inline void USB_Host_ResetBus(void) ATTR_ALWAYS_INLINE; + static inline void USB_Host_ResetBus(void) + { + AVR32_USBB.UHCON.reset = true; + } + + /** Determines if a previously issued bus reset (via the \ref USB_Host_ResetBus() macro) has + * completed. + * + * \return Boolean \c true if no bus reset is currently being sent, \c false otherwise. + */ + static inline bool USB_Host_IsBusResetComplete(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool USB_Host_IsBusResetComplete(void) + { + return AVR32_USBB.UHCON.reset; + } + + /** Resumes USB communications with an attached and enumerated device, by resuming the transmission + * of the 1MS Start Of Frame messages to the device. When resumed, USB communications between the + * host and attached device may occur. + */ + static inline void USB_Host_ResumeBus(void) ATTR_ALWAYS_INLINE; + static inline void USB_Host_ResumeBus(void) + { + AVR32_USBB.UHCON.sofe = true; + } + + /** Suspends the USB bus, preventing any communications from occurring between the host and attached + * device until the bus has been resumed. This stops the transmission of the 1MS Start Of Frame + * messages to the device. + * + * \note While the USB bus is suspended, all USB interrupt sources are also disabled; this means that + * some events (such as device disconnections) will not fire until the bus is resumed. + */ + static inline void USB_Host_SuspendBus(void) ATTR_ALWAYS_INLINE; + static inline void USB_Host_SuspendBus(void) + { + AVR32_USBB.UHCON.sofe = false; + } + + /** Determines if the USB bus has been suspended via the use of the \ref USB_Host_SuspendBus() macro, + * false otherwise. While suspended, no USB communications can occur until the bus is resumed, + * except for the Remote Wakeup event from the device if supported. + * + * \return Boolean \c true if the bus is currently suspended, \c false otherwise. + */ + static inline bool USB_Host_IsBusSuspended(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool USB_Host_IsBusSuspended(void) + { + return AVR32_USBB.UHCON.sofe; + } + + /** Determines if the attached device is currently enumerated in Full Speed mode (12Mb/s), or + * false if the attached device is enumerated in Low Speed mode (1.5Mb/s). + * + * \return Boolean \c true if the attached device is enumerated in Full Speed mode, \c false otherwise. + */ + static inline bool USB_Host_IsDeviceFullSpeed(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool USB_Host_IsDeviceFullSpeed(void) + { + return (AVR32_USBB.USBSTA.speed == AVR32_USBB_SPEED_FULL); + } + + /** Determines if the attached device is currently issuing a Remote Wakeup request, requesting + * that the host resume the USB bus and wake up the device, false otherwise. + * + * \return Boolean \c true if the attached device has sent a Remote Wakeup request, \c false otherwise. + */ + static inline bool USB_Host_IsRemoteWakeupSent(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool USB_Host_IsRemoteWakeupSent(void) + { + return AVR32_USBB.UHINT.rxrsmi; + } + + /** Clears the flag indicating that a Remote Wakeup request has been issued by an attached device. */ + static inline void USB_Host_ClearRemoteWakeupSent(void) ATTR_ALWAYS_INLINE; + static inline void USB_Host_ClearRemoteWakeupSent(void) + { + AVR32_USBB.UHINTCLR.rxrsmic = true; + } + + /** Accepts a Remote Wakeup request from an attached device. This must be issued in response to + * a device's Remote Wakeup request within 2ms for the request to be accepted and the bus to + * be resumed. + */ + static inline void USB_Host_ResumeFromWakeupRequest(void) ATTR_ALWAYS_INLINE; + static inline void USB_Host_ResumeFromWakeupRequest(void) + { + AVR32_USBB.UHCON.resume = true; + } + + /** Determines if a resume from Remote Wakeup request is currently being sent to an attached + * device. + * + * \return Boolean \c true if no resume request is currently being sent, \c false otherwise. + */ + static inline bool USB_Host_IsResumeFromWakeupRequestSent(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool USB_Host_IsResumeFromWakeupRequestSent(void) + { + return AVR32_USBB.UHCON.resume; + } + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Macros: */ + static inline void USB_Host_HostMode_On(void) ATTR_ALWAYS_INLINE; + static inline void USB_Host_HostMode_On(void) + { + // Not required for UC3B + } + + static inline void USB_Host_HostMode_Off(void) ATTR_ALWAYS_INLINE; + static inline void USB_Host_HostMode_Off(void) + { + // Not required for UC3B + } + + static inline void USB_Host_VBUS_Auto_Enable(void) ATTR_ALWAYS_INLINE; + static inline void USB_Host_VBUS_Auto_Enable(void) + { + AVR32_USBB.USBCON.vbushwc = false; + } + + static inline void USB_Host_VBUS_Manual_Enable(void) ATTR_ALWAYS_INLINE; + static inline void USB_Host_VBUS_Manual_Enable(void) + { + AVR32_USBB.USBCON.vbushwc = true; + } + + static inline void USB_Host_VBUS_Auto_On(void) ATTR_ALWAYS_INLINE; + static inline void USB_Host_VBUS_Auto_On(void) + { + AVR32_USBB.USBSTASET.vbusrqs = true; + } + + static inline void USB_Host_VBUS_Manual_On(void) ATTR_ALWAYS_INLINE; + static inline void USB_Host_VBUS_Manual_On(void) + { + AVR32_USBB.USBSTASET.vbusrqs = true; + } + + static inline void USB_Host_VBUS_Auto_Off(void) ATTR_ALWAYS_INLINE; + static inline void USB_Host_VBUS_Auto_Off(void) + { + AVR32_USBB.USBSTACLR.vbusrqc = true; + } + + static inline void USB_Host_VBUS_Manual_Off(void) ATTR_ALWAYS_INLINE; + static inline void USB_Host_VBUS_Manual_Off(void) + { + AVR32_USBB.USBSTACLR.vbusrqc = true; + } + + static inline void USB_Host_SetDeviceAddress(const uint8_t Address) ATTR_ALWAYS_INLINE; + static inline void USB_Host_SetDeviceAddress(const uint8_t Address) + { + AVR32_USBB.UHADDR1.uhaddr_p0 = Address; + AVR32_USBB.UHADDR1.uhaddr_p1 = Address; + AVR32_USBB.UHADDR1.uhaddr_p2 = Address; + AVR32_USBB.UHADDR1.uhaddr_p3 = Address; + AVR32_USBB.UHADDR2.uhaddr_p4 = Address; + AVR32_USBB.UHADDR2.uhaddr_p5 = Address; + AVR32_USBB.UHADDR2.uhaddr_p6 = Address; + } + + /* Enums: */ + enum USB_Host_WaitMSErrorCodes_t + { + HOST_WAITERROR_Successful = 0, + HOST_WAITERROR_DeviceDisconnect = 1, + HOST_WAITERROR_PipeError = 2, + HOST_WAITERROR_SetupStalled = 3, + }; + + /* Function Prototypes: */ + void USB_Host_ProcessNextHostState(void); + uint8_t USB_Host_WaitMS(uint8_t MS); + + #if defined(__INCLUDE_FROM_HOST_C) + static void USB_Host_ResetDevice(void); + #endif + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/PipeStream_UC3.c b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/PipeStream_UC3.c new file mode 100644 index 00000000..20c8bf1e --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/PipeStream_UC3.c @@ -0,0 +1,166 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#include "../../../../Common/Common.h" +#if (ARCH == ARCH_UC3) + +#define __INCLUDE_FROM_USB_DRIVER +#include "../USBMode.h" + +#if defined(USB_CAN_BE_HOST) + +#include "PipeStream_UC3.h" + +uint8_t Pipe_Discard_Stream(uint16_t Length, + uint16_t* const BytesProcessed) +{ + uint8_t ErrorCode; + uint16_t BytesInTransfer = 0; + + Pipe_SetPipeToken(PIPE_TOKEN_IN); + + if ((ErrorCode = Pipe_WaitUntilReady())) + return ErrorCode; + + if (BytesProcessed != NULL) + Length -= *BytesProcessed; + + while (Length) + { + if (!(Pipe_IsReadWriteAllowed())) + { + Pipe_ClearIN(); + + if (BytesProcessed != NULL) + { + *BytesProcessed += BytesInTransfer; + return PIPE_RWSTREAM_IncompleteTransfer; + } + + if ((ErrorCode = Pipe_WaitUntilReady())) + return ErrorCode; + } + else + { + Pipe_Discard_8(); + + Length--; + BytesInTransfer++; + } + } + + return PIPE_RWSTREAM_NoError; +} + +uint8_t Pipe_Null_Stream(uint16_t Length, + uint16_t* const BytesProcessed) +{ + uint8_t ErrorCode; + uint16_t BytesInTransfer = 0; + + Pipe_SetPipeToken(PIPE_TOKEN_OUT); + + if ((ErrorCode = Pipe_WaitUntilReady())) + return ErrorCode; + + if (BytesProcessed != NULL) + Length -= *BytesProcessed; + + while (Length) + { + if (!(Pipe_IsReadWriteAllowed())) + { + Pipe_ClearOUT(); + + if (BytesProcessed != NULL) + { + *BytesProcessed += BytesInTransfer; + return PIPE_RWSTREAM_IncompleteTransfer; + } + + USB_USBTask(); + + if ((ErrorCode = Pipe_WaitUntilReady())) + return ErrorCode; + } + else + { + Pipe_Write_8(0); + + Length--; + BytesInTransfer++; + } + } + + return PIPE_RWSTREAM_NoError; +} + +/* The following abuses the C preprocessor in order to copy-paste common code with slight alterations, + * so that the code needs to be written once. It is a crude form of templating to reduce code maintenance. */ + +#define TEMPLATE_FUNC_NAME Pipe_Write_Stream_LE +#define TEMPLATE_BUFFER_TYPE const void* +#define TEMPLATE_TOKEN PIPE_TOKEN_OUT +#define TEMPLATE_CLEAR_PIPE() Pipe_ClearOUT() +#define TEMPLATE_BUFFER_OFFSET(Length) 0 +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) DataStream += Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Pipe_Write_8(*BufferPtr) +#include "Template/Template_Pipe_RW.c" + +#define TEMPLATE_FUNC_NAME Pipe_Write_Stream_BE +#define TEMPLATE_BUFFER_TYPE const void* +#define TEMPLATE_TOKEN PIPE_TOKEN_OUT +#define TEMPLATE_CLEAR_PIPE() Pipe_ClearOUT() +#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) DataStream -= Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Pipe_Write_8(*BufferPtr) +#include "Template/Template_Pipe_RW.c" + +#define TEMPLATE_FUNC_NAME Pipe_Read_Stream_LE +#define TEMPLATE_BUFFER_TYPE void* +#define TEMPLATE_TOKEN PIPE_TOKEN_IN +#define TEMPLATE_CLEAR_PIPE() Pipe_ClearIN() +#define TEMPLATE_BUFFER_OFFSET(Length) 0 +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) DataStream += Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *BufferPtr = Pipe_Read_8() +#include "Template/Template_Pipe_RW.c" + +#define TEMPLATE_FUNC_NAME Pipe_Read_Stream_BE +#define TEMPLATE_BUFFER_TYPE void* +#define TEMPLATE_TOKEN PIPE_TOKEN_IN +#define TEMPLATE_CLEAR_PIPE() Pipe_ClearIN() +#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) DataStream -= Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *BufferPtr = Pipe_Read_8() +#include "Template/Template_Pipe_RW.c" + +#endif + +#endif diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/PipeStream_UC3.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/PipeStream_UC3.h new file mode 100644 index 00000000..34c82ad2 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/PipeStream_UC3.h @@ -0,0 +1,352 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Pipe data stream transmission and reception management for the AVR32 UC3 microcontrollers. + * \copydetails Group_PipeStreamRW_UC3 + * + * \note This file should not be included directly. It is automatically included as needed by the USB driver + * dispatch header located in LUFA/Drivers/USB/USB.h. + */ + +/** \ingroup Group_PipeStreamRW + * \defgroup Group_PipeStreamRW_UC3 Read/Write of Multi-Byte Streams (UC3) + * \brief Pipe data stream transmission and reception management for the Atmel AVR32 UC3 architecture. + * + * Functions, macros, variables, enums and types related to data reading and writing of data streams from + * and to pipes. + * + * @{ + */ + +#ifndef __PIPE_STREAM_UC3_H__ +#define __PIPE_STREAM_UC3_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + #include "../USBMode.h" + #include "../USBTask.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_USB_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB/USB.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Function Prototypes: */ + /** \name Stream functions for null data */ + //@{ + + /** Reads and discards the given number of bytes from the pipe, discarding fully read packets from the host + * as needed. The last packet is not automatically discarded once the remaining bytes has been read; the + * user is responsible for manually discarding the last packet from the device via the \ref Pipe_ClearIN() macro. + * + * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, failing or + * succeeding as a single unit. If the BytesProcessed parameter points to a valid storage location, the transfer + * will instead be performed as a series of chunks. Each time the pipe bank becomes empty while there is still data + * to process (and after the current packet has been acknowledged) the BytesProcessed location will be updated with + * the total number of bytes processed in the stream, and the function will exit with an error code of + * \ref PIPE_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed in the user code - to + * continue the transfer, call the function again with identical parameters and it will resume until the BytesProcessed + * value reaches the total transfer length. + * + * Single Stream Transfer Example: + * \code + * uint8_t ErrorCode; + * + * if ((ErrorCode = Pipe_Discard_Stream(512, NULL)) != PIPE_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * Partial Stream Transfers Example: + * \code + * uint8_t ErrorCode; + * uint16_t BytesProcessed; + * + * BytesProcessed = 0; + * while ((ErrorCode = Pipe_Discard_Stream(512, &BytesProcessed)) == PIPE_RWSTREAM_IncompleteTransfer) + * { + * // Stream not yet complete - do other actions here, abort if required + * } + * + * if (ErrorCode != PIPE_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * \note The pipe token is set automatically, thus this can be used on bi-directional pipes directly without + * having to explicitly change the data direction with a call to \ref Pipe_SetPipeToken(). + * + * \param[in] Length Number of bytes to discard via the currently selected pipe. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should + * updated, \c NULL if the entire stream should be processed at once. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Pipe_Discard_Stream(uint16_t Length, + uint16_t* const BytesProcessed); + + /** Writes a given number of zeroed bytes to the pipe, sending full pipe packets from the host to the device + * as needed. The last packet is not automatically sent once the remaining bytes has been written; the + * user is responsible for manually discarding the last packet from the device via the \ref Pipe_ClearOUT() macro. + * + * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, failing or + * succeeding as a single unit. If the BytesProcessed parameter points to a valid storage location, the transfer + * will instead be performed as a series of chunks. Each time the pipe bank becomes full while there is still data + * to process (and after the current packet transmission has been initiated) the BytesProcessed location will be + * updated with the total number of bytes processed in the stream, and the function will exit with an error code of + * \ref PIPE_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed in the user code - to + * continue the transfer, call the function again with identical parameters and it will resume until the BytesProcessed + * value reaches the total transfer length. + * + * Single Stream Transfer Example: + * \code + * uint8_t ErrorCode; + * + * if ((ErrorCode = Pipe_Null_Stream(512, NULL)) != PIPE_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * Partial Stream Transfers Example: + * \code + * uint8_t ErrorCode; + * uint16_t BytesProcessed; + * + * BytesProcessed = 0; + * while ((ErrorCode = Pipe_Null_Stream(512, &BytesProcessed)) == PIPE_RWSTREAM_IncompleteTransfer) + * { + * // Stream not yet complete - do other actions here, abort if required + * } + * + * if (ErrorCode != PIPE_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * \note The pipe token is set automatically, thus this can be used on bi-directional pipes directly without + * having to explicitly change the data direction with a call to \ref Pipe_SetPipeToken(). + * + * \param[in] Length Number of zero bytes to write via the currently selected pipe. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should + * updated, \c NULL if the entire stream should be processed at once. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Pipe_Null_Stream(uint16_t Length, + uint16_t* const BytesProcessed); + + //@} + + /** \name Stream functions for RAM source/destination data */ + //@{ + + /** Writes the given number of bytes to the pipe from the given buffer in little endian, + * sending full packets to the device as needed. The last packet filled is not automatically sent; + * the user is responsible for manually sending the last written packet to the host via the + * \ref Pipe_ClearOUT() macro. Between each USB packet, the given stream callback function is + * executed repeatedly until the next packet is ready, allowing for early aborts of stream transfers. + * + * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, + * failing or succeeding as a single unit. If the BytesProcessed parameter points to a valid + * storage location, the transfer will instead be performed as a series of chunks. Each time + * the pipe bank becomes full while there is still data to process (and after the current + * packet transmission has been initiated) the BytesProcessed location will be updated with the + * total number of bytes processed in the stream, and the function will exit with an error code of + * \ref PIPE_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed + * in the user code - to continue the transfer, call the function again with identical parameters + * and it will resume until the BytesProcessed value reaches the total transfer length. + * + * Single Stream Transfer Example: + * \code + * uint8_t DataStream[512]; + * uint8_t ErrorCode; + * + * if ((ErrorCode = Pipe_Write_Stream_LE(DataStream, sizeof(DataStream), + * NULL)) != PIPE_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * Partial Stream Transfers Example: + * \code + * uint8_t DataStream[512]; + * uint8_t ErrorCode; + * uint16_t BytesProcessed; + * + * BytesProcessed = 0; + * while ((ErrorCode = Pipe_Write_Stream_LE(DataStream, sizeof(DataStream), + * &BytesProcessed)) == PIPE_RWSTREAM_IncompleteTransfer) + * { + * // Stream not yet complete - do other actions here, abort if required + * } + * + * if (ErrorCode != PIPE_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * \note The pipe token is set automatically, thus this can be used on bi-directional pipes directly without + * having to explicitly change the data direction with a call to \ref Pipe_SetPipeToken(). + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected pipe into the buffer. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should + * updated, \c NULL if the entire stream should be written at once. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Pipe_Write_Stream_LE(const void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** Writes the given number of bytes to the pipe from the given buffer in big endian, + * sending full packets to the device as needed. The last packet filled is not automatically sent; + * the user is responsible for manually sending the last written packet to the host via the + * \ref Pipe_ClearOUT() macro. Between each USB packet, the given stream callback function is + * executed repeatedly until the next packet is ready, allowing for early aborts of stream transfers. + * + * \note The pipe token is set automatically, thus this can be used on bi-directional pipes directly without + * having to explicitly change the data direction with a call to \ref Pipe_SetPipeToken(). + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected pipe into the buffer. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should + * updated, \c NULL if the entire stream should be written at once. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Pipe_Write_Stream_BE(const void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** Reads the given number of bytes from the pipe into the given buffer in little endian, + * sending full packets to the device as needed. The last packet filled is not automatically sent; + * the user is responsible for manually sending the last written packet to the host via the + * \ref Pipe_ClearIN() macro. Between each USB packet, the given stream callback function is + * executed repeatedly until the next packet is ready, allowing for early aborts of stream transfers. + * + * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, + * failing or succeeding as a single unit. If the BytesProcessed parameter points to a valid + * storage location, the transfer will instead be performed as a series of chunks. Each time + * the pipe bank becomes empty while there is still data to process (and after the current + * packet has been acknowledged) the BytesProcessed location will be updated with the total number + * of bytes processed in the stream, and the function will exit with an error code of + * \ref PIPE_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed + * in the user code - to continue the transfer, call the function again with identical parameters + * and it will resume until the BytesProcessed value reaches the total transfer length. + * + * Single Stream Transfer Example: + * \code + * uint8_t DataStream[512]; + * uint8_t ErrorCode; + * + * if ((ErrorCode = Pipe_Read_Stream_LE(DataStream, sizeof(DataStream), + * NULL)) != PIPE_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * Partial Stream Transfers Example: + * \code + * uint8_t DataStream[512]; + * uint8_t ErrorCode; + * uint16_t BytesProcessed; + * + * BytesProcessed = 0; + * while ((ErrorCode = Pipe_Read_Stream_LE(DataStream, sizeof(DataStream), + * &BytesProcessed)) == PIPE_RWSTREAM_IncompleteTransfer) + * { + * // Stream not yet complete - do other actions here, abort if required + * } + * + * if (ErrorCode != PIPE_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * \note The pipe token is set automatically, thus this can be used on bi-directional pipes directly without + * having to explicitly change the data direction with a call to \ref Pipe_SetPipeToken(). + * + * \param[out] Buffer Pointer to the source data buffer to write to. + * \param[in] Length Number of bytes to read for the currently selected pipe to read from. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should + * updated, \c NULL if the entire stream should be read at once. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Pipe_Read_Stream_LE(void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** Reads the given number of bytes from the pipe into the given buffer in big endian, + * sending full packets to the device as needed. The last packet filled is not automatically sent; + * the user is responsible for manually sending the last written packet to the host via the + * \ref Pipe_ClearIN() macro. Between each USB packet, the given stream callback function is + * executed repeatedly until the next packet is ready, allowing for early aborts of stream transfers. + * + * \note The pipe token is set automatically, thus this can be used on bi-directional pipes directly without + * having to explicitly change the data direction with a call to \ref Pipe_SetPipeToken(). + * + * \param[out] Buffer Pointer to the source data buffer to write to. + * \param[in] Length Number of bytes to read for the currently selected pipe to read from. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes already processed should + * updated, \c NULL if the entire stream should be read at once. + * + * \return A value from the \ref Pipe_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Pipe_Read_Stream_BE(void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + //@} + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/Pipe_UC3.c b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/Pipe_UC3.c new file mode 100644 index 00000000..6128869b --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/Pipe_UC3.c @@ -0,0 +1,209 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#include "../../../../Common/Common.h" +#if (ARCH == ARCH_UC3) + +#define __INCLUDE_FROM_USB_DRIVER +#include "../USBMode.h" + +#if defined(USB_CAN_BE_HOST) + +#include "../Pipe.h" + +uint8_t USB_Host_ControlPipeSize = PIPE_CONTROLPIPE_DEFAULT_SIZE; + +volatile uint32_t USB_Pipe_SelectedPipe = PIPE_CONTROLPIPE; +volatile uint8_t* USB_Pipe_FIFOPos[PIPE_TOTAL_PIPES]; + +bool Pipe_ConfigurePipeTable(const USB_Pipe_Table_t* const Table, + const uint8_t Entries) +{ + for (uint8_t i = 0; i < Entries; i++) + { + if (!(Table[i].Address)) + continue; + + if (!(Pipe_ConfigurePipe(Table[i].Address, Table[i].Type, Table[i].EndpointAddress, Table[i].Size, Table[i].Banks))) + { + return false; + } + } + + return true; +} + +bool Pipe_ConfigurePipe(const uint8_t Address, + const uint8_t Type, + const uint8_t EndpointAddress, + const uint16_t Size, + const uint8_t Banks) +{ + uint8_t Number = (Address & PIPE_EPNUM_MASK); + uint8_t Token = (Address & PIPE_DIR_IN) ? PIPE_TOKEN_IN : PIPE_TOKEN_OUT; + + if (Number >= PIPE_TOTAL_PIPES) + return false; + + if (Type == EP_TYPE_CONTROL) + Token = PIPE_TOKEN_SETUP; + + USB_Pipe_FIFOPos[Number] = &AVR32_USBB_SLAVE[Number * PIPE_HSB_ADDRESS_SPACE_SIZE]; + +#if defined(ORDERED_EP_CONFIG) + Pipe_SelectPipe(Number); + Pipe_EnablePipe(); + + (&AVR32_USBB.upcfg0)[Number] = 0; + (&AVR32_USBB.upcfg0)[Number] = (AVR32_USBB_ALLOC_MASK | + ((uint32_t)Type << AVR32_USBB_PTYPE_OFFSET) | + ((uint32_t)Token << AVR32_USBB_PTOKEN_OFFSET) | + ((Banks > 1) ? AVR32_USBB_PBK_MASK : 0) | + Pipe_BytesToEPSizeMask(Size) | + ((uint32_t)Number << AVR32_USBB_PEPNUM_OFFSET)); + + Pipe_SetInfiniteINRequests(); + + return Pipe_IsConfigured(); +#else + for (uint8_t PNum = Number; PNum < PIPE_TOTAL_PIPES; PNum++) + { + uint32_t UPCFG0Temp; + + Pipe_SelectPipe(PNum); + + if (PNum == Number) + { + UPCFG0Temp = (AVR32_USBB_ALLOC_MASK | + ((uint32_t)Type << AVR32_USBB_PTYPE_OFFSET) | + ((uint32_t)Token << AVR32_USBB_PTOKEN_OFFSET) | + ((Banks > 1) ? AVR32_USBB_PBK_MASK : 0) | + Pipe_BytesToEPSizeMask(Size) | + ((EndpointAddress & PIPE_EPNUM_MASK) << AVR32_USBB_PEPNUM_OFFSET)); + } + else + { + UPCFG0Temp = (&AVR32_USBB.upcfg0)[PNum]; + } + + if (!(UPCFG0Temp & AVR32_USBB_ALLOC_MASK)) + continue; + + Pipe_DisablePipe(); + (&AVR32_USBB.upcfg0)[PNum] &= ~AVR32_USBB_ALLOC_MASK; + + Pipe_EnablePipe(); + (&AVR32_USBB.upcfg0)[PNum] = UPCFG0Temp; + + Pipe_SetInfiniteINRequests(); + + if (!(Pipe_IsConfigured())) + return false; + } + + Pipe_SelectPipe(Number); + return true; +#endif +} + +void Pipe_ClearPipes(void) +{ + for (uint8_t PNum = 0; PNum < PIPE_TOTAL_PIPES; PNum++) + { + Pipe_SelectPipe(PNum); + (&AVR32_USBB.upcfg0)[PNum] = 0; + (&AVR32_USBB.upcon0clr)[PNum] = -1; + USB_Pipe_FIFOPos[PNum] = &AVR32_USBB_SLAVE[PNum * 0x10000]; + Pipe_DisablePipe(); + } +} + +bool Pipe_IsEndpointBound(const uint8_t EndpointAddress) +{ + uint8_t PrevPipeNumber = Pipe_GetCurrentPipe(); + + for (uint8_t PNum = 0; PNum < PIPE_TOTAL_PIPES; PNum++) + { + Pipe_SelectPipe(PNum); + + if (!(Pipe_IsConfigured())) + continue; + + if (Pipe_GetBoundEndpointAddress() == EndpointAddress) + return true; + } + + Pipe_SelectPipe(PrevPipeNumber); + return false; +} + +uint8_t Pipe_WaitUntilReady(void) +{ + #if (USB_STREAM_TIMEOUT_MS < 0xFF) + uint8_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS; + #else + uint16_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS; + #endif + + uint16_t PreviousFrameNumber = USB_Host_GetFrameNumber(); + + for (;;) + { + if (Pipe_GetPipeToken() == PIPE_TOKEN_IN) + { + if (Pipe_IsINReceived()) + return PIPE_READYWAIT_NoError; + } + else + { + if (Pipe_IsOUTReady()) + return PIPE_READYWAIT_NoError; + } + + if (Pipe_IsStalled()) + return PIPE_READYWAIT_PipeStalled; + else if (USB_HostState == HOST_STATE_Unattached) + return PIPE_READYWAIT_DeviceDisconnected; + + uint16_t CurrentFrameNumber = USB_Host_GetFrameNumber(); + + if (CurrentFrameNumber != PreviousFrameNumber) + { + PreviousFrameNumber = CurrentFrameNumber; + + if (!(TimeoutMSRem--)) + return PIPE_READYWAIT_Timeout; + } + } +} + +#endif + +#endif diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/Pipe_UC3.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/Pipe_UC3.h new file mode 100644 index 00000000..6de574e9 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/Pipe_UC3.h @@ -0,0 +1,924 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief USB Pipe definitions for the AVR32 UC3 microcontrollers. + * \copydetails Group_PipeManagement_UC3 + * + * \note This file should not be included directly. It is automatically included as needed by the USB driver + * dispatch header located in LUFA/Drivers/USB/USB.h. + */ + +/** \ingroup Group_PipeRW + * \defgroup Group_PipeRW_UC3 Pipe Data Reading and Writing (UC3) + * \brief Pipe data read/write definitions for the Atmel AVR32 UC3 architecture. + * + * Functions, macros, variables, enums and types related to data reading and writing from and to pipes. + */ + +/** \ingroup Group_PipePrimitiveRW + * \defgroup Group_PipePrimitiveRW_UC3 Read/Write of Primitive Data Types (UC3) + * \brief Pipe primitive data read/write definitions for the Atmel AVR32 UC3 architecture. + * + * Functions, macros, variables, enums and types related to data reading and writing of primitive data types + * from and to pipes. + */ + +/** \ingroup Group_PipePacketManagement + * \defgroup Group_PipePacketManagement_UC3 Pipe Packet Management (UC3) + * \brief Pipe packet management definitions for the Atmel AVR32 UC3 architecture. + * + * Functions, macros, variables, enums and types related to packet management of pipes. + */ + +/** \ingroup Group_PipeControlReq + * \defgroup Group_PipeControlReq_UC3 Pipe Control Request Management (UC3) + * \brief Pipe control request management definitions for the Atmel AVR32 UC3 architecture. + * + * Module for host mode request processing. This module allows for the transmission of standard, class and + * vendor control requests to the default control endpoint of an attached device while in host mode. + * + * \see Chapter 9 of the USB 2.0 specification. + */ + +/** \ingroup Group_PipeManagement + * \defgroup Group_PipeManagement_UC3 Pipe Management (UC3) + * \brief Pipe management definitions for the Atmel AVR32 UC3 architecture. + * + * This module contains functions, macros and enums related to pipe management when in USB Host mode. This + * module contains the pipe management macros, as well as pipe interrupt and data send/receive functions + * for various data types. + * + * @{ + */ + +#ifndef __PIPE_UC3_H__ +#define __PIPE_UC3_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + #include "../USBTask.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_USB_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB/USB.h instead. + #endif + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Macros: */ + #define PIPE_HSB_ADDRESS_SPACE_SIZE (64 * 1024UL) + + /* External Variables: */ + extern volatile uint32_t USB_Pipe_SelectedPipe; + extern volatile uint8_t* USB_Pipe_FIFOPos[]; + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** \name Pipe Error Flag Masks */ + //@{ + /** Mask for \ref Pipe_GetErrorFlags(), indicating that an overflow error occurred in the pipe on the received data. */ + #define PIPE_ERRORFLAG_OVERFLOW (AVR32_USBB_UPSTA0_OVERFI_MASK << 8) + + /** Mask for \ref Pipe_GetErrorFlags(), indicating that a CRC error occurred in the pipe on the received data. */ + #define PIPE_ERRORFLAG_CRC16 AVR32_USBB_UPERR0_CRC16_MASK + + /** Mask for \ref Pipe_GetErrorFlags(), indicating that a hardware timeout error occurred in the pipe. */ + #define PIPE_ERRORFLAG_TIMEOUT AVR32_USBB_UPERR0_TIMEOUT_MASK + + /** Mask for \ref Pipe_GetErrorFlags(), indicating that a hardware PID error occurred in the pipe. */ + #define PIPE_ERRORFLAG_PID AVR32_USBB_UPERR0_PID_MASK + + /** Mask for \ref Pipe_GetErrorFlags(), indicating that a hardware data PID error occurred in the pipe. */ + #define PIPE_ERRORFLAG_DATAPID AVR32_USBB_UPERR0_DATAPID_MASK + + /** Mask for \ref Pipe_GetErrorFlags(), indicating that a hardware data toggle error occurred in the pipe. */ + #define PIPE_ERRORFLAG_DATATGL AVR32_USBB_UPERR0_DATATGL_MASK + //@} + + /** \name Pipe Token Masks */ + //@{ + /** Token mask for \ref Pipe_SetPipeToken() and \ref Pipe_GetPipeToken(). This sets the pipe as a SETUP token (for CONTROL type pipes), + * which will trigger a control request on the attached device when data is written to the pipe. + */ + #define PIPE_TOKEN_SETUP AVR32_USBB_UPCFG0_PTOKEN_SETUP + + /** Token mask for \ref Pipe_SetPipeToken() and \ref Pipe_GetPipeToken(). This sets the pipe as a IN token (for non-CONTROL type pipes), + * indicating that the pipe data will flow from device to host. + */ + #define PIPE_TOKEN_IN AVR32_USBB_UPCFG0_PTOKEN_IN + + /** Token mask for \ref Pipe_SetPipeToken() and \ref Pipe_GetPipeToken(). This sets the pipe as a OUT token (for non-CONTROL type pipes), + * indicating that the pipe data will flow from host to device. + */ + #define PIPE_TOKEN_OUT AVR32_USBB_UPCFG0_PTOKEN_OUT + //@} + + /** Default size of the default control pipe's bank, until altered by the Endpoint0Size value + * in the device descriptor of the attached device. + */ + #define PIPE_CONTROLPIPE_DEFAULT_SIZE 64 + + #if defined(USB_SERIES_UC3A3_AVR32) || defined(USB_SERIES_UC3A4_AVR32) || defined(__DOXYGEN__) + /** Total number of pipes (including the default control pipe at address 0) which may be used in + * the device. + */ + #define PIPE_TOTAL_PIPES 8 + #else + #define PIPE_TOTAL_PIPES 7 + #endif + + /** Size in bytes of the largest pipe bank size possible in the device. Not all banks on each AVR + * model supports the largest bank size possible on the device; different pipe numbers support + * different maximum bank sizes. This value reflects the largest possible bank of any pipe on the + * currently selected UC3 AVR model. + */ + #define PIPE_MAX_SIZE 256 + + /* Enums: */ + /** Enum for the possible error return codes of the \ref Pipe_WaitUntilReady() function. + * + * \ingroup Group_PipeRW_UC3 + */ + enum Pipe_WaitUntilReady_ErrorCodes_t + { + PIPE_READYWAIT_NoError = 0, /**< Pipe ready for next packet, no error. */ + PIPE_READYWAIT_PipeStalled = 1, /**< The device stalled the pipe while waiting. */ + PIPE_READYWAIT_DeviceDisconnected = 2, /**< Device was disconnected from the host while waiting. */ + PIPE_READYWAIT_Timeout = 3, /**< The device failed to accept or send the next packet + * within the software timeout period set by the + * \ref USB_STREAM_TIMEOUT_MS macro. + */ + }; + + /* Inline Functions: */ + /** Indicates the number of bytes currently stored in the current pipes's selected bank. + * + * \ingroup Group_PipeRW_UC3 + * + * \return Total number of bytes in the currently selected pipe's FIFO buffer. + */ + static inline uint16_t Pipe_BytesInPipe(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint16_t Pipe_BytesInPipe(void) + { + return (&AVR32_USBB.UPSTA0)[USB_Pipe_SelectedPipe].pbyct; + } + + /** Determines the currently selected pipe's direction. + * + * \return The currently selected pipe's direction, as a \c PIPE_DIR_* mask. + */ + static inline uint8_t Pipe_GetPipeDirection(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint8_t Pipe_GetPipeDirection(void) + { + return (((&AVR32_USBB.UPCFG0)[USB_Pipe_SelectedPipe].ptoken == PIPE_TOKEN_OUT) ? PIPE_DIR_OUT : PIPE_DIR_IN); + } + + /** Returns the pipe address of the currently selected pipe. This is typically used to save the + * currently selected pipe number so that it can be restored after another pipe has been manipulated. + * + * \return Index of the currently selected pipe. + */ + static inline uint8_t Pipe_GetCurrentPipe(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint8_t Pipe_GetCurrentPipe(void) + { + return (USB_Pipe_SelectedPipe | Pipe_GetPipeDirection()); + } + + /** Selects the given pipe address. Any pipe operations which do not require the pipe address to be + * indicated will operate on the currently selected pipe. + * + * \param[in] Address Address of the pipe to select. + */ + static inline void Pipe_SelectPipe(const uint8_t Address) ATTR_ALWAYS_INLINE; + static inline void Pipe_SelectPipe(const uint8_t Address) + { + USB_Pipe_SelectedPipe = (Address & PIPE_EPNUM_MASK); + } + + /** Resets the desired pipe, including the pipe banks and flags. + * + * \param[in] Address Index of the pipe to reset. + */ + static inline void Pipe_ResetPipe(const uint8_t Address) ATTR_ALWAYS_INLINE; + static inline void Pipe_ResetPipe(const uint8_t Address) + { + uint32_t PipeNumber = (Address & PIPE_EPNUM_MASK); + + AVR32_USBB.uprst |= (AVR32_USBB_PRST0_MASK << PipeNumber); + AVR32_USBB.uprst &= ~(AVR32_USBB_PRST0_MASK << PipeNumber); + USB_Pipe_FIFOPos[PipeNumber] = &AVR32_USBB_SLAVE[PipeNumber * PIPE_HSB_ADDRESS_SPACE_SIZE]; + } + + /** Enables the currently selected pipe so that data can be sent and received through it to and from + * an attached device. + * + * \pre The currently selected pipe must first be configured properly via \ref Pipe_ConfigurePipe(). + */ + static inline void Pipe_EnablePipe(void) ATTR_ALWAYS_INLINE; + static inline void Pipe_EnablePipe(void) + { + AVR32_USBB.uprst |= (AVR32_USBB_PEN0_MASK << USB_Pipe_SelectedPipe); + } + + /** Disables the currently selected pipe so that data cannot be sent and received through it to and + * from an attached device. + */ + static inline void Pipe_DisablePipe(void) ATTR_ALWAYS_INLINE; + static inline void Pipe_DisablePipe(void) + { + AVR32_USBB.uprst &= ~(AVR32_USBB_PEN0_MASK << USB_Pipe_SelectedPipe); + } + + /** Determines if the currently selected pipe is enabled, but not necessarily configured. + * + * \return Boolean \c true if the currently selected pipe is enabled, \c false otherwise. + */ + static inline bool Pipe_IsEnabled(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool Pipe_IsEnabled(void) + { + return ((AVR32_USBB.uprst & (AVR32_USBB_PEN0_MASK << USB_Pipe_SelectedPipe)) ? true : false); + } + + /** Gets the current pipe token, indicating the pipe's data direction and type. + * + * \return The current pipe token, as a \c PIPE_TOKEN_* mask. + */ + static inline uint8_t Pipe_GetPipeToken(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint8_t Pipe_GetPipeToken(void) + { + return (&AVR32_USBB.UPCFG0)[USB_Pipe_SelectedPipe].ptoken; + } + + /** Sets the token for the currently selected pipe to one of the tokens specified by the \c PIPE_TOKEN_* + * masks. This can be used on CONTROL type pipes, to allow for bidirectional transfer of data during + * control requests, or on regular pipes to allow for half-duplex bidirectional data transfer to devices + * which have two endpoints of opposite direction sharing the same endpoint address within the device. + * + * \param[in] Token New pipe token to set the selected pipe to, as a \c PIPE_TOKEN_* mask. + */ + static inline void Pipe_SetPipeToken(const uint8_t Token) ATTR_ALWAYS_INLINE; + static inline void Pipe_SetPipeToken(const uint8_t Token) + { + (&AVR32_USBB.UPCFG0)[USB_Pipe_SelectedPipe].ptoken = Token; + } + + /** Configures the currently selected pipe to allow for an unlimited number of IN requests. */ + static inline void Pipe_SetInfiniteINRequests(void) ATTR_ALWAYS_INLINE; + static inline void Pipe_SetInfiniteINRequests(void) + { + (&AVR32_USBB.UPINRQ0)[USB_Pipe_SelectedPipe].inmode = true; + } + + /** Configures the currently selected pipe to only allow the specified number of IN requests to be + * accepted by the pipe before it is automatically frozen. + * + * \param[in] TotalINRequests Total number of IN requests that the pipe may receive before freezing. + */ + static inline void Pipe_SetFiniteINRequests(const uint8_t TotalINRequests) ATTR_ALWAYS_INLINE; + static inline void Pipe_SetFiniteINRequests(const uint8_t TotalINRequests) + { + (&AVR32_USBB.UPINRQ0)[USB_Pipe_SelectedPipe].inmode = false; + (&AVR32_USBB.UPINRQ0)[USB_Pipe_SelectedPipe].inrq = TotalINRequests; + } + + /** Determines if the currently selected pipe is configured. + * + * \return Boolean \c true if the selected pipe is configured, \c false otherwise. + */ + static inline bool Pipe_IsConfigured(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool Pipe_IsConfigured(void) + { + return (&AVR32_USBB.UPSTA0)[USB_Pipe_SelectedPipe].cfgok; + } + + /** Retrieves the endpoint address of the endpoint within the attached device that the currently selected + * pipe is bound to. + * + * \return Endpoint address the currently selected pipe is bound to. + */ + static inline uint8_t Pipe_GetBoundEndpointAddress(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint8_t Pipe_GetBoundEndpointAddress(void) + { + return ((&AVR32_USBB.UPCFG0)[USB_Pipe_SelectedPipe].pepnum | + ((Pipe_GetPipeToken() == PIPE_TOKEN_IN) ? PIPE_DIR_IN : PIPE_DIR_OUT)); + } + + /** Sets the period between interrupts for an INTERRUPT type pipe to a specified number of milliseconds. + * + * \param[in] Milliseconds Number of milliseconds between each pipe poll. + */ + static inline void Pipe_SetInterruptPeriod(const uint8_t Milliseconds) ATTR_ALWAYS_INLINE; + static inline void Pipe_SetInterruptPeriod(const uint8_t Milliseconds) + { + (&AVR32_USBB.UPCFG0)[USB_Pipe_SelectedPipe].intfrq = Milliseconds; + } + + /** Returns a mask indicating which pipe's interrupt periods have elapsed, indicating that the pipe should + * be serviced. + * + * \return Mask whose bits indicate which pipes have interrupted. + */ + static inline uint8_t Pipe_GetPipeInterrupts(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint8_t Pipe_GetPipeInterrupts(void) + { + return ((AVR32_USBB.uhint & (AVR32_USBB_P6INT_MASK | AVR32_USBB_P5INT_MASK | + AVR32_USBB_P4INT_MASK | AVR32_USBB_P3INT_MASK | + AVR32_USBB_P2INT_MASK | AVR32_USBB_P1INT_MASK | + AVR32_USBB_P0INT_MASK)) >> AVR32_USBB_P0INT_OFFSET); + } + + /** Determines if the specified pipe address has interrupted (valid only for INTERRUPT type + * pipes). + * + * \param[in] Address Address of the pipe whose interrupt flag should be tested. + * + * \return Boolean \c true if the specified pipe has interrupted, \c false otherwise. + */ + static inline bool Pipe_HasPipeInterrupted(const uint8_t Address) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool Pipe_HasPipeInterrupted(const uint8_t Address) + { + return ((AVR32_USBB.uhint & (AVR32_USBB_P0INTES_MASK << (Address & PIPE_EPNUM_MASK))) ? true : false); + } + + /** Unfreezes the selected pipe, allowing it to communicate with an attached device. */ + static inline void Pipe_Unfreeze(void) ATTR_ALWAYS_INLINE; + static inline void Pipe_Unfreeze(void) + { + (&AVR32_USBB.UPCON0CLR)[USB_Pipe_SelectedPipe].pfreezec = true; + } + + /** Freezes the selected pipe, preventing it from communicating with an attached device. */ + static inline void Pipe_Freeze(void) ATTR_ALWAYS_INLINE; + static inline void Pipe_Freeze(void) + { + (&AVR32_USBB.UPCON0SET)[USB_Pipe_SelectedPipe].pfreezes = true; + } + + /** Determines if the currently selected pipe is frozen, and not able to accept data. + * + * \return Boolean \c true if the currently selected pipe is frozen, \c false otherwise. + */ + static inline bool Pipe_IsFrozen(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool Pipe_IsFrozen(void) + { + return (((&AVR32_USBB.UPCON0)[USB_Pipe_SelectedPipe].pfreeze) ? true : false); + } + + /** Clears the error flags for the currently selected pipe. */ + static inline void Pipe_ClearError(void) ATTR_ALWAYS_INLINE; + static inline void Pipe_ClearError(void) + { + (&AVR32_USBB.uperr0)[USB_Pipe_SelectedPipe] = 0; + (&AVR32_USBB.UPSTA0CLR)[USB_Pipe_SelectedPipe].overfic = true; + } + + /** Determines if the master pipe error flag is set for the currently selected pipe, indicating that + * some sort of hardware error has occurred on the pipe. + * + * \see \ref Pipe_GetErrorFlags() macro for information on retrieving the exact error flag. + * + * \return Boolean \c true if an error has occurred on the selected pipe, \c false otherwise. + */ + static inline bool Pipe_IsError(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool Pipe_IsError(void) + { + return (((&AVR32_USBB.upsta0)[USB_Pipe_SelectedPipe] & + (AVR32_USBB_PERRI_MASK | AVR32_USBB_OVERFI_MASK)) ? true : false); + } + + /** Gets a mask of the hardware error flags which have occurred on the currently selected pipe. This + * value can then be masked against the \c PIPE_ERRORFLAG_* masks to determine what error has occurred. + * + * \return Mask comprising of \c PIPE_ERRORFLAG_* bits indicating what error has occurred on the selected pipe. + */ + static inline uint8_t Pipe_GetErrorFlags(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint8_t Pipe_GetErrorFlags(void) + { + + return (((&AVR32_USBB.uperr0)[USB_Pipe_SelectedPipe] & + (PIPE_ERRORFLAG_CRC16 | PIPE_ERRORFLAG_TIMEOUT | + PIPE_ERRORFLAG_PID | PIPE_ERRORFLAG_DATAPID | + PIPE_ERRORFLAG_DATATGL)) | + (((&AVR32_USBB.upsta0)[USB_Pipe_SelectedPipe] << 8) & + PIPE_ERRORFLAG_OVERFLOW)); + } + + /** Retrieves the number of busy banks in the currently selected pipe, which have been queued for + * transmission via the \ref Pipe_ClearOUT() command, or are awaiting acknowledgement via the + * \ref Pipe_ClearIN() command. + * + * \ingroup Group_PipePacketManagement_UC3 + * + * \return Total number of busy banks in the selected pipe. + */ + static inline uint8_t Pipe_GetBusyBanks(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint8_t Pipe_GetBusyBanks(void) + { + return (&AVR32_USBB.UPSTA0)[USB_Pipe_SelectedPipe].nbusybk; + } + + /** Determines if the currently selected pipe may be read from (if data is waiting in the pipe + * bank and the pipe is an IN direction, or if the bank is not yet full if the pipe is an OUT + * direction). This function will return false if an error has occurred in the pipe, or if the pipe + * is an IN direction and no packet (or an empty packet) has been received, or if the pipe is an OUT + * direction and the pipe bank is full. + * + * \note This function is not valid on CONTROL type pipes. + * + * \ingroup Group_PipePacketManagement_UC3 + * + * \return Boolean \c true if the currently selected pipe may be read from or written to, depending + * on its direction. + */ + static inline bool Pipe_IsReadWriteAllowed(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool Pipe_IsReadWriteAllowed(void) + { + return (&AVR32_USBB.UPSTA0)[USB_Pipe_SelectedPipe].rwall; + } + + /** Determines if a packet has been received on the currently selected IN pipe from the attached device. + * + * \ingroup Group_PipePacketManagement_UC3 + * + * \return Boolean \c true if the current pipe has received an IN packet, \c false otherwise. + */ + static inline bool Pipe_IsINReceived(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool Pipe_IsINReceived(void) + { + return (&AVR32_USBB.UPSTA0)[USB_Pipe_SelectedPipe].rxini; + } + + /** Determines if the currently selected OUT pipe is ready to send an OUT packet to the attached device. + * + * \ingroup Group_PipePacketManagement_UC3 + * + * \return Boolean \c true if the current pipe is ready for an OUT packet, \c false otherwise. + */ + static inline bool Pipe_IsOUTReady(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool Pipe_IsOUTReady(void) + { + return (&AVR32_USBB.UPSTA0)[USB_Pipe_SelectedPipe].txouti; + } + + /** Determines if no SETUP request is currently being sent to the attached device on the selected + * CONTROL type pipe. + * + * \ingroup Group_PipePacketManagement_UC3 + * + * \return Boolean \c true if the current pipe is ready for a SETUP packet, \c false otherwise. + */ + static inline bool Pipe_IsSETUPSent(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool Pipe_IsSETUPSent(void) + { + return (&AVR32_USBB.UPSTA0)[USB_Pipe_SelectedPipe].txstpi; + } + + /** Sends the currently selected CONTROL type pipe's contents to the device as a SETUP packet. + * + * \ingroup Group_PipePacketManagement_UC3 + */ + static inline void Pipe_ClearSETUP(void) ATTR_ALWAYS_INLINE; + static inline void Pipe_ClearSETUP(void) + { + (&AVR32_USBB.UPSTA0CLR)[USB_Pipe_SelectedPipe].txstpic = true; + (&AVR32_USBB.UPCON0CLR)[USB_Pipe_SelectedPipe].fifoconc = true; + USB_Pipe_FIFOPos[USB_Pipe_SelectedPipe] = &AVR32_USBB_SLAVE[USB_Pipe_SelectedPipe * PIPE_HSB_ADDRESS_SPACE_SIZE]; + } + + /** Acknowledges the reception of a setup IN request from the attached device on the currently selected + * pipe, freeing the bank ready for the next packet. + * + * \ingroup Group_PipePacketManagement_UC3 + */ + static inline void Pipe_ClearIN(void) ATTR_ALWAYS_INLINE; + static inline void Pipe_ClearIN(void) + { + (&AVR32_USBB.UPSTA0CLR)[USB_Pipe_SelectedPipe].rxinic = true; + (&AVR32_USBB.UPCON0CLR)[USB_Pipe_SelectedPipe].fifoconc = true; + USB_Pipe_FIFOPos[USB_Pipe_SelectedPipe] = &AVR32_USBB_SLAVE[USB_Pipe_SelectedPipe * PIPE_HSB_ADDRESS_SPACE_SIZE]; + } + + /** Sends the currently selected pipe's contents to the device as an OUT packet on the selected pipe, freeing + * the bank ready for the next packet. + * + * \ingroup Group_PipePacketManagement_UC3 + */ + static inline void Pipe_ClearOUT(void) ATTR_ALWAYS_INLINE; + static inline void Pipe_ClearOUT(void) + { + (&AVR32_USBB.UPSTA0CLR)[USB_Pipe_SelectedPipe].txoutic = true; + (&AVR32_USBB.UPCON0CLR)[USB_Pipe_SelectedPipe].fifoconc = true; + USB_Pipe_FIFOPos[USB_Pipe_SelectedPipe] = &AVR32_USBB_SLAVE[USB_Pipe_SelectedPipe * PIPE_HSB_ADDRESS_SPACE_SIZE]; + } + + /** Determines if the device sent a NAK (Negative Acknowledge) in response to the last sent packet on + * the currently selected pipe. This occurs when the host sends a packet to the device, but the device + * is not currently ready to handle the packet (i.e. its endpoint banks are full). Once a NAK has been + * received, it must be cleared using \ref Pipe_ClearNAKReceived() before the previous (or any other) packet + * can be re-sent. + * + * \ingroup Group_PipePacketManagement_UC3 + * + * \return Boolean \c true if an NAK has been received on the current pipe, \c false otherwise. + */ + static inline bool Pipe_IsNAKReceived(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool Pipe_IsNAKReceived(void) + { + return (&AVR32_USBB.UPSTA0)[USB_Pipe_SelectedPipe].nakedi; + } + + /** Clears the NAK condition on the currently selected pipe. + * + * \ingroup Group_PipePacketManagement_UC3 + * + * \see \ref Pipe_IsNAKReceived() for more details. + */ + static inline void Pipe_ClearNAKReceived(void) ATTR_ALWAYS_INLINE; + static inline void Pipe_ClearNAKReceived(void) + { + (&AVR32_USBB.UPSTA0CLR)[USB_Pipe_SelectedPipe].nakedic = true; + } + + /** Determines if the currently selected pipe has had the STALL condition set by the attached device. + * + * \ingroup Group_PipePacketManagement_UC3 + * + * \return Boolean \c true if the current pipe has been stalled by the attached device, \c false otherwise. + */ + static inline bool Pipe_IsStalled(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool Pipe_IsStalled(void) + { + return (&AVR32_USBB.UPSTA0)[USB_Pipe_SelectedPipe].rxstalldi; + } + + /** Clears the STALL condition detection flag on the currently selected pipe, but does not clear the + * STALL condition itself (this must be done via a ClearFeature control request to the device). + * + * \ingroup Group_PipePacketManagement_UC3 + */ + static inline void Pipe_ClearStall(void) ATTR_ALWAYS_INLINE; + static inline void Pipe_ClearStall(void) + { + (&AVR32_USBB.UPSTA0CLR)[USB_Pipe_SelectedPipe].rxstalldic = true; + USB_Pipe_FIFOPos[USB_Pipe_SelectedPipe] = &AVR32_USBB_SLAVE[USB_Pipe_SelectedPipe * PIPE_HSB_ADDRESS_SPACE_SIZE]; + } + + /** Reads one byte from the currently selected pipe's bank, for OUT direction pipes. + * + * \ingroup Group_PipePrimitiveRW_UC3 + * + * \return Next byte in the currently selected pipe's FIFO buffer. + */ + static inline uint8_t Pipe_Read_8(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint8_t Pipe_Read_8(void) + { + return *(USB_Pipe_FIFOPos[USB_Pipe_SelectedPipe]++); + } + + /** Writes one byte to the currently selected pipe's bank, for IN direction pipes. + * + * \ingroup Group_PipePrimitiveRW_UC3 + * + * \param[in] Data Data to write into the the currently selected pipe's FIFO buffer. + */ + static inline void Pipe_Write_8(const uint8_t Data) ATTR_ALWAYS_INLINE; + static inline void Pipe_Write_8(const uint8_t Data) + { + *(USB_Pipe_FIFOPos[USB_Pipe_SelectedPipe]++) = Data; + } + + /** Discards one byte from the currently selected pipe's bank, for OUT direction pipes. + * + * \ingroup Group_PipePrimitiveRW_UC3 + */ + static inline void Pipe_Discard_8(void) ATTR_ALWAYS_INLINE; + static inline void Pipe_Discard_8(void) + { + uint8_t Dummy; + + Dummy = *(USB_Pipe_FIFOPos[USB_Pipe_SelectedPipe]++); + + (void)Dummy; + } + + /** Reads two bytes from the currently selected pipe's bank in little endian format, for OUT + * direction pipes. + * + * \ingroup Group_PipePrimitiveRW_UC3 + * + * \return Next two bytes in the currently selected pipe's FIFO buffer. + */ + static inline uint16_t Pipe_Read_16_LE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint16_t Pipe_Read_16_LE(void) + { + uint16_t Byte0 = *(USB_Pipe_FIFOPos[USB_Pipe_SelectedPipe]++); + uint16_t Byte1 = *(USB_Pipe_FIFOPos[USB_Pipe_SelectedPipe]++); + + return ((Byte1 << 8) | Byte0); + } + + /** Reads two bytes from the currently selected pipe's bank in big endian format, for OUT + * direction pipes. + * + * \ingroup Group_PipePrimitiveRW_UC3 + * + * \return Next two bytes in the currently selected pipe's FIFO buffer. + */ + static inline uint16_t Pipe_Read_16_BE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint16_t Pipe_Read_16_BE(void) + { + uint16_t Byte0 = *(USB_Pipe_FIFOPos[USB_Pipe_SelectedPipe]++); + uint16_t Byte1 = *(USB_Pipe_FIFOPos[USB_Pipe_SelectedPipe]++); + + return ((Byte0 << 8) | Byte1); + } + + /** Writes two bytes to the currently selected pipe's bank in little endian format, for IN + * direction pipes. + * + * \ingroup Group_PipePrimitiveRW_UC3 + * + * \param[in] Data Data to write to the currently selected pipe's FIFO buffer. + */ + static inline void Pipe_Write_16_LE(const uint16_t Data) ATTR_ALWAYS_INLINE; + static inline void Pipe_Write_16_LE(const uint16_t Data) + { + *(USB_Pipe_FIFOPos[USB_Pipe_SelectedPipe]++) = (Data & 0xFF); + *(USB_Pipe_FIFOPos[USB_Pipe_SelectedPipe]++) = (Data >> 8); + } + + /** Writes two bytes to the currently selected pipe's bank in big endian format, for IN + * direction pipes. + * + * \ingroup Group_PipePrimitiveRW_UC3 + * + * \param[in] Data Data to write to the currently selected pipe's FIFO buffer. + */ + static inline void Pipe_Write_16_BE(const uint16_t Data) ATTR_ALWAYS_INLINE; + static inline void Pipe_Write_16_BE(const uint16_t Data) + { + *(USB_Pipe_FIFOPos[USB_Pipe_SelectedPipe]++) = (Data >> 8); + *(USB_Pipe_FIFOPos[USB_Pipe_SelectedPipe]++) = (Data & 0xFF); + } + + /** Discards two bytes from the currently selected pipe's bank, for OUT direction pipes. + * + * \ingroup Group_PipePrimitiveRW_UC3 + */ + static inline void Pipe_Discard_16(void) ATTR_ALWAYS_INLINE; + static inline void Pipe_Discard_16(void) + { + uint8_t Dummy; + + Dummy = *(USB_Pipe_FIFOPos[USB_Pipe_SelectedPipe]++); + Dummy = *(USB_Pipe_FIFOPos[USB_Pipe_SelectedPipe]++); + + (void)Dummy; + } + + /** Reads four bytes from the currently selected pipe's bank in little endian format, for OUT + * direction pipes. + * + * \ingroup Group_PipePrimitiveRW_UC3 + * + * \return Next four bytes in the currently selected pipe's FIFO buffer. + */ + static inline uint32_t Pipe_Read_32_LE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint32_t Pipe_Read_32_LE(void) + { + uint32_t Byte0 = *(USB_Pipe_FIFOPos[USB_Pipe_SelectedPipe]++); + uint32_t Byte1 = *(USB_Pipe_FIFOPos[USB_Pipe_SelectedPipe]++); + uint32_t Byte2 = *(USB_Pipe_FIFOPos[USB_Pipe_SelectedPipe]++); + uint32_t Byte3 = *(USB_Pipe_FIFOPos[USB_Pipe_SelectedPipe]++); + + return ((Byte3 << 24) | (Byte2 << 16) | (Byte1 << 8) | Byte0); + } + + /** Reads four bytes from the currently selected pipe's bank in big endian format, for OUT + * direction pipes. + * + * \ingroup Group_PipePrimitiveRW_UC3 + * + * \return Next four bytes in the currently selected pipe's FIFO buffer. + */ + static inline uint32_t Pipe_Read_32_BE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint32_t Pipe_Read_32_BE(void) + { + uint32_t Byte0 = *(USB_Pipe_FIFOPos[USB_Pipe_SelectedPipe]++); + uint32_t Byte1 = *(USB_Pipe_FIFOPos[USB_Pipe_SelectedPipe]++); + uint32_t Byte2 = *(USB_Pipe_FIFOPos[USB_Pipe_SelectedPipe]++); + uint32_t Byte3 = *(USB_Pipe_FIFOPos[USB_Pipe_SelectedPipe]++); + + return ((Byte0 << 24) | (Byte1 << 16) | (Byte2 << 8) | Byte3); + } + + /** Writes four bytes to the currently selected pipe's bank in little endian format, for IN + * direction pipes. + * + * \ingroup Group_PipePrimitiveRW_UC3 + * + * \param[in] Data Data to write to the currently selected pipe's FIFO buffer. + */ + static inline void Pipe_Write_32_LE(const uint32_t Data) ATTR_ALWAYS_INLINE; + static inline void Pipe_Write_32_LE(const uint32_t Data) + { + *(USB_Pipe_FIFOPos[USB_Pipe_SelectedPipe]++) = (Data & 0xFF); + *(USB_Pipe_FIFOPos[USB_Pipe_SelectedPipe]++) = (Data >> 8); + *(USB_Pipe_FIFOPos[USB_Pipe_SelectedPipe]++) = (Data >> 16); + *(USB_Pipe_FIFOPos[USB_Pipe_SelectedPipe]++) = (Data >> 24); + } + + /** Writes four bytes to the currently selected pipe's bank in big endian format, for IN + * direction pipes. + * + * \ingroup Group_PipePrimitiveRW_UC3 + * + * \param[in] Data Data to write to the currently selected pipe's FIFO buffer. + */ + static inline void Pipe_Write_32_BE(const uint32_t Data) ATTR_ALWAYS_INLINE; + static inline void Pipe_Write_32_BE(const uint32_t Data) + { + *(USB_Pipe_FIFOPos[USB_Pipe_SelectedPipe]++) = (Data >> 24); + *(USB_Pipe_FIFOPos[USB_Pipe_SelectedPipe]++) = (Data >> 16); + *(USB_Pipe_FIFOPos[USB_Pipe_SelectedPipe]++) = (Data >> 8); + *(USB_Pipe_FIFOPos[USB_Pipe_SelectedPipe]++) = (Data & 0xFF); + } + + /** Discards four bytes from the currently selected pipe's bank, for OUT direction pipes. + * + * \ingroup Group_PipePrimitiveRW_UC3 + */ + static inline void Pipe_Discard_32(void) ATTR_ALWAYS_INLINE; + static inline void Pipe_Discard_32(void) + { + uint8_t Dummy; + + Dummy = *(USB_Pipe_FIFOPos[USB_Pipe_SelectedPipe]++); + Dummy = *(USB_Pipe_FIFOPos[USB_Pipe_SelectedPipe]++); + Dummy = *(USB_Pipe_FIFOPos[USB_Pipe_SelectedPipe]++); + Dummy = *(USB_Pipe_FIFOPos[USB_Pipe_SelectedPipe]++); + + (void)Dummy; + } + + /* External Variables: */ + /** Global indicating the maximum packet size of the default control pipe located at address + * 0 in the device. This value is set to the value indicated in the attached device's device + * descriptor once the USB interface is initialized into host mode and a device is attached + * to the USB bus. + * + * \attention This variable should be treated as read-only in the user application, and never manually + * changed in value. + */ + extern uint8_t USB_Host_ControlPipeSize; + + /* Function Prototypes: */ + /** Configures a table of pipe descriptions, in sequence. This function can be used to configure multiple + * pipes at the same time. + * + * \note Pipe with a zero address will be ignored, thus this function cannot be used to configure the + * control pipe. + * + * \param[in] Table Pointer to a table of pipe descriptions. + * \param[in] Entries Number of entries in the pipe table to configure. + * + * \return Boolean \c true if all pipes configured successfully, \c false otherwise. + */ + bool Pipe_ConfigurePipeTable(const USB_Pipe_Table_t* const Table, + const uint8_t Entries); + + /** Configures the specified pipe address with the given pipe type, endpoint address within the attached device, bank size + * and number of hardware banks. + * + * A newly configured pipe is frozen by default, and must be unfrozen before use via the \ref Pipe_Unfreeze() + * before being used. Pipes should be kept frozen unless waiting for data from a device while in IN mode, or + * sending data to the device in OUT mode. IN type pipes are also automatically configured to accept infinite + * numbers of IN requests without automatic freezing - this can be overridden by a call to + * \ref Pipe_SetFiniteINRequests(). + * + * \param[in] Address Pipe address to configure. + * + * \param[in] Type Type of pipe to configure, an \c EP_TYPE_* mask. Not all pipe types are available on Low + * Speed USB devices - refer to the USB 2.0 specification. + * + * \param[in] EndpointAddress Endpoint address within the attached device that the pipe should interface to. + * + * \param[in] Size Size of the pipe's bank, where packets are stored before they are transmitted to + * the USB device, or after they have been received from the USB device (depending on + * the pipe's data direction). The bank size must indicate the maximum packet size that + * the pipe can handle. + * + * \param[in] Banks Number of banks to use for the pipe being configured. + * + * \note When the \c ORDERED_EP_CONFIG compile time option is used, Pipes must be configured in ascending order, + * or bank corruption will occur. + * \n\n + * + * \note Certain microcontroller model's pipes may have different maximum packet sizes based on the pipe's + * index - refer to the chosen microcontroller's datasheet to determine the maximum bank size for each pipe. + * \n\n + * + * \note The default control pipe should not be manually configured by the user application, as it is + * automatically configured by the library internally. + * \n\n + * + * \note This routine will automatically select the specified pipe upon success. Upon failure, the pipe which + * failed to reconfigure correctly will be selected. + * + * \return Boolean \c true if the configuration succeeded, \c false otherwise. + */ + bool Pipe_ConfigurePipe(const uint8_t Address, + const uint8_t Type, + const uint8_t EndpointAddress, + const uint16_t Size, + const uint8_t Banks); + + /** Spin-loops until the currently selected non-control pipe is ready for the next packet of data to be read + * or written to it, aborting in the case of an error condition (such as a timeout or device disconnect). + * + * \ingroup Group_PipeRW_UC3 + * + * \return A value from the \ref Pipe_WaitUntilReady_ErrorCodes_t enum. + */ + uint8_t Pipe_WaitUntilReady(void); + + /** Determines if a pipe has been bound to the given device endpoint address. If a pipe which is bound to the given + * endpoint is found, it is automatically selected. + * + * \param[in] EndpointAddress Address and direction mask of the endpoint within the attached device to check. + * + * \return Boolean \c true if a pipe bound to the given endpoint address of the specified direction is found, + * \c false otherwise. + */ + bool Pipe_IsEndpointBound(const uint8_t EndpointAddress) ATTR_WARN_UNUSED_RESULT; + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Macros: */ + #if !defined(ENDPOINT_CONTROLEP) + #define ENDPOINT_CONTROLEP 0 + #endif + + /* Inline Functions: */ + static inline uint8_t Pipe_BytesToEPSizeMask(const uint16_t Bytes) ATTR_WARN_UNUSED_RESULT ATTR_CONST ATTR_ALWAYS_INLINE; + static inline uint8_t Pipe_BytesToEPSizeMask(const uint16_t Bytes) + { + uint8_t MaskVal = 0; + uint16_t CheckBytes = 8; + + while ((CheckBytes < Bytes) && (CheckBytes < PIPE_MAX_SIZE)) + { + MaskVal++; + CheckBytes <<= 1; + } + + return (MaskVal << AVR32_USBB_PSIZE_OFFSET); + } + + /* Function Prototypes: */ + void Pipe_ClearPipes(void); + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/Template/Template_Endpoint_Control_R.c b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/Template/Template_Endpoint_Control_R.c new file mode 100644 index 00000000..ab69536b --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/Template/Template_Endpoint_Control_R.c @@ -0,0 +1,85 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#if defined(TEMPLATE_FUNC_NAME) + +// cppcheck-suppress unusedFunction +uint8_t TEMPLATE_FUNC_NAME (void* const Buffer, + uint16_t Length) +{ + uint8_t* DataStream = ((uint8_t*)Buffer + TEMPLATE_BUFFER_OFFSET(Length)); + + if (!(Length)) + Endpoint_ClearOUT(); + + while (Length) + { + uint8_t USB_DeviceState_LCL = USB_DeviceState; + + if (USB_DeviceState_LCL == DEVICE_STATE_Unattached) + return ENDPOINT_RWCSTREAM_DeviceDisconnected; + else if (USB_DeviceState_LCL == DEVICE_STATE_Suspended) + return ENDPOINT_RWCSTREAM_BusSuspended; + else if (Endpoint_IsSETUPReceived()) + return ENDPOINT_RWCSTREAM_HostAborted; + + if (Endpoint_IsOUTReceived()) + { + while (Length && Endpoint_BytesInEndpoint()) + { + TEMPLATE_TRANSFER_BYTE(DataStream); + TEMPLATE_BUFFER_MOVE(DataStream, 1); + Length--; + } + + Endpoint_ClearOUT(); + } + } + + while (!(Endpoint_IsINReady())) + { + uint8_t USB_DeviceState_LCL = USB_DeviceState; + + if (USB_DeviceState_LCL == DEVICE_STATE_Unattached) + return ENDPOINT_RWCSTREAM_DeviceDisconnected; + else if (USB_DeviceState_LCL == DEVICE_STATE_Suspended) + return ENDPOINT_RWCSTREAM_BusSuspended; + } + + return ENDPOINT_RWCSTREAM_NoError; +} + +#undef TEMPLATE_BUFFER_OFFSET +#undef TEMPLATE_BUFFER_MOVE +#undef TEMPLATE_FUNC_NAME +#undef TEMPLATE_TRANSFER_BYTE + +#endif + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/Template/Template_Endpoint_Control_W.c b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/Template/Template_Endpoint_Control_W.c new file mode 100644 index 00000000..c2d171db --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/Template/Template_Endpoint_Control_W.c @@ -0,0 +1,94 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#if defined(TEMPLATE_FUNC_NAME) + +// cppcheck-suppress unusedFunction +uint8_t TEMPLATE_FUNC_NAME (const void* const Buffer, + uint16_t Length) +{ + uint8_t* DataStream = ((uint8_t*)Buffer + TEMPLATE_BUFFER_OFFSET(Length)); + bool LastPacketFull = false; + + if (Length > USB_ControlRequest.wLength) + Length = USB_ControlRequest.wLength; + else if (!(Length)) + Endpoint_ClearIN(); + + while (Length || LastPacketFull) + { + uint8_t USB_DeviceState_LCL = USB_DeviceState; + + if (USB_DeviceState_LCL == DEVICE_STATE_Unattached) + return ENDPOINT_RWCSTREAM_DeviceDisconnected; + else if (USB_DeviceState_LCL == DEVICE_STATE_Suspended) + return ENDPOINT_RWCSTREAM_BusSuspended; + else if (Endpoint_IsSETUPReceived()) + return ENDPOINT_RWCSTREAM_HostAborted; + else if (Endpoint_IsOUTReceived()) + break; + + if (Endpoint_IsINReady()) + { + uint16_t BytesInEndpoint = Endpoint_BytesInEndpoint(); + + while (Length && (BytesInEndpoint < USB_Device_ControlEndpointSize)) + { + TEMPLATE_TRANSFER_BYTE(DataStream); + TEMPLATE_BUFFER_MOVE(DataStream, 1); + Length--; + BytesInEndpoint++; + } + + LastPacketFull = (BytesInEndpoint == USB_Device_ControlEndpointSize); + Endpoint_ClearIN(); + } + } + + while (!(Endpoint_IsOUTReceived())) + { + uint8_t USB_DeviceState_LCL = USB_DeviceState; + + if (USB_DeviceState_LCL == DEVICE_STATE_Unattached) + return ENDPOINT_RWCSTREAM_DeviceDisconnected; + else if (USB_DeviceState_LCL == DEVICE_STATE_Suspended) + return ENDPOINT_RWCSTREAM_BusSuspended; + } + + return ENDPOINT_RWCSTREAM_NoError; +} + +#undef TEMPLATE_BUFFER_OFFSET +#undef TEMPLATE_BUFFER_MOVE +#undef TEMPLATE_FUNC_NAME +#undef TEMPLATE_TRANSFER_BYTE + +#endif + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/Template/Template_Endpoint_RW.c b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/Template/Template_Endpoint_RW.c new file mode 100644 index 00000000..02ad9786 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/Template/Template_Endpoint_RW.c @@ -0,0 +1,90 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#if defined(TEMPLATE_FUNC_NAME) + +// cppcheck-suppress unusedFunction +uint8_t TEMPLATE_FUNC_NAME (TEMPLATE_BUFFER_TYPE const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) +{ + uint8_t* DataStream = ((uint8_t*)Buffer + TEMPLATE_BUFFER_OFFSET(Length)); + uint16_t BytesInTransfer = 0; + uint8_t ErrorCode; + + if ((ErrorCode = Endpoint_WaitUntilReady())) + return ErrorCode; + + if (BytesProcessed != NULL) + { + Length -= *BytesProcessed; + TEMPLATE_BUFFER_MOVE(DataStream, *BytesProcessed); + } + + while (Length) + { + if (!(Endpoint_IsReadWriteAllowed())) + { + TEMPLATE_CLEAR_ENDPOINT(); + + #if !defined(INTERRUPT_CONTROL_ENDPOINT) + USB_USBTask(); + #endif + + if (BytesProcessed != NULL) + { + *BytesProcessed += BytesInTransfer; + return ENDPOINT_RWSTREAM_IncompleteTransfer; + } + + if ((ErrorCode = Endpoint_WaitUntilReady())) + return ErrorCode; + } + else + { + TEMPLATE_TRANSFER_BYTE(DataStream); + TEMPLATE_BUFFER_MOVE(DataStream, 1); + Length--; + BytesInTransfer++; + } + } + + return ENDPOINT_RWSTREAM_NoError; +} + +#undef TEMPLATE_FUNC_NAME +#undef TEMPLATE_BUFFER_TYPE +#undef TEMPLATE_TRANSFER_BYTE +#undef TEMPLATE_CLEAR_ENDPOINT +#undef TEMPLATE_BUFFER_OFFSET +#undef TEMPLATE_BUFFER_MOVE + +#endif + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/Template/Template_Pipe_RW.c b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/Template/Template_Pipe_RW.c new file mode 100644 index 00000000..05846bb6 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/Template/Template_Pipe_RW.c @@ -0,0 +1,89 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#if defined(TEMPLATE_FUNC_NAME) + +// cppcheck-suppress unusedFunction +uint8_t TEMPLATE_FUNC_NAME (TEMPLATE_BUFFER_TYPE const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) +{ + uint8_t* DataStream = ((uint8_t*)Buffer + TEMPLATE_BUFFER_OFFSET(Length)); + uint16_t BytesInTransfer = 0; + uint8_t ErrorCode; + + Pipe_SetPipeToken(TEMPLATE_TOKEN); + + if ((ErrorCode = Pipe_WaitUntilReady())) + return ErrorCode; + + if (BytesProcessed != NULL) + { + Length -= *BytesProcessed; + TEMPLATE_BUFFER_MOVE(DataStream, *BytesProcessed); + } + + while (Length) + { + if (!(Pipe_IsReadWriteAllowed())) + { + TEMPLATE_CLEAR_PIPE(); + + if (BytesProcessed != NULL) + { + *BytesProcessed += BytesInTransfer; + return PIPE_RWSTREAM_IncompleteTransfer; + } + + if ((ErrorCode = Pipe_WaitUntilReady())) + return ErrorCode; + } + else + { + TEMPLATE_TRANSFER_BYTE(DataStream); + TEMPLATE_BUFFER_MOVE(DataStream, 1); + Length--; + BytesInTransfer++; + } + } + + return PIPE_RWSTREAM_NoError; +} + +#undef TEMPLATE_FUNC_NAME +#undef TEMPLATE_BUFFER_TYPE +#undef TEMPLATE_TOKEN +#undef TEMPLATE_TRANSFER_BYTE +#undef TEMPLATE_CLEAR_PIPE +#undef TEMPLATE_BUFFER_OFFSET +#undef TEMPLATE_BUFFER_MOVE + +#endif + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/USBController_UC3.c b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/USBController_UC3.c new file mode 100644 index 00000000..8ee63318 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/USBController_UC3.c @@ -0,0 +1,222 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#include "../../../../Common/Common.h" +#if (ARCH == ARCH_UC3) + +#define __INCLUDE_FROM_USB_DRIVER +#define __INCLUDE_FROM_USB_CONTROLLER_C +#include "../USBController.h" + +#if (!defined(USB_HOST_ONLY) && !defined(USB_DEVICE_ONLY)) +volatile uint8_t USB_CurrentMode = USB_MODE_None; +#endif + +#if !defined(USE_STATIC_OPTIONS) +volatile uint8_t USB_Options; +#endif + +void USB_Init( + #if defined(USB_CAN_BE_BOTH) + const uint8_t Mode + #endif + + #if (defined(USB_CAN_BE_BOTH) && !defined(USE_STATIC_OPTIONS)) + , + #elif (!defined(USB_CAN_BE_BOTH) && defined(USE_STATIC_OPTIONS)) + void + #endif + + #if !defined(USE_STATIC_OPTIONS) + const uint8_t Options + #endif + ) +{ + #if !defined(USE_STATIC_OPTIONS) + USB_Options = Options; + #endif + + #if defined(USB_CAN_BE_BOTH) + if (Mode == USB_MODE_UID) + { + AVR32_USBB.USBCON.uide = true; + USB_INT_Enable(USB_INT_IDTI); + USB_CurrentMode = USB_GetUSBModeFromUID(); + } + else + { + AVR32_USBB.USBCON.uide = false; + USB_CurrentMode = Mode; + } + #else + AVR32_USBB.USBCON.uide = false; + #endif + + USB_IsInitialized = true; + + USB_ResetInterface(); +} + +void USB_Disable(void) +{ + USB_INT_DisableAllInterrupts(); + USB_INT_ClearAllInterrupts(); + + USB_Detach(); + USB_Controller_Disable(); + + USB_OTGPAD_Off(); + + #if defined(USB_CAN_BE_BOTH) + USB_CurrentMode = USB_MODE_None; + #endif + + AVR32_PM.GCCTRL[3].cen = false; + + USB_IsInitialized = false; +} + +void USB_ResetInterface(void) +{ + #if defined(USB_CAN_BE_BOTH) + bool UIDModeSelectEnabled = AVR32_USBB.USBCON.uide; + #endif + + AVR32_PM.GCCTRL[AVR32_PM_GCLK_USBB].pllsel = !(USB_Options & USB_OPT_GCLK_SRC_OSC); + AVR32_PM.GCCTRL[AVR32_PM_GCLK_USBB].oscsel = !(USB_Options & USB_OPT_GCLK_CHANNEL_0); + AVR32_PM.GCCTRL[AVR32_PM_GCLK_USBB].diven = (F_USB != USB_CLOCK_REQUIRED_FREQ); + AVR32_PM.GCCTRL[AVR32_PM_GCLK_USBB].div = (F_USB == USB_CLOCK_REQUIRED_FREQ) ? 0 : (uint32_t)((F_USB / USB_CLOCK_REQUIRED_FREQ / 2) - 1); + AVR32_PM.GCCTRL[AVR32_PM_GCLK_USBB].cen = true; + + USB_INT_DisableAllInterrupts(); + USB_INT_ClearAllInterrupts(); + + USB_Controller_Reset(); + + #if defined(USB_CAN_BE_BOTH) + if (UIDModeSelectEnabled) + USB_INT_Enable(USB_INT_IDTI); + #endif + + USB_CLK_Unfreeze(); + + if (USB_CurrentMode == USB_MODE_Device) + { + #if defined(USB_CAN_BE_DEVICE) + AVR32_USBB.USBCON.uimod = true; + + USB_Init_Device(); + #endif + } + else if (USB_CurrentMode == USB_MODE_Host) + { + #if defined(INVERTED_VBUS_ENABLE_LINE) + AVR32_USBB.USBCON.vbuspo = true; + #endif + + #if defined(USB_CAN_BE_HOST) + AVR32_USBB.USBCON.uimod = false; + + USB_Init_Host(); + #endif + } + + USB_OTGPAD_On(); +} + +#if defined(USB_CAN_BE_DEVICE) +static void USB_Init_Device(void) +{ + USB_DeviceState = DEVICE_STATE_Unattached; + USB_Device_ConfigurationNumber = 0; + + #if !defined(NO_DEVICE_REMOTE_WAKEUP) + USB_Device_RemoteWakeupEnabled = false; + #endif + + #if !defined(NO_DEVICE_SELF_POWER) + USB_Device_CurrentlySelfPowered = false; + #endif + + #if !defined(FIXED_CONTROL_ENDPOINT_SIZE) + USB_Descriptor_Device_t* DeviceDescriptorPtr; + + if (CALLBACK_USB_GetDescriptor((DTYPE_Device << 8), 0, (void*)&DeviceDescriptorPtr) != NO_DESCRIPTOR) + USB_Device_ControlEndpointSize = DeviceDescriptorPtr->Endpoint0Size; + #endif + + if (USB_Options & USB_DEVICE_OPT_LOWSPEED) + { + USB_Device_SetLowSpeed(); + } + else + { + #if defined(USB_DEVICE_OPT_HIGHSPEED) + if (USB_Options & USB_DEVICE_OPT_HIGHSPEED) + USB_Device_SetHighSpeed(); + else + USB_Device_SetFullSpeed(); + #else + USB_Device_SetFullSpeed(); + #endif + } + + USB_INT_Enable(USB_INT_VBUSTI); + + Endpoint_ConfigureEndpoint(ENDPOINT_CONTROLEP, EP_TYPE_CONTROL, + USB_Device_ControlEndpointSize, 1); + + USB_INT_Clear(USB_INT_SUSPI); + USB_INT_Enable(USB_INT_SUSPI); + USB_INT_Enable(USB_INT_EORSTI); + + USB_Attach(); +} +#endif + +#if defined(USB_CAN_BE_HOST) +static void USB_Init_Host(void) +{ + USB_HostState = HOST_STATE_Unattached; + USB_Host_ConfigurationNumber = 0; + USB_Host_ControlPipeSize = PIPE_CONTROLPIPE_DEFAULT_SIZE; + + USB_Host_HostMode_On(); + + USB_Host_VBUS_Auto_On(); + + USB_INT_Enable(USB_INT_DCONNI); + USB_INT_Enable(USB_INT_BCERRI); + + USB_Attach(); +} +#endif + +#endif diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/USBController_UC3.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/USBController_UC3.h new file mode 100644 index 00000000..bcae49bd --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/USBController_UC3.h @@ -0,0 +1,365 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief USB Controller definitions for the AVR32 UC3 microcontrollers. + * \copydetails Group_USBManagement_UC3 + * + * \note This file should not be included directly. It is automatically included as needed by the USB driver + * dispatch header located in LUFA/Drivers/USB/USB.h. + */ + +/** \ingroup Group_USBManagement + * \defgroup Group_USBManagement_UC3 USB Interface Management (UC3) + * \brief USB Controller definitions for the AVR32 UC3 microcontrollers. + * + * Functions, macros, variables, enums and types related to the setup and management of the USB interface. + * + * @{ + */ + +#ifndef __USBCONTROLLER_UC3_H__ +#define __USBCONTROLLER_UC3_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + #include "../USBMode.h" + #include "../Events.h" + #include "../USBTask.h" + #include "../USBInterrupt.h" + + #if defined(USB_CAN_BE_HOST) || defined(__DOXYGEN__) + #include "../Host.h" + #include "../OTG.h" + #include "../Pipe.h" + #include "../HostStandardReq.h" + #include "../PipeStream.h" + #endif + + #if defined(USB_CAN_BE_DEVICE) || defined(__DOXYGEN__) + #include "../Device.h" + #include "../Endpoint.h" + #include "../DeviceStandardReq.h" + #include "../EndpointStream.h" + #endif + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks and Defines: */ + #if !defined(__INCLUDE_FROM_USB_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB/USB.h instead. + #endif + + #if !defined(F_USB) + #error F_USB is not defined. You must define F_USB to the frequency of the clock input to the USB module. + #endif + + #if (defined(USB_SERIES_UC3A3_AVR) || defined(USB_SERIES_UC3A4_AVR)) + #if ((F_USB < 12000000) || (F_USB % 12000000)) + #error Invalid F_USB specified. F_USB must be a multiple of 12MHz for UC3A3 and UC3A4 devices. + #endif + #else + #if ((F_USB < 48000000) || (F_USB % 48000000)) + #error Invalid F_USB specified. F_USB must be a multiple of 48MHz for UC3A and UC3B devices. + #endif + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** \name USB Controller Option Masks */ + //@{ + /** Selects one of the system's main clock oscillators as the input clock to the USB Generic Clock source + * generation module. This indicates that an external oscillator should be used directly instead of an + * internal PLL clock source. + */ + #define USB_OPT_GCLK_SRC_OSC (1 << 2) + + /** Selects one of the system's PLL oscillators as the input clock to the USB Generic Clock source + * generation module. This indicates that one of the device's PLL outputs should be used instead of an + * external oscillator source. + */ + #define USB_OPT_GCLK_SRC_PLL (0 << 2) + + /** Selects PLL or External Oscillator 0 as the USB Generic Clock source module input clock. */ + #define USB_OPT_GCLK_CHANNEL_0 (1 << 3) + + /** Selects PLL or External Oscillator 1 as the USB Generic Clock source module input clock. */ + #define USB_OPT_GCLK_CHANNEL_1 (0 << 3) + //@} + + #if !defined(USB_STREAM_TIMEOUT_MS) || defined(__DOXYGEN__) + /** Constant for the maximum software timeout period of the USB data stream transfer functions + * (both control and standard) when in either device or host mode. If the next packet of a stream + * is not received or acknowledged within this time period, the stream function will fail. + * + * This value may be overridden in the user project makefile as the value of the + * \ref USB_STREAM_TIMEOUT_MS token, and passed to the compiler using the -D switch. + */ + #define USB_STREAM_TIMEOUT_MS 100 + #endif + + /* Inline Functions: */ + /** Determines if the VBUS line is currently high (i.e. the USB host is supplying power). + * + * \return Boolean \c true if the VBUS line is currently detecting power from a host, \c false otherwise. + */ + static inline bool USB_VBUS_GetStatus(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool USB_VBUS_GetStatus(void) + { + return AVR32_USBB.USBSTA.vbus; + } + + /** Detaches the device from the USB bus. This has the effect of removing the device from any + * attached host, ceasing USB communications. If no host is present, this prevents any host from + * enumerating the device once attached until \ref USB_Attach() is called. + */ + static inline void USB_Detach(void) ATTR_ALWAYS_INLINE; + static inline void USB_Detach(void) + { + AVR32_USBB.UDCON.detach = true; + } + + /** Attaches the device to the USB bus. This announces the device's presence to any attached + * USB host, starting the enumeration process. If no host is present, attaching the device + * will allow for enumeration once a host is connected to the device. + * + * This is inexplicably also required for proper operation while in host mode, to enable the + * attachment of a device to the host. This is despite the bit being located in the device-mode + * register and despite the datasheet making no mention of its requirement in host mode. + */ + static inline void USB_Attach(void) ATTR_ALWAYS_INLINE; + static inline void USB_Attach(void) + { + AVR32_USBB.UDCON.detach = false; + } + + /* Function Prototypes: */ + /** Main function to initialize and start the USB interface. Once active, the USB interface will + * allow for device connection to a host when in device mode, or for device enumeration while in + * host mode. + * + * As the USB library relies on interrupts for the device and host mode enumeration processes, + * the user must enable global interrupts before or shortly after this function is called. In + * device mode, interrupts must be enabled within 500ms of this function being called to ensure + * that the host does not time out whilst enumerating the device. In host mode, interrupts may be + * enabled at the application's leisure however enumeration will not begin of an attached device + * until after this has occurred. + * + * Calling this function when the USB interface is already initialized will cause a complete USB + * interface reset and re-enumeration. + * + * \param[in] Mode This is a mask indicating what mode the USB interface is to be initialized to, a value + * from the \ref USB_Modes_t enum. + * + * \param[in] Options Mask indicating the options which should be used when initializing the USB + * interface to control the USB interface's behavior. This should be comprised of + * a \c USB_OPT_REG_* mask to control the regulator, a \c USB_OPT_*_PLL mask to control the + * PLL, and a \c USB_DEVICE_OPT_* mask (when the device mode is enabled) to set the device + * mode speed. + * + * \note To reduce the FLASH requirements of the library if only device or host mode is required, + * the mode can be statically set in the project makefile by defining the token \c USB_DEVICE_ONLY + * (for device mode) or \c USB_HOST_ONLY (for host mode), passing the token to the compiler + * via the -D switch. If the mode is statically set, this parameter does not exist in the + * function prototype. + * \n\n + * + * \note To reduce the FLASH requirements of the library if only fixed settings are required, + * the options may be set statically in the same manner as the mode (see the Mode parameter of + * this function). To statically set the USB options, pass in the \c USE_STATIC_OPTIONS token, + * defined to the appropriate options masks. When the options are statically set, this + * parameter does not exist in the function prototype. + * + * \see \ref Group_Device for the \c USB_DEVICE_OPT_* masks. + */ + void USB_Init( + #if defined(USB_CAN_BE_BOTH) || defined(__DOXYGEN__) + const uint8_t Mode + #endif + + #if (defined(USB_CAN_BE_BOTH) && !defined(USE_STATIC_OPTIONS)) || defined(__DOXYGEN__) + , + #elif (!defined(USB_CAN_BE_BOTH) && defined(USE_STATIC_OPTIONS)) + void + #endif + + #if !defined(USE_STATIC_OPTIONS) || defined(__DOXYGEN__) + const uint8_t Options + #endif + ); + + /** Shuts down the USB interface. This turns off the USB interface after deallocating all USB FIFO + * memory, endpoints and pipes. When turned off, no USB functionality can be used until the interface + * is restarted with the \ref USB_Init() function. + */ + void USB_Disable(void); + + /** Resets the interface, when already initialized. This will re-enumerate the device if already connected + * to a host, or re-enumerate an already attached device when in host mode. + */ + void USB_ResetInterface(void); + + /* Global Variables: */ + #if (!defined(USB_HOST_ONLY) && !defined(USB_DEVICE_ONLY)) || defined(__DOXYGEN__) + /** Indicates the mode that the USB interface is currently initialized to, a value from the + * \ref USB_Modes_t enum. + * + * \attention This variable should be treated as read-only in the user application, and never manually + * changed in value. + * + * \note When the controller is initialized into UID auto-detection mode, this variable will hold the + * currently selected USB mode (i.e. \ref USB_MODE_Device or \ref USB_MODE_Host). If the controller + * is fixed into a specific mode (either through the \c USB_DEVICE_ONLY or \c USB_HOST_ONLY compile time + * options, or a limitation of the USB controller in the chosen device model) this will evaluate to + * a constant of the appropriate value and will never evaluate to \ref USB_MODE_None even when the + * USB interface is not initialized. + */ + extern volatile uint8_t USB_CurrentMode; + #elif defined(USB_HOST_ONLY) + #define USB_CurrentMode USB_MODE_Host + #elif defined(USB_DEVICE_ONLY) + #define USB_CurrentMode USB_MODE_Device + #endif + + #if !defined(USE_STATIC_OPTIONS) || defined(__DOXYGEN__) + /** Indicates the current USB options that the USB interface was initialized with when \ref USB_Init() + * was called. This value will be one of the \c USB_MODE_* masks defined elsewhere in this module. + * + * \attention This variable should be treated as read-only in the user application, and never manually + * changed in value. + */ + extern volatile uint8_t USB_Options; + #elif defined(USE_STATIC_OPTIONS) + #define USB_Options USE_STATIC_OPTIONS + #endif + + /* Enums: */ + /** Enum for the possible USB controller modes, for initialization via \ref USB_Init() and indication back to the + * user application via \ref USB_CurrentMode. + */ + enum USB_Modes_t + { + USB_MODE_None = 0, /**< Indicates that the controller is currently not initialized in any specific USB mode. */ + USB_MODE_Device = 1, /**< Indicates that the controller is currently initialized in USB Device mode. */ + USB_MODE_Host = 2, /**< Indicates that the controller is currently initialized in USB Host mode. */ + USB_MODE_UID = 3, /**< Indicates that the controller should determine the USB mode from the UID pin of the + * USB connector. + */ + }; + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Macros: */ + #if defined(USB_SERIES_UC3A3_AVR32) || defined(USB_SERIES_UC3A4_AVR32) + #define USB_CLOCK_REQUIRED_FREQ 12000000UL + #else + #define USB_CLOCK_REQUIRED_FREQ 48000000UL + #endif + + /* Function Prototypes: */ + #if defined(__INCLUDE_FROM_USB_CONTROLLER_C) + #if defined(USB_CAN_BE_DEVICE) + static void USB_Init_Device(void); + #endif + + #if defined(USB_CAN_BE_HOST) + static void USB_Init_Host(void); + #endif + #endif + + /* Inline Functions: */ + static inline void USB_OTGPAD_On(void) ATTR_ALWAYS_INLINE; + static inline void USB_OTGPAD_On(void) + { + AVR32_USBB.USBCON.otgpade = true; + } + + static inline void USB_OTGPAD_Off(void) ATTR_ALWAYS_INLINE; + static inline void USB_OTGPAD_Off(void) + { + AVR32_USBB.USBCON.otgpade = false; + } + + static inline void USB_CLK_Freeze(void) ATTR_ALWAYS_INLINE; + static inline void USB_CLK_Freeze(void) + { + AVR32_USBB.USBCON.frzclk = true; + } + + static inline void USB_CLK_Unfreeze(void) ATTR_ALWAYS_INLINE; + static inline void USB_CLK_Unfreeze(void) + { + AVR32_USBB.USBCON.frzclk = false; + } + + static inline void USB_Controller_Enable(void) ATTR_ALWAYS_INLINE; + static inline void USB_Controller_Enable(void) + { + AVR32_USBB.USBCON.usbe = true; + } + + static inline void USB_Controller_Disable(void) ATTR_ALWAYS_INLINE; + static inline void USB_Controller_Disable(void) + { + AVR32_USBB.USBCON.usbe = false; + } + + static inline void USB_Controller_Reset(void) ATTR_ALWAYS_INLINE; + static inline void USB_Controller_Reset(void) + { + AVR32_USBB.USBCON.usbe = false; + AVR32_USBB.USBCON.usbe = true; + } + + #if defined(USB_CAN_BE_BOTH) + static inline uint8_t USB_GetUSBModeFromUID(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint8_t USB_GetUSBModeFromUID(void) + { + if (AVR32_USBB.USBSTA.id) + return USB_MODE_Device; + else + return USB_MODE_Host; + } + #endif + + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/USBInterrupt_UC3.c b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/USBInterrupt_UC3.c new file mode 100644 index 00000000..e11a4b64 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/USBInterrupt_UC3.c @@ -0,0 +1,228 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#include "../../../../Common/Common.h" +#if (ARCH == ARCH_UC3) + +#define __INCLUDE_FROM_USB_DRIVER +#include "../USBInterrupt.h" + +void USB_INT_DisableAllInterrupts(void) +{ + AVR32_USBB.USBCON.vbuste = false; + AVR32_USBB.USBCON.idte = false; + + AVR32_USBB.uhinteclr = -1; + AVR32_USBB.udinteclr = -1; +} + +void USB_INT_ClearAllInterrupts(void) +{ + AVR32_USBB.USBSTACLR.vbustic = true; + AVR32_USBB.USBSTACLR.idtic = true; + + AVR32_USBB.uhintclr = -1; + AVR32_USBB.udintclr = -1; +} + +ISR(USB_GEN_vect) +{ + #if defined(USB_CAN_BE_DEVICE) + #if !defined(NO_SOF_EVENTS) + if (USB_INT_HasOccurred(USB_INT_SOFI) && USB_INT_IsEnabled(USB_INT_SOFI)) + { + USB_INT_Clear(USB_INT_SOFI); + + EVENT_USB_Device_StartOfFrame(); + } + #endif + + if (USB_INT_HasOccurred(USB_INT_VBUSTI) && USB_INT_IsEnabled(USB_INT_VBUSTI)) + { + USB_INT_Clear(USB_INT_VBUSTI); + + if (USB_VBUS_GetStatus()) + { + USB_DeviceState = DEVICE_STATE_Powered; + EVENT_USB_Device_Connect(); + } + else + { + USB_DeviceState = DEVICE_STATE_Unattached; + EVENT_USB_Device_Disconnect(); + } + } + + if (USB_INT_HasOccurred(USB_INT_SUSPI) && USB_INT_IsEnabled(USB_INT_SUSPI)) + { + USB_INT_Disable(USB_INT_SUSPI); + USB_INT_Enable(USB_INT_WAKEUPI); + + USB_CLK_Freeze(); + + USB_DeviceState = DEVICE_STATE_Suspended; + EVENT_USB_Device_Suspend(); + } + + if (USB_INT_HasOccurred(USB_INT_WAKEUPI) && USB_INT_IsEnabled(USB_INT_WAKEUPI)) + { + USB_CLK_Unfreeze(); + + USB_INT_Clear(USB_INT_WAKEUPI); + + USB_INT_Disable(USB_INT_WAKEUPI); + USB_INT_Enable(USB_INT_SUSPI); + + if (USB_Device_ConfigurationNumber) + USB_DeviceState = DEVICE_STATE_Configured; + else + USB_DeviceState = (USB_Device_IsAddressSet()) ? DEVICE_STATE_Configured : DEVICE_STATE_Powered; + + EVENT_USB_Device_WakeUp(); + } + + if (USB_INT_HasOccurred(USB_INT_EORSTI) && USB_INT_IsEnabled(USB_INT_EORSTI)) + { + USB_INT_Clear(USB_INT_EORSTI); + + USB_DeviceState = DEVICE_STATE_Default; + USB_Device_ConfigurationNumber = 0; + + USB_INT_Clear(USB_INT_SUSPI); + USB_INT_Disable(USB_INT_SUSPI); + USB_INT_Enable(USB_INT_WAKEUPI); + + USB_Device_SetDeviceAddress(0); + Endpoint_ConfigureEndpoint(ENDPOINT_CONTROLEP, EP_TYPE_CONTROL, + USB_Device_ControlEndpointSize, 1); + + #if defined(INTERRUPT_CONTROL_ENDPOINT) + USB_INT_Enable(USB_INT_RXSTPI); + #endif + + EVENT_USB_Device_Reset(); + } + #endif + + #if defined(USB_CAN_BE_HOST) + #if !defined(NO_SOF_EVENTS) + if (USB_INT_HasOccurred(USB_INT_HSOFI) && USB_INT_IsEnabled(USB_INT_HSOFI)) + { + USB_INT_Clear(USB_INT_HSOFI); + + EVENT_USB_Host_StartOfFrame(); + } + #endif + + if (USB_INT_HasOccurred(USB_INT_DDISCI) && USB_INT_IsEnabled(USB_INT_DDISCI)) + { + USB_INT_Clear(USB_INT_DDISCI); + USB_INT_Clear(USB_INT_DCONNI); + USB_INT_Disable(USB_INT_DDISCI); + + EVENT_USB_Host_DeviceUnattached(); + + USB_ResetInterface(); + } + + if (USB_INT_HasOccurred(USB_INT_VBERRI) && USB_INT_IsEnabled(USB_INT_VBERRI)) + { + USB_INT_Clear(USB_INT_VBERRI); + + USB_Host_VBUS_Manual_Off(); + USB_Host_VBUS_Auto_Off(); + + EVENT_USB_Host_HostError(HOST_ERROR_VBusVoltageDip); + EVENT_USB_Host_DeviceUnattached(); + + USB_HostState = HOST_STATE_Unattached; + } + + if (USB_INT_HasOccurred(USB_INT_DCONNI) && USB_INT_IsEnabled(USB_INT_DCONNI)) + { + USB_INT_Clear(USB_INT_DCONNI); + USB_INT_Disable(USB_INT_DCONNI); + + EVENT_USB_Host_DeviceAttached(); + + USB_INT_Enable(USB_INT_DDISCI); + + USB_HostState = HOST_STATE_Powered; + } + + if (USB_INT_HasOccurred(USB_INT_BCERRI) && USB_INT_IsEnabled(USB_INT_BCERRI)) + { + USB_INT_Clear(USB_INT_BCERRI); + + EVENT_USB_Host_DeviceEnumerationFailed(HOST_ENUMERROR_NoDeviceDetected, 0); + EVENT_USB_Host_DeviceUnattached(); + + USB_ResetInterface(); + } + #endif + + #if defined(USB_CAN_BE_BOTH) + if (USB_INT_HasOccurred(USB_INT_IDTI) && USB_INT_IsEnabled(USB_INT_IDTI)) + { + USB_INT_Clear(USB_INT_IDTI); + + if (USB_DeviceState != DEVICE_STATE_Unattached) + EVENT_USB_Device_Disconnect(); + + if (USB_HostState != HOST_STATE_Unattached) + EVENT_USB_Host_DeviceUnattached(); + + USB_CurrentMode = USB_GetUSBModeFromUID(); + USB_ResetInterface(); + + EVENT_USB_UIDChange(); + } + #endif +} + +#if defined(INTERRUPT_CONTROL_ENDPOINT) && defined(USB_CAN_BE_DEVICE) +ISR(USB_COM_vect) +{ + uint8_t PrevSelectedEndpoint = Endpoint_GetCurrentEndpoint(); + + Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP); + USB_INT_Disable(USB_INT_RXSTPI); + + GlobalInterruptEnable(); + + USB_Device_ProcessControlRequest(); + + Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP); + USB_INT_Enable(USB_INT_RXSTPI); + Endpoint_SelectEndpoint(PrevSelectedEndpoint); +} +#endif + +#endif diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/USBInterrupt_UC3.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/USBInterrupt_UC3.h new file mode 100644 index 00000000..625e3f78 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/UC3/USBInterrupt_UC3.h @@ -0,0 +1,370 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief USB Controller Interrupt definitions for the AVR32 UC3 microcontrollers. + * + * This file contains definitions required for the correct handling of low level USB service routine interrupts + * from the USB controller. + * + * \note This file should not be included directly. It is automatically included as needed by the USB driver + * dispatch header located in LUFA/Drivers/USB/USB.h. + */ + +#ifndef __USBINTERRUPT_UC3_H__ +#define __USBINTERRUPT_UC3_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_USB_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB/USB.h instead. + #endif + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* External Variables: */ + extern volatile uint32_t USB_Endpoint_SelectedEndpoint; + + /* Enums: */ + enum USB_Interrupts_t + { + USB_INT_VBUSTI = 0, + #if (defined(USB_CAN_BE_BOTH) || defined(__DOXYGEN__)) + USB_INT_IDTI = 1, + #endif + #if (defined(USB_CAN_BE_DEVICE) || defined(__DOXYGEN__)) + USB_INT_WAKEUPI = 2, + USB_INT_SUSPI = 3, + USB_INT_EORSTI = 4, + USB_INT_SOFI = 5, + USB_INT_RXSTPI = 6, + #endif + #if (defined(USB_CAN_BE_HOST) || defined(__DOXYGEN__)) + USB_INT_HSOFI = 7, + USB_INT_DCONNI = 8, + USB_INT_DDISCI = 9, + USB_INT_RSTI = 10, + USB_INT_BCERRI = 11, + USB_INT_VBERRI = 12, + #endif + }; + + /* Inline Functions: */ + static inline void USB_INT_Enable(const uint8_t Interrupt) ATTR_ALWAYS_INLINE; + static inline void USB_INT_Enable(const uint8_t Interrupt) + { + switch (Interrupt) + { + case USB_INT_VBUSTI: + AVR32_USBB.USBCON.vbuste = true; + break; + #if defined(USB_CAN_BE_BOTH) + case USB_INT_IDTI: + AVR32_USBB.USBCON.idte = true; + break; + #endif + #if defined(USB_CAN_BE_DEVICE) + case USB_INT_WAKEUPI: + AVR32_USBB.UDINTESET.wakeupes = true; + break; + case USB_INT_SUSPI: + AVR32_USBB.UDINTESET.suspes = true; + break; + case USB_INT_EORSTI: + AVR32_USBB.UDINTESET.eorstes = true; + break; + case USB_INT_SOFI: + AVR32_USBB.UDINTESET.sofes = true; + break; + case USB_INT_RXSTPI: + (&AVR32_USBB.UECON0SET)[USB_Endpoint_SelectedEndpoint].rxstpes = true; + break; + #endif + #if defined(USB_CAN_BE_HOST) + case USB_INT_HSOFI: + AVR32_USBB.UHINTESET.hsofies = true; + break; + case USB_INT_DCONNI: + AVR32_USBB.UHINTESET.dconnies = true; + break; + case USB_INT_DDISCI: + AVR32_USBB.UHINTESET.ddiscies = true; + break; + case USB_INT_RSTI: + AVR32_USBB.UHINTESET.rsties = true; + break; + case USB_INT_BCERRI: + AVR32_USBB.USBCON.bcerre = true; + break; + case USB_INT_VBERRI: + AVR32_USBB.USBCON.vberre = true; + break; + #endif + } + } + + static inline void USB_INT_Disable(const uint8_t Interrupt) ATTR_ALWAYS_INLINE; + static inline void USB_INT_Disable(const uint8_t Interrupt) + { + switch (Interrupt) + { + case USB_INT_VBUSTI: + AVR32_USBB.USBCON.vbuste = false; + break; + #if defined(USB_CAN_BE_BOTH) + case USB_INT_IDTI: + AVR32_USBB.USBCON.idte = false; + break; + #endif + #if defined(USB_CAN_BE_DEVICE) + case USB_INT_WAKEUPI: + AVR32_USBB.UDINTECLR.wakeupec = true; + break; + case USB_INT_SUSPI: + AVR32_USBB.UDINTECLR.suspec = true; + break; + case USB_INT_EORSTI: + AVR32_USBB.UDINTECLR.eorstec = true; + break; + case USB_INT_SOFI: + AVR32_USBB.UDINTECLR.sofec = true; + break; + case USB_INT_RXSTPI: + (&AVR32_USBB.UECON0CLR)[USB_Endpoint_SelectedEndpoint].rxstpec = true; + break; + #endif + #if defined(USB_CAN_BE_HOST) + case USB_INT_HSOFI: + AVR32_USBB.UHINTECLR.hsofiec = true; + break; + case USB_INT_DCONNI: + AVR32_USBB.UHINTECLR.dconniec = true; + break; + case USB_INT_DDISCI: + AVR32_USBB.UHINTECLR.ddisciec = true; + break; + case USB_INT_RSTI: + AVR32_USBB.UHINTECLR.rstiec = true; + break; + case USB_INT_BCERRI: + AVR32_USBB.USBCON.bcerre = false; + break; + case USB_INT_VBERRI: + AVR32_USBB.USBCON.vberre = false; + break; + #endif + } + } + + static inline void USB_INT_Clear(const uint8_t Interrupt) ATTR_ALWAYS_INLINE; + static inline void USB_INT_Clear(const uint8_t Interrupt) + { + switch (Interrupt) + { + case USB_INT_VBUSTI: + AVR32_USBB.USBSTACLR.vbustic = true; + (void)AVR32_USBB.USBSTACLR; + break; + #if defined(USB_CAN_BE_BOTH) + case USB_INT_IDTI: + AVR32_USBB.USBSTACLR.idtic = true; + (void)AVR32_USBB.USBSTACLR; + break; + #endif + #if defined(USB_CAN_BE_DEVICE) + case USB_INT_WAKEUPI: + AVR32_USBB.UDINTCLR.wakeupc = true; + (void)AVR32_USBB.UDINTCLR; + break; + case USB_INT_SUSPI: + AVR32_USBB.UDINTCLR.suspc = true; + (void)AVR32_USBB.UDINTCLR; + break; + case USB_INT_EORSTI: + AVR32_USBB.UDINTCLR.eorstc = true; + (void)AVR32_USBB.UDINTCLR; + break; + case USB_INT_SOFI: + AVR32_USBB.UDINTCLR.sofc = true; + (void)AVR32_USBB.UDINTCLR; + break; + case USB_INT_RXSTPI: + (&AVR32_USBB.UESTA0CLR)[USB_Endpoint_SelectedEndpoint].rxstpic = true; + break; + #endif + #if defined(USB_CAN_BE_HOST) + case USB_INT_HSOFI: + AVR32_USBB.UHINTCLR.hsofic = true; + (void)AVR32_USBB.UHINTCLR; + break; + case USB_INT_DCONNI: + AVR32_USBB.UHINTCLR.dconnic = true; + (void)AVR32_USBB.UHINTCLR; + break; + case USB_INT_DDISCI: + AVR32_USBB.UHINTCLR.ddiscic = true; + (void)AVR32_USBB.UHINTCLR; + break; + case USB_INT_RSTI: + AVR32_USBB.UHINTCLR.rstic = true; + (void)AVR32_USBB.UHINTCLR; + break; + case USB_INT_BCERRI: + AVR32_USBB.USBSTACLR.bcerric = true; + (void)AVR32_USBB.USBSTACLR; + break; + case USB_INT_VBERRI: + AVR32_USBB.USBSTACLR.vberric = true; + (void)AVR32_USBB.USBSTACLR; + break; + #endif + } + } + + static inline bool USB_INT_IsEnabled(const uint8_t Interrupt) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT; + static inline bool USB_INT_IsEnabled(const uint8_t Interrupt) + { + switch (Interrupt) + { + case USB_INT_VBUSTI: + return AVR32_USBB.USBCON.vbuste; + #if defined(USB_CAN_BE_BOTH) + case USB_INT_IDTI: + return AVR32_USBB.USBCON.idte; + #endif + #if defined(USB_CAN_BE_DEVICE) + case USB_INT_WAKEUPI: + return AVR32_USBB.UDINTE.wakeupe; + case USB_INT_SUSPI: + return AVR32_USBB.UDINTE.suspe; + case USB_INT_EORSTI: + return AVR32_USBB.UDINTE.eorste; + case USB_INT_SOFI: + return AVR32_USBB.UDINTE.sofe; + case USB_INT_RXSTPI: + return (&AVR32_USBB.UECON0)[USB_Endpoint_SelectedEndpoint].rxstpe; + #endif + #if defined(USB_CAN_BE_HOST) + case USB_INT_HSOFI: + return AVR32_USBB.UHINTE.hsofie; + case USB_INT_DCONNI: + return AVR32_USBB.UHINTE.dconnie; + case USB_INT_DDISCI: + return AVR32_USBB.UHINTE.ddiscie; + case USB_INT_RSTI: + return AVR32_USBB.UHINTE.rstie; + case USB_INT_BCERRI: + return AVR32_USBB.USBCON.bcerre; + case USB_INT_VBERRI: + return AVR32_USBB.USBCON.vberre; + #endif + } + + return false; + } + + static inline bool USB_INT_HasOccurred(const uint8_t Interrupt) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT; + static inline bool USB_INT_HasOccurred(const uint8_t Interrupt) + { + switch (Interrupt) + { + case USB_INT_VBUSTI: + return AVR32_USBB.USBSTA.vbusti; + #if defined(USB_CAN_BE_BOTH) + case USB_INT_IDTI: + return AVR32_USBB.USBSTA.idti; + #endif + #if defined(USB_CAN_BE_DEVICE) + case USB_INT_WAKEUPI: + return AVR32_USBB.UDINT.wakeup; + case USB_INT_SUSPI: + return AVR32_USBB.UDINT.susp; + case USB_INT_EORSTI: + return AVR32_USBB.UDINT.eorst; + case USB_INT_SOFI: + return AVR32_USBB.UDINT.sof; + case USB_INT_RXSTPI: + return (&AVR32_USBB.UESTA0)[USB_Endpoint_SelectedEndpoint].rxstpi; + #endif + #if defined(USB_CAN_BE_HOST) + case USB_INT_HSOFI: + return AVR32_USBB.UHINT.hsofi; + case USB_INT_DCONNI: + return AVR32_USBB.UHINT.dconni; + case USB_INT_DDISCI: + return AVR32_USBB.UHINT.ddisci; + case USB_INT_RSTI: + return AVR32_USBB.UHINT.rsti; + case USB_INT_BCERRI: + return AVR32_USBB.USBSTA.bcerri; + case USB_INT_VBERRI: + return AVR32_USBB.USBSTA.vberri; + #endif + } + + return false; + } + + /* Includes: */ + #include "../USBMode.h" + #include "../Events.h" + #include "../USBController.h" + + /* Function Prototypes: */ + void USB_INT_ClearAllInterrupts(void); + void USB_INT_DisableAllInterrupts(void); + #endif + + /* Public Interface - May be used in end-application: */ + /* Function Prototypes: */ + #if defined(__DOXYGEN__) + /** Interrupt service routine handler for the USB controller ISR group. This interrupt routine must be + * linked to the entire USB controller ISR vector group inside the AVR32's interrupt controller peripheral, + * using the user application's preferred USB controller driver. + */ + void USB_GEN_vect(void); + #else + ISR(USB_GEN_vect); + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/USBController.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/USBController.h new file mode 100644 index 00000000..9b1f0a9a --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/USBController.h @@ -0,0 +1,151 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Common USB Controller definitions for all architectures. + * \copydetails Group_USBManagement + * + * \note This file should not be included directly. It is automatically included as needed by the USB driver + * dispatch header located in LUFA/Drivers/USB/USB.h. + */ + +/** \ingroup Group_USB + * \defgroup Group_USBManagement USB Interface Management + * \brief USB Controller definitions for general USB controller management. + * + * Functions, macros, variables, enums and types related to the setup and management of the USB interface. + * + * @{ + */ + +#ifndef __USBCONTROLLER_H__ +#define __USBCONTROLLER_H__ + + /* Includes: */ + #include "../../../Common/Common.h" + #include "USBMode.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks and Defines: */ + #if !defined(__INCLUDE_FROM_USB_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB/USB.h instead. + #endif + + /* Defines: */ + /** \name Endpoint Direction Masks */ + //@{ + /** Endpoint direction mask, for masking against endpoint addresses to retrieve the endpoint's + * direction for comparing with the \c ENDPOINT_DIR_* masks. + */ + #define ENDPOINT_DIR_MASK 0x80 + + /** Endpoint address direction mask for an OUT direction (Host to Device) endpoint. This may be ORed with + * the index of the address within a device to obtain the full endpoint address. + */ + #define ENDPOINT_DIR_OUT 0x00 + + /** Endpoint address direction mask for an IN direction (Device to Host) endpoint. This may be ORed with + * the index of the address within a device to obtain the full endpoint address. + */ + #define ENDPOINT_DIR_IN 0x80 + //@} + + /** \name Pipe Direction Masks */ + //@{ + /** Pipe direction mask, for masking against pipe addresses to retrieve the pipe's + * direction for comparing with the \c PIPE_DIR_* masks. + */ + #define PIPE_DIR_MASK 0x80 + + /** Endpoint address direction mask for an OUT direction (Host to Device) endpoint. This may be ORed with + * the index of the address within a device to obtain the full endpoint address. + */ + #define PIPE_DIR_OUT 0x00 + + /** Endpoint address direction mask for an IN direction (Device to Host) endpoint. This may be ORed with + * the index of the address within a device to obtain the full endpoint address. + */ + #define PIPE_DIR_IN 0x80 + //@} + + /** \name Endpoint/Pipe Type Masks */ + //@{ + /** Mask for determining the type of an endpoint from an endpoint descriptor. This should then be compared + * with the \c EP_TYPE_* masks to determine the exact type of the endpoint. + */ + #define EP_TYPE_MASK 0x03 + + /** Mask for a CONTROL type endpoint or pipe. + * + * \note See \ref Group_EndpointManagement and \ref Group_PipeManagement for endpoint/pipe functions. + */ + #define EP_TYPE_CONTROL 0x00 + + /** Mask for an ISOCHRONOUS type endpoint or pipe. + * + * \note See \ref Group_EndpointManagement and \ref Group_PipeManagement for endpoint/pipe functions. + */ + #define EP_TYPE_ISOCHRONOUS 0x01 + + /** Mask for a BULK type endpoint or pipe. + * + * \note See \ref Group_EndpointManagement and \ref Group_PipeManagement for endpoint/pipe functions. + */ + #define EP_TYPE_BULK 0x02 + + /** Mask for an INTERRUPT type endpoint or pipe. + * + * \note See \ref Group_EndpointManagement and \ref Group_PipeManagement for endpoint/pipe functions. + */ + #define EP_TYPE_INTERRUPT 0x03 + //@} + + /* Architecture Includes: */ + #if (ARCH == ARCH_AVR8) + #include "AVR8/USBController_AVR8.h" + #elif (ARCH == ARCH_UC3) + #include "UC3/USBController_UC3.h" + #elif (ARCH == ARCH_XMEGA) + #include "XMEGA/USBController_XMEGA.h" + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/USBInterrupt.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/USBInterrupt.h new file mode 100644 index 00000000..58386026 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/USBInterrupt.h @@ -0,0 +1,73 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief USB controller interrupt service routine management. + * + * This file contains definitions required for the correct handling of low level USB service routine interrupts + * from the USB controller. + * + * \note This file should not be included directly. It is automatically included as needed by the USB driver + * dispatch header located in LUFA/Drivers/USB/USB.h. + */ + +#ifndef __USBINTERRUPT_H__ +#define __USBINTERRUPT_H__ + + /* Includes: */ + #include "../../../Common/Common.h" + #include "USBMode.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_USB_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB/USB.h instead. + #endif + + /* Architecture Includes: */ + #if (ARCH == ARCH_AVR8) + #include "AVR8/USBInterrupt_AVR8.h" + #elif (ARCH == ARCH_UC3) + #include "UC3/USBInterrupt_UC3.h" + #elif (ARCH == ARCH_XMEGA) + #include "XMEGA/USBInterrupt_XMEGA.h" + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/USBMode.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/USBMode.h new file mode 100644 index 00000000..8a52b092 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/USBMode.h @@ -0,0 +1,286 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief USB mode and feature support definitions. + * \copydetails Group_USBMode + * + * \note This file should not be included directly. It is automatically included as needed by the USB driver + * dispatch header located in LUFA/Drivers/USB/USB.h. + */ + +/** \ingroup Group_USB + * \defgroup Group_USBMode USB Mode Tokens + * \brief USB mode and feature support definitions. + * + * This file defines macros indicating the type of USB controller the library is being compiled for, and its + * capabilities. These macros may then be referenced in the user application to selectively enable or disable + * code sections depending on if they are defined or not. + * + * After the inclusion of the master USB driver header, one or more of the following tokens may be defined, to + * allow the user code to conditionally enable or disable code based on the USB controller family and allowable + * USB modes. These tokens may be tested against to eliminate code relating to a USB mode which is not enabled for + * the given compilation. + * + * @{ + */ + +#ifndef __USBMODE_H__ +#define __USBMODE_H__ + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_USB_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB/USB.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + #if defined(__DOXYGEN__) + /** Indicates that the target AVR microcontroller belongs to the Series 2 AVR8 USB controller + * (i.e. AT90USBxxx2 or ATMEGAxxU2) when defined. + */ + #define USB_SERIES_2_AVR + + /** Indicates that the target AVR microcontroller belongs to the Series 4 AVR8 USB controller + * (i.e. ATMEGAxxU4) when defined. + */ + #define USB_SERIES_4_AVR + + /** Indicates that the target AVR microcontroller belongs to the Series 6 AVR8 USB controller + * (i.e. AT90USBxxx6) when defined. + */ + #define USB_SERIES_6_AVR + + /** Indicates that the target AVR microcontroller belongs to the Series 7 AVR8 USB controller + * (i.e. AT90USBxxx7) when defined. + */ + #define USB_SERIES_7_AVR + + /** Indicates that the target AVR microcontroller belongs to the AVR32 UC3A0 Series USB controller + * (i.e. AT32UC3A0*) when defined. + */ + #define USB_SERIES_UC3A0_AVR + + /** Indicates that the target AVR microcontroller belongs to the AVR32 UC3A1 Series USB controller + * (i.e. AT32UC3A1*) when defined. + */ + #define USB_SERIES_UC3A1_AVR + + /** Indicates that the target AVR microcontroller belongs to the AVR32 UC3A3 Series USB controller + * (i.e. AT32UC3A3*) when defined. + */ + #define USB_SERIES_UC3A3_AVR + + /** Indicates that the target AVR microcontroller belongs to the AVR32 UC3A4 Series USB controller + * (i.e. AT32UC3A4*) when defined. + */ + #define USB_SERIES_UC3A4_AVR + + /** Indicates that the target AVR microcontroller belongs to the AVR32 UC3B0 Series USB controller + * (i.e. AT32UC3B0*) when defined. + */ + #define USB_SERIES_UC3B0_AVR + + /** Indicates that the target AVR microcontroller belongs to the AVR32 UC3B1 Series USB controller + * (i.e. AT32UC3B1*) when defined. + */ + #define USB_SERIES_UC3B1_AVR + + /** Indicates that the target AVR microcontroller belongs to the XMEGA A1U Series USB controller + * (i.e. ATXMEGA*A1U) when defined. + */ + #define USB_SERIES_A1U_XMEGA + + /** Indicates that the target AVR microcontroller belongs to the XMEGA A3U Series USB controller + * (i.e. ATXMEGA*A3U) when defined. + */ + #define USB_SERIES_A3U_XMEGA + + /** Indicates that the target AVR microcontroller belongs to the XMEGA A4U Series USB controller + * (i.e. ATXMEGA*A4U) when defined. + */ + #define USB_SERIES_A4U_XMEGA + + /** Indicates that the target AVR microcontroller belongs to the XMEGA B1 Series USB controller + * (i.e. ATXMEGA*B1) when defined. + */ + #define USB_SERIES_B1_XMEGA + + /** Indicates that the target AVR microcontroller belongs to the XMEGA B3 Series USB controller + * (i.e. ATXMEGA*B3) when defined. + */ + #define USB_SERIES_B3_XMEGA + + /** Indicates that the target AVR microcontroller belongs to the XMEGA C3 Series USB controller + * (i.e. ATXMEGA*C3) when defined. + */ + #define USB_SERIES_C3_XMEGA + + /** Indicates that the target AVR microcontroller belongs to the XMEGA C4 Series USB controller + * (i.e. ATXMEGA*C4) when defined. + */ + #define USB_SERIES_C4_XMEGA + + /** Indicates that the target microcontroller and compilation settings allow for the + * target to be configured in USB Device mode when defined. + */ + #define USB_CAN_BE_DEVICE + + /** Indicates that the target microcontroller and compilation settings allow for the + * target to be configured in USB Host mode when defined. + */ + #define USB_CAN_BE_HOST + + /** Indicates that the target microcontroller and compilation settings allow for the + * target to be configured in either USB Device or Host mode when defined. + */ + #define USB_CAN_BE_BOTH + #else + /* Macros: */ + #if (defined(__AVR_AT90USB162__) || defined(__AVR_AT90USB82__) || \ + defined(__AVR_ATmega32U2__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega8U2__)) + #define USB_SERIES_2_AVR + #define USB_CAN_BE_DEVICE + #elif (defined(__AVR_ATmega32U4__) || defined(__AVR_ATmega16U4__)) + #define USB_SERIES_4_AVR + #define USB_CAN_BE_DEVICE + #elif (defined(__AVR_ATmega32U6__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)) + #define USB_SERIES_6_AVR + #define USB_CAN_BE_DEVICE + #elif (defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1287__)) + #define USB_SERIES_7_AVR + #define USB_CAN_BE_DEVICE + #define USB_CAN_BE_HOST + #elif (defined(__AVR32_UC3A0512__) || defined(__AVR32_UC3A0256__) || \ + defined(__AVR32_UC3A0128__) || defined(__AVR32_UC3A064__)) + #define USB_SERIES_UC3A0_AVR32 + #define USB_CAN_BE_DEVICE + #define USB_CAN_BE_HOST + #elif (defined(__AVR32_UC3A1512__) || defined(__AVR32_UC3A1256__) || \ + defined(__AVR32_UC3A1128__) || defined(__AVR32_UC3A164__)) + #define USB_SERIES_UC3A1_AVR32 + #define USB_CAN_BE_DEVICE + #define USB_CAN_BE_HOST + #elif (defined(__AVR32_UC3A3256__) || defined(__AVR32_UC3A3256S__) || \ + defined(__AVR32_UC3A3128__) || defined(__AVR32_UC3A3128S__) || \ + defined(__AVR32_UC3A364__) || defined(__AVR32_UC3A364S__)) + #define USB_SERIES_UC3A3_AVR32 + #define USB_CAN_BE_DEVICE + #define USB_CAN_BE_HOST + #elif (defined(__AVR32_UC3A4256__) || defined(__AVR32_UC3A4256S__) || \ + defined(__AVR32_UC3A4128__) || defined(__AVR32_UC3A4128S__) || \ + defined(__AVR32_UC3A464__) || defined(__AVR32_UC3A464S__)) + #define USB_SERIES_UC3A4_AVR32 + #define USB_CAN_BE_DEVICE + #define USB_CAN_BE_HOST + #elif (defined(__AVR32_UC3B0512__) || defined(__AVR32_UC3B0256__) || \ + defined(__AVR32_UC3B0128__) || defined(__AVR32_UC3B064__)) + #define USB_SERIES_UC3B0_AVR32 + #define USB_CAN_BE_DEVICE + #define USB_CAN_BE_HOST + #elif (defined(__AVR32_UC3B1512__) || defined(__AVR32_UC3B1256__) || \ + defined(__AVR32_UC3B1128__) || defined(__AVR32_UC3B164__)) + #define USB_SERIES_UC3B1_AVR32 + #define USB_CAN_BE_DEVICE + #define USB_CAN_BE_HOST + #elif (defined(__AVR_ATxmega128A1U__) || defined(__AVR_ATxmega64A1U__)) + #define USB_SERIES_A1U_XMEGA + #define USB_CAN_BE_DEVICE + #elif (defined(__AVR_ATxmega64A3U__) || defined(__AVR_ATxmega128A3U__) || \ + defined(__AVR_ATxmega192A3U__) || defined(__AVR_ATxmega256A3U__)) + #define USB_SERIES_A3U_XMEGA + #define USB_CAN_BE_DEVICE + #elif (defined(__AVR_ATxmega256A3BU__)) + #define USB_SERIES_A3BU_XMEGA + #define USB_CAN_BE_DEVICE + #elif (defined(__AVR_ATxmega16A4U__) || defined(__AVR_ATxmega32A4U__) || \ + defined(__AVR_ATxmega64A4U__) || defined(__AVR_ATxmega128A4U__)) + #define USB_SERIES_A4U_XMEGA + #define USB_CAN_BE_DEVICE + #elif (defined(__AVR_ATxmega128B1__) || defined(__AVR_ATxmega64B1__)) + #define USB_SERIES_B1_XMEGA + #define USB_CAN_BE_DEVICE + #elif (defined(__AVR_ATxmega128B3__) || defined(__AVR_ATxmega64B3__)) + #define USB_SERIES_B3_XMEGA + #define USB_CAN_BE_DEVICE + #elif (defined(__AVR_ATxmega128C3__) || defined(__AVR_ATxmega64C3__) || \ + defined(__AVR_ATxmega192C3__) || defined(__AVR_ATxmega256C3__) || \ + defined(__AVR_ATxmega384C3__)) + #define USB_SERIES_C3_XMEGA + #define USB_CAN_BE_DEVICE + #elif (defined(__AVR_ATxmega16C4__) || defined(__AVR_ATxmega32C4__)) + #define USB_SERIES_C4_XMEGA + #define USB_CAN_BE_DEVICE + #endif + + #if (defined(USB_CAN_BE_DEVICE) && defined(USB_CAN_BE_HOST)) + #define USB_CAN_BE_BOTH + #endif + + #if defined(USB_HOST_ONLY) + #if !defined(USB_CAN_BE_HOST) + #error USB_HOST_ONLY is not available for the currently selected microcontroller model. + #else + #undef USB_CAN_BE_DEVICE + #undef USB_CAN_BE_BOTH + #endif + #endif + + #if defined(USB_DEVICE_ONLY) + #if !defined(USB_CAN_BE_DEVICE) + #error USB_DEVICE_ONLY is not available for the currently selected microcontroller model. + #else + #undef USB_CAN_BE_HOST + #undef USB_CAN_BE_BOTH + #endif + #endif + + #if (defined(USB_HOST_ONLY) && defined(USB_DEVICE_ONLY)) + #error USB_HOST_ONLY and USB_DEVICE_ONLY are mutually exclusive. + #endif + + #if (!defined(USB_CAN_BE_DEVICE) && !defined(USB_CAN_BE_HOST)) + #error The currently selected device or architecture is not supported under the USB component of the library. + #endif + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/USBTask.c b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/USBTask.c new file mode 100644 index 00000000..e0a99150 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/USBTask.c @@ -0,0 +1,91 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#define __INCLUDE_FROM_USBTASK_C +#define __INCLUDE_FROM_USB_DRIVER +#include "USBTask.h" + +volatile bool USB_IsInitialized; +USB_Request_Header_t USB_ControlRequest; + +#if defined(USB_CAN_BE_HOST) && !defined(HOST_STATE_AS_GPIOR) +volatile uint8_t USB_HostState; +#endif + +#if defined(USB_CAN_BE_DEVICE) && !defined(DEVICE_STATE_AS_GPIOR) +volatile uint8_t USB_DeviceState; +#endif + +void USB_USBTask(void) +{ + #if defined(USB_HOST_ONLY) + USB_HostTask(); + #elif defined(USB_DEVICE_ONLY) + USB_DeviceTask(); + #else + if (USB_CurrentMode == USB_MODE_Device) + USB_DeviceTask(); + #if defined(USB_CAN_BE_HOST) + else if (USB_CurrentMode == USB_MODE_Host) + USB_HostTask(); + #endif + #endif +} + +#if defined(USB_CAN_BE_DEVICE) +static void USB_DeviceTask(void) +{ + if (USB_DeviceState != DEVICE_STATE_Unattached) + { + uint8_t PrevEndpoint = Endpoint_GetCurrentEndpoint(); + + Endpoint_SelectEndpoint(ENDPOINT_CONTROLEP); + + if (Endpoint_IsSETUPReceived()) + USB_Device_ProcessControlRequest(); + + Endpoint_SelectEndpoint(PrevEndpoint); + } +} +#endif + +#if defined(USB_CAN_BE_HOST) +static void USB_HostTask(void) +{ + uint8_t PrevPipe = Pipe_GetCurrentPipe(); + + Pipe_SelectPipe(PIPE_CONTROLPIPE); + + USB_Host_ProcessNextHostState(); + + Pipe_SelectPipe(PrevPipe); +} +#endif + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/USBTask.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/USBTask.h new file mode 100644 index 00000000..531fa6dc --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/USBTask.h @@ -0,0 +1,204 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Main USB service task management. + * + * This file contains the function definitions required for the main USB service task, which must be called + * from the user application to ensure that the USB connection to or from a connected USB device is maintained. + * + * \note This file should not be included directly. It is automatically included as needed by the USB driver + * dispatch header located in LUFA/Drivers/USB/USB.h. + */ + +#ifndef __USBTASK_H__ +#define __USBTASK_H__ + + /* Includes: */ + #include "../../../Common/Common.h" + #include "USBMode.h" + #include "USBController.h" + #include "Events.h" + #include "StdRequestType.h" + #include "StdDescriptors.h" + + #if defined(USB_CAN_BE_DEVICE) + #include "DeviceStandardReq.h" + #endif + + #if defined(USB_CAN_BE_HOST) + #include "HostStandardReq.h" + #endif + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_USB_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB/USB.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Global Variables: */ + /** Indicates if the USB interface is currently initialized but not necessarily connected to a host + * or device (i.e. if \ref USB_Init() has been run). If this is false, all other library globals related + * to the USB driver are invalid. + * + * \attention This variable should be treated as read-only in the user application, and never manually + * changed in value. + * + * \ingroup Group_USBManagement + */ + extern volatile bool USB_IsInitialized; + + /** Structure containing the last received Control request when in Device mode (for use in user-applications + * inside of the \ref EVENT_USB_Device_ControlRequest() event, or for filling up with a control request to + * issue when in Host mode before calling \ref USB_Host_SendControlRequest(). + * + * \note The contents of this structure is automatically endian-corrected for the current CPU architecture. + * + * \ingroup Group_USBManagement + */ + extern USB_Request_Header_t USB_ControlRequest; + + #if defined(USB_CAN_BE_HOST) || defined(__DOXYGEN__) + #if !defined(HOST_STATE_AS_GPIOR) || defined(__DOXYGEN__) + /** Indicates the current host state machine state. When in host mode, this indicates the state + * via one of the values of the \ref USB_Host_States_t enum values. + * + * This value should not be altered by the user application as it is handled automatically by the + * library. + * + * To reduce program size and speed up checks of this global on the AVR8 architecture, it can be + * placed into one of the AVR's \c GPIOR hardware registers instead of RAM by defining the + * \c HOST_STATE_AS_GPIOR token to a value between 0 and 2 in the project makefile and passing it to + * the compiler via the -D switch. When defined, the corresponding GPIOR register should not be used + * in the user application except implicitly via the library APIs. + * + * \note This global is only present if the user application can be a USB host. + * + * \see \ref USB_Host_States_t for a list of possible device states. + * + * \ingroup Group_Host + */ + extern volatile uint8_t USB_HostState; + #else + #define _GET_HOST_GPIOR_NAME2(y) GPIOR ## y + #define _GET_HOST_GPIOR_NAME(x) _GET_HOST_GPIOR_NAME2(x) + #define USB_HostState _GET_HOST_GPIOR_NAME(HOST_STATE_AS_GPIOR) + #endif + #endif + + #if defined(USB_CAN_BE_DEVICE) || defined(__DOXYGEN__) + #if !defined(DEVICE_STATE_AS_GPIOR) || defined(__DOXYGEN__) + /** Indicates the current device state machine state. When in device mode, this indicates the state + * via one of the values of the \ref USB_Device_States_t enum values. + * + * This value should not be altered by the user application as it is handled automatically by the + * library. The only exception to this rule is if the NO_LIMITED_CONTROLLER_CONNECT token is used + * (see \ref EVENT_USB_Device_Connect() and \ref EVENT_USB_Device_Disconnect() events). + * + * To reduce program size and speed up checks of this global on the AVR8 architecture, it can be + * placed into one of the AVR's \c GPIOR hardware registers instead of RAM by defining the + * \c DEVICE_STATE_AS_GPIOR token to a value between 0 and 2 in the project makefile and passing it to + * the compiler via the -D switch. When defined, the corresponding GPIOR register should not be used + * in the user application except implicitly via the library APIs. + * + * \attention This variable should be treated as read-only in the user application, and never manually + * changed in value except in the circumstances outlined above. + * + * \note This global is only present if the user application can be a USB device. + * \n\n + * + * \see \ref USB_Device_States_t for a list of possible device states. + * + * \ingroup Group_Device + */ + extern volatile uint8_t USB_DeviceState; + #else + #define _GET_DEVICE_GPIOR_NAME2(y) GPIOR ## y + #define _GET_DEVICE_GPIOR_NAME(x) _GET_DEVICE_GPIOR_NAME2(x) + #define USB_DeviceState _GET_DEVICE_GPIOR_NAME(DEVICE_STATE_AS_GPIOR) + #endif + #endif + + /* Function Prototypes: */ + /** This is the main USB management task. The USB driver requires this task to be executed + * continuously when the USB system is active (device attached in host mode, or attached to a host + * in device mode) in order to manage USB communications. This task may be executed inside an RTOS, + * fast timer ISR or the main user application loop. + * + * The USB task must be serviced within 30ms while in device mode, or within 1ms while in host mode. + * The task may be serviced at all times, or (for minimum CPU consumption): + * + * - In device mode, it may be disabled at start-up, enabled on the firing of the \ref EVENT_USB_Device_Connect() + * event and disabled again on the firing of the \ref EVENT_USB_Device_Disconnect() event. + * + * - In host mode, it may be disabled at start-up, enabled on the firing of the \ref EVENT_USB_Host_DeviceAttached() + * event and disabled again on the firing of the \ref EVENT_USB_Host_DeviceEnumerationComplete() or + * \ref EVENT_USB_Host_DeviceEnumerationFailed() events. + * + * If in device mode (only), the control endpoint can instead be managed via interrupts entirely by the library + * by defining the INTERRUPT_CONTROL_ENDPOINT token and passing it to the compiler via the -D switch. + * + * \see \ref Group_Events for more information on the USB events. + * + * \ingroup Group_USBManagement + */ + void USB_USBTask(void); + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Function Prototypes: */ + #if defined(__INCLUDE_FROM_USBTASK_C) + #if defined(USB_CAN_BE_HOST) + static void USB_HostTask(void); + #endif + + #if defined(USB_CAN_BE_DEVICE) + static void USB_DeviceTask(void); + #endif + #endif + + /* Macros: */ + #define HOST_TASK_NONBLOCK_WAIT(Duration, NextState) MACROS{ USB_HostState = HOST_STATE_WaitForDevice; \ + WaitMSRemaining = (Duration); \ + PostWaitState = (NextState); }MACROE + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/Device_XMEGA.c b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/Device_XMEGA.c new file mode 100644 index 00000000..47c34590 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/Device_XMEGA.c @@ -0,0 +1,49 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#include "../../../../Common/Common.h" +#if (ARCH == ARCH_XMEGA) + +#define __INCLUDE_FROM_USB_DRIVER +#include "../USBMode.h" + +#if defined(USB_CAN_BE_DEVICE) + +#include "../Device.h" + +void USB_Device_SendRemoteWakeup(void) +{ + USB.CTRLB |= USB_RWAKEUP_bm; +} + +#endif + +#endif + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/Device_XMEGA.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/Device_XMEGA.h new file mode 100644 index 00000000..aec693a3 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/Device_XMEGA.h @@ -0,0 +1,258 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief USB Device definitions for the AVR XMEGA microcontrollers. + * \copydetails Group_Device_XMEGA + * + * \note This file should not be included directly. It is automatically included as needed by the USB driver + * dispatch header located in LUFA/Drivers/USB/USB.h. + */ + +/** \ingroup Group_Device + * \defgroup Group_Device_XMEGA Device Management (XMEGA) + * \brief USB Device definitions for the AVR XMEGA microcontrollers. + * + * Architecture specific USB Device definitions for the Atmel AVR XMEGA microcontrollers. + * + * @{ + */ + +#ifndef __USBDEVICE_XMEGA_H__ +#define __USBDEVICE_XMEGA_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + #include "../USBController.h" + #include "../StdDescriptors.h" + #include "../USBInterrupt.h" + #include "../Endpoint.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_USB_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB/USB.h instead. + #endif + + #if (defined(USE_RAM_DESCRIPTORS) && defined(USE_EEPROM_DESCRIPTORS)) + #error USE_RAM_DESCRIPTORS and USE_EEPROM_DESCRIPTORS are mutually exclusive. + #endif + + #if (defined(USE_FLASH_DESCRIPTORS) && defined(USE_EEPROM_DESCRIPTORS)) + #error USE_FLASH_DESCRIPTORS and USE_EEPROM_DESCRIPTORS are mutually exclusive. + #endif + + #if (defined(USE_FLASH_DESCRIPTORS) && defined(USE_RAM_DESCRIPTORS)) + #error USE_FLASH_DESCRIPTORS and USE_RAM_DESCRIPTORS are mutually exclusive. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** \name USB Device Mode Option Masks */ + //@{ + /** Mask for the Options parameter of the \ref USB_Init() function. This indicates that the + * USB interface should be initialized in low speed (1.5Mb/s) mode. + * + * \note Low Speed mode is not available on all USB AVR models. + * \n + * + * \note Restrictions apply on the number, size and type of endpoints which can be used + * when running in low speed mode - refer to the USB 2.0 specification. + */ + #define USB_DEVICE_OPT_LOWSPEED (1 << 0) + + #if (F_USB > 6000000) + /** Mask for the Options parameter of the \ref USB_Init() function. This indicates that the + * USB interface should be initialized in full speed (12Mb/s) mode. + */ + #define USB_DEVICE_OPT_FULLSPEED (0 << 0) + #endif + //@} + + #if (!defined(NO_INTERNAL_SERIAL) || defined(__DOXYGEN__)) + /** String descriptor index for the device's unique serial number string descriptor within the device. + * This unique serial number is used by the host to associate resources to the device (such as drivers or COM port + * number allocations) to a device regardless of the port it is plugged in to on the host. Some microcontrollers contain + * a unique serial number internally, and setting the device descriptors serial number string index to this value + * will cause it to use the internal serial number. + * + * On unsupported devices, this will evaluate to \ref NO_DESCRIPTOR and so will force the host to create a pseudo-serial + * number for the device. + */ + #define USE_INTERNAL_SERIAL 0xDC + + /** Length of the device's unique internal serial number, in bits, if present on the selected microcontroller + * model. + */ + #define INTERNAL_SERIAL_LENGTH_BITS (8 * (1 + (offsetof(NVM_PROD_SIGNATURES_t, COORDY1) - offsetof(NVM_PROD_SIGNATURES_t, LOTNUM0)))) + + /** Start address of the internal serial number, in the appropriate address space, if present on the selected microcontroller + * model. + */ + #define INTERNAL_SERIAL_START_ADDRESS offsetof(NVM_PROD_SIGNATURES_t, LOTNUM0) + #else + #define USE_INTERNAL_SERIAL NO_DESCRIPTOR + + #define INTERNAL_SERIAL_LENGTH_BITS 0 + #define INTERNAL_SERIAL_START_ADDRESS 0 + #endif + + /* Function Prototypes: */ + /** Sends a Remote Wakeup request to the host. This signals to the host that the device should + * be taken out of suspended mode, and communications should resume. + * + * Typically, this is implemented so that HID devices (mice, keyboards, etc.) can wake up the + * host computer when the host has suspended all USB devices to enter a low power state. + * + * \note This function should only be used if the device has indicated to the host that it + * supports the Remote Wakeup feature in the device descriptors, and should only be + * issued if the host is currently allowing remote wakeup events from the device (i.e., + * the \ref USB_Device_RemoteWakeupEnabled flag is set). When the \c NO_DEVICE_REMOTE_WAKEUP + * compile time option is used, this function is unavailable. + * \n\n + * + * \note The USB clock must be running for this function to operate. If the stack is initialized with + * the \ref USB_OPT_MANUAL_PLL option enabled, the user must ensure that the PLL is running + * before attempting to call this function. + * + * \see \ref Group_StdDescriptors for more information on the RMWAKEUP feature and device descriptors. + */ + void USB_Device_SendRemoteWakeup(void); + + /* Inline Functions: */ + /** Returns the current USB frame number, when in device mode. Every millisecond the USB bus is active (i.e. enumerated to a host) + * the frame number is incremented by one. + * + * \return Current USB frame number from the USB controller. + */ + static inline uint16_t USB_Device_GetFrameNumber(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT; + static inline uint16_t USB_Device_GetFrameNumber(void) + { + return ((USB_EndpointTable_t*)USB.EPPTR)->FrameNum; + } + + #if !defined(NO_SOF_EVENTS) + /** Enables the device mode Start Of Frame events. When enabled, this causes the + * \ref EVENT_USB_Device_StartOfFrame() event to fire once per millisecond, synchronized to the USB bus, + * at the start of each USB frame when enumerated in device mode. + * + * \note This function is not available when the \c NO_SOF_EVENTS compile time token is defined. + */ + static inline void USB_Device_EnableSOFEvents(void) ATTR_ALWAYS_INLINE; + static inline void USB_Device_EnableSOFEvents(void) + { + USB.INTCTRLA |= USB_SOFIE_bm; + } + + /** Disables the device mode Start Of Frame events. When disabled, this stops the firing of the + * \ref EVENT_USB_Device_StartOfFrame() event when enumerated in device mode. + * + * \note This function is not available when the \c NO_SOF_EVENTS compile time token is defined. + */ + static inline void USB_Device_DisableSOFEvents(void) ATTR_ALWAYS_INLINE; + static inline void USB_Device_DisableSOFEvents(void) + { + USB.INTCTRLA &= ~USB_SOFIE_bm; + } + #endif + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Inline Functions: */ + static inline void USB_Device_SetLowSpeed(void) ATTR_ALWAYS_INLINE; + static inline void USB_Device_SetLowSpeed(void) + { + USB.CTRLA &= ~USB_SPEED_bm; + } + + static inline void USB_Device_SetFullSpeed(void) ATTR_ALWAYS_INLINE; + static inline void USB_Device_SetFullSpeed(void) + { + USB.CTRLA |= USB_SPEED_bm; + } + + static inline void USB_Device_SetDeviceAddress(const uint8_t Address) ATTR_ALWAYS_INLINE; + static inline void USB_Device_SetDeviceAddress(const uint8_t Address) + { + USB.ADDR = Address; + } + + static inline bool USB_Device_IsAddressSet(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT; + static inline bool USB_Device_IsAddressSet(void) + { + return ((USB.ADDR != 0) ? true : false); + } + + static inline void USB_Device_GetSerialString(uint16_t* const UnicodeString) ATTR_NON_NULL_PTR_ARG(1); + static inline void USB_Device_GetSerialString(uint16_t* const UnicodeString) + { + uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask(); + GlobalInterruptDisable(); + + uint8_t SigReadAddress = INTERNAL_SERIAL_START_ADDRESS; + + for (uint8_t SerialCharNum = 0; SerialCharNum < (INTERNAL_SERIAL_LENGTH_BITS / 4); SerialCharNum++) + { + uint8_t SerialByte; + + NVM.CMD = NVM_CMD_READ_CALIB_ROW_gc; + SerialByte = pgm_read_byte(SigReadAddress); + NVM.CMD = 0; + + if (SerialCharNum & 0x01) + { + SerialByte >>= 4; + SigReadAddress++; + } + + SerialByte &= 0x0F; + + UnicodeString[SerialCharNum] = cpu_to_le16((SerialByte >= 10) ? + (('A' - 10) + SerialByte) : ('0' + SerialByte)); + } + + SetGlobalInterruptMask(CurrentGlobalInt); + } + + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/EndpointStream_XMEGA.c b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/EndpointStream_XMEGA.c new file mode 100644 index 00000000..0a1a7750 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/EndpointStream_XMEGA.c @@ -0,0 +1,275 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#include "../../../../Common/Common.h" +#if (ARCH == ARCH_XMEGA) + +#define __INCLUDE_FROM_USB_DRIVER +#include "../USBMode.h" + +#if defined(USB_CAN_BE_DEVICE) + +#include "EndpointStream_XMEGA.h" + +#if !defined(CONTROL_ONLY_DEVICE) +uint8_t Endpoint_Discard_Stream(uint16_t Length, + uint16_t* const BytesProcessed) +{ + uint8_t ErrorCode; + uint16_t BytesInTransfer = 0; + + if ((ErrorCode = Endpoint_WaitUntilReady())) + return ErrorCode; + + if (BytesProcessed != NULL) + Length -= *BytesProcessed; + + while (Length) + { + if (!(Endpoint_IsReadWriteAllowed())) + { + Endpoint_ClearOUT(); + + if (BytesProcessed != NULL) + { + *BytesProcessed += BytesInTransfer; + return ENDPOINT_RWSTREAM_IncompleteTransfer; + } + + if ((ErrorCode = Endpoint_WaitUntilReady())) + return ErrorCode; + } + else + { + Endpoint_Discard_8(); + + Length--; + BytesInTransfer++; + } + } + + return ENDPOINT_RWSTREAM_NoError; +} + +uint8_t Endpoint_Null_Stream(uint16_t Length, + uint16_t* const BytesProcessed) +{ + uint8_t ErrorCode; + uint16_t BytesInTransfer = 0; + + if ((ErrorCode = Endpoint_WaitUntilReady())) + return ErrorCode; + + if (BytesProcessed != NULL) + Length -= *BytesProcessed; + + while (Length) + { + if (!(Endpoint_IsReadWriteAllowed())) + { + Endpoint_ClearIN(); + + if (BytesProcessed != NULL) + { + *BytesProcessed += BytesInTransfer; + return ENDPOINT_RWSTREAM_IncompleteTransfer; + } + + if ((ErrorCode = Endpoint_WaitUntilReady())) + return ErrorCode; + } + else + { + Endpoint_Write_8(0); + + Length--; + BytesInTransfer++; + } + } + + return ENDPOINT_RWSTREAM_NoError; +} + +/* The following abuses the C preprocessor in order to copy-paste common code with slight alterations, + * so that the code needs to be written once. It is a crude form of templating to reduce code maintenance. */ + +#define TEMPLATE_FUNC_NAME Endpoint_Write_Stream_LE +#define TEMPLATE_BUFFER_TYPE const void* +#define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN() +#define TEMPLATE_BUFFER_OFFSET(Length) 0 +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(*BufferPtr) +#include "Template/Template_Endpoint_RW.c" + +#define TEMPLATE_FUNC_NAME Endpoint_Write_Stream_BE +#define TEMPLATE_BUFFER_TYPE const void* +#define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN() +#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(*BufferPtr) +#include "Template/Template_Endpoint_RW.c" + +#define TEMPLATE_FUNC_NAME Endpoint_Read_Stream_LE +#define TEMPLATE_BUFFER_TYPE void* +#define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearOUT() +#define TEMPLATE_BUFFER_OFFSET(Length) 0 +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *BufferPtr = Endpoint_Read_8() +#include "Template/Template_Endpoint_RW.c" + +#define TEMPLATE_FUNC_NAME Endpoint_Read_Stream_BE +#define TEMPLATE_BUFFER_TYPE void* +#define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearOUT() +#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *BufferPtr = Endpoint_Read_8() +#include "Template/Template_Endpoint_RW.c" + +#if defined(ARCH_HAS_FLASH_ADDRESS_SPACE) + #define TEMPLATE_FUNC_NAME Endpoint_Write_PStream_LE + #define TEMPLATE_BUFFER_TYPE const void* + #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN() + #define TEMPLATE_BUFFER_OFFSET(Length) 0 + #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount + #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(pgm_read_byte(BufferPtr)) + #include "Template/Template_Endpoint_RW.c" + + #define TEMPLATE_FUNC_NAME Endpoint_Write_PStream_BE + #define TEMPLATE_BUFFER_TYPE const void* + #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN() + #define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) + #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount + #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(pgm_read_byte(BufferPtr)) + #include "Template/Template_Endpoint_RW.c" +#endif + +#if defined(ARCH_HAS_EEPROM_ADDRESS_SPACE) + #define TEMPLATE_FUNC_NAME Endpoint_Write_EStream_LE + #define TEMPLATE_BUFFER_TYPE const void* + #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN() + #define TEMPLATE_BUFFER_OFFSET(Length) 0 + #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount + #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(eeprom_read_byte(BufferPtr)) + #include "Template/Template_Endpoint_RW.c" + + #define TEMPLATE_FUNC_NAME Endpoint_Write_EStream_BE + #define TEMPLATE_BUFFER_TYPE const void* + #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearIN() + #define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) + #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount + #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(eeprom_read_byte(BufferPtr)) + #include "Template/Template_Endpoint_RW.c" + + #define TEMPLATE_FUNC_NAME Endpoint_Read_EStream_LE + #define TEMPLATE_BUFFER_TYPE void* + #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearOUT() + #define TEMPLATE_BUFFER_OFFSET(Length) 0 + #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount + #define TEMPLATE_TRANSFER_BYTE(BufferPtr) eeprom_update_byte(BufferPtr, Endpoint_Read_8()) + #include "Template/Template_Endpoint_RW.c" + + #define TEMPLATE_FUNC_NAME Endpoint_Read_EStream_BE + #define TEMPLATE_BUFFER_TYPE void* + #define TEMPLATE_CLEAR_ENDPOINT() Endpoint_ClearOUT() + #define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) + #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount + #define TEMPLATE_TRANSFER_BYTE(BufferPtr) eeprom_update_byte(BufferPtr, Endpoint_Read_8()) + #include "Template/Template_Endpoint_RW.c" +#endif + +#endif + +#define TEMPLATE_FUNC_NAME Endpoint_Write_Control_Stream_LE +#define TEMPLATE_BUFFER_OFFSET(Length) 0 +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(*BufferPtr) +#include "Template/Template_Endpoint_Control_W.c" + +#define TEMPLATE_FUNC_NAME Endpoint_Write_Control_Stream_BE +#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(*BufferPtr) +#include "Template/Template_Endpoint_Control_W.c" + +#define TEMPLATE_FUNC_NAME Endpoint_Read_Control_Stream_LE +#define TEMPLATE_BUFFER_OFFSET(Length) 0 +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *BufferPtr = Endpoint_Read_8() +#include "Template/Template_Endpoint_Control_R.c" + +#define TEMPLATE_FUNC_NAME Endpoint_Read_Control_Stream_BE +#define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) +#define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount +#define TEMPLATE_TRANSFER_BYTE(BufferPtr) *BufferPtr = Endpoint_Read_8() +#include "Template/Template_Endpoint_Control_R.c" + +#if defined(ARCH_HAS_FLASH_ADDRESS_SPACE) + #define TEMPLATE_FUNC_NAME Endpoint_Write_Control_PStream_LE + #define TEMPLATE_BUFFER_OFFSET(Length) 0 + #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount + #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(pgm_read_byte(BufferPtr)) + #include "Template/Template_Endpoint_Control_W.c" + + #define TEMPLATE_FUNC_NAME Endpoint_Write_Control_PStream_BE + #define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) + #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount + #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(pgm_read_byte(BufferPtr)) + #include "Template/Template_Endpoint_Control_W.c" +#endif + +#if defined(ARCH_HAS_EEPROM_ADDRESS_SPACE) + #define TEMPLATE_FUNC_NAME Endpoint_Write_Control_EStream_LE + #define TEMPLATE_BUFFER_OFFSET(Length) 0 + #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount + #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(eeprom_read_byte(BufferPtr)) + #include "Template/Template_Endpoint_Control_W.c" + + #define TEMPLATE_FUNC_NAME Endpoint_Write_Control_EStream_BE + #define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) + #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount + #define TEMPLATE_TRANSFER_BYTE(BufferPtr) Endpoint_Write_8(eeprom_read_byte(BufferPtr)) + #include "Template/Template_Endpoint_Control_W.c" + + #define TEMPLATE_FUNC_NAME Endpoint_Read_Control_EStream_LE + #define TEMPLATE_BUFFER_OFFSET(Length) 0 + #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr += Amount + #define TEMPLATE_TRANSFER_BYTE(BufferPtr) eeprom_update_byte(BufferPtr, Endpoint_Read_8()) + #include "Template/Template_Endpoint_Control_R.c" + + #define TEMPLATE_FUNC_NAME Endpoint_Read_Control_EStream_BE + #define TEMPLATE_BUFFER_OFFSET(Length) (Length - 1) + #define TEMPLATE_BUFFER_MOVE(BufferPtr, Amount) BufferPtr -= Amount + #define TEMPLATE_TRANSFER_BYTE(BufferPtr) eeprom_update_byte(BufferPtr, Endpoint_Read_8()) + #include "Template/Template_Endpoint_Control_R.c" +#endif + +#endif + +#endif diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/EndpointStream_XMEGA.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/EndpointStream_XMEGA.h new file mode 100644 index 00000000..4d2a9f57 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/EndpointStream_XMEGA.h @@ -0,0 +1,648 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Endpoint data stream transmission and reception management for the AVR XMEGA microcontrollers. + * \copydetails Group_EndpointStreamRW_XMEGA + * + * \note This file should not be included directly. It is automatically included as needed by the USB driver + * dispatch header located in LUFA/Drivers/USB/USB.h. + */ + +/** \ingroup Group_EndpointStreamRW + * \defgroup Group_EndpointStreamRW_XMEGA Read/Write of Multi-Byte Streams (XMEGA) + * \brief Endpoint data stream transmission and reception management for the Atmel AVR XMEGA architecture. + * + * Functions, macros, variables, enums and types related to data reading and writing of data streams from + * and to endpoints. + * + * @{ + */ + +#ifndef __ENDPOINT_STREAM_XMEGA_H__ +#define __ENDPOINT_STREAM_XMEGA_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + #include "../USBMode.h" + #include "../USBTask.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_USB_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB/USB.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Function Prototypes: */ + /** \name Stream functions for null data */ + //@{ + + /** Reads and discards the given number of bytes from the currently selected endpoint's bank, + * discarding fully read packets from the host as needed. The last packet is not automatically + * discarded once the remaining bytes has been read; the user is responsible for manually + * discarding the last packet from the host via the \ref Endpoint_ClearOUT() macro. + * + * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, + * failing or succeeding as a single unit. If the BytesProcessed parameter points to a valid + * storage location, the transfer will instead be performed as a series of chunks. Each time + * the endpoint bank becomes empty while there is still data to process (and after the current + * packet has been acknowledged) the BytesProcessed location will be updated with the total number + * of bytes processed in the stream, and the function will exit with an error code of + * \ref ENDPOINT_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed + * in the user code - to continue the transfer, call the function again with identical parameters + * and it will resume until the BytesProcessed value reaches the total transfer length. + * + * Single Stream Transfer Example: + * \code + * uint8_t ErrorCode; + * + * if ((ErrorCode = Endpoint_Discard_Stream(512, NULL)) != ENDPOINT_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * Partial Stream Transfers Example: + * \code + * uint8_t ErrorCode; + * uint16_t BytesProcessed; + * + * BytesProcessed = 0; + * while ((ErrorCode = Endpoint_Discard_Stream(512, &BytesProcessed)) == ENDPOINT_RWSTREAM_IncompleteTransfer) + * { + * // Stream not yet complete - do other actions here, abort if required + * } + * + * if (ErrorCode != ENDPOINT_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * \note This routine should not be used on CONTROL type endpoints. + * + * \param[in] Length Number of bytes to discard via the currently selected endpoint. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current + * transaction should be updated, \c NULL if the entire stream should be read at once. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Discard_Stream(uint16_t Length, + uint16_t* const BytesProcessed); + + /** Writes a given number of zeroed bytes to the currently selected endpoint's bank, sending + * full packets to the host as needed. The last packet is not automatically sent once the + * remaining bytes have been written; the user is responsible for manually sending the last + * packet to the host via the \ref Endpoint_ClearIN() macro. + * + * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, + * failing or succeeding as a single unit. If the BytesProcessed parameter points to a valid + * storage location, the transfer will instead be performed as a series of chunks. Each time + * the endpoint bank becomes full while there is still data to process (and after the current + * packet transmission has been initiated) the BytesProcessed location will be updated with the + * total number of bytes processed in the stream, and the function will exit with an error code of + * \ref ENDPOINT_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed + * in the user code - to continue the transfer, call the function again with identical parameters + * and it will resume until the BytesProcessed value reaches the total transfer length. + * + * Single Stream Transfer Example: + * \code + * uint8_t ErrorCode; + * + * if ((ErrorCode = Endpoint_Null_Stream(512, NULL)) != ENDPOINT_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * Partial Stream Transfers Example: + * \code + * uint8_t ErrorCode; + * uint16_t BytesProcessed; + * + * BytesProcessed = 0; + * while ((ErrorCode = Endpoint_Null_Stream(512, &BytesProcessed)) == ENDPOINT_RWSTREAM_IncompleteTransfer) + * { + * // Stream not yet complete - do other actions here, abort if required + * } + * + * if (ErrorCode != ENDPOINT_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * \note This routine should not be used on CONTROL type endpoints. + * + * \param[in] Length Number of zero bytes to send via the currently selected endpoint. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current + * transaction should be updated, \c NULL if the entire stream should be read at once. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Null_Stream(uint16_t Length, + uint16_t* const BytesProcessed); + + //@} + + /** \name Stream functions for RAM source/destination data */ + //@{ + + /** Writes the given number of bytes to the endpoint from the given buffer in little endian, + * sending full packets to the host as needed. The last packet filled is not automatically sent; + * the user is responsible for manually sending the last written packet to the host via the + * \ref Endpoint_ClearIN() macro. + * + * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, + * failing or succeeding as a single unit. If the BytesProcessed parameter points to a valid + * storage location, the transfer will instead be performed as a series of chunks. Each time + * the endpoint bank becomes full while there is still data to process (and after the current + * packet transmission has been initiated) the BytesProcessed location will be updated with the + * total number of bytes processed in the stream, and the function will exit with an error code of + * \ref ENDPOINT_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed + * in the user code - to continue the transfer, call the function again with identical parameters + * and it will resume until the BytesProcessed value reaches the total transfer length. + * + * Single Stream Transfer Example: + * \code + * uint8_t DataStream[512]; + * uint8_t ErrorCode; + * + * if ((ErrorCode = Endpoint_Write_Stream_LE(DataStream, sizeof(DataStream), + * NULL)) != ENDPOINT_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * Partial Stream Transfers Example: + * \code + * uint8_t DataStream[512]; + * uint8_t ErrorCode; + * uint16_t BytesProcessed; + * + * BytesProcessed = 0; + * while ((ErrorCode = Endpoint_Write_Stream_LE(DataStream, sizeof(DataStream), + * &BytesProcessed)) == ENDPOINT_RWSTREAM_IncompleteTransfer) + * { + * // Stream not yet complete - do other actions here, abort if required + * } + * + * if (ErrorCode != ENDPOINT_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * \note This routine should not be used on CONTROL type endpoints. + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current + * transaction should be updated, \c NULL if the entire stream should be written at once. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Write_Stream_LE(const void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** Writes the given number of bytes to the endpoint from the given buffer in big endian, + * sending full packets to the host as needed. The last packet filled is not automatically sent; + * the user is responsible for manually sending the last written packet to the host via the + * \ref Endpoint_ClearIN() macro. + * + * \note This routine should not be used on CONTROL type endpoints. + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current + * transaction should be updated, \c NULL if the entire stream should be written at once. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Write_Stream_BE(const void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** Reads the given number of bytes from the endpoint from the given buffer in little endian, + * discarding fully read packets from the host as needed. The last packet is not automatically + * discarded once the remaining bytes has been read; the user is responsible for manually + * discarding the last packet from the host via the \ref Endpoint_ClearOUT() macro. + * + * If the BytesProcessed parameter is \c NULL, the entire stream transfer is attempted at once, + * failing or succeeding as a single unit. If the BytesProcessed parameter points to a valid + * storage location, the transfer will instead be performed as a series of chunks. Each time + * the endpoint bank becomes empty while there is still data to process (and after the current + * packet has been acknowledged) the BytesProcessed location will be updated with the total number + * of bytes processed in the stream, and the function will exit with an error code of + * \ref ENDPOINT_RWSTREAM_IncompleteTransfer. This allows for any abort checking to be performed + * in the user code - to continue the transfer, call the function again with identical parameters + * and it will resume until the BytesProcessed value reaches the total transfer length. + * + * Single Stream Transfer Example: + * \code + * uint8_t DataStream[512]; + * uint8_t ErrorCode; + * + * if ((ErrorCode = Endpoint_Read_Stream_LE(DataStream, sizeof(DataStream), + * NULL)) != ENDPOINT_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * Partial Stream Transfers Example: + * \code + * uint8_t DataStream[512]; + * uint8_t ErrorCode; + * uint16_t BytesProcessed; + * + * BytesProcessed = 0; + * while ((ErrorCode = Endpoint_Read_Stream_LE(DataStream, sizeof(DataStream), + * &BytesProcessed)) == ENDPOINT_RWSTREAM_IncompleteTransfer) + * { + * // Stream not yet complete - do other actions here, abort if required + * } + * + * if (ErrorCode != ENDPOINT_RWSTREAM_NoError) + * { + * // Stream failed to complete - check ErrorCode here + * } + * \endcode + * + * \note This routine should not be used on CONTROL type endpoints. + * + * \param[out] Buffer Pointer to the destination data buffer to write to. + * \param[in] Length Number of bytes to send via the currently selected endpoint. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current + * transaction should be updated, \c NULL if the entire stream should be read at once. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Read_Stream_LE(void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** Reads the given number of bytes from the endpoint from the given buffer in big endian, + * discarding fully read packets from the host as needed. The last packet is not automatically + * discarded once the remaining bytes has been read; the user is responsible for manually + * discarding the last packet from the host via the \ref Endpoint_ClearOUT() macro. + * + * \note This routine should not be used on CONTROL type endpoints. + * + * \param[out] Buffer Pointer to the destination data buffer to write to. + * \param[in] Length Number of bytes to send via the currently selected endpoint. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current + * transaction should be updated, \c NULL if the entire stream should be read at once. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Read_Stream_BE(void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** Writes the given number of bytes to the CONTROL type endpoint from the given buffer in little endian, + * sending full packets to the host as needed. The host OUT acknowledgement is not automatically cleared + * in both failure and success states; the user is responsible for manually clearing the status OUT packet + * to finalize the transfer's status stage via the \ref Endpoint_ClearOUT() macro. + * + * \note This function automatically clears the control transfer's status stage. Do not manually attempt + * to clear the status stage when using this routine in a control transaction. + * \n\n + * + * \note This routine should only be used on CONTROL type endpoints. + * + * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained + * together; i.e. the entire stream data must be read or written at the one time. + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. + * + * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Write_Control_Stream_LE(const void* const Buffer, + uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); + + /** Writes the given number of bytes to the CONTROL type endpoint from the given buffer in big endian, + * sending full packets to the host as needed. The host OUT acknowledgement is not automatically cleared + * in both failure and success states; the user is responsible for manually clearing the status OUT packet + * to finalize the transfer's status stage via the \ref Endpoint_ClearOUT() macro. + * + * \note This function automatically clears the control transfer's status stage. Do not manually attempt + * to clear the status stage when using this routine in a control transaction. + * \n\n + * + * \note This routine should only be used on CONTROL type endpoints. + * + * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained + * together; i.e. the entire stream data must be read or written at the one time. + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. + * + * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Write_Control_Stream_BE(const void* const Buffer, + uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); + + /** Reads the given number of bytes from the CONTROL endpoint from the given buffer in little endian, + * discarding fully read packets from the host as needed. The device IN acknowledgement is not + * automatically sent after success or failure states; the user is responsible for manually sending the + * status IN packet to finalize the transfer's status stage via the \ref Endpoint_ClearIN() macro. + * + * \note This function automatically clears the control transfer's status stage. Do not manually attempt + * to clear the status stage when using this routine in a control transaction. + * \n\n + * + * \note This routine should only be used on CONTROL type endpoints. + * + * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained + * together; i.e. the entire stream data must be read or written at the one time. + * + * \param[out] Buffer Pointer to the destination data buffer to write to. + * \param[in] Length Number of bytes to send via the currently selected endpoint. + * + * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Read_Control_Stream_LE(void* const Buffer, + uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); + + /** Reads the given number of bytes from the CONTROL endpoint from the given buffer in big endian, + * discarding fully read packets from the host as needed. The device IN acknowledgement is not + * automatically sent after success or failure states; the user is responsible for manually sending the + * status IN packet to finalize the transfer's status stage via the \ref Endpoint_ClearIN() macro. + * + * \note This function automatically clears the control transfer's status stage. Do not manually attempt + * to clear the status stage when using this routine in a control transaction. + * \n\n + * + * \note This routine should only be used on CONTROL type endpoints. + * + * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained + * together; i.e. the entire stream data must be read or written at the one time. + * + * \param[out] Buffer Pointer to the destination data buffer to write to. + * \param[in] Length Number of bytes to send via the currently selected endpoint. + * + * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Read_Control_Stream_BE(void* const Buffer, + uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); + //@} + + /** \name Stream functions for EEPROM source/destination data */ + //@{ + + /** EEPROM buffer source version of \ref Endpoint_Write_Stream_LE(). + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current + * transaction should be updated, \c NULL if the entire stream should be written at once. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Write_EStream_LE(const void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** EEPROM buffer source version of \ref Endpoint_Write_Stream_BE(). + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current + * transaction should be updated, \c NULL if the entire stream should be written at once. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Write_EStream_BE(const void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** EEPROM buffer destination version of \ref Endpoint_Read_Stream_LE(). + * + * \param[out] Buffer Pointer to the destination data buffer to write to, located in EEPROM memory space. + * \param[in] Length Number of bytes to send via the currently selected endpoint. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current + * transaction should be updated, \c NULL if the entire stream should be read at once. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Read_EStream_LE(void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** EEPROM buffer destination version of \ref Endpoint_Read_Stream_BE(). + * + * \param[out] Buffer Pointer to the destination data buffer to write to, located in EEPROM memory space. + * \param[in] Length Number of bytes to send via the currently selected endpoint. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current + * transaction should be updated, \c NULL if the entire stream should be read at once. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Read_EStream_BE(void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** EEPROM buffer source version of Endpoint_Write_Control_Stream_LE. + * + * \note This function automatically clears the control transfer's status stage. Do not manually attempt + * to clear the status stage when using this routine in a control transaction. + * \n\n + * + * \note This routine should only be used on CONTROL type endpoints. + * \n\n + * + * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained + * together; i.e. the entire stream data must be read or written at the one time. + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. + * + * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Write_Control_EStream_LE(const void* const Buffer, + uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); + + /** EEPROM buffer source version of \ref Endpoint_Write_Control_Stream_BE(). + * + * \note This function automatically clears the control transfer's status stage. Do not manually attempt + * to clear the status stage when using this routine in a control transaction. + * \n\n + * + * \note This routine should only be used on CONTROL type endpoints. + * \n\n + * + * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained + * together; i.e. the entire stream data must be read or written at the one time. + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. + * + * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Write_Control_EStream_BE(const void* const Buffer, + uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); + + /** EEPROM buffer source version of \ref Endpoint_Read_Control_Stream_LE(). + * + * \note This function automatically clears the control transfer's status stage. Do not manually attempt + * to clear the status stage when using this routine in a control transaction. + * \n\n + * + * \note This routine should only be used on CONTROL type endpoints. + * \n\n + * + * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained + * together; i.e. the entire stream data must be read or written at the one time. + * + * \param[out] Buffer Pointer to the destination data buffer to write to. + * \param[in] Length Number of bytes to send via the currently selected endpoint. + * + * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Read_Control_EStream_LE(void* const Buffer, + uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); + + /** EEPROM buffer source version of \ref Endpoint_Read_Control_Stream_BE(). + * + * \note This function automatically clears the control transfer's status stage. Do not manually attempt + * to clear the status stage when using this routine in a control transaction. + * \n\n + * + * \note This routine should only be used on CONTROL type endpoints. + * \n\n + * + * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained + * together; i.e. the entire stream data must be read or written at the one time. + * + * \param[out] Buffer Pointer to the destination data buffer to write to. + * \param[in] Length Number of bytes to send via the currently selected endpoint. + * + * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Read_Control_EStream_BE(void* const Buffer, + uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); + //@} + + /** \name Stream functions for PROGMEM source/destination data */ + //@{ + + /** FLASH buffer source version of \ref Endpoint_Write_Stream_LE(). + * + * \pre The FLASH data must be located in the first 64KB of FLASH for this function to work correctly. + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current + * transaction should be updated, \c NULL if the entire stream should be written at once. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Write_PStream_LE(const void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** FLASH buffer source version of \ref Endpoint_Write_Stream_BE(). + * + * \pre The FLASH data must be located in the first 64KB of FLASH for this function to work correctly. + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. + * \param[in] BytesProcessed Pointer to a location where the total number of bytes processed in the current + * transaction should be updated, \c NULL if the entire stream should be written at once. + * + * \return A value from the \ref Endpoint_Stream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Write_PStream_BE(const void* const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) ATTR_NON_NULL_PTR_ARG(1); + + /** FLASH buffer source version of \ref Endpoint_Write_Control_Stream_LE(). + * + * \pre The FLASH data must be located in the first 64KB of FLASH for this function to work correctly. + * + * \note This function automatically clears the control transfer's status stage. Do not manually attempt + * to clear the status stage when using this routine in a control transaction. + * \n\n + * + * \note This routine should only be used on CONTROL type endpoints. + * \n\n + * + * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained + * together; i.e. the entire stream data must be read or written at the one time. + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. + * + * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Write_Control_PStream_LE(const void* const Buffer, + uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); + + /** FLASH buffer source version of \ref Endpoint_Write_Control_Stream_BE(). + * + * \pre The FLASH data must be located in the first 64KB of FLASH for this function to work correctly. + * + * \note This function automatically clears the control transfer's status stage. Do not manually attempt + * to clear the status stage when using this routine in a control transaction. + * \n\n + * + * \note This routine should only be used on CONTROL type endpoints. + * \n\n + * + * \warning Unlike the standard stream read/write commands, the control stream commands cannot be chained + * together; i.e. the entire stream data must be read or written at the one time. + * + * \param[in] Buffer Pointer to the source data buffer to read from. + * \param[in] Length Number of bytes to read for the currently selected endpoint into the buffer. + * + * \return A value from the \ref Endpoint_ControlStream_RW_ErrorCodes_t enum. + */ + uint8_t Endpoint_Write_Control_PStream_BE(const void* const Buffer, + uint16_t Length) ATTR_NON_NULL_PTR_ARG(1); + //@} + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.c b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.c new file mode 100644 index 00000000..b105e18c --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.c @@ -0,0 +1,168 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#include "../../../../Common/Common.h" +#if (ARCH == ARCH_XMEGA) + +#define __INCLUDE_FROM_USB_DRIVER +#include "../USBMode.h" + +#if defined(USB_CAN_BE_DEVICE) + +#include "../Endpoint.h" + +#if !defined(FIXED_CONTROL_ENDPOINT_SIZE) +uint8_t USB_Device_ControlEndpointSize = ENDPOINT_CONTROLEP_DEFAULT_SIZE; +#endif + +Endpoint_FIFOPair_t USB_Endpoint_FIFOs[ENDPOINT_TOTAL_ENDPOINTS]; + +volatile uint8_t USB_Endpoint_SelectedEndpoint; +volatile USB_EP_t* USB_Endpoint_SelectedHandle; +volatile Endpoint_FIFO_t* USB_Endpoint_SelectedFIFO; + +bool Endpoint_ConfigureEndpointTable(const USB_Endpoint_Table_t* const Table, + const uint8_t Entries) +{ + for (uint8_t i = 0; i < Entries; i++) + { + if (!(Table[i].Address)) + continue; + + if (!(Endpoint_ConfigureEndpoint(Table[i].Address, Table[i].Type, Table[i].Size, Table[i].Banks))) + { + return false; + } + } + + return true; +} + +bool Endpoint_ConfigureEndpoint_PRV(const uint8_t Address, + const uint8_t Config, + const uint8_t Size) +{ + Endpoint_SelectEndpoint(Address); + + USB_Endpoint_SelectedHandle->CTRL = 0; + USB_Endpoint_SelectedHandle->STATUS = (Address & ENDPOINT_DIR_IN) ? USB_EP_BUSNACK0_bm : 0; + USB_Endpoint_SelectedHandle->CTRL = Config; + USB_Endpoint_SelectedHandle->CNT = 0; + USB_Endpoint_SelectedHandle->DATAPTR = (intptr_t)USB_Endpoint_SelectedFIFO->Data; + + USB_Endpoint_SelectedFIFO->Length = (Address & ENDPOINT_DIR_IN) ? Size : 0; + USB_Endpoint_SelectedFIFO->Position = 0; + + return true; +} + +void Endpoint_ClearEndpoints(void) +{ + for (uint8_t EPNum = 0; EPNum < ENDPOINT_TOTAL_ENDPOINTS; EPNum++) + { + ((USB_EndpointTable_t*)USB.EPPTR)->Endpoints[EPNum].IN.CTRL = 0; + ((USB_EndpointTable_t*)USB.EPPTR)->Endpoints[EPNum].OUT.CTRL = 0; + } +} + +void Endpoint_ClearStatusStage(void) +{ + if (USB_ControlRequest.bmRequestType & REQDIR_DEVICETOHOST) + { + while (!(Endpoint_IsOUTReceived())) + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return; + } + + Endpoint_ClearOUT(); + } + else + { + while (!(Endpoint_IsINReady())) + { + if (USB_DeviceState == DEVICE_STATE_Unattached) + return; + } + + Endpoint_ClearIN(); + } +} + +#if !defined(CONTROL_ONLY_DEVICE) +uint8_t Endpoint_WaitUntilReady(void) +{ + #if (USB_STREAM_TIMEOUT_MS < 0xFF) + uint8_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS; + #else + uint16_t TimeoutMSRem = USB_STREAM_TIMEOUT_MS; + #endif + + uint16_t PreviousFrameNumber = USB_Device_GetFrameNumber(); + + for (;;) + { + if (Endpoint_GetEndpointDirection() == ENDPOINT_DIR_IN) + { + if (Endpoint_IsINReady()) + return ENDPOINT_READYWAIT_NoError; + } + else + { + if (Endpoint_IsOUTReceived()) + return ENDPOINT_READYWAIT_NoError; + } + + uint8_t USB_DeviceState_LCL = USB_DeviceState; + + if (USB_DeviceState_LCL == DEVICE_STATE_Unattached) + return ENDPOINT_READYWAIT_DeviceDisconnected; + else if (USB_DeviceState_LCL == DEVICE_STATE_Suspended) + return ENDPOINT_READYWAIT_BusSuspended; + else if (Endpoint_IsStalled()) + return ENDPOINT_READYWAIT_EndpointStalled; + + uint16_t CurrentFrameNumber = USB_Device_GetFrameNumber(); + + if (CurrentFrameNumber != PreviousFrameNumber) + { + PreviousFrameNumber = CurrentFrameNumber; + + if (!(TimeoutMSRem--)) + return ENDPOINT_READYWAIT_Timeout; + } + } +} +#endif + +#endif + +#endif + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.h new file mode 100644 index 00000000..a4118889 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/Endpoint_XMEGA.h @@ -0,0 +1,777 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief USB Endpoint definitions for the AVR XMEGA microcontrollers. + * \copydetails Group_EndpointManagement_XMEGA + * + * \note This file should not be included directly. It is automatically included as needed by the USB driver + * dispatch header located in LUFA/Drivers/USB/USB.h. + */ + +/** \ingroup Group_EndpointRW + * \defgroup Group_EndpointRW_XMEGA Endpoint Data Reading and Writing (XMEGA) + * \brief Endpoint data read/write definitions for the Atmel AVR XMEGA architecture. + * + * Functions, macros, variables, enums and types related to data reading and writing from and to endpoints. + */ + +/** \ingroup Group_EndpointPrimitiveRW + * \defgroup Group_EndpointPrimitiveRW_XMEGA Read/Write of Primitive Data Types (XMEGA) + * \brief Endpoint primitive read/write definitions for the Atmel AVR XMEGA architecture. + * + * Functions, macros, variables, enums and types related to data reading and writing of primitive data types + * from and to endpoints. + */ + +/** \ingroup Group_EndpointPacketManagement + * \defgroup Group_EndpointPacketManagement_XMEGA Endpoint Packet Management (XMEGA) + * \brief Endpoint packet management definitions for the Atmel AVR XMEGA architecture. + * + * Functions, macros, variables, enums and types related to packet management of endpoints. + */ + +/** \ingroup Group_EndpointManagement + * \defgroup Group_EndpointManagement_XMEGA Endpoint Management (XMEGA) + * \brief Endpoint management definitions for the Atmel AVR XMEGA architecture. + * + * Functions, macros and enums related to endpoint management when in USB Device mode. This + * module contains the endpoint management macros, as well as endpoint interrupt and data + * send/receive functions for various data types. + * + * @{ + */ + +#ifndef __ENDPOINT_XMEGA_H__ +#define __ENDPOINT_XMEGA_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + #include "../USBTask.h" + #include "../USBInterrupt.h" + #include "../USBController.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_USB_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB/USB.h instead. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + #if (!defined(MAX_ENDPOINT_INDEX) && !defined(CONTROL_ONLY_DEVICE)) || defined(__DOXYGEN__) + /** Total number of endpoints (including the default control endpoint at address 0) which may + * be used in the device. Different USB AVR models support different amounts of endpoints, + * this value reflects the maximum number of endpoints for the currently selected AVR model. + */ + #define ENDPOINT_TOTAL_ENDPOINTS 16 + #else + #if defined(CONTROL_ONLY_DEVICE) + #define ENDPOINT_TOTAL_ENDPOINTS 1 + #else + #define ENDPOINT_TOTAL_ENDPOINTS (MAX_ENDPOINT_INDEX + 1) + #endif + #endif + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Type Defines: */ + typedef struct + { + uint8_t Data[64]; + + uint8_t Length; + uint8_t Position; + } Endpoint_FIFO_t; + + typedef struct + { + Endpoint_FIFO_t OUT; + Endpoint_FIFO_t IN; + } Endpoint_FIFOPair_t; + + /* External Variables: */ + extern Endpoint_FIFOPair_t USB_Endpoint_FIFOs[ENDPOINT_TOTAL_ENDPOINTS]; + extern volatile uint8_t USB_Endpoint_SelectedEndpoint; + extern volatile USB_EP_t* USB_Endpoint_SelectedHandle; + extern volatile Endpoint_FIFO_t* USB_Endpoint_SelectedFIFO; + + /* Inline Functions: */ + static inline uint8_t Endpoint_BytesToEPSizeMask(const uint16_t Bytes) ATTR_WARN_UNUSED_RESULT ATTR_CONST + ATTR_ALWAYS_INLINE; + static inline uint8_t Endpoint_BytesToEPSizeMask(const uint16_t Bytes) + { + uint8_t MaskVal = 0; + uint16_t CheckBytes = 8; + + while (CheckBytes < Bytes) + { + MaskVal++; + CheckBytes <<= 1; + } + + return (MaskVal << USB_EP_BUFSIZE_gp); + } + + /* Function Prototypes: */ + bool Endpoint_ConfigureEndpoint_PRV(const uint8_t Address, + const uint8_t Config, + const uint8_t Size); + void Endpoint_ClearEndpoints(void); + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + #if (!defined(FIXED_CONTROL_ENDPOINT_SIZE) || defined(__DOXYGEN__)) + /** Default size of the default control endpoint's bank, until altered by the control endpoint bank size + * value in the device descriptor. Not available if the \c FIXED_CONTROL_ENDPOINT_SIZE token is defined. + */ + #define ENDPOINT_CONTROLEP_DEFAULT_SIZE 8 + #endif + + /* Enums: */ + /** Enum for the possible error return codes of the \ref Endpoint_WaitUntilReady() function. + * + * \ingroup Group_EndpointRW_XMEGA + */ + enum Endpoint_WaitUntilReady_ErrorCodes_t + { + ENDPOINT_READYWAIT_NoError = 0, /**< Endpoint is ready for next packet, no error. */ + ENDPOINT_READYWAIT_EndpointStalled = 1, /**< The endpoint was stalled during the stream + * transfer by the host or device. + */ + ENDPOINT_READYWAIT_DeviceDisconnected = 2, /**< Device was disconnected from the host while + * waiting for the endpoint to become ready. + */ + ENDPOINT_READYWAIT_BusSuspended = 3, /**< The USB bus has been suspended by the host and + * no USB endpoint traffic can occur until the bus + * has resumed. + */ + ENDPOINT_READYWAIT_Timeout = 4, /**< The host failed to accept or send the next packet + * within the software timeout period set by the + * \ref USB_STREAM_TIMEOUT_MS macro. + */ + }; + + /* Inline Functions: */ + /** Selects the given endpoint address. + * + * Any endpoint operations which do not require the endpoint address to be indicated will operate on + * the currently selected endpoint. + * + * \param[in] Address Endpoint address to select. + */ + static inline void Endpoint_SelectEndpoint(const uint8_t Address); + static inline void Endpoint_SelectEndpoint(const uint8_t Address) + { + uint8_t EndpointNumber = (Address & ENDPOINT_EPNUM_MASK); + + USB_Endpoint_SelectedEndpoint = Address; + + if (Address & ENDPOINT_DIR_IN) + { + USB_Endpoint_SelectedFIFO = &USB_Endpoint_FIFOs[EndpointNumber].IN; + USB_Endpoint_SelectedHandle = &((USB_EndpointTable_t*)USB.EPPTR)->Endpoints[EndpointNumber].IN; + } + else + { + USB_Endpoint_SelectedFIFO = &USB_Endpoint_FIFOs[EndpointNumber].OUT; + USB_Endpoint_SelectedHandle = &((USB_EndpointTable_t*)USB.EPPTR)->Endpoints[EndpointNumber].OUT; + } + } + + /** Configures the specified endpoint address with the given endpoint type, direction, bank size + * and banking mode. Once configured, the endpoint may be read from or written to, depending + * on its direction. + * + * \param[in] Address Endpoint address to configure. + * + * \param[in] Type Type of endpoint to configure, a \c EP_TYPE_* mask. Not all endpoint types + * are available on Low Speed USB devices - refer to the USB 2.0 specification. + * + * \param[in] Size Size of the endpoint's bank, where packets are stored before they are transmitted + * to the USB host, or after they have been received from the USB host (depending on + * the endpoint's data direction). The bank size must indicate the maximum packet size + * that the endpoint can handle. + * + * \param[in] Banks Number of hardware banks to use for the endpoint being configured. + * + * \note The default control endpoint should not be manually configured by the user application, as + * it is automatically configured by the library internally. + * \n\n + * + * \note This routine will automatically select the specified endpoint. + * + * \return Boolean \c true if the configuration succeeded, \c false otherwise. + */ + static inline bool Endpoint_ConfigureEndpoint(const uint8_t Address, + const uint8_t Type, + const uint16_t Size, + const uint8_t Banks) ATTR_ALWAYS_INLINE; + static inline bool Endpoint_ConfigureEndpoint(const uint8_t Address, + const uint8_t Type, + const uint16_t Size, + const uint8_t Banks) + { + uint8_t EPConfigMask = (USB_EP_INTDSBL_bm | ((Banks > 1) ? USB_EP_PINGPONG_bm : 0) | Endpoint_BytesToEPSizeMask(Size)); + + if ((Address & ENDPOINT_EPNUM_MASK) >= ENDPOINT_TOTAL_ENDPOINTS) + return false; + + // TODO - Fix once limitations are lifted + EPConfigMask &= ~USB_EP_PINGPONG_bm; + if (Size > 64) + return false; + + switch (Type) + { + case EP_TYPE_CONTROL: + EPConfigMask |= USB_EP_TYPE_CONTROL_gc; + break; + case EP_TYPE_ISOCHRONOUS: + EPConfigMask |= USB_EP_TYPE_ISOCHRONOUS_gc; + break; + default: + EPConfigMask |= USB_EP_TYPE_BULK_gc; + break; + } + + if (Type == EP_TYPE_CONTROL) + Endpoint_ConfigureEndpoint_PRV(Address ^ ENDPOINT_DIR_IN, EPConfigMask, Size); + + return Endpoint_ConfigureEndpoint_PRV(Address, EPConfigMask, Size); + } + + /** Indicates the number of bytes currently stored in the current endpoint's selected bank. + * + * \ingroup Group_EndpointRW_XMEGA + * + * \return Total number of bytes in the currently selected Endpoint's FIFO buffer. + */ + static inline uint16_t Endpoint_BytesInEndpoint(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint16_t Endpoint_BytesInEndpoint(void) + { + if (USB_Endpoint_SelectedEndpoint & ENDPOINT_DIR_IN) + return USB_Endpoint_SelectedFIFO->Position; + else + return (USB_Endpoint_SelectedFIFO->Length - USB_Endpoint_SelectedFIFO->Position); + } + + /** Get the endpoint address of the currently selected endpoint. This is typically used to save + * the currently selected endpoint so that it can be restored after another endpoint has been + * manipulated. + * + * \return Index of the currently selected endpoint. + */ + static inline uint8_t Endpoint_GetCurrentEndpoint(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint8_t Endpoint_GetCurrentEndpoint(void) + { + return USB_Endpoint_SelectedEndpoint; + } + + /** Resets the endpoint bank FIFO. This clears all the endpoint banks and resets the USB controller's + * data In and Out pointers to the bank's contents. + * + * \param[in] Address Endpoint address whose FIFO buffers are to be reset. + */ + static inline void Endpoint_ResetEndpoint(const uint8_t Address) ATTR_ALWAYS_INLINE; + static inline void Endpoint_ResetEndpoint(const uint8_t Address) + { + if (Address & ENDPOINT_DIR_IN) + USB_Endpoint_FIFOs[Address & ENDPOINT_EPNUM_MASK].IN.Position = 0; + else + USB_Endpoint_FIFOs[Address & ENDPOINT_EPNUM_MASK].OUT.Position = 0; + } + + /** Determines if the currently selected endpoint is enabled, but not necessarily configured. + * + * \return Boolean \c true if the currently selected endpoint is enabled, \c false otherwise. + */ + static inline bool Endpoint_IsEnabled(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool Endpoint_IsEnabled(void) + { + return true; + } + + /** Aborts all pending IN transactions on the currently selected endpoint, once the bank + * has been queued for transmission to the host via \ref Endpoint_ClearIN(). This function + * will terminate all queued transactions, resetting the endpoint banks ready for a new + * packet. + * + * \ingroup Group_EndpointPacketManagement_XMEGA + */ + static inline void Endpoint_AbortPendingIN(void) + { + USB_Endpoint_SelectedHandle->STATUS |= USB_EP_BUSNACK0_bm; + } + + /** Determines if the currently selected endpoint may be read from (if data is waiting in the endpoint + * bank and the endpoint is an OUT direction, or if the bank is not yet full if the endpoint is an IN + * direction). This function will return false if an error has occurred in the endpoint, if the endpoint + * is an OUT direction and no packet (or an empty packet) has been received, or if the endpoint is an IN + * direction and the endpoint bank is full. + * + * \ingroup Group_EndpointPacketManagement_XMEGA + * + * \return Boolean \c true if the currently selected endpoint may be read from or written to, depending + * on its direction. + */ + static inline bool Endpoint_IsReadWriteAllowed(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool Endpoint_IsReadWriteAllowed(void) + { + return (USB_Endpoint_SelectedFIFO->Position < USB_Endpoint_SelectedFIFO->Length); + } + + /** Determines if the currently selected endpoint is configured. + * + * \return Boolean \c true if the currently selected endpoint has been configured, \c false otherwise. + */ + static inline bool Endpoint_IsConfigured(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool Endpoint_IsConfigured(void) + { + return ((USB_Endpoint_SelectedHandle->CTRL & USB_EP_TYPE_gm) ? true : false); + } + + /** Determines if the selected IN endpoint is ready for a new packet to be sent to the host. + * + * \ingroup Group_EndpointPacketManagement_XMEGA + * + * \return Boolean \c true if the current endpoint is ready for an IN packet, \c false otherwise. + */ + static inline bool Endpoint_IsINReady(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool Endpoint_IsINReady(void) + { + Endpoint_SelectEndpoint(USB_Endpoint_SelectedEndpoint | ENDPOINT_DIR_IN); + + return ((USB_Endpoint_SelectedHandle->STATUS & USB_EP_BUSNACK0_bm) ? true : false); + } + + /** Determines if the selected OUT endpoint has received new packet from the host. + * + * \ingroup Group_EndpointPacketManagement_XMEGA + * + * \return Boolean \c true if current endpoint is has received an OUT packet, \c false otherwise. + */ + static inline bool Endpoint_IsOUTReceived(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool Endpoint_IsOUTReceived(void) + { + Endpoint_SelectEndpoint(USB_Endpoint_SelectedEndpoint & ~ENDPOINT_DIR_IN); + + if (USB_Endpoint_SelectedHandle->STATUS & USB_EP_TRNCOMPL0_bm) + { + USB_Endpoint_SelectedFIFO->Length = USB_Endpoint_SelectedHandle->CNT; + return true; + } + + return false; + } + + /** Determines if the current CONTROL type endpoint has received a SETUP packet. + * + * \ingroup Group_EndpointPacketManagement_XMEGA + * + * \return Boolean \c true if the selected endpoint has received a SETUP packet, \c false otherwise. + */ + static inline bool Endpoint_IsSETUPReceived(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool Endpoint_IsSETUPReceived(void) + { + Endpoint_SelectEndpoint(USB_Endpoint_SelectedEndpoint & ~ENDPOINT_DIR_IN); + + if (USB_Endpoint_SelectedHandle->STATUS & USB_EP_SETUP_bm) + { + USB_Endpoint_SelectedFIFO->Length = USB_Endpoint_SelectedHandle->CNT; + return true; + } + + return false; + } + + /** Clears a received SETUP packet on the currently selected CONTROL type endpoint, freeing up the + * endpoint for the next packet. + * + * \ingroup Group_EndpointPacketManagement_XMEGA + * + * \note This is not applicable for non CONTROL type endpoints. + */ + static inline void Endpoint_ClearSETUP(void) ATTR_ALWAYS_INLINE; + static inline void Endpoint_ClearSETUP(void) + { + Endpoint_SelectEndpoint(USB_Endpoint_SelectedEndpoint & ~ENDPOINT_DIR_IN); + USB_Endpoint_SelectedHandle->STATUS &= ~(USB_EP_SETUP_bm | USB_EP_TRNCOMPL0_bm | USB_EP_BUSNACK0_bm | USB_EP_OVF_bm); + USB_Endpoint_SelectedHandle->STATUS |= USB_EP_TOGGLE_bm; + USB_Endpoint_SelectedFIFO->Position = 0; + + Endpoint_SelectEndpoint(USB_Endpoint_SelectedEndpoint | ENDPOINT_DIR_IN); + USB_Endpoint_SelectedHandle->STATUS |= USB_EP_TOGGLE_bm; + USB_Endpoint_SelectedFIFO->Position = 0; + } + + /** Sends an IN packet to the host on the currently selected endpoint, freeing up the endpoint for the + * next packet and switching to the alternative endpoint bank if double banked. + * + * \ingroup Group_EndpointPacketManagement_XMEGA + */ + static inline void Endpoint_ClearIN(void) ATTR_ALWAYS_INLINE; + static inline void Endpoint_ClearIN(void) + { + USB_Endpoint_SelectedHandle->CNT = USB_Endpoint_SelectedFIFO->Position; + USB_Endpoint_SelectedHandle->STATUS &= ~(USB_EP_TRNCOMPL0_bm | USB_EP_BUSNACK0_bm | USB_EP_OVF_bm); + USB_Endpoint_SelectedFIFO->Position = 0; + } + + /** Acknowledges an OUT packet to the host on the currently selected endpoint, freeing up the endpoint + * for the next packet and switching to the alternative endpoint bank if double banked. + * + * \ingroup Group_EndpointPacketManagement_XMEGA + */ + static inline void Endpoint_ClearOUT(void) ATTR_ALWAYS_INLINE; + static inline void Endpoint_ClearOUT(void) + { + USB_Endpoint_SelectedHandle->STATUS &= ~(USB_EP_TRNCOMPL0_bm | USB_EP_BUSNACK0_bm | USB_EP_OVF_bm); + USB_Endpoint_SelectedFIFO->Position = 0; + } + + /** Stalls the current endpoint, indicating to the host that a logical problem occurred with the + * indicated endpoint and that the current transfer sequence should be aborted. This provides a + * way for devices to indicate invalid commands to the host so that the current transfer can be + * aborted and the host can begin its own recovery sequence. + * + * The currently selected endpoint remains stalled until either the \ref Endpoint_ClearStall() macro + * is called, or the host issues a CLEAR FEATURE request to the device for the currently selected + * endpoint. + * + * \ingroup Group_EndpointPacketManagement_XMEGA + */ + static inline void Endpoint_StallTransaction(void) ATTR_ALWAYS_INLINE; + static inline void Endpoint_StallTransaction(void) + { + USB_Endpoint_SelectedHandle->CTRL |= USB_EP_STALL_bm; + + if ((USB_Endpoint_SelectedHandle->CTRL & USB_EP_TYPE_gm) == USB_EP_TYPE_CONTROL_gc) + { + Endpoint_SelectEndpoint(USB_Endpoint_SelectedEndpoint ^ ENDPOINT_DIR_IN); + USB_Endpoint_SelectedHandle->CTRL |= USB_EP_STALL_bm; + } + } + + /** Clears the STALL condition on the currently selected endpoint. + * + * \ingroup Group_EndpointPacketManagement_XMEGA + */ + static inline void Endpoint_ClearStall(void) ATTR_ALWAYS_INLINE; + static inline void Endpoint_ClearStall(void) + { + USB_Endpoint_SelectedHandle->CTRL &= ~USB_EP_STALL_bm; + } + + /** Determines if the currently selected endpoint is stalled, false otherwise. + * + * \ingroup Group_EndpointPacketManagement_XMEGA + * + * \return Boolean \c true if the currently selected endpoint is stalled, \c false otherwise. + */ + static inline bool Endpoint_IsStalled(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline bool Endpoint_IsStalled(void) + { + return ((USB_Endpoint_SelectedHandle->CTRL & USB_EP_STALL_bm) ? true : false); + } + + /** Resets the data toggle of the currently selected endpoint. */ + static inline void Endpoint_ResetDataToggle(void) ATTR_ALWAYS_INLINE; + static inline void Endpoint_ResetDataToggle(void) + { + USB_Endpoint_SelectedHandle->STATUS &= ~USB_EP_TOGGLE_bm; + } + + /** Determines the currently selected endpoint's direction. + * + * \return The currently selected endpoint's direction, as a \c ENDPOINT_DIR_* mask. + */ + static inline uint8_t Endpoint_GetEndpointDirection(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint8_t Endpoint_GetEndpointDirection(void) + { + return (USB_Endpoint_SelectedEndpoint & ENDPOINT_DIR_IN); + } + + /** Reads one byte from the currently selected endpoint's bank, for OUT direction endpoints. + * + * \ingroup Group_EndpointPrimitiveRW_XMEGA + * + * \return Next byte in the currently selected endpoint's FIFO buffer. + */ + static inline uint8_t Endpoint_Read_8(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint8_t Endpoint_Read_8(void) + { + return USB_Endpoint_SelectedFIFO->Data[USB_Endpoint_SelectedFIFO->Position++]; + } + + /** Writes one byte to the currently selected endpoint's bank, for IN direction endpoints. + * + * \ingroup Group_EndpointPrimitiveRW_XMEGA + * + * \param[in] Data Data to write into the the currently selected endpoint's FIFO buffer. + */ + static inline void Endpoint_Write_8(const uint8_t Data) ATTR_ALWAYS_INLINE; + static inline void Endpoint_Write_8(const uint8_t Data) + { + USB_Endpoint_SelectedFIFO->Data[USB_Endpoint_SelectedFIFO->Position++] = Data; + } + + /** Discards one byte from the currently selected endpoint's bank, for OUT direction endpoints. + * + * \ingroup Group_EndpointPrimitiveRW_XMEGA + */ + static inline void Endpoint_Discard_8(void) ATTR_ALWAYS_INLINE; + static inline void Endpoint_Discard_8(void) + { + USB_Endpoint_SelectedFIFO->Position++; + } + + /** Reads two bytes from the currently selected endpoint's bank in little endian format, for OUT + * direction endpoints. + * + * \ingroup Group_EndpointPrimitiveRW_XMEGA + * + * \return Next two bytes in the currently selected endpoint's FIFO buffer. + */ + static inline uint16_t Endpoint_Read_16_LE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint16_t Endpoint_Read_16_LE(void) + { + uint16_t Byte0 = Endpoint_Read_8(); + uint16_t Byte1 = Endpoint_Read_8(); + + return ((Byte1 << 8) | Byte0); + } + + /** Reads two bytes from the currently selected endpoint's bank in big endian format, for OUT + * direction endpoints. + * + * \ingroup Group_EndpointPrimitiveRW_XMEGA + * + * \return Next two bytes in the currently selected endpoint's FIFO buffer. + */ + static inline uint16_t Endpoint_Read_16_BE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint16_t Endpoint_Read_16_BE(void) + { + uint16_t Byte0 = Endpoint_Read_8(); + uint16_t Byte1 = Endpoint_Read_8(); + + return ((Byte0 << 8) | Byte1); + } + + /** Writes two bytes to the currently selected endpoint's bank in little endian format, for IN + * direction endpoints. + * + * \ingroup Group_EndpointPrimitiveRW_XMEGA + * + * \param[in] Data Data to write to the currently selected endpoint's FIFO buffer. + */ + static inline void Endpoint_Write_16_LE(const uint16_t Data) ATTR_ALWAYS_INLINE; + static inline void Endpoint_Write_16_LE(const uint16_t Data) + { + Endpoint_Write_8(Data & 0xFF); + Endpoint_Write_8(Data >> 8); + } + + /** Writes two bytes to the currently selected endpoint's bank in big endian format, for IN + * direction endpoints. + * + * \ingroup Group_EndpointPrimitiveRW_XMEGA + * + * \param[in] Data Data to write to the currently selected endpoint's FIFO buffer. + */ + static inline void Endpoint_Write_16_BE(const uint16_t Data) ATTR_ALWAYS_INLINE; + static inline void Endpoint_Write_16_BE(const uint16_t Data) + { + Endpoint_Write_8(Data >> 8); + Endpoint_Write_8(Data & 0xFF); + } + + /** Discards two bytes from the currently selected endpoint's bank, for OUT direction endpoints. + * + * \ingroup Group_EndpointPrimitiveRW_XMEGA + */ + static inline void Endpoint_Discard_16(void) ATTR_ALWAYS_INLINE; + static inline void Endpoint_Discard_16(void) + { + Endpoint_Discard_8(); + Endpoint_Discard_8(); + } + + /** Reads four bytes from the currently selected endpoint's bank in little endian format, for OUT + * direction endpoints. + * + * \ingroup Group_EndpointPrimitiveRW_XMEGA + * + * \return Next four bytes in the currently selected endpoint's FIFO buffer. + */ + static inline uint32_t Endpoint_Read_32_LE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint32_t Endpoint_Read_32_LE(void) + { + uint32_t Byte0 = Endpoint_Read_8(); + uint32_t Byte1 = Endpoint_Read_8(); + uint32_t Byte2 = Endpoint_Read_8(); + uint32_t Byte3 = Endpoint_Read_8(); + + return ((Byte3 << 24) | (Byte2 << 16) | (Byte1 << 8) | Byte0); + } + + /** Reads four bytes from the currently selected endpoint's bank in big endian format, for OUT + * direction endpoints. + * + * \ingroup Group_EndpointPrimitiveRW_XMEGA + * + * \return Next four bytes in the currently selected endpoint's FIFO buffer. + */ + static inline uint32_t Endpoint_Read_32_BE(void) ATTR_WARN_UNUSED_RESULT ATTR_ALWAYS_INLINE; + static inline uint32_t Endpoint_Read_32_BE(void) + { + uint32_t Byte0 = Endpoint_Read_8(); + uint32_t Byte1 = Endpoint_Read_8(); + uint32_t Byte2 = Endpoint_Read_8(); + uint32_t Byte3 = Endpoint_Read_8(); + + return ((Byte0 << 24) | (Byte1 << 16) | (Byte2 << 8) | Byte3); + } + + /** Writes four bytes to the currently selected endpoint's bank in little endian format, for IN + * direction endpoints. + * + * \ingroup Group_EndpointPrimitiveRW_XMEGA + * + * \param[in] Data Data to write to the currently selected endpoint's FIFO buffer. + */ + static inline void Endpoint_Write_32_LE(const uint32_t Data) ATTR_ALWAYS_INLINE; + static inline void Endpoint_Write_32_LE(const uint32_t Data) + { + Endpoint_Write_8(Data & 0xFF); + Endpoint_Write_8(Data >> 8); + Endpoint_Write_8(Data >> 16); + Endpoint_Write_8(Data >> 24); + } + + /** Writes four bytes to the currently selected endpoint's bank in big endian format, for IN + * direction endpoints. + * + * \ingroup Group_EndpointPrimitiveRW_XMEGA + * + * \param[in] Data Data to write to the currently selected endpoint's FIFO buffer. + */ + static inline void Endpoint_Write_32_BE(const uint32_t Data) ATTR_ALWAYS_INLINE; + static inline void Endpoint_Write_32_BE(const uint32_t Data) + { + Endpoint_Write_8(Data >> 24); + Endpoint_Write_8(Data >> 16); + Endpoint_Write_8(Data >> 8); + Endpoint_Write_8(Data & 0xFF); + } + + /** Discards four bytes from the currently selected endpoint's bank, for OUT direction endpoints. + * + * \ingroup Group_EndpointPrimitiveRW_XMEGA + */ + static inline void Endpoint_Discard_32(void) ATTR_ALWAYS_INLINE; + static inline void Endpoint_Discard_32(void) + { + Endpoint_Discard_8(); + Endpoint_Discard_8(); + Endpoint_Discard_8(); + Endpoint_Discard_8(); + } + + /* External Variables: */ + /** Global indicating the maximum packet size of the default control endpoint located at address + * 0 in the device. This value is set to the value indicated in the device descriptor in the user + * project once the USB interface is initialized into device mode. + * + * If space is an issue, it is possible to fix this to a static value by defining the control + * endpoint size in the \c FIXED_CONTROL_ENDPOINT_SIZE token passed to the compiler in the makefile + * via the -D switch. When a fixed control endpoint size is used, the size is no longer dynamically + * read from the descriptors at runtime and instead fixed to the given value. When used, it is + * important that the descriptor control endpoint size value matches the size given as the + * \c FIXED_CONTROL_ENDPOINT_SIZE token - it is recommended that the \c FIXED_CONTROL_ENDPOINT_SIZE token + * be used in the device descriptors to ensure this. + * + * \attention This variable should be treated as read-only in the user application, and never manually + * changed in value. + */ + #if (!defined(FIXED_CONTROL_ENDPOINT_SIZE) || defined(__DOXYGEN__)) + extern uint8_t USB_Device_ControlEndpointSize; + #else + #define USB_Device_ControlEndpointSize FIXED_CONTROL_ENDPOINT_SIZE + #endif + + /* Function Prototypes: */ + /** Configures a table of endpoint descriptions, in sequence. This function can be used to configure multiple + * endpoints at the same time. + * + * \note Endpoints with a zero address will be ignored, thus this function cannot be used to configure the + * control endpoint. + * + * \param[in] Table Pointer to a table of endpoint descriptions. + * \param[in] Entries Number of entries in the endpoint table to configure. + * + * \return Boolean \c true if all endpoints configured successfully, \c false otherwise. + */ + bool Endpoint_ConfigureEndpointTable(const USB_Endpoint_Table_t* const Table, + const uint8_t Entries); + + /** Completes the status stage of a control transfer on a CONTROL type endpoint automatically, + * with respect to the data direction. This is a convenience function which can be used to + * simplify user control request handling. + * + * \note This routine should not be called on non CONTROL type endpoints. + */ + void Endpoint_ClearStatusStage(void); + + /** Spin-loops until the currently selected non-control endpoint is ready for the next packet of data + * to be read or written to it. + * + * \note This routine should not be called on CONTROL type endpoints. + * + * \ingroup Group_EndpointRW_XMEGA + * + * \return A value from the \ref Endpoint_WaitUntilReady_ErrorCodes_t enum. + */ + uint8_t Endpoint_WaitUntilReady(void); + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/Host_XMEGA.c b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/Host_XMEGA.c new file mode 100644 index 00000000..39d920af --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/Host_XMEGA.c @@ -0,0 +1,41 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#include "../../../../Common/Common.h" +#if (ARCH == ARCH_XMEGA) + +#define __INCLUDE_FROM_USB_DRIVER +#include "../USBMode.h" + +#if defined(USB_CAN_BE_HOST) + +#endif + +#endif diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/PipeStream_XMEGA.c b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/PipeStream_XMEGA.c new file mode 100644 index 00000000..39d920af --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/PipeStream_XMEGA.c @@ -0,0 +1,41 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#include "../../../../Common/Common.h" +#if (ARCH == ARCH_XMEGA) + +#define __INCLUDE_FROM_USB_DRIVER +#include "../USBMode.h" + +#if defined(USB_CAN_BE_HOST) + +#endif + +#endif diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/Pipe_XMEGA.c b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/Pipe_XMEGA.c new file mode 100644 index 00000000..6106cb58 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/Pipe_XMEGA.c @@ -0,0 +1,37 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#define __INCLUDE_FROM_USB_DRIVER +#include "../USBMode.h" + +#if defined(USB_CAN_BE_HOST) + +#endif + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/Template/Template_Endpoint_Control_R.c b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/Template/Template_Endpoint_Control_R.c new file mode 100644 index 00000000..35776410 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/Template/Template_Endpoint_Control_R.c @@ -0,0 +1,87 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#if defined(TEMPLATE_FUNC_NAME) + +// cppcheck-suppress unusedFunction +uint8_t TEMPLATE_FUNC_NAME (void* const Buffer, + uint16_t Length) +{ + uint8_t* DataStream = ((uint8_t*)Buffer + TEMPLATE_BUFFER_OFFSET(Length)); + + Endpoint_SelectEndpoint(USB_Endpoint_SelectedEndpoint & ~ENDPOINT_DIR_IN); + + if (!(Length)) + Endpoint_ClearOUT(); + + while (Length) + { + uint8_t USB_DeviceState_LCL = USB_DeviceState; + + if (USB_DeviceState_LCL == DEVICE_STATE_Unattached) + return ENDPOINT_RWCSTREAM_DeviceDisconnected; + else if (USB_DeviceState_LCL == DEVICE_STATE_Suspended) + return ENDPOINT_RWCSTREAM_BusSuspended; + else if (Endpoint_IsSETUPReceived()) + return ENDPOINT_RWCSTREAM_HostAborted; + + if (Endpoint_IsOUTReceived()) + { + while (Length && Endpoint_BytesInEndpoint()) + { + TEMPLATE_TRANSFER_BYTE(DataStream); + TEMPLATE_BUFFER_MOVE(DataStream, 1); + Length--; + } + + Endpoint_ClearOUT(); + } + } + + while (!(Endpoint_IsINReady())) + { + uint8_t USB_DeviceState_LCL = USB_DeviceState; + + if (USB_DeviceState_LCL == DEVICE_STATE_Unattached) + return ENDPOINT_RWCSTREAM_DeviceDisconnected; + else if (USB_DeviceState_LCL == DEVICE_STATE_Suspended) + return ENDPOINT_RWCSTREAM_BusSuspended; + } + + return ENDPOINT_RWCSTREAM_NoError; +} + +#undef TEMPLATE_BUFFER_OFFSET +#undef TEMPLATE_BUFFER_MOVE +#undef TEMPLATE_FUNC_NAME +#undef TEMPLATE_TRANSFER_BYTE + +#endif + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/Template/Template_Endpoint_Control_W.c b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/Template/Template_Endpoint_Control_W.c new file mode 100644 index 00000000..ed2d2d9b --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/Template/Template_Endpoint_Control_W.c @@ -0,0 +1,96 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#if defined(TEMPLATE_FUNC_NAME) + +// cppcheck-suppress unusedFunction +uint8_t TEMPLATE_FUNC_NAME (const void* const Buffer, + uint16_t Length) +{ + uint8_t* DataStream = ((uint8_t*)Buffer + TEMPLATE_BUFFER_OFFSET(Length)); + bool LastPacketFull = false; + + Endpoint_SelectEndpoint(USB_Endpoint_SelectedEndpoint | ENDPOINT_DIR_IN); + + if (Length > USB_ControlRequest.wLength) + Length = USB_ControlRequest.wLength; + else if (!(Length)) + Endpoint_ClearIN(); + + while (Length || LastPacketFull) + { + uint8_t USB_DeviceState_LCL = USB_DeviceState; + + if (USB_DeviceState_LCL == DEVICE_STATE_Unattached) + return ENDPOINT_RWCSTREAM_DeviceDisconnected; + else if (USB_DeviceState_LCL == DEVICE_STATE_Suspended) + return ENDPOINT_RWCSTREAM_BusSuspended; + else if (Endpoint_IsSETUPReceived()) + return ENDPOINT_RWCSTREAM_HostAborted; + else if (Endpoint_IsOUTReceived()) + break; + + if (Endpoint_IsINReady()) + { + uint16_t BytesInEndpoint = Endpoint_BytesInEndpoint(); + + while (Length && (BytesInEndpoint < USB_Device_ControlEndpointSize)) + { + TEMPLATE_TRANSFER_BYTE(DataStream); + TEMPLATE_BUFFER_MOVE(DataStream, 1); + Length--; + BytesInEndpoint++; + } + + LastPacketFull = (BytesInEndpoint == USB_Device_ControlEndpointSize); + Endpoint_ClearIN(); + } + } + + while (!(Endpoint_IsOUTReceived())) + { + uint8_t USB_DeviceState_LCL = USB_DeviceState; + + if (USB_DeviceState_LCL == DEVICE_STATE_Unattached) + return ENDPOINT_RWCSTREAM_DeviceDisconnected; + else if (USB_DeviceState_LCL == DEVICE_STATE_Suspended) + return ENDPOINT_RWCSTREAM_BusSuspended; + } + + return ENDPOINT_RWCSTREAM_NoError; +} + +#undef TEMPLATE_BUFFER_OFFSET +#undef TEMPLATE_BUFFER_MOVE +#undef TEMPLATE_FUNC_NAME +#undef TEMPLATE_TRANSFER_BYTE + +#endif + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/Template/Template_Endpoint_RW.c b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/Template/Template_Endpoint_RW.c new file mode 100644 index 00000000..02ad9786 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/Template/Template_Endpoint_RW.c @@ -0,0 +1,90 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#if defined(TEMPLATE_FUNC_NAME) + +// cppcheck-suppress unusedFunction +uint8_t TEMPLATE_FUNC_NAME (TEMPLATE_BUFFER_TYPE const Buffer, + uint16_t Length, + uint16_t* const BytesProcessed) +{ + uint8_t* DataStream = ((uint8_t*)Buffer + TEMPLATE_BUFFER_OFFSET(Length)); + uint16_t BytesInTransfer = 0; + uint8_t ErrorCode; + + if ((ErrorCode = Endpoint_WaitUntilReady())) + return ErrorCode; + + if (BytesProcessed != NULL) + { + Length -= *BytesProcessed; + TEMPLATE_BUFFER_MOVE(DataStream, *BytesProcessed); + } + + while (Length) + { + if (!(Endpoint_IsReadWriteAllowed())) + { + TEMPLATE_CLEAR_ENDPOINT(); + + #if !defined(INTERRUPT_CONTROL_ENDPOINT) + USB_USBTask(); + #endif + + if (BytesProcessed != NULL) + { + *BytesProcessed += BytesInTransfer; + return ENDPOINT_RWSTREAM_IncompleteTransfer; + } + + if ((ErrorCode = Endpoint_WaitUntilReady())) + return ErrorCode; + } + else + { + TEMPLATE_TRANSFER_BYTE(DataStream); + TEMPLATE_BUFFER_MOVE(DataStream, 1); + Length--; + BytesInTransfer++; + } + } + + return ENDPOINT_RWSTREAM_NoError; +} + +#undef TEMPLATE_FUNC_NAME +#undef TEMPLATE_BUFFER_TYPE +#undef TEMPLATE_TRANSFER_BYTE +#undef TEMPLATE_CLEAR_ENDPOINT +#undef TEMPLATE_BUFFER_OFFSET +#undef TEMPLATE_BUFFER_MOVE + +#endif + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/USBController_XMEGA.c b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/USBController_XMEGA.c new file mode 100644 index 00000000..3899278d --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/USBController_XMEGA.c @@ -0,0 +1,189 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#include "../../../../Common/Common.h" +#if (ARCH == ARCH_XMEGA) + +#define __INCLUDE_FROM_USB_DRIVER +#define __INCLUDE_FROM_USB_CONTROLLER_C +#include "../USBController.h" + +#if (!defined(USB_HOST_ONLY) && !defined(USB_DEVICE_ONLY)) +volatile uint8_t USB_CurrentMode = USB_MODE_None; +#endif + +#if !defined(USE_STATIC_OPTIONS) +volatile uint8_t USB_Options; +#endif + +/* Ugly workaround to ensure an aligned table, since __BIGGEST_ALIGNMENT__ == 1 for 8-bit AVR-GCC */ +uint8_t USB_EndpointTable[sizeof(USB_EndpointTable_t) + 1]; + +void USB_Init( + #if defined(USB_CAN_BE_BOTH) + const uint8_t Mode + #endif + + #if (defined(USB_CAN_BE_BOTH) && !defined(USE_STATIC_OPTIONS)) + , + #elif (!defined(USB_CAN_BE_BOTH) && defined(USE_STATIC_OPTIONS)) + void + #endif + + #if !defined(USE_STATIC_OPTIONS) + const uint8_t Options + #endif + ) +{ + #if !defined(USE_STATIC_OPTIONS) + USB_Options = Options; + #endif + + USB_IsInitialized = true; + + uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask(); + GlobalInterruptDisable(); + + NVM.CMD = NVM_CMD_READ_CALIB_ROW_gc; + USB.CAL0 = pgm_read_byte(offsetof(NVM_PROD_SIGNATURES_t, USBCAL0)); + USB.CAL1 = pgm_read_byte(offsetof(NVM_PROD_SIGNATURES_t, USBCAL1)); + NVM.CMD = 0; + + /* Ugly workaround to ensure an aligned table, since __BIGGEST_ALIGNMENT__ == 1 for the 8-bit AVR-GCC toochain */ + USB.EPPTR = ((intptr_t)&USB_EndpointTable[1] & ~(1 << 0)); + USB.CTRLA = (USB_STFRNUM_bm | ((ENDPOINT_TOTAL_ENDPOINTS - 1) << USB_MAXEP_gp)); + + if ((USB_Options & USB_OPT_BUSEVENT_PRIHIGH) == USB_OPT_BUSEVENT_PRIHIGH) + USB.INTCTRLA = (3 << USB_INTLVL_gp); + else if ((USB_Options & USB_OPT_BUSEVENT_PRIMED) == USB_OPT_BUSEVENT_PRIMED) + USB.INTCTRLA = (2 << USB_INTLVL_gp); + else + USB.INTCTRLA = (1 << USB_INTLVL_gp); + + SetGlobalInterruptMask(CurrentGlobalInt); + + USB_ResetInterface(); +} + +void USB_Disable(void) +{ + USB_INT_DisableAllInterrupts(); + USB_INT_ClearAllInterrupts(); + + USB_Detach(); + USB_Controller_Disable(); + + USB_IsInitialized = false; +} + +void USB_ResetInterface(void) +{ + #if defined(USB_DEVICE_OPT_FULLSPEED) + if (USB_Options & USB_DEVICE_OPT_LOWSPEED) + CLK.USBCTRL = (((F_USB / 6000000) - 1) << CLK_USBPSDIV_gp); + else + CLK.USBCTRL = (((F_USB / 48000000) - 1) << CLK_USBPSDIV_gp); + #else + CLK.USBCTRL = (((F_USB / 6000000) - 1) << CLK_USBPSDIV_gp); + #endif + + if (USB_Options & USB_OPT_PLLCLKSRC) + CLK.USBCTRL |= (CLK_USBSRC_PLL_gc | CLK_USBSEN_bm); + else + CLK.USBCTRL |= (CLK_USBSRC_RC32M_gc | CLK_USBSEN_bm); + + USB_Device_SetDeviceAddress(0); + + USB_INT_DisableAllInterrupts(); + USB_INT_ClearAllInterrupts(); + + USB_Controller_Reset(); + USB_Init_Device(); +} + +#if defined(USB_CAN_BE_DEVICE) +static void USB_Init_Device(void) +{ + USB_DeviceState = DEVICE_STATE_Unattached; + USB_Device_ConfigurationNumber = 0; + + #if !defined(NO_DEVICE_REMOTE_WAKEUP) + USB_Device_RemoteWakeupEnabled = false; + #endif + + #if !defined(NO_DEVICE_SELF_POWER) + USB_Device_CurrentlySelfPowered = false; + #endif + + #if !defined(FIXED_CONTROL_ENDPOINT_SIZE) + USB_Descriptor_Device_t* DeviceDescriptorPtr; + + #if defined(ARCH_HAS_MULTI_ADDRESS_SPACE) && \ + !(defined(USE_FLASH_DESCRIPTORS) || defined(USE_EEPROM_DESCRIPTORS) || defined(USE_RAM_DESCRIPTORS)) + uint8_t DescriptorAddressSpace; + + if (CALLBACK_USB_GetDescriptor((DTYPE_Device << 8), 0, (void*)&DeviceDescriptorPtr, &DescriptorAddressSpace) != NO_DESCRIPTOR) + { + if (DescriptorAddressSpace == MEMSPACE_FLASH) + USB_Device_ControlEndpointSize = pgm_read_byte(&DeviceDescriptorPtr->Endpoint0Size); + else if (DescriptorAddressSpace == MEMSPACE_EEPROM) + USB_Device_ControlEndpointSize = eeprom_read_byte(&DeviceDescriptorPtr->Endpoint0Size); + else + USB_Device_ControlEndpointSize = DeviceDescriptorPtr->Endpoint0Size; + } + #else + if (CALLBACK_USB_GetDescriptor((DTYPE_Device << 8), 0, (void*)&DeviceDescriptorPtr) != NO_DESCRIPTOR) + { + #if defined(USE_RAM_DESCRIPTORS) + USB_Device_ControlEndpointSize = DeviceDescriptorPtr->Endpoint0Size; + #elif defined(USE_EEPROM_DESCRIPTORS) + USB_Device_ControlEndpointSize = eeprom_read_byte(&DeviceDescriptorPtr->Endpoint0Size); + #else + USB_Device_ControlEndpointSize = pgm_read_byte(&DeviceDescriptorPtr->Endpoint0Size); + #endif + } + #endif + #endif + + if (USB_Options & USB_DEVICE_OPT_LOWSPEED) + USB_Device_SetLowSpeed(); + else + USB_Device_SetFullSpeed(); + + Endpoint_ConfigureEndpoint(ENDPOINT_CONTROLEP, EP_TYPE_CONTROL, + USB_Device_ControlEndpointSize, 1); + + USB_INT_Enable(USB_INT_BUSEVENTI); + + USB_Attach(); +} +#endif + +#endif diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/USBController_XMEGA.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/USBController_XMEGA.h new file mode 100644 index 00000000..bb37905a --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/USBController_XMEGA.h @@ -0,0 +1,313 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief USB Controller definitions for the AVR XMEGA microcontrollers. + * \copydetails Group_USBManagement_XMEGA + * + * \note This file should not be included directly. It is automatically included as needed by the USB driver + * dispatch header located in LUFA/Drivers/USB/USB.h. + */ + +/** \ingroup Group_USBManagement + * \defgroup Group_USBManagement_XMEGA USB Interface Management (XMEGA) + * \brief USB Controller definitions for the AVR XMEGA microcontrollers. + * + * Functions, macros, variables, enums and types related to the setup and management of the USB interface. + * + * @{ + */ + +#ifndef __USBCONTROLLER_XMEGA_H__ +#define __USBCONTROLLER_XMEGA_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + #include "../USBMode.h" + #include "../Events.h" + #include "../USBTask.h" + #include "../USBInterrupt.h" + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Type Defines: */ + typedef struct + { + struct + { + USB_EP_t OUT; + USB_EP_t IN; + } Endpoints[16]; + uint16_t FrameNum; + } ATTR_PACKED USB_EndpointTable_t; + + /* External Variables: */ + extern uint8_t USB_EndpointTable[]; + + #endif + + /* Includes: */ + #if defined(USB_CAN_BE_DEVICE) || defined(__DOXYGEN__) + #include "../Device.h" + #include "../Endpoint.h" + #include "../DeviceStandardReq.h" + #include "../EndpointStream.h" + #endif + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks and Defines: */ + #if !defined(__INCLUDE_FROM_USB_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB/USB.h instead. + #endif + + #if !defined(F_USB) + #error F_USB is not defined. You must define F_USB to the frequency of the unprescaled USB controller clock in your project makefile. + #endif + + #if ((F_USB % 6000000) || (F_USB < 6000000)) + #error Invalid F_USB specified. F_USB must be a multiple of 6MHz for USB Low Speed operation, and a multiple of 48MHz for Full Speed operation. + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** \name USB Controller Option Masks */ + //@{ + /** Sets the USB bus interrupt priority level to be low priority. The USB bus interrupt is used for Start of Frame events, bus suspend + * and resume events, bus reset events and other events related to the management of the USB bus. + */ + #define USB_OPT_BUSEVENT_PRILOW ((0 << 2) | (0 << 1)) + + /** Sets the USB bus interrupt priority level to be medium priority. The USB bus interrupt is used for Start of Frame events, bus suspend + * and resume events, bus reset events and other events related to the management of the USB bus. + */ + #define USB_OPT_BUSEVENT_PRIMED ((0 << 2) | (1 << 1)) + + /** Sets the USB bus interrupt priority level to be high priority. The USB bus interrupt is used for Start of Frame events, bus suspend + * and resume events, bus reset events and other events related to the management of the USB bus. + */ + #define USB_OPT_BUSEVENT_PRIHIGH ((1 << 2) | (0 << 1)) + + /** Sets the USB controller to source its clock from the internal RC 32MHz clock, once it has been DFLL calibrated to 48MHz. */ + #define USB_OPT_RC32MCLKSRC (0 << 3) + + /** Sets the USB controller to source its clock from the internal PLL. */ + #define USB_OPT_PLLCLKSRC (1 << 3) + //@} + + #if !defined(USB_STREAM_TIMEOUT_MS) || defined(__DOXYGEN__) + /** Constant for the maximum software timeout period of the USB data stream transfer functions + * (both control and standard) when in either device or host mode. If the next packet of a stream + * is not received or acknowledged within this time period, the stream function will fail. + * + * This value may be overridden in the user project makefile as the value of the + * \ref USB_STREAM_TIMEOUT_MS token, and passed to the compiler using the -D switch. + */ + #define USB_STREAM_TIMEOUT_MS 100 + #endif + + /* Inline Functions: */ + /** Detaches the device from the USB bus. This has the effect of removing the device from any + * attached host, ceasing USB communications. If no host is present, this prevents any host from + * enumerating the device once attached until \ref USB_Attach() is called. + */ + static inline void USB_Detach(void) ATTR_ALWAYS_INLINE; + static inline void USB_Detach(void) + { + USB.CTRLB &= ~USB_ATTACH_bm; + } + + /** Attaches the device to the USB bus. This announces the device's presence to any attached + * USB host, starting the enumeration process. If no host is present, attaching the device + * will allow for enumeration once a host is connected to the device. + * + * This is inexplicably also required for proper operation while in host mode, to enable the + * attachment of a device to the host. This is despite the bit being located in the device-mode + * register and despite the datasheet making no mention of its requirement in host mode. + */ + static inline void USB_Attach(void) ATTR_ALWAYS_INLINE; + static inline void USB_Attach(void) + { + USB.CTRLB |= USB_ATTACH_bm; + } + + /* Function Prototypes: */ + /** Main function to initialize and start the USB interface. Once active, the USB interface will + * allow for device connection to a host when in device mode, or for device enumeration while in + * host mode. + * + * As the USB library relies on interrupts for the device and host mode enumeration processes, + * the user must enable global interrupts before or shortly after this function is called. In + * device mode, interrupts must be enabled within 500ms of this function being called to ensure + * that the host does not time out whilst enumerating the device. In host mode, interrupts may be + * enabled at the application's leisure however enumeration will not begin of an attached device + * until after this has occurred. + * + * Calling this function when the USB interface is already initialized will cause a complete USB + * interface reset and re-enumeration. + * + * \param[in] Mode This is a mask indicating what mode the USB interface is to be initialized to, a value + * from the \ref USB_Modes_t enum. + * + * \param[in] Options Mask indicating the options which should be used when initializing the USB + * interface to control the USB interface's behavior. This should be comprised of + * a \c USB_OPT_REG_* mask to control the regulator, a \c USB_OPT_*_PLL mask to control the + * PLL, and a \c USB_DEVICE_OPT_* mask (when the device mode is enabled) to set the device + * mode speed. + * + * \note To reduce the FLASH requirements of the library if only device or host mode is required, + * the mode can be statically set in the project makefile by defining the token \c USB_DEVICE_ONLY + * (for device mode) or \c USB_HOST_ONLY (for host mode), passing the token to the compiler + * via the -D switch. If the mode is statically set, this parameter does not exist in the + * function prototype. + * \n\n + * + * \note To reduce the FLASH requirements of the library if only fixed settings are required, + * the options may be set statically in the same manner as the mode (see the Mode parameter of + * this function). To statically set the USB options, pass in the \c USE_STATIC_OPTIONS token, + * defined to the appropriate options masks. When the options are statically set, this + * parameter does not exist in the function prototype. + * \n\n + * + * \note The mode parameter does not exist on devices where only one mode is possible, such as USB + * AVR models which only implement the USB device mode in hardware. + * + * \see \ref Group_Device for the \c USB_DEVICE_OPT_* masks. + */ + void USB_Init( + #if defined(USB_CAN_BE_BOTH) || defined(__DOXYGEN__) + const uint8_t Mode + #endif + + #if (defined(USB_CAN_BE_BOTH) && !defined(USE_STATIC_OPTIONS)) || defined(__DOXYGEN__) + , + #elif (!defined(USB_CAN_BE_BOTH) && defined(USE_STATIC_OPTIONS)) + void + #endif + + #if !defined(USE_STATIC_OPTIONS) || defined(__DOXYGEN__) + const uint8_t Options + #endif + ); + + /** Shuts down the USB interface. This turns off the USB interface after deallocating all USB FIFO + * memory, endpoints and pipes. When turned off, no USB functionality can be used until the interface + * is restarted with the \ref USB_Init() function. + */ + void USB_Disable(void); + + /** Resets the interface, when already initialized. This will re-enumerate the device if already connected + * to a host, or re-enumerate an already attached device when in host mode. + */ + void USB_ResetInterface(void); + + /* Global Variables: */ + #if (!defined(USB_HOST_ONLY) && !defined(USB_DEVICE_ONLY)) || defined(__DOXYGEN__) + /** Indicates the mode that the USB interface is currently initialized to, a value from the + * \ref USB_Modes_t enum. + * + * \attention This variable should be treated as read-only in the user application, and never manually + * changed in value. + * + * \note When the controller is initialized into UID auto-detection mode, this variable will hold the + * currently selected USB mode (i.e. \ref USB_MODE_Device or \ref USB_MODE_Host). If the controller + * is fixed into a specific mode (either through the \c USB_DEVICE_ONLY or \c USB_HOST_ONLY compile time + * options, or a limitation of the USB controller in the chosen device model) this will evaluate to + * a constant of the appropriate value and will never evaluate to \ref USB_MODE_None even when the + * USB interface is not initialized. + */ + extern volatile uint8_t USB_CurrentMode; + #elif defined(USB_DEVICE_ONLY) + #define USB_CurrentMode USB_MODE_Device + #endif + + #if !defined(USE_STATIC_OPTIONS) || defined(__DOXYGEN__) + /** Indicates the current USB options that the USB interface was initialized with when \ref USB_Init() + * was called. This value will be one of the \c USB_MODE_* masks defined elsewhere in this module. + * + * \attention This variable should be treated as read-only in the user application, and never manually + * changed in value. + */ + extern volatile uint8_t USB_Options; + #elif defined(USE_STATIC_OPTIONS) + #define USB_Options USE_STATIC_OPTIONS + #endif + + /* Enums: */ + /** Enum for the possible USB controller modes, for initialization via \ref USB_Init() and indication back to the + * user application via \ref USB_CurrentMode. + */ + enum USB_Modes_t + { + USB_MODE_None = 0, /**< Indicates that the controller is currently not initialized in any specific USB mode. */ + USB_MODE_Device = 1, /**< Indicates that the controller is currently initialized in USB Device mode. */ + }; + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Function Prototypes: */ + #if defined(__INCLUDE_FROM_USB_CONTROLLER_C) + static void USB_Init_Device(void); + #endif + + /* Inline Functions: */ + static inline void USB_Controller_Enable(void) ATTR_ALWAYS_INLINE; + static inline void USB_Controller_Enable(void) + { + USB.CTRLA |= USB_ENABLE_bm; + } + + static inline void USB_Controller_Disable(void) ATTR_ALWAYS_INLINE; + static inline void USB_Controller_Disable(void) + { + USB.CTRLA &= ~USB_ENABLE_bm; + } + + static inline void USB_Controller_Reset(void) ATTR_ALWAYS_INLINE; + static inline void USB_Controller_Reset(void) + { + USB.CTRLA &= ~USB_ENABLE_bm; + USB.CTRLA |= USB_ENABLE_bm; + } + + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/USBInterrupt_XMEGA.c b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/USBInterrupt_XMEGA.c new file mode 100644 index 00000000..9bba25ae --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/USBInterrupt_XMEGA.c @@ -0,0 +1,106 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#include "../../../../Common/Common.h" +#if (ARCH == ARCH_XMEGA) + +#define __INCLUDE_FROM_USB_DRIVER +#include "../USBInterrupt.h" + +void USB_INT_DisableAllInterrupts(void) +{ + USB.INTCTRLA &= USB_INTLVL_gm; + USB.INTCTRLB = 0; +} + +void USB_INT_ClearAllInterrupts(void) +{ + USB.INTFLAGSACLR = 0xFF; + USB.INTFLAGSBCLR = 0xFF; +} + +ISR(USB_BUSEVENT_vect) +{ + #if !defined(NO_SOF_EVENTS) + if (USB_INT_HasOccurred(USB_INT_SOFI) && USB_INT_IsEnabled(USB_INT_SOFI)) + { + USB_INT_Clear(USB_INT_SOFI); + + EVENT_USB_Device_StartOfFrame(); + } + #endif + + if (USB_INT_HasOccurred(USB_INT_BUSEVENTI_Suspend)) + { + USB_INT_Clear(USB_INT_BUSEVENTI_Suspend); + + #if !defined(NO_LIMITED_CONTROLLER_CONNECT) + USB_DeviceState = DEVICE_STATE_Unattached; + EVENT_USB_Device_Disconnect(); + #else + USB_DeviceState = DEVICE_STATE_Suspended; + EVENT_USB_Device_Suspend(); + #endif + } + + if (USB_INT_HasOccurred(USB_INT_BUSEVENTI_Resume)) + { + USB_INT_Clear(USB_INT_BUSEVENTI_Resume); + + if (USB_Device_ConfigurationNumber) + USB_DeviceState = DEVICE_STATE_Configured; + else + USB_DeviceState = (USB_Device_IsAddressSet()) ? DEVICE_STATE_Configured : DEVICE_STATE_Powered; + + #if !defined(NO_LIMITED_CONTROLLER_CONNECT) + EVENT_USB_Device_Connect(); + #else + EVENT_USB_Device_WakeUp(); + #endif + } + + if (USB_INT_HasOccurred(USB_INT_BUSEVENTI_Reset)) + { + USB_INT_Clear(USB_INT_BUSEVENTI_Reset); + + USB_DeviceState = DEVICE_STATE_Default; + USB_Device_ConfigurationNumber = 0; + + USB_Device_SetDeviceAddress(0); + + Endpoint_ClearEndpoints(); + Endpoint_ConfigureEndpoint(ENDPOINT_CONTROLEP, EP_TYPE_CONTROL, + USB_Device_ControlEndpointSize, 1); + + EVENT_USB_Device_Reset(); + } +} + +#endif diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/USBInterrupt_XMEGA.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/USBInterrupt_XMEGA.h new file mode 100644 index 00000000..5eef7121 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/Core/XMEGA/USBInterrupt_XMEGA.h @@ -0,0 +1,166 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief USB Controller Interrupt definitions for the AVR XMEGA microcontrollers. + * + * This file contains definitions required for the correct handling of low level USB service routine interrupts + * from the USB controller. + * + * \note This file should not be included directly. It is automatically included as needed by the USB driver + * dispatch header located in LUFA/Drivers/USB/USB.h. + */ + +#ifndef __USBINTERRUPT_XMEGA_H__ +#define __USBINTERRUPT_XMEGA_H__ + + /* Includes: */ + #include "../../../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Preprocessor Checks: */ + #if !defined(__INCLUDE_FROM_USB_DRIVER) + #error Do not include this file directly. Include LUFA/Drivers/USB/USB.h instead. + #endif + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Enums: */ + enum USB_Interrupts_t + { + USB_INT_BUSEVENTI = 1, + USB_INT_BUSEVENTI_Suspend = 2, + USB_INT_BUSEVENTI_Resume = 3, + USB_INT_BUSEVENTI_Reset = 4, + USB_INT_SOFI = 5, + }; + + /* Inline Functions: */ + static inline void USB_INT_Enable(const uint8_t Interrupt) ATTR_ALWAYS_INLINE; + static inline void USB_INT_Enable(const uint8_t Interrupt) + { + switch (Interrupt) + { + case USB_INT_BUSEVENTI: + USB.INTCTRLA |= USB_BUSEVIE_bm; + return; + case USB_INT_SOFI: + USB.INTCTRLA |= USB_SOFIE_bm; + return; + } + } + + static inline void USB_INT_Disable(const uint8_t Interrupt) ATTR_ALWAYS_INLINE; + static inline void USB_INT_Disable(const uint8_t Interrupt) + { + switch (Interrupt) + { + case USB_INT_BUSEVENTI: + USB.INTCTRLA &= ~USB_BUSEVIE_bm; + return; + case USB_INT_SOFI: + USB.INTCTRLA &= ~USB_SOFIE_bm; + return; + } + } + + static inline void USB_INT_Clear(const uint8_t Interrupt) ATTR_ALWAYS_INLINE; + static inline void USB_INT_Clear(const uint8_t Interrupt) + { + switch (Interrupt) + { + case USB_INT_BUSEVENTI_Suspend: + USB.INTFLAGSACLR = USB_SUSPENDIF_bm; + return; + case USB_INT_BUSEVENTI_Resume: + USB.INTFLAGSACLR = USB_RESUMEIF_bm; + return; + case USB_INT_BUSEVENTI_Reset: + USB.INTFLAGSACLR = USB_RSTIF_bm; + return; + case USB_INT_SOFI: + USB.INTFLAGSACLR = USB_SOFIF_bm; + return; + } + } + + static inline bool USB_INT_IsEnabled(const uint8_t Interrupt) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT; + static inline bool USB_INT_IsEnabled(const uint8_t Interrupt) + { + switch (Interrupt) + { + case USB_INT_BUSEVENTI: + return ((USB.INTCTRLA & USB_BUSEVIE_bm) ? true : false); + case USB_INT_SOFI: + return ((USB.INTCTRLA & USB_SOFIE_bm) ? true : false); + } + + return false; + } + + static inline bool USB_INT_HasOccurred(const uint8_t Interrupt) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT; + static inline bool USB_INT_HasOccurred(const uint8_t Interrupt) + { + switch (Interrupt) + { + case USB_INT_BUSEVENTI_Suspend: + return ((USB.INTFLAGSACLR & USB_SUSPENDIF_bm) ? true : false); + case USB_INT_BUSEVENTI_Resume: + return ((USB.INTFLAGSACLR & USB_RESUMEIF_bm) ? true : false); + case USB_INT_BUSEVENTI_Reset: + return ((USB.INTFLAGSACLR & USB_RSTIF_bm) ? true : false); + case USB_INT_SOFI: + return ((USB.INTFLAGSACLR & USB_SOFIF_bm) ? true : false); + } + + return false; + } + + /* Includes: */ + #include "../USBMode.h" + #include "../Events.h" + #include "../USBController.h" + + /* Function Prototypes: */ + void USB_INT_ClearAllInterrupts(void); + void USB_INT_DisableAllInterrupts(void); + #endif + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + diff --git a/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/USB.h b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/USB.h new file mode 100644 index 00000000..66f0fd3c --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Drivers/USB/USB.h @@ -0,0 +1,418 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Master include file for the library USB functionality. + * + * Master include file for the library USB functionality. + * + * This file should be included in all user projects making use of the USB portions of the library, instead of + * the individual USB driver submodule headers. + */ + +/** \defgroup Group_USB USB Core - LUFA/Drivers/USB/USB.h + * + * \section Sec_Dependencies Module Source Dependencies + * The following files must be built with any user project that uses this module: + * - LUFA/Drivers/USB/Core/ConfigDescriptors.c (Makefile source module name: LUFA_SRC_USB) + * - LUFA/Drivers/USB/Core/DeviceStandardReq.c (Makefile source module name: LUFA_SRC_USB) + * - LUFA/Drivers/USB/Core/Events.c (Makefile source module name: LUFA_SRC_USB) + * - LUFA/Drivers/USB/Core/HostStandardReq.c (Makefile source module name: LUFA_SRC_USB) + * - LUFA/Drivers/USB/Core/USBTask.c (Makefile source module name: LUFA_SRC_USB) + * - LUFA/Drivers/USB/Core/ARCH/Device_ARCH.c (Makefile source module name: LUFA_SRC_USB) + * - LUFA/Drivers/USB/Core/ARCH/Endpoint_ARCH.c (Makefile source module name: LUFA_SRC_USB) + * - LUFA/Drivers/USB/Core/ARCH/EndpointStream_ARCH.c (Makefile source module name: LUFA_SRC_USB) + * - LUFA/Drivers/USB/Core/ARCH/Host_ARCH.c (Makefile source module name: LUFA_SRC_USB) + * - LUFA/Drivers/USB/Core/ARCH/Pipe_ARCH.c (Makefile source module name: LUFA_SRC_USB) + * - LUFA/Drivers/USB/Core/ARCH/PipeStream_ARCH.c (Makefile source module name: LUFA_SRC_USB) + * - LUFA/Drivers/USB/Core/ARCH/USBController_ARCH.c (Makefile source module name: LUFA_SRC_USB) + * - LUFA/Drivers/USB/Core/ARCH/USBInterrupt_ARCH.c (Makefile source module name: LUFA_SRC_USB) + * - LUFA/Drivers/USB/Class/Common/HIDParser.c (Makefile source module name: LUFA_SRC_USB) + * + * \section Sec_ModDescription Module Description + * Driver and framework for the USB controller of the selected architecture and microcontroller model. This module + * consists of many submodules, and is designed to provide an easy way to configure and control USB host, device + * or OTG mode USB applications. + * + * The USB stack requires the sole control over the USB controller in the microcontroller only; i.e. it does not + * require any additional timers or other peripherals to operate. This ensures that the USB stack requires as few + * resources as possible. + * + * The USB stack can be used in Device Mode for connections to USB Hosts (see \ref Group_Device), in Host mode for + * hosting of other USB devices (see \ref Group_Host), or as a dual role device which can either act as a USB host + * or device depending on what peripheral is connected (see \ref Group_OTG). Both modes also require a common set + * of USB management functions found \ref Group_USBManagement. + */ + +/** \defgroup Group_USBClassDrivers USB Class Drivers + * + * Drivers for both host and device mode of the standard USB classes, for rapid application development. + * Class drivers give a framework which sits on top of the low level library API, allowing for standard + * USB classes to be implemented in a project with minimal user code. These drivers can be used in + * conjunction with the library low level APIs to implement interfaces both via the class drivers and via + * the standard library APIs. + * + * Multiple device mode class drivers can be used within a project, including multiple instances of the + * same class driver. In this way, USB Hosts and Devices can be made quickly using the internal class drivers + * so that more time and effort can be put into the end application instead of the USB protocol. + * + * The available class drivers and their modes are listed below. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * +* + * + * + * + * + * + * + * + * + * + * + * + *
USB ClassDevice ModeHost Mode
Android Open AccessoryNoYes
Audio 1.0YesYes
CDC-ACMYesYes
HIDYesYes
MIDIYesYes
Mass StorageYesYes
PrinterNoYes
RNDISYesYes
Still ImageNoYes
+ * + * + * \section Sec_UsingClassDrivers Using the Class Drivers + * To make the Class drivers easy to integrate into a user application, they all implement a standardized + * design with similarly named/used function, enums, defines and types. The two different modes are implemented + * slightly differently, and thus will be explained separately. For information on a specific class driver, read + * the class driver's module documentation. + * + * \subsection Sec_ClassDriverDevice Device Mode Class Drivers + * Implementing a Device Mode Class Driver in a user application requires a number of steps to be followed. Firstly, + * the module configuration and state structure must be added to the project source. These structures are named in a + * similar manner between classes, that of USB_ClassInfo_{Class Name}_Device_t, and are used to hold the + * complete state and configuration for each class instance. Multiple class instances is where the power of the class + * drivers lie; multiple interfaces of the same class simply require more instances of the Class Driver's \c USB_ClassInfo_* + * structure. + * + * Inside the ClassInfo structure lies two sections, a \c Config section, and a \c State section. The \c Config + * section contains the instance's configuration parameters, and must have all fields set by the user application + * before the class driver is used. Each Device mode Class driver typically contains a set of configuration parameters + * for the endpoint size/number of the associated logical USB interface, plus any class-specific configuration parameters. + * + * The following is an example of a properly initialized instance of the Audio Class Driver structure: + * + * \code + * USB_ClassInfo_Audio_Device_t My_Audio_Interface = + * { + * .Config = + * { + * .StreamingInterfaceNumber = 1, + * .DataINEndpoint = + * { + * .Address = (ENDPOINT_DIR_IN | 1), + * .Size = 64, + * .Banks = 1, + * }, + * }, + * }; + * \endcode + * + * \note The class driver's configuration parameters should match those used in the device's descriptors that are + * sent to the host. + * + * To initialize the Class driver instance, the driver's {Class Name}_Device_ConfigureEndpoints() function + * should be called in response to the \ref EVENT_USB_Device_ConfigurationChanged() event. This function will return a + * boolean true value if the driver successfully initialized the instance. Like all the class driver functions, this function + * takes in the address of the specific instance you wish to initialize - in this manner, multiple separate instances of + * the same class type can be initialized like this: + * + * \code + * void EVENT_USB_Device_ConfigurationChanged(void) + * { + * LEDs_SetAllLEDs(LEDMASK_USB_READY); + * + * if (!(Audio_Device_ConfigureEndpoints(&My_Audio_Interface))) + * LEDs_SetAllLEDs(LEDMASK_USB_ERROR); + * } + * \endcode + * + * Once initialized, it is important to maintain the class driver's state by repeatedly calling the Class Driver's + * {Class Name}_Device_USBTask() function in the main program loop. The exact implementation of this + * function varies between class drivers, and can be used for any internal class driver purpose to maintain each + * instance. Again, this function uses the address of the instance to operate on, and thus needs to be called for each + * separate instance, just like the main USB maintenance routine \ref USB_USBTask(): + * + * \code + * int main(void) + * { + * SetupHardware(); + * + * LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); + * + * for (;;) + * { + * if (USB_DeviceState != DEVICE_STATE_Configured) + * Create_And_Process_Samples(); + * + * Audio_Device_USBTask(&My_Audio_Interface); + * USB_USBTask(); + * } + * } + * \endcode + * + * The final standardized Device Class Driver function is the Control Request handler function + * {Class Name}_Device_ProcessControlRequest(), which should be called when the + * \ref EVENT_USB_Device_ControlRequest() event fires. This function should also be called for + * each class driver instance, using the address of the instance to operate on as the function's + * parameter. The request handler will abort if it is determined that the current request is not + * targeted at the given class driver instance, thus these methods can safely be called + * one-after-another in the event handler with no form of error checking: + * + * \code + * void EVENT_USB_Device_ControlRequest(void) + * { + * Audio_Device_ProcessControlRequest(&My_Audio_Interface); + * } + * \endcode + * + * Each class driver may also define a set of callback functions (which are prefixed by \c CALLBACK_* + * in the function's name) which must also be added to the user application - refer to each + * individual class driver's documentation for mandatory callbacks. In addition, each class driver may + * also define a set of events (identifiable by their prefix of \c EVENT_* in the function's name), which + * the user application may choose to implement, or ignore if not needed. + * + * The individual Device Mode Class Driver documentation contains more information on the non-standardized, + * class-specific functions which the user application can then use on the driver instances, such as data + * read and write routines. See each driver's individual documentation for more information on the + * class-specific functions. + * + * \subsection Sec_ClassDriverHost Host Mode Class Drivers + * Implementing a Host Mode Class Driver in a user application requires a number of steps to be followed. Firstly, + * the module configuration and state structure must be added to the project source. These structures are named in a + * similar manner between classes, that of USB_ClassInfo_{Class Name}_Host_t, and are used to hold the + * complete state and configuration for each class instance. Multiple class instances is where the power of the class + * drivers lie; multiple interfaces of the same class simply require more instances of the Class Driver's \c USB_ClassInfo_* + * structure. + * + * Inside the \c USB_ClassInfo_* structure lies two sections, a \c Config section, and a \c State section. The \c Config + * section contains the instance's configuration parameters, and must have all fields set by the user application + * before the class driver is used. Each Device mode Class driver typically contains a set of configuration parameters + * for the endpoint size/number of the associated logical USB interface, plus any class-specific configuration parameters. + * + * The following is an example of a properly initialized instance of the MIDI Host Class Driver structure: + * + * \code + * USB_ClassInfo_MIDI_Host_t My_MIDI_Interface = + * { + * .Config = + * { + * .DataINPipe = + * { + * .Address = (PIPE_DIR_IN | 1), + * .Size = 64, + * .Banks = 1, + * }, + * .DataOUTPipe = + * { + * .Address = (PIPE_DIR_OUT | 2), + * .Size = 64, + * .Banks = 1, + * }, + * }, + * }; + * \endcode + * + * To initialize the Class driver instance, the driver's {Class Name}_Host_ConfigurePipes() function + * should be called in response to the \c EVENT_USB_Host_DeviceEnumerationComplete() event firing. This function will + * will return an error code from the class driver's {Class Name}_EnumerationFailure_ErrorCodes_t enum + * to indicate if the driver successfully initialized the instance and bound it to an interface in the attached device. + * Like all the class driver functions, this function takes in the address of the specific instance you wish to initialize - + * in this manner, multiple separate instances of the same class type can be initialized. A fragment of a Class Driver + * based Host mode application may look like the following: + * + * \code + * void EVENT_USB_Host_DeviceEnumerationComplete(void) + * { + * LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING); + * + * uint16_t ConfigDescriptorSize; + * uint8_t ConfigDescriptorData[512]; + * + * if (USB_Host_GetDeviceConfigDescriptor(1, &ConfigDescriptorSize, ConfigDescriptorData, + * sizeof(ConfigDescriptorData)) != HOST_GETCONFIG_Successful) + * { + * LEDs_SetAllLEDs(LEDMASK_USB_ERROR); + * return; + * } + * + * if (MIDI_Host_ConfigurePipes(&Keyboard_MIDI_Interface, + * ConfigDescriptorSize, ConfigDescriptorData) != MIDI_ENUMERROR_NoError) + * { + * LEDs_SetAllLEDs(LEDMASK_USB_ERROR); + * return; + * } + * + * if (USB_Host_SetDeviceConfiguration(1) != HOST_SENDCONTROL_Successful) + * { + * LEDs_SetAllLEDs(LEDMASK_USB_ERROR); + * return; + * } + * + * LEDs_SetAllLEDs(LEDMASK_USB_READY); + * } + * \endcode + * + * Note that the function also requires the device's configuration descriptor so that it can determine which interface + * in the device to bind to - this can be retrieved as shown in the above fragment using the + * \ref USB_Host_GetDeviceConfigDescriptor() function. If the device does not implement the interface the class driver + * is looking for, if all the matching interfaces are already bound to class driver instances or if an error occurs while + * binding to a device interface (for example, a device endpoint bank larger that the maximum supported bank size is used) + * the configuration will fail. + * + * To complete the device enumeration after binding the host mode Class Drivers to the attached device, a call to + * \c USB_Host_SetDeviceConfiguration() must be made. If the device configuration is not set within the + * \c EVENT_USB_Host_DeviceEnumerationComplete() event, the host still will assume the device enumeration has failed. + * + * Once initialized, it is important to maintain the class driver's state by repeatedly calling the Class Driver's + * {Class Name}_Host_USBTask() function in the main program loop. The exact implementation of this + * function varies between class drivers, and can be used for any internal class driver purpose to maintain each + * instance. Again, this function uses the address of the instance to operate on, and thus needs to be called for each + * separate instance, just like the main USB maintenance routine \ref USB_USBTask(): + * + * \code + * int main(void) + * { + * SetupHardware(); + * + * LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); + * + * for (;;) + * { + * if (USB_HostState != HOST_STATE_Configured) + * Create_And_Process_Samples(); + * + * MIDI_Host_USBTask(&My_Audio_Interface); + * USB_USBTask(); + * } + * } + * \endcode + * + * Each class driver may also define a set of callback functions (which are prefixed by \c CALLBACK_* + * in the function's name) which must also be added to the user application - refer to each + * individual class driver's documentation for mandatory callbacks. In addition, each class driver may + * also define a set of events (identifiable by their prefix of \c EVENT_* in the function's name), which + * the user application may choose to implement, or ignore if not needed. + * + * The individual Host Mode Class Driver documentation contains more information on the non-standardized, + * class-specific functions which the user application can then use on the driver instances, such as data + * read and write routines. See each driver's individual documentation for more information on the + * class-specific functions. + */ + +#ifndef __USB_H__ +#define __USB_H__ + + /* Macros: */ + #define __INCLUDE_FROM_USB_DRIVER + + /* Includes: */ + #include "../../Common/Common.h" + #include "Core/USBMode.h" + + /* Includes: */ + #include "Core/USBTask.h" + #include "Core/Events.h" + #include "Core/StdDescriptors.h" + #include "Core/ConfigDescriptors.h" + #include "Core/USBController.h" + #include "Core/USBInterrupt.h" + + #if defined(USB_CAN_BE_HOST) || defined(__DOXYGEN__) + #include "Core/Host.h" + #include "Core/Pipe.h" + #include "Core/HostStandardReq.h" + #include "Core/PipeStream.h" + #endif + + #if defined(USB_CAN_BE_DEVICE) || defined(__DOXYGEN__) + #include "Core/Device.h" + #include "Core/Endpoint.h" + #include "Core/DeviceStandardReq.h" + #include "Core/EndpointStream.h" + #endif + + #if defined(USB_CAN_BE_BOTH) || defined(__DOXYGEN__) + #include "Core/OTG.h" + #endif + + #include "Class/AndroidAccessoryClass.h" + #include "Class/AudioClass.h" + #include "Class/CDCClass.h" + #include "Class/HIDClass.h" + #include "Class/MassStorageClass.h" + #include "Class/MIDIClass.h" + #include "Class/PrinterClass.h" + #include "Class/RNDISClass.h" + #include "Class/StillImageClass.h" + +#endif + diff --git a/protocol/lufa/LUFA-120730/LUFA/License.txt b/protocol/lufa/LUFA-120730/LUFA/License.txt new file mode 100644 index 00000000..9e27adfb --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/License.txt @@ -0,0 +1,24 @@ + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org + + +Permission to use, copy, modify, and distribute this software +and its documentation for any purpose is hereby granted without +fee, provided that the above copyright notice appear in all +copies and that both that the copyright notice and this +permission notice and warranty disclaimer appear in supporting +documentation, and that the name of the author not be used in +advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +The author disclaim all warranties with regard to this +software, including all implied warranties of merchantability +and fitness. In no event shall the author be liable for any +special, indirect or consequential damages or any damages +whatsoever resulting from loss of use, data or profits, whether +in an action of contract, negligence or other tortious action, +arising out of or in connection with the use or performance of +this software. \ No newline at end of file diff --git a/protocol/lufa/LUFA-120730/LUFA/Platform/Platform.h b/protocol/lufa/LUFA-120730/LUFA/Platform/Platform.h new file mode 100644 index 00000000..9bd29f5c --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Platform/Platform.h @@ -0,0 +1,80 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Architecture Specific Hardware Platform Drivers. + * + * This file is the master dispatch header file for the device-specific hardware platform drivers, for low level + * hardware configuration and management. The platform drivers are a set of drivers which are designed to provide + * a high level management layer for the various low level system functions such as clock control and interrupt + * management. + * + * User code may choose to either include this master dispatch header file to include all available platform + * driver header files for the current architecture, or may choose to only include the specific platform driver + * modules required for a particular application. + */ + +/** \defgroup Group_PlatformDrivers System Platform Drivers - LUFA/Platform/Platform.h + * \brief Hardware platform drivers. + * + * \section Sec_Dependencies Module Source Dependencies + * The following files must be built with any user project that uses this module: + * - UC3 Architecture Only: LUFA/Platform/UC3/InterruptManagement.c (Makefile source module name: LUFA_SRC_PLATFORM) + * - UC3 Architecture Only: LUFA/Platform/UC3/Exception.S (Makefile source module name: LUFA_SRC_PLATFORM) + * + * \section Sec_ModDescription Module Description + * Device-specific hardware platform drivers, for low level hardware configuration and management. The platform + * drivers are a set of drivers which are designed to provide a high level management layer for the various low level + * system functions such as clock control and interrupt management. + * + * User code may choose to either include this master dispatch header file to include all available platform + * driver header files for the current architecture, or may choose to only include the specific platform driver + * modules required for a particular application. + * + * \note The exact APIs and availability of sub-modules within the platform driver group may vary depending on the + * target used - see individual target module documentation for the API specific to your target processor. + */ + +#ifndef __LUFA_PLATFORM_H__ +#define __LUFA_PLATFORM_H__ + + /* Includes: */ + #include "../Common/Common.h" + + /* Includes: */ + #if (ARCH == ARCH_UC3) + #include "UC3/ClockManagement.h" + #include "UC3/InterruptManagement.h" + #elif (ARCH == ARCH_XMEGA) + #include "XMEGA/ClockManagement.h" + #endif + +#endif + diff --git a/protocol/lufa/LUFA-120730/LUFA/Platform/UC3/ClockManagement.h b/protocol/lufa/LUFA-120730/LUFA/Platform/UC3/ClockManagement.h new file mode 100644 index 00000000..fb62fdcc --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Platform/UC3/ClockManagement.h @@ -0,0 +1,338 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Module Clock Driver for the AVR32 UC3 microcontrollers. + * + * Clock management driver for the AVR32 UC3 microcontrollers. This driver allows for the configuration + * of the various clocks within the device to clock the various peripherals. + */ + +/** \ingroup Group_PlatformDrivers_UC3 + * \defgroup Group_PlatformDrivers_UC3Clocks Clock Management Driver - LUFA/Platform/UC3/ClockManagement.h + * \brief Module Clock Driver for the AVR32 UC3 microcontrollers. + * + * \section Sec_Dependencies Module Source Dependencies + * The following files must be built with any user project that uses this module: + * - None + * + * \section Sec_ModDescription Module Description + * Clock management driver for the AVR32 UC3 microcontrollers. This driver allows for the configuration + * of the various clocks within the device to clock the various peripherals. + * + * Usage Example: + * \code + * #include + * + * void main(void) + * { + * // Start the master external oscillator which will be used as the main clock reference + * AVR32CLK_StartExternalOscillator(0, EXOSC_MODE_8MHZ_OR_MORE, EXOSC_START_0CLK); + * + * // Start the PLL for the CPU clock, switch CPU to it + * AVR32CLK_StartPLL(0, CLOCK_SRC_OSC0, 12000000, F_CPU); + * AVR32CLK_SetCPUClockSource(CLOCK_SRC_PLL0, F_CPU); + * + * // Start the PLL for the USB Generic Clock module + * AVR32CLK_StartPLL(1, CLOCK_SRC_OSC0, 12000000, 48000000); + * } + * \endcode + * + * @{ + */ + +#ifndef _UC3_CLOCK_MANAGEMENT_H_ +#define _UC3_CLOCK_MANAGEMENT_H_ + + /* Includes: */ + #include "../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Enum for the possible external oscillator types. */ + enum UC3_Extern_OSC_ClockTypes_t + { + EXOSC_MODE_CLOCK = AVR32_PM_OSCCTRL0_MODE_EXT_CLOCK, /**< External clock (non-crystal) mode. */ + EXOSC_MODE_900KHZ_MAX = AVR32_PM_OSCCTRL0_MODE_CRYSTAL_G0, /**< External crystal oscillator equal to or slower than 900KHz. */ + EXOSC_MODE_3MHZ_MAX = AVR32_PM_OSCCTRL0_MODE_CRYSTAL_G1, /**< External crystal oscillator equal to or slower than 3MHz. */ + EXOSC_MODE_8MHZ_MAX = AVR32_PM_OSCCTRL0_MODE_CRYSTAL_G2, /**< External crystal oscillator equal to or slower than 8MHz. */ + EXOSC_MODE_8MHZ_OR_MORE = AVR32_PM_OSCCTRL0_MODE_CRYSTAL_G3, /**< External crystal oscillator equal to or faster than 8MHz. */ + }; + + /** Enum for the possible external oscillator startup times. */ + enum UC3_Extern_OSC_ClockStartup_t + { + EXOSC_START_0CLK = AVR32_PM_OSCCTRL0_STARTUP_0_RCOSC, /**< Immediate startup, no delay. */ + EXOSC_START_64CLK = AVR32_PM_OSCCTRL0_STARTUP_64_RCOSC, /**< Wait 64 clock cycles before startup for stability. */ + EXOSC_START_128CLK = AVR32_PM_OSCCTRL0_STARTUP_128_RCOSC, /**< Wait 128 clock cycles before startup for stability. */ + EXOSC_START_2048CLK = AVR32_PM_OSCCTRL0_STARTUP_2048_RCOSC, /**< Wait 2048 clock cycles before startup for stability. */ + EXOSC_START_4096CLK = AVR32_PM_OSCCTRL0_STARTUP_4096_RCOSC, /**< Wait 4096 clock cycles before startup for stability. */ + EXOSC_START_8192CLK = AVR32_PM_OSCCTRL0_STARTUP_8192_RCOSC, /**< Wait 8192 clock cycles before startup for stability. */ + EXOSC_START_16384CLK = AVR32_PM_OSCCTRL0_STARTUP_16384_RCOSC, /**< Wait 16384 clock cycles before startup for stability. */ + }; + + /** Enum for the possible module clock sources. */ + enum UC3_System_ClockSource_t + { + CLOCK_SRC_SLOW_CLK = 0, /**< Clock sourced from the internal slow clock. */ + CLOCK_SRC_OSC0 = 1, /**< Clock sourced from the Oscillator 0 clock. */ + CLOCK_SRC_OSC1 = 2, /**< Clock sourced from the Oscillator 1 clock. */ + CLOCK_SRC_PLL0 = 3, /**< Clock sourced from the PLL 0 clock. */ + CLOCK_SRC_PLL1 = 4, /**< Clock sourced from the PLL 1 clock. */ + }; + + /* Inline Functions: */ + /** Starts the given external oscillator of the UC3 microcontroller, with the given options. This routine blocks until + * the oscillator is ready for use. + * + * \param[in] Channel Index of the external oscillator to start. + * \param[in] Type Type of clock attached to the given oscillator channel, a value from \ref UC3_Extern_OSC_ClockTypes_t. + * \param[in] Startup Statup time of the external oscillator, a value from \ref UC3_Extern_OSC_ClockStartup_t. + * + * \return Boolean \c true if the external oscillator was successfully started, \c false if invalid parameters specified. + */ + static inline bool AVR32CLK_StartExternalOscillator(const uint8_t Channel, + const uint8_t Type, + const uint8_t Startup) ATTR_ALWAYS_INLINE; + static inline bool AVR32CLK_StartExternalOscillator(const uint8_t Channel, + const uint8_t Type, + const uint8_t Startup) + { + switch (Channel) + { + case 0: + AVR32_PM.OSCCTRL0.startup = Startup; + AVR32_PM.OSCCTRL0.mode = Type; + break; + case 1: + AVR32_PM.OSCCTRL1.startup = Startup; + AVR32_PM.OSCCTRL1.mode = Type; + break; + default: + return false; + } + + AVR32_PM.mcctrl |= (1 << (AVR32_PM_MCCTRL_OSC0EN_OFFSET + Channel)); + + while (!(AVR32_PM.poscsr & (1 << (AVR32_PM_POSCSR_OSC0RDY_OFFSET + Channel)))); + return true; + } + + /** Stops the given external oscillator of the UC3 microcontroller. + * + * \param[in] Channel Index of the external oscillator to stop. + */ + static inline void AVR32CLK_StopExternalOscillator(const uint8_t Channel) ATTR_ALWAYS_INLINE; + static inline void AVR32CLK_StopExternalOscillator(const uint8_t Channel) + { + AVR32_PM.mcctrl &= ~(1 << (AVR32_PM_MCCTRL_OSC0EN_OFFSET + Channel)); + } + + /** Starts the given PLL of the UC3 microcontroller, with the given options. This routine blocks until the PLL is ready for use. + * + * \attention The output frequency must be equal to or greater than the source frequency. + * + * \param[in] Channel Index of the PLL to start. + * \param[in] Source Clock source for the PLL, a value from \ref UC3_System_ClockSource_t. + * \param[in] SourceFreq Frequency of the PLL's clock source, in Hz. + * \param[in] Frequency Target frequency of the PLL's output. + * + * \return Boolean \c true if the PLL was successfully started, \c false if invalid parameters specified. + */ + static inline bool AVR32CLK_StartPLL(const uint8_t Channel, + const uint8_t Source, + const uint32_t SourceFreq, + const uint32_t Frequency) ATTR_ALWAYS_INLINE; + static inline bool AVR32CLK_StartPLL(const uint8_t Channel, + const uint8_t Source, + const uint32_t SourceFreq, + const uint32_t Frequency) + { + if (SourceFreq > Frequency) + return false; + + switch (Source) + { + case CLOCK_SRC_OSC0: + AVR32_PM.PLL[Channel].pllosc = 0; + break; + case CLOCK_SRC_OSC1: + AVR32_PM.PLL[Channel].pllosc = 1; + break; + default: + return false; + } + + AVR32_PM.PLL[Channel].pllmul = (Frequency / SourceFreq) ? (((Frequency / SourceFreq) - 1) / 2) : 0; + AVR32_PM.PLL[Channel].plldiv = 0; + AVR32_PM.PLL[Channel].pllen = true; + + while (!(AVR32_PM.poscsr & (1 << (AVR32_PM_POSCSR_LOCK0_OFFSET + Channel)))); + return true; + } + + /** Stops the given PLL of the UC3 microcontroller. + * + * \param[in] Channel Index of the PLL to stop. + */ + static inline void AVR32CLK_StopPLL(const uint8_t Channel) ATTR_ALWAYS_INLINE; + static inline void AVR32CLK_StopPLL(const uint8_t Channel) + { + AVR32_PM.PLL[Channel].pllen = false; + } + + /** Starts the given Generic Clock of the UC3 microcontroller, with the given options. + * + * \param[in] Channel Index of the Generic Clock to start. + * \param[in] Source Clock source for the Generic Clock, a value from \ref UC3_System_ClockSource_t. + * \param[in] SourceFreq Frequency of the Generic Clock's clock source, in Hz. + * \param[in] Frequency Target frequency of the Generic Clock's output. + * + * \return Boolean \c true if the Generic Clock was successfully started, \c false if invalid parameters specified. + */ + static inline bool AVR32CLK_StartGenericClock(const uint8_t Channel, + const uint8_t Source, + const uint32_t SourceFreq, + const uint32_t Frequency) ATTR_ALWAYS_INLINE; + static inline bool AVR32CLK_StartGenericClock(const uint8_t Channel, + const uint8_t Source, + const uint32_t SourceFreq, + const uint32_t Frequency) + { + if (Channel >= AVR32_PM_GCLK_NUM) + return false; + + if (SourceFreq < Frequency) + return false; + + switch (Source) + { + case CLOCK_SRC_OSC0: + AVR32_PM.GCCTRL[Channel].pllsel = false; + AVR32_PM.GCCTRL[Channel].oscsel = 0; + break; + case CLOCK_SRC_OSC1: + AVR32_PM.GCCTRL[Channel].pllsel = false; + AVR32_PM.GCCTRL[Channel].oscsel = 1; + break; + case CLOCK_SRC_PLL0: + AVR32_PM.GCCTRL[Channel].pllsel = true; + AVR32_PM.GCCTRL[Channel].oscsel = 0; + break; + case CLOCK_SRC_PLL1: + AVR32_PM.GCCTRL[Channel].pllsel = true; + AVR32_PM.GCCTRL[Channel].oscsel = 1; + break; + default: + return false; + } + + AVR32_PM.GCCTRL[Channel].diven = (SourceFreq > Frequency) ? true : false; + AVR32_PM.GCCTRL[Channel].div = (((SourceFreq / Frequency) - 1) / 2); + AVR32_PM.GCCTRL[Channel].cen = true; + + return true; + } + + /** Stops the given generic clock of the UC3 microcontroller. + * + * \param[in] Channel Index of the generic clock to stop. + * + * \return Boolean \c true if the generic clock was sucessfully stopped, \c false if invalid parameters specified. + */ + static inline bool AVR32CLK_StopGenericClock(const uint8_t Channel) ATTR_ALWAYS_INLINE; + static inline bool AVR32CLK_StopGenericClock(const uint8_t Channel) + { + if (Channel >= AVR32_PM_GCLK_NUM) + return false; + + AVR32_PM.GCCTRL[Channel].cen = false; + + return true; + } + + /** Sets the clock source for the main microcontroller core. The given clock source should be configured + * and ready for use before this function is called. + * + * This function will configure the FLASH controller's wait states automatically to suit the given clock source. + * + * \param[in] Source Clock source for the CPU core, a value from \ref UC3_System_ClockSource_t. + * \param[in] SourceFreq Frequency of the CPU core's clock source, in Hz. + * + * \return Boolean \c true if the CPU core clock was sucessfully altered, \c false if invalid parameters specified. + */ + static inline bool AVR32CLK_SetCPUClockSource(const uint8_t Source, + const uint32_t SourceFreq) ATTR_ALWAYS_INLINE; + static inline bool AVR32CLK_SetCPUClockSource(const uint8_t Source, + const uint32_t SourceFreq) + { + if (SourceFreq > AVR32_PM_CPU_MAX_FREQ) + return false; + + AVR32_FLASHC.FCR.fws = (SourceFreq > AVR32_FLASHC_FWS_0_MAX_FREQ) ? true : false; + + switch (Source) + { + #if defined(AVR32_PM_MCCTRL_MCSEL_SLOW) + case CLOCK_SRC_SLOW_CLK: + AVR32_PM.MCCTRL.mcsel = AVR32_PM_MCCTRL_MCSEL_SLOW; + break; + #endif + #if defined(AVR32_PM_MCCTRL_MCSEL_OSC0) + case CLOCK_SRC_OSC0: + AVR32_PM.MCCTRL.mcsel = AVR32_PM_MCCTRL_MCSEL_OSC0; + break; + #endif + #if defined(AVR32_PM_MCCTRL_MCSEL_PLL0) + case CLOCK_SRC_PLL0: + AVR32_PM.MCCTRL.mcsel = AVR32_PM_MCCTRL_MCSEL_PLL0; + break; + #endif + default: + return false; + } + + return true; + } + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Platform/UC3/Exception.S b/protocol/lufa/LUFA-120730/LUFA/Platform/UC3/Exception.S new file mode 100644 index 00000000..1666323e --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Platform/UC3/Exception.S @@ -0,0 +1,128 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2011. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2011 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#if defined(__AVR32__) +#include + +.section .exception_handlers, "ax", @progbits + +// ================= EXCEPTION TABLE ================ +.balign 0x200 +.global EVBA_Table +EVBA_Table: + +.org 0x000 +Exception_Unrecoverable_Exception: + rjmp $ +.org 0x004 +Exception_TLB_Multiple_Hit: + rjmp $ +.org 0x008 +Exception_Bus_Error_Data_Fetch: + rjmp $ +.org 0x00C +Exception_Bus_Error_Instruction_Fetch: + rjmp $ +.org 0x010 +Exception_NMI: + rjmp $ +.org 0x014 +Exception_Instruction_Address: + rjmp $ +.org 0x018 +Exception_ITLB_Protection: + rjmp $ +.org 0x01C +Exception_OCD_Breakpoint: + rjmp $ +.org 0x020 +Exception_Illegal_Opcode: + rjmp $ +.org 0x024 +Exception_Unimplemented_Instruction: + rjmp $ +.org 0x028 +Exception_Privilege_Violation: + rjmp $ +.org 0x02C +Exception_Floating_Point: + rjmp $ +.org 0x030 +Exception_Coprocessor_Absent: + rjmp $ +.org 0x034 +Exception_Data_Address_Read: + rjmp $ +.org 0x038 +Exception_Data_Address_Write: + rjmp $ +.org 0x03C +Exception_DTLB_Protection_Read: + rjmp $ +.org 0x040 +Exception_DTLB_Protection_Write: + rjmp $ +.org 0x044 +Exception_DTLB_Modified: + rjmp $ +.org 0x050 +Exception_ITLB_Miss: + rjmp $ +.org 0x060 +Exception_DTLB_Miss_Read: + rjmp $ +.org 0x070 +Exception_DTLB_Miss_Write: + rjmp $ +.org 0x100 +Exception_Supervisor_Call: + rjmp $ +// ============== END OF EXCEPTION TABLE ============= + +// ============= GENERAL INTERRUPT HANDLER =========== +.balign 4 +.irp Level, 0, 1, 2, 3 +Exception_INT\Level: + mov r12, \Level + call INTC_GetInterruptHandler + mov pc, r12 +.endr +// ========= END OF GENERAL INTERRUPT HANDLER ======== + +// ====== GENERAL INTERRUPT HANDLER OFFSET TABLE ====== +.balign 4 +.global Autovector_Table +Autovector_Table: +.irp Level, 0, 1, 2, 3 + .word ((AVR32_INTC_INT0 + \Level) << AVR32_INTC_IPR_INTLEVEL_OFFSET) | (Exception_INT\Level - EVBA_Table) +.endr +// === END OF GENERAL INTERRUPT HANDLER OFFSET TABLE === + +#endif diff --git a/protocol/lufa/LUFA-120730/LUFA/Platform/UC3/InterruptManagement.c b/protocol/lufa/LUFA-120730/LUFA/Platform/UC3/InterruptManagement.c new file mode 100644 index 00000000..84e16ba2 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Platform/UC3/InterruptManagement.c @@ -0,0 +1,68 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +#include "../../Common/Common.h" +#if (ARCH == ARCH_UC3) + +#define __INCLUDE_FROM_INTMANAGEMENT_C +#include "InterruptManagement.h" + +/** Interrupt vector table, containing the ISR to call for each interrupt group */ +InterruptHandlerPtr_t InterruptHandlers[AVR32_INTC_NUM_INT_GRPS]; + +/** ISR for unhandled interrupt groups */ +ISR(Unhandled_Interrupt) +{ + for (;;); +} + +/** Retrieves the associated interrupt handler for the interrupt group currently being fired. This + * is called directly from the exception handler routine before dispatching to the ISR. + */ +InterruptHandlerPtr_t INTC_GetInterruptHandler(const uint_reg_t InterruptLevel) +{ + return InterruptHandlers[AVR32_INTC.icr[AVR32_INTC_INT3 - InterruptLevel]]; +} + +/** Initializes the interrupt controller ready to handle interrupts. This must be called at the + * start of the user program before any interrupts are registered or enabled. + */ +void INTC_Init(void) +{ + for (uint8_t InterruptGroup = 0; InterruptGroup < AVR32_INTC_NUM_INT_GRPS; InterruptGroup++) + { + InterruptHandlers[InterruptGroup] = Unhandled_Interrupt; + AVR32_INTC.ipr[InterruptGroup] = Autovector_Table[AVR32_INTC_INT0]; + } + + __builtin_mtsr(AVR32_EVBA, (uintptr_t)&EVBA_Table); +} + +#endif diff --git a/protocol/lufa/LUFA-120730/LUFA/Platform/UC3/InterruptManagement.h b/protocol/lufa/LUFA-120730/LUFA/Platform/UC3/InterruptManagement.h new file mode 100644 index 00000000..b0e1e3ec --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Platform/UC3/InterruptManagement.h @@ -0,0 +1,163 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Interrupt Controller Driver for the AVR32 UC3 microcontrollers. + * + * Interrupt controller driver for the AVR32 UC3 microcontrollers, for the configuration of interrupt + * handlers within the device. + */ + +/** \ingroup Group_PlatformDrivers_UC3 + * \defgroup Group_PlatformDrivers_UC3Interrupts Interrupt Controller Driver - LUFA/Platform/UC3/InterruptManagement.h + * \brief Interrupt Controller Driver for the AVR32 UC3 microcontrollers. + * + * \section Sec_Dependencies Module Source Dependencies + * The following files must be built with any user project that uses this module: + * - LUFA/Platform/UC3/InterruptManagement.c (Makefile source module name: LUFA_SRC_PLATFORM) + * - LUFA/Platform/UC3/Exception.S (Makefile source module name: LUFA_SRC_PLATFORM) + * + * \section Sec_ModDescription Module Description + * Interrupt controller driver for the AVR32 UC3 microcontrollers, for the configuration of interrupt + * handlers within the device. + * + * Usage Example: + * \code + * #include + * + * ISR(USB_Group_IRQ_Handler) + * { + * // USB group handler code here + * } + * + * void main(void) + * { + * INTC_Init(); + * INTC_RegisterGroupHandler(INTC_IRQ_GROUP(AVR32_USBB_IRQ), AVR32_INTC_INT0, USB_Group_IRQ_Handler); + * } + * \endcode + * + * @{ + */ + +#ifndef _UC3_INTERRUPT_MANAGEMENT_H_ +#define _UC3_INTERRUPT_MANAGEMENT_H_ + + /* Includes: */ + #include "../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Private Interface - For use in library only: */ + #if !defined(__DOXYGEN__) + /* Type Defines: */ + typedef void (*InterruptHandlerPtr_t)(void); + + /* External Variables: */ + #if defined(__INCLUDE_FROM_INTMANAGEMENT_C) + extern const void EVBA_Table; + #endif + extern InterruptHandlerPtr_t InterruptHandlers[AVR32_INTC_NUM_INT_GRPS]; + extern const uint32_t Autovector_Table[]; + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Converts a given interrupt index into its associated interrupt group. + * + * \param[in] IRQIndex Index of the interrupt request to convert. + * + * \return Interrupt group number associated with the interrupt index. + */ + #define INTC_IRQ_GROUP(IRQIndex) (IRQIndex / 32) + + /** Converts a given interrupt index into its associated interrupt line. + * + * \param[in] IRQIndex Index of the interrupt request to convert. + * + * \return Interrupt line number associated with the interrupt index. + */ + #define INTC_IRQ_LINE(IRQIndex) (IRQIndex % 32) + + /* Function Prototypes: */ + void INTC_Init(void); + InterruptHandlerPtr_t INTC_GetInterruptHandler(const uint_reg_t InterruptLevel); + + /* Inline Functions: */ + /** Registers a handler for a given interrupt group. On the AVR32 UC3 devices, interrupts are grouped by + * peripheral. To save on SRAM used, a single ISR handles all interrupt lines within a single group - to + * determine the exact line that has interrupted within the group ISR handler, use \ref INTC_GetGroupInterrupts(). + * + * If multiple interrupts with the same group are registered, the last registered handler will become the + * handler called for interrupts raised within that group. + * + * To obtain the group number of a specific interrupt index, use the \ref INTC_IRQ_GROUP() macro. + * + * \param[in] GroupNumber Group number of the interrupt group to register a handler for. + * \param[in] InterruptLevel Priority level for the specified interrupt, a \c AVR32_INTC_INT* mask. + * \param[in] Handler Address of the ISR handler for the interrupt group. + */ + static inline void INTC_RegisterGroupHandler(const uint16_t GroupNumber, + const uint8_t InterruptLevel, + const InterruptHandlerPtr_t Handler) ATTR_ALWAYS_INLINE; + static inline void INTC_RegisterGroupHandler(const uint16_t GroupNumber, + const uint8_t InterruptLevel, + const InterruptHandlerPtr_t Handler) + { + InterruptHandlers[GroupNumber] = Handler; + AVR32_INTC.ipr[GroupNumber] = Autovector_Table[InterruptLevel]; + } + + /** Retrieves the pending interrupts for a given interrupt group. The result of this function should be masked + * against interrupt request indexes converted to a request line number via the \ref INTC_IRQ_LINE() macro. To + * obtain the group number of a given interrupt request, use the \ref INTC_IRQ_GROUP() macro. + * + * \param[in] GroupNumber Group number of the interrupt group to check. + * + * \return Mask of pending interrupt lines for the given interrupt group. + */ + static inline uint_reg_t INTC_GetGroupInterrupts(const uint16_t GroupNumber) ATTR_ALWAYS_INLINE; + static inline uint_reg_t INTC_GetGroupInterrupts(const uint16_t GroupNumber) + { + return AVR32_INTC.irr[GroupNumber]; + } + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Platform/XMEGA/ClockManagement.h b/protocol/lufa/LUFA-120730/LUFA/Platform/XMEGA/ClockManagement.h new file mode 100644 index 00000000..cd9c5f49 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Platform/XMEGA/ClockManagement.h @@ -0,0 +1,397 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * \brief Module Clock Driver for the AVR USB XMEGA microcontrollers. + * + * Clock management driver for the AVR USB XMEGA microcontrollers. This driver allows for the configuration + * of the various clocks within the device to clock the various peripherals. + */ + +/** \ingroup Group_PlatformDrivers_XMEGA + * \defgroup Group_PlatformDrivers_XMEGAClocks Clock Management Driver - LUFA/Platform/XMEGA/ClockManagement.h + * \brief Module Clock Driver for the AVR USB XMEGA microcontrollers. + * + * \section Sec_Dependencies Module Source Dependencies + * The following files must be built with any user project that uses this module: + * - None + * + * \section Sec_ModDescription Module Description + * Clock management driver for the AVR USB XMEGA microcontrollers. This driver allows for the configuration + * of the various clocks within the device to clock the various peripherals. + * + * Usage Example: + * \code + * #include + * + * void main(void) + * { + * // Start the PLL to multiply the 2MHz RC oscillator to F_CPU and switch the CPU core to run from it + * XMEGACLK_StartPLL(CLOCK_SRC_INT_RC2MHZ, 2000000, F_CPU); + * XMEGACLK_SetCPUClockSource(CLOCK_SRC_PLL); + * + * // Start the 32MHz internal RC oscillator and start the DFLL to increase it to F_USB using the USB SOF as a reference + * XMEGACLK_StartInternalOscillator(CLOCK_SRC_INT_RC32MHZ); + * XMEGACLK_StartDFLL(CLOCK_SRC_INT_RC32MHZ, DFLL_REF_INT_USBSOF, F_USB); + * } + * \endcode + * + * @{ + */ + +#ifndef _XMEGA_CLOCK_MANAGEMENT_H_ +#define _XMEGA_CLOCK_MANAGEMENT_H_ + + /* Includes: */ + #include "../../Common/Common.h" + + /* Enable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + extern "C" { + #endif + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Enum for the possible external oscillator frequency ranges. */ + enum XMEGA_Extern_OSC_ClockFrequency_t + { + EXOSC_FREQ_2MHZ_MAX = OSC_FRQRANGE_04TO2_gc, /**< External crystal oscillator equal to or slower than 2MHz. */ + EXOSC_FREQ_9MHZ_MAX = OSC_FRQRANGE_2TO9_gc, /**< External crystal oscillator equal to or slower than 9MHz. */ + EXOSC_FREQ_12MHZ_MAX = OSC_FRQRANGE_9TO12_gc, /**< External crystal oscillator equal to or slower than 12MHz. */ + EXOSC_FREQ_16MHZ_MAX = OSC_FRQRANGE_12TO16_gc, /**< External crystal oscillator equal to or slower than 16MHz. */ + }; + + /** Enum for the possible external oscillator startup times. */ + enum XMEGA_Extern_OSC_ClockStartup_t + { + EXOSC_START_6CLK = OSC_XOSCSEL_EXTCLK_gc, /**< Wait 6 clock cycles before startup (external clock). */ + EXOSC_START_32KCLK = OSC_XOSCSEL_32KHz_gc, /**< Wait 32K clock cycles before startup (32.768KHz crystal). */ + EXOSC_START_256CLK = OSC_XOSCSEL_XTAL_256CLK_gc, /**< Wait 256 clock cycles before startup. */ + EXOSC_START_1KCLK = OSC_XOSCSEL_XTAL_1KCLK_gc, /**< Wait 1K clock cycles before startup. */ + EXOSC_START_16KCLK = OSC_XOSCSEL_XTAL_16KCLK_gc, /**< Wait 16K clock cycles before startup. */ + }; + + /** Enum for the possible module clock sources. */ + enum XMEGA_System_ClockSource_t + { + CLOCK_SRC_INT_RC2MHZ = 0, /**< Clock sourced from the Internal 2MHz RC Oscillator clock. */ + CLOCK_SRC_INT_RC32MHZ = 1, /**< Clock sourced from the Internal 32MHz RC Oscillator clock. */ + CLOCK_SRC_INT_RC32KHZ = 2, /**< Clock sourced from the Internal 32KHz RC Oscillator clock. */ + CLOCK_SRC_XOSC = 3, /**< Clock sourced from the External Oscillator clock. */ + CLOCK_SRC_PLL = 4, /**< Clock sourced from the Internal PLL clock. */ + }; + + /** Enum for the possible DFLL clock reference sources. */ + enum XMEGA_System_DFLLReference_t + { + DFLL_REF_INT_RC32KHZ = 0, /**< Reference clock sourced from the Internal 32KHz RC Oscillator clock. */ + DFLL_REF_EXT_RC32KHZ = 1, /**< Reference clock sourced from the External 32KHz RC Oscillator clock connected to TOSC pins. */ + DFLL_REF_INT_USBSOF = 2, /**< Reference clock sourced from the USB Start Of Frame packets. */ + }; + + /* Inline Functions: */ + /** Write a value to a location protected by the XMEGA CCP protection mechanism. This function uses inline assembly to ensure that + * the protected address is written to within four clock cycles of the CCP key being written. + * + * \param[in] Address Address to write to, a memory address protected by the CCP mechanism + * \param[in] Value Value to write to the protected location + */ + static inline void XMEGACLK_CCP_Write(volatile void* Address, const uint8_t Value) ATTR_ALWAYS_INLINE; + static inline void XMEGACLK_CCP_Write(volatile void* Address, const uint8_t Value) + { + __asm__ __volatile__ ( + "out %0, __zero_reg__" "\n\t" /* Zero RAMPZ using fixed zero value register */ + "movw r30, %1" "\n\t" /* Copy address to Z register pair */ + "out %2, %3" "\n\t" /* Write key to CCP register */ + "st Z, %4" "\n\t" /* Indirectly write value to address */ + : /* No output operands */ + : /* Input operands: */ "m" (RAMPZ), "e" (Address), "m" (CCP), "r" (CCP_IOREG_gc), "r" (Value) + : /* Clobbered registers: */ "r30", "r31" + ); + } + + /** Starts the external oscillator of the XMEGA microcontroller, with the given options. This routine blocks until + * the oscillator is ready for use. + * + * \param[in] FreqRange Frequency range of the external oscillator, a value from \ref XMEGA_Extern_OSC_ClockFrequency_t. + * \param[in] Startup Startup time of the external oscillator, a value from \ref XMEGA_Extern_OSC_ClockStartup_t. + * + * \return Boolean \c true if the external oscillator was successfully started, \c false if invalid parameters specified. + */ + static inline bool XMEGACLK_StartExternalOscillator(const uint8_t FreqRange, + const uint8_t Startup) ATTR_ALWAYS_INLINE; + static inline bool XMEGACLK_StartExternalOscillator(const uint8_t FreqRange, + const uint8_t Startup) + { + OSC.XOSCCTRL = (FreqRange | ((Startup == EXOSC_START_32KCLK) ? OSC_X32KLPM_bm : 0) | Startup); + OSC.CTRL |= OSC_XOSCEN_bm; + + while (!(OSC.STATUS & OSC_XOSCRDY_bm)); + return true; + } + + /** Stops the external oscillator of the XMEGA microcontroller. */ + static inline void XMEGACLK_StopExternalOscillator(void) ATTR_ALWAYS_INLINE; + static inline void XMEGACLK_StopExternalOscillator(void) + { + OSC.CTRL &= ~OSC_XOSCEN_bm; + } + + /** Starts the given internal oscillator of the XMEGA microcontroller, with the given options. This routine blocks until + * the oscillator is ready for use. + * + * \param[in] Source Internal oscillator to start, a value from \ref XMEGA_System_ClockSource_t. + * + * \return Boolean \c true if the internal oscillator was successfully started, \c false if invalid parameters specified. + */ + static inline uint8_t XMEGACLK_StartInternalOscillator(const uint8_t Source) ATTR_ALWAYS_INLINE; + static inline uint8_t XMEGACLK_StartInternalOscillator(const uint8_t Source) + { + switch (Source) + { + case CLOCK_SRC_INT_RC2MHZ: + OSC.CTRL |= OSC_RC2MEN_bm; + while (!(OSC.STATUS & OSC_RC2MRDY_bm)); + return true; + case CLOCK_SRC_INT_RC32MHZ: + OSC.CTRL |= OSC_RC32MEN_bm; + while (!(OSC.STATUS & OSC_RC32MRDY_bm)); + return true; + case CLOCK_SRC_INT_RC32KHZ: + OSC.CTRL |= OSC_RC32KEN_bm; + while (!(OSC.STATUS & OSC_RC32KRDY_bm)); + return true; + } + + return false; + } + + /** Stops the given internal oscillator of the XMEGA microcontroller. + * + * \param[in] Source Internal oscillator to stop, a value from \ref XMEGA_System_ClockSource_t. + * + * \return Boolean \c true if the internal oscillator was successfully stopped, \c false if invalid parameters specified. + */ + static inline bool XMEGACLK_StopInternalOscillator(const uint8_t Source) ATTR_ALWAYS_INLINE; + static inline bool XMEGACLK_StopInternalOscillator(const uint8_t Source) + { + switch (Source) + { + case CLOCK_SRC_INT_RC2MHZ: + OSC.CTRL &= ~OSC_RC2MEN_bm; + return true; + case CLOCK_SRC_INT_RC32MHZ: + OSC.CTRL &= ~OSC_RC32MEN_bm; + return true; + case CLOCK_SRC_INT_RC32KHZ: + OSC.CTRL &= ~OSC_RC32KEN_bm; + return true; + } + + return false; + } + + /** Starts the PLL of the XMEGA microcontroller, with the given options. This routine blocks until the PLL is ready for use. + * + * \attention The output frequency must be equal to or greater than the source frequency. + * + * \param[in] Source Clock source for the PLL, a value from \ref XMEGA_System_ClockSource_t. + * \param[in] SourceFreq Frequency of the PLL's clock source, in Hz. + * \param[in] Frequency Target frequency of the PLL's output. + * + * \return Boolean \c true if the PLL was successfully started, \c false if invalid parameters specified. + */ + static inline bool XMEGACLK_StartPLL(const uint8_t Source, + const uint32_t SourceFreq, + const uint32_t Frequency) ATTR_ALWAYS_INLINE; + static inline bool XMEGACLK_StartPLL(const uint8_t Source, + const uint32_t SourceFreq, + const uint32_t Frequency) + { + uint8_t MulFactor = (Frequency / SourceFreq); + + if (SourceFreq > Frequency) + return false; + + if (MulFactor > 31) + return false; + + switch (Source) + { + case CLOCK_SRC_INT_RC2MHZ: + OSC.PLLCTRL = (OSC_PLLSRC_RC2M_gc | MulFactor); + break; + case CLOCK_SRC_INT_RC32MHZ: + OSC.PLLCTRL = (OSC_PLLSRC_RC32M_gc | MulFactor); + break; + case CLOCK_SRC_XOSC: + OSC.PLLCTRL = (OSC_PLLSRC_XOSC_gc | MulFactor); + break; + default: + return false; + } + + OSC.CTRL |= OSC_PLLEN_bm; + + while (!(OSC.STATUS & OSC_PLLRDY_bm)); + return true; + } + + /** Stops the PLL of the XMEGA microcontroller. */ + static inline void XMEGACLK_StopPLL(void) ATTR_ALWAYS_INLINE; + static inline void XMEGACLK_StopPLL(void) + { + OSC.CTRL &= ~OSC_PLLEN_bm; + } + + /** Starts the DFLL of the XMEGA microcontroller, with the given options. + * + * \param[in] Source RC Clock source for the DFLL, a value from \ref XMEGA_System_ClockSource_t. + * \param[in] Reference Reference clock source for the DFLL, an value from \ref XMEGA_System_DFLLReference_t. + * \param[in] Frequency Target frequency of the DFLL's output. + * + * \return Boolean \c true if the DFLL was successfully started, \c false if invalid parameters specified. + */ + static inline bool XMEGACLK_StartDFLL(const uint8_t Source, + const uint8_t Reference, + const uint32_t Frequency) ATTR_ALWAYS_INLINE; + static inline bool XMEGACLK_StartDFLL(const uint8_t Source, + const uint8_t Reference, + const uint32_t Frequency) + { + uint16_t DFLLCompare = (Frequency / 1000); + + switch (Source) + { + case CLOCK_SRC_INT_RC2MHZ: + OSC.DFLLCTRL |= (Reference << OSC_RC2MCREF_bp); + DFLLRC2M.COMP1 = (DFLLCompare & 0xFF); + DFLLRC2M.COMP2 = (DFLLCompare >> 8); + DFLLRC2M.CTRL = DFLL_ENABLE_bm; + break; + case CLOCK_SRC_INT_RC32MHZ: + OSC.DFLLCTRL |= (Reference << OSC_RC32MCREF_gp); + DFLLRC32M.COMP1 = (DFLLCompare & 0xFF); + DFLLRC32M.COMP2 = (DFLLCompare >> 8); + + if (Reference == DFLL_REF_INT_USBSOF) + { + NVM.CMD = NVM_CMD_READ_CALIB_ROW_gc; + DFLLRC32M.CALA = pgm_read_byte(offsetof(NVM_PROD_SIGNATURES_t, USBRCOSCA)); + DFLLRC32M.CALB = pgm_read_byte(offsetof(NVM_PROD_SIGNATURES_t, USBRCOSC)); + NVM.CMD = 0; + } + + DFLLRC32M.CTRL = DFLL_ENABLE_bm; + break; + default: + return false; + } + + return true; + } + + /** Stops the given DFLL of the XMEGA microcontroller. + * + * \param[in] Source RC Clock source for the DFLL to be stopped, a value from \ref XMEGA_System_ClockSource_t. + * + * \return Boolean \c true if the DFLL was successfully stopped, \c false if invalid parameters specified. + */ + static inline bool XMEGACLK_StopDFLL(const uint8_t Source) ATTR_ALWAYS_INLINE; + static inline bool XMEGACLK_StopDFLL(const uint8_t Source) + { + switch (Source) + { + case CLOCK_SRC_INT_RC2MHZ: + DFLLRC2M.CTRL = 0; + break; + case CLOCK_SRC_INT_RC32MHZ: + DFLLRC32M.CTRL = 0; + break; + default: + return false; + } + + return true; + } + + /** Sets the clock source for the main microcontroller core. The given clock source should be configured + * and ready for use before this function is called. + * + * \param[in] Source Clock source for the CPU core, a value from \ref XMEGA_System_ClockSource_t. + * + * \return Boolean \c true if the CPU core clock was successfully altered, \c false if invalid parameters specified. + */ + static inline bool XMEGACLK_SetCPUClockSource(const uint8_t Source) ATTR_ALWAYS_INLINE; + static inline bool XMEGACLK_SetCPUClockSource(const uint8_t Source) + { + uint8_t ClockSourceMask = 0; + + switch (Source) + { + case CLOCK_SRC_INT_RC2MHZ: + ClockSourceMask = CLK_SCLKSEL_RC2M_gc; + break; + case CLOCK_SRC_INT_RC32MHZ: + ClockSourceMask = CLK_SCLKSEL_RC32M_gc; + break; + case CLOCK_SRC_INT_RC32KHZ: + ClockSourceMask = CLK_SCLKSEL_RC32K_gc; + break; + case CLOCK_SRC_XOSC: + ClockSourceMask = CLK_SCLKSEL_XOSC_gc; + break; + case CLOCK_SRC_PLL: + ClockSourceMask = CLK_SCLKSEL_PLL_gc; + break; + default: + return false; + } + + uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask(); + GlobalInterruptDisable(); + + XMEGACLK_CCP_Write(&CLK.CTRL, ClockSourceMask); + + SetGlobalInterruptMask(CurrentGlobalInt); + + Delay_MS(1); + return (CLK.CTRL == ClockSourceMask); + } + + /* Disable C linkage for C++ Compilers: */ + #if defined(__cplusplus) + } + #endif + +#endif + +/** @} */ + diff --git a/protocol/lufa/LUFA-120730/LUFA/Version.h b/protocol/lufa/LUFA-120730/LUFA/Version.h new file mode 100644 index 00000000..29b5020f --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/Version.h @@ -0,0 +1,52 @@ +/* + LUFA Library + Copyright (C) Dean Camera, 2012. + + dean [at] fourwalledcubicle [dot] com + www.lufa-lib.org +*/ + +/* + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) + + Permission to use, copy, modify, distribute, and sell this + software and its documentation for any purpose is hereby granted + without fee, provided that the above copyright notice appear in + all copies and that both that the copyright notice and this + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the + software without specific, written prior permission. + + The author disclaim all warranties with regard to this + software, including all implied warranties of merchantability + and fitness. In no event shall the author be liable for any + special, indirect or consequential damages or any damages + whatsoever resulting from loss of use, data or profits, whether + in an action of contract, negligence or other tortious action, + arising out of or in connection with the use or performance of + this software. +*/ + +/** \file + * + * \brief LUFA library version constants. + * + * Version constants for informational purposes and version-specific macro creation. This header file contains the + * current LUFA version number in several forms, for use in the user-application (for example, for printing out + * whilst debugging, or for testing for version compatibility). + */ + +#ifndef __LUFA_VERSION_H__ +#define __LUFA_VERSION_H__ + + /* Public Interface - May be used in end-application: */ + /* Macros: */ + /** Indicates the version number of the library, as an integer. */ + #define LUFA_VERSION_INTEGER 0x120730 + + /** Indicates the version number of the library, as a string. */ + #define LUFA_VERSION_STRING "120730" + +#endif + diff --git a/protocol/lufa/LUFA-120730/LUFA/makefile b/protocol/lufa/LUFA-120730/LUFA/makefile new file mode 100644 index 00000000..fcf46bf6 --- /dev/null +++ b/protocol/lufa/LUFA-120730/LUFA/makefile @@ -0,0 +1,50 @@ +# +# LUFA Library +# Copyright (C) Dean Camera, 2012. +# +# dean [at] fourwalledcubicle [dot] com +# www.lufa-lib.org +# +# --------------------------------------- +# Makefile for the LUFA library itself. +# --------------------------------------- + +LUFA_VERSION_NUM := $(shell grep LUFA_VERSION_STRING Version.h | cut -d'"' -f2) +EXCLUDE_FROM_EXPORT := Documentation DoxygenPages CodeTemplates Build *.conf *.tar *.o *.d *.lss *.lst *.hex *.elf *.hex *.eep *.map *.bin + +all: + +export_tar: + @echo Exporting LUFA library to a TAR archive... + @tar -cf LUFA_$(LUFA_VERSION_NUM).tar --directory=. $(EXCLUDE_FROM_EXPORT:%=--exclude=%) * + @tar -cf LUFA_$(LUFA_VERSION_NUM)_Code_Templates.tar CodeTemplates + @echo Export LUFA_$(LUFA_VERSION_NUM).tar complete. + +version: + @echo "LUFA $(LUFA_VERSION_NUM)" + +# Check if this is being included from a legacy or non LUFA build system makefile +ifneq ($(LUFA_PATH),) + LUFA_ROOT_PATH = $(patsubst %/,%,$(LUFA_PATH))/LUFA/ + + include $(patsubst %/,%,$(LUFA_PATH))/LUFA/Build/lufa.sources.in +else + LUFA_BUILD_MODULES += MASTER + LUFA_BUILD_TARGETS += export_tar version + + LUFA_PATH = . + ARCH = {AVR8,UC3,XMEGA} + DOXYGEN_OVERRIDE_PARAMS = QUIET=YES PROJECT_NUMBER=$(LUFA_VERSION_NUM) + + clean: + rm -f $(LUFA_SRC_ALL_FILES:%.c=%.o) + rm -f $(LUFA_SRC_ALL_FILES:%.c=%.d) + rm -f $(LUFA_SRC_ALL_FILES:%.c=%.lst) + + include Build/lufa_core.mk + include Build/lufa_sources.mk + include Build/lufa_doxygen.mk +endif + + +.PHONY: all export_tar version clean \ No newline at end of file diff --git a/protocol/lufa/LUFA-120730/README.txt b/protocol/lufa/LUFA-120730/README.txt new file mode 100644 index 00000000..aacb4af9 --- /dev/null +++ b/protocol/lufa/LUFA-120730/README.txt @@ -0,0 +1,56 @@ + + _ _ _ ___ _ + | | | | | __/ \ + | |_| U | _| o | - The Lightweight USB + |___|___|_||_n_| Framework for AVRs + ========================================= + Written by Dean Camera + dean [at] fourwalledcubicle [dot] com + + http://www.lufa-lib.org + ========================================= + + LUFA is donation supported. To support LUFA, + please donate at http://www.lufa-lib.org/donate + + Released under a modified MIT license - see + LUFA/License.txt for license details. + + For Commercial Licensing information, see + http://www.lufa-lib.org/license + + +This package contains the complete LUFA library, demos, user-submitted +projects and bootloaders for use with compatible microcontroller models. +LUFA is a simple to use, lightweight framework which sits atop the hardware +USB controller in specific AVR microcontroller models, and allows for the +quick and easy creation of complex USB devices and hosts. + +To get started, you will need to install the "Doxygen" documentation +generation tool. If you use Linux, this can be installed via the "doxygen" +package in your chosen package management tool - under Ubuntu, this can be +achieved by running the following command in the terminal: + + sudo apt-get install doxygen + +Other package managers and distributions will have similar methods to +install Doxygen. In Windows, you can download a prebuilt installer for +Doxygen from its website, www.doxygen.org. + +Once installed, you can then use the Doxygen tool to generate the library +documentation from the command line or terminal of your operating system. To +do this, open your terminal or command line to the root directory of the +LUFA package, and type the following command: + + make doxygen + +Which will recursively generate documentation for all elements in the +library - the core, plus all demos, projects and bootloaders. Generated +documentation will then be available by opening the file "index.html" of the +created Documentation/html/ subdirectories inside each project folder. + +The documentation for the library itself (but not the documentation for the +individual demos, projects or bootloaders) is also available as a separate +package from the project webpage for convenience if Doxygen cannot be +installed. + -- 2.39.3